Skip to content Skip to sidebar Skip to footer

Drawing Multiple Sets Of Multiple Lines On A D3.js Chart

I have a d3 chart that displays two lines showing a country's imports and exports over time. It works fine, and uses the modular style described in 'Developing a D3.js Edge' so tha

Solution 1:

The key to achieving what you want are nested selections. You first bind the entire data to the SVG element, then add a group for each group in the data (each country), and finally get the values for each line from the data bound to the group. In code, it looks like this (I've simplified the real code here):

var svg = d3.select(this)
              .selectAll('svg')
              .data([data]);

  var g = svg.enter().append('svg').append('g');

  varinner = g.selectAll("g.lines").data(function(d) { return d; });
  inner.enter().append("g").attr("class", "lines");

  inner.selectAll("path.line.imports").data(function(d) { return [d.values]; })
      .enter().append("path").attr('class', 'line imports')
      .attr("d", function(d) { return imports_line(d); });

The structure generated by this looks like svg > g > g.lines > path.line.imports. I've omitted the code for the export line here -- that would be below g.lines as well. Your data consists of a list of key-value pairs with a list as value. This is mirrored by the SVG structure -- each g.lines corresponds to a key-value pair and each path to the value list.

Complete demo here.

Solution 2:

The point is that you're thinking to imperative. That's why you have so much code. I really can't put it better than Mike Bostock, you have to start Thinking with Joins:

svg.append("circle")
    .attr("cx", d.x)
    .attr("cy", d.y)
    .attr("r", 2.5);

But that’s just a single circle, and you want many circles: one for each data point. Before you bust out a for loop and brute-force it, consider this mystifying sequence from one of D3’s examples.

Here data is an array of JSON objects with x and y properties, such as: [{"x": 1.0, "y": 1.1}, {"x": 2.0, "y": 2.5}, …].

svg.selectAll("circle")
    .data(data)
  .enter().append("circle")
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .attr("r", 2.5);

I'll leave translating this example to the "from one line to many lines" as an excerxise.

Post a Comment for "Drawing Multiple Sets Of Multiple Lines On A D3.js Chart"