Knocktorius Maxima
Knocktorius Maxima

Reputation: 371

D3.js Trendline x-axis date

Want to build a trendline similar to what Mike Bostock did.

There's a difference in the dataset: on the first column, mine has a number which represents the year (2000) and Mike has a date (24-Apr-07).

The result I'm getting is the following: enter image description here

Goal: I want the x axis to show the years.

Problem: For some weird reason, it's showing some other numbers.

Action:

.index.html:

<!DOCTYPE html>
<title>Plotting a Trendline with D3.js</title>
<svg width="960" height="500"></svg>
<script src="d3.v4.min.js"></script>
<script>

var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 50},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom,
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var parseTime = d3.timeParse("%y");

var x = d3.scaleTime()
    .rangeRound([0, width]);

var y = d3.scaleLinear()
    .rangeRound([height, 0]);

var line = d3.line()
    .x(function(d) { return x(d.ano); })
    .y(function(d) { return y(d.total); });

d3.tsv("data.tsv", function(d) {
  d.ano = d.ano;
  d.total = +d.total;
  return d;
}, function(error, data) {
  if (error) throw error;

  x.domain(d3.extent(data, function(d) { return d.ano; }));
  y.domain(d3.extent(data, function(d) { return d.total; }));

  g.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x))
    .select(".domain")
      .remove();

  g.append("g")
      .call(d3.axisLeft(y))
    .append("text")
      .attr("fill", "#000")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", "0.71em")
      .attr("text-anchor", "end")
      .text("Numero de acidentes mortais");

  g.append("path")
      .datum(data)
      .attr("fill", "none")
      .attr("stroke", "steelblue")
      .attr("stroke-linejoin", "round")
      .attr("stroke-linecap", "round")
      .attr("stroke-width", 1.5)
      .attr("d", line);
});

</script>

.data.tsv:

ano total
2000    368
2001    365
2002    357
2003    312
2004    306
2005    300
2006    253
2007    276
2008    231
2009    217
2010    208
2011    196
2012    175
2013    160

What can i do to solve this?

Upvotes: 2

Views: 579

Answers (1)

Mikhail Shabrikov
Mikhail Shabrikov

Reputation: 8509

Just change your time parsing function (you should use Y in uppercase):

var parseTime = d3.timeParse("%Y");

Working demo (I hardcoded tsv data to simplify example):

  var dataAsTsv = `ano	total
2000	368
2001	365
2002	357
2003	312
2004	306
2005	300
2006	253
2007	276
2008	231
2009	217
2010	208
2011	196
2012	175
2013	160`;

var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 50},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom,
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var parseTime = d3.timeParse("%Y");

var x = d3.scaleTime()
    .rangeRound([0, width]);

var y = d3.scaleLinear()
    .rangeRound([height, 0]);

var line = d3.line()
    .x(function(d) { return x(d.ano); })
    .y(function(d) { return y(d.total); });

function processData(d) {
  d.ano = parseTime(d.ano);
  d.total = +d.total;
  return d;
};

var data = d3.tsvParse(dataAsTsv, processData);

x.domain(d3.extent(data, function(d) { return d.ano; }));
y.domain(d3.extent(data, function(d) { return d.total; }));

g.append("g")
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(x))
  .select(".domain")
  .remove();

g.append("g")
  .call(d3.axisLeft(y))
  .append("text")
  .attr("fill", "#000")
  .attr("transform", "rotate(-90)")
  .attr("y", 6)
  .attr("dy", "0.71em")
  .attr("text-anchor", "end")
  .text("Numero de acidentes mortais");

g.append("path")
  .datum(data)
  .attr("fill", "none")
  .attr("stroke", "steelblue")
  .attr("stroke-linejoin", "round")
  .attr("stroke-linecap", "round")
  .attr("stroke-width", 1.5)
  .attr("d", line);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.2/d3.min.js"></script>
<svg width="960" height="500"></svg>

Upvotes: 2

Related Questions