Reputation: 101
I am creating a chart that has daily data for some number of sequential days. Each object in the data array has a date property, which is that day's JavaScript Date representation at midnight. Here is the relevant code:
const x = d3.scaleTime()
.range([0, width])
.domain(d3.extent(data.map(d => d.date)));
const days = data.length;
let interval = 1;
while (width / (days - 1) * interval < 60) {
interval += 1;
}
const xAxis = d3.axisBottom(x)
.tickFormat(d3.timeFormat('%b %d'))
.ticks(d3.timeDay.every(interval));
The problem is that d3.timeDay.every(interval) resets at the start of each month. The d3 docs clearly point this out, so it is not a bug.
Unfortunately, it leads to ticks and labels that are too close together when dates cross month boundaries.
Is there a way to make the X axis (which is a scaleTime) create ticks every interval days regardless of month boundaries?
Upvotes: 2
Views: 2928
Reputation: 101
OK, asking the question made me focus. I found an answer. I needed to provide my own tick values. This worked:
const xValues = data.filter((d, i) => i % interval === 0).map(d => d.date);
const xAxis = d3.axisBottom(x)
.tickFormat(d3.timeFormat('%b %d'))
// .ticks(d3.timeDay.every(interval))
.tickValues(xValues);
I am beginner with d3 and would welcome a better answer.
Upvotes: 4