问题
I am new to d3 but I have set the tick interval for my x-axis to every 7 days using d3.timeDay.every(7)
. However when my graph is created, I also see a tick mark added for the first of every month. For example, my graph shows ticks at 10/1, 10/8, 10/15, 10/22, 10/29, and 11/1, even though 11/1 is not 7 days after 10/29. If I expand this range to include multiple months, I see a tick at the first of every month.
I have included my code for this axis below. What might be causing the first of each month to be displayed as a tick?
const xScale = d3.scaleTime().range([0, innerWidth]);
const tickAmount = d3.timeDay.every(7);
chart.append("g")
.classed('x-axis', true)
.attr("transform", "translate(0," + innerHeight + ")")
.call(d3.axisBottom(xScale)
.ticks(tickAmount)
.tickSize(-innerHeight)
.tickFormat(d3.timeFormat('%m/%d/%y')));
回答1:
Try const tickAmount = d3.timeWeek.every(1);
instead:
Note that for some intervals, the resulting dates may not be uniformly-spaced; d3.timeDay’s parent interval is d3.timeMonth, and thus the interval number resets at the start of each month. If step is not valid, returns null. If step is one, returns this interval. from the d3 docs
You can also use .tickFormat(function(d, i) { return d; })
to filter out given ticks from display if you like (e.g. exclude first tick: return i>0 ? d : ''
), though this is more hacky.
Found a better way to do this from d3 issue tracker:
d3.axisBottom(x)
.ticks(d3.timeDay.filter(d=>d3.timeDay.count(0, d) % N === 0))
.tickFormat(d3.timeFormat('%m/%d/%y'))
.tickSizeOuter(0)
This will give you consistent ticks every N-th day without the months repeating. That a tick exists does not mean a point exists at that date in your dataset, but they are scaled correctly over the date range.
Here's a demo: https://beta.observablehq.com/@thmsdnnr/d3-ticks-every-7-or-10-days
来源:https://stackoverflow.com/questions/49178363/why-does-my-d3-charts-x-axis-include-the-first-of-every-month-as-a-tick-even-th