D3 Bar Chart: Struggling to customize Date ticks


I’m losing my mind over finishing my first D3 project to visualize the US GDP bar chart (https://codepen.io/spreeni/pen/bQwoGN). I can’t get my x-axis to display just ticks for every 5 years or so. Right now it just takes the automatically chosen ticks and they’re not very pretty. Two of the test cases also keep failing, apparently

  • The bar elements’ “data-date” properties don’t match the order of the provided data
  • The data-date attribute and its corresponding bar element don’t align with the corresponding value on the x-axis.

Which implies that my scaling for my xAxis is off I guess, but I can’t find a mistake.

And for the tick problem, I have tried multiple things to costumize the ticks, including

xAxis.ticks(d3.timeYear.every(5).range(new Date(1950, 0, 1), new Date(2015, 0, 1)))

but nothing seems to work.

Would be extremely grateful for any help! :slight_smile:


Thanks for the answer, but I tried that before already. It just automatically sequences again and doesn’t let me customize it. I found solutions online, but for some reason they don’t work for my chart. All my x-values are Date types, so it should work with these functions. Down below I listed some sources I’ve checked out already, maybe someone can see sth I don’t.


This is my xScale for comparison:

const xScale = d3.scaleLinear()
			          d3.min(data, (d) => d[0]), 
				      d3.max(data, (d) => new Date(d[0]).setMonth(d[0].getMonth()+3))
                 .range([padding, w-padding]);

And this is my call for the xAxis together with some things that I tried:

const xAxis = d3.axisBottom(xScale)
				//.ticks(d3.timeYear.every(5).range(new Date(1950, 0, 1), new Date(2015, 0, 1)))

Happy about any advice!

How about using d3.scaleTime() instead of scaleLinear() ? Then .ticks(d3.timeYear.every(5)) should work.

1 Like

Thank you!! It was right in front of my eyes I guess. Now a last test doesn’t compute, it still doesn’t pass the test for

  • The bar elements’ “data-date” properties should match the order of the provided data

Any ideas? Because I can’t really find a way how that wouldn’t be the case. And I did it analog to the data-gdp value, which passes the test. Here is my code for the bars:

         .attr("x", (d) => xScale(d[0]))
         .attr("y", (d) => yScale(d[1]))
		 .attr("width", wBar)
		 .attr("height", (d) => h-padding-yScale(d[1]))
         .attr("class", "bar")
		 .attr("data-date", (d) => d[0])
		 .attr("data-gdp", (d) => d[1])

Edit: Solved it - it didn’t accept the data-date attribute as a Date object, just as a string similar to the JSON object we started with.