Accepted answer

As been mentioned before JSON data already returns years as years (as numbers). No parsing required. But d3.format required for tickFormat.

1.xScale.domain becomes:

xScale.domain(d3.extent(data, d => 

.attr("cx", d =>

2.tickFormat therefore:



Make sure the type of your data.year is a javascript date data type. Add the for loop shown below...

//Fetch data using promises
d3.json("").then(data => {

// ADD THIS after the line above!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
for(var i = 0; i < data.length; i++)
    data[i].year = new Date(data[i].year, 1, 1);


Your JSON data (from the CodePen) already returns years as years i.e. don't need to format them. And anyway your dateFormat function expects a full date, it can't deal with just a year.

Just remove the dateFormat function and all references to it, and you will get the result you expected.

Here's an updated, working codePen:


d3.timeParse is what you're looking for.

As the data consists just the year as numbers, you have to parse it to full dates using d3.timeParse. Here's how:

  1. Define a parser: let parseDate = d3.timeParse("%Y")
  2. Parse the data based on the above:

    data.forEach(function (d) {
      d.year = parseDate(d.year);
  3. And the tickFormat would change to: .tickFormat(d => d.getFullYear()) (Date.getFullYear) as you're trying to just print the years.

    Here's a fork of your codepen:

Hope this helps.

Related Query

More Query from same tag