2
votes

Using d3 I want to draw several time series line charts on a single page, each one featuring two lines.

Using the example on this page for multiple charts, I've got code working with single lines on each chart. But I'm not sure how best to modify that example to work with multi-line charts.

The example does this:

d3.csv("sp500.csv", function(data) {
  var formatDate = d3.time.format("%b %Y");

  d3.select("#example")
      .datum(data)
    .call(timeSeriesChart()
      .x(function(d) { return formatDate.parse(d.date); })
      .y(function(d) { return +d.price; }));
});

with TimeSeriesChart() defined in this file.

How would I best adapt this to cope with two (or more) lines (with the same x-axis values, and the same y scales)?

FWIW, my data is in JS arrays/hashes, rather than being read from CSV, but I guess the principle will be the same.

1
have you taken a look at this example of multiseries line charts: bl.ocks.org/mbostock/3884955rysloan
Yes, thanks. I'm currently trying to make that work for multiple charts on one page, which might be a simpler approach than the other way round... Not quite there yet...Phil Gyford

1 Answers

1
votes

You can pass in your data structure that contains data for several lines in the same way. The only difference would in how you would handle the data in the referenced file. You need to change the function in

selection.each(function(data) {

First, you need to adapt the preprocessing being done and similarly the code that determines the limits of the axes. Further down, you would change

// Update the line path.
  g.select(".line")
      .attr("d", line); 

to something like

g.selectAll(".line").data(<data for your two lines here>)
 .enter()
 .append("path")
 .attr("class", "line")
 .attr("d", line);

and remove the line

gEnter.append("path").attr("class", "line");

before that.

The exact changes will depend on the format that you're passing in.

An alternative (and if you're just starting probably easier) approach would be to simply add the additional data in a new attribute, add a new line generator that accesses that data and repeat the code that generates the line and calls the line generator with a different class name and the different generator. This is a hacky approach that I wouldn't recommend in general, but it might be easier to get started that way.