d3.js: Multiple linechart plots on one page

Yes, it’s possible. Just use the same logic you normally use to draw multiple lines/bars/points/labels/anything really, and apply it to charts. Move the logic to create a chart in the function draw and it should draw three separate line charts.

Note that I’ve changed your data type from a key-value pair to an array though, because those are easier to handle in d3. It’s not necessary, but a convenience. Otherwise, just iterate over the key-value pairs using Object.keys(signalData) to get the array ["signal1", "signal2", "signal3"] and access the underlying data as signalData[myKey]

const signalData = [
  {
    name: "Signal 1",
    data: [1,2,3,4,5,6,7],
  },
  {
    name: "Signal 2",
    data: [2,3,1,4,5,1,3],
  },
  {
    name: "Signal 3",
    data: [1,7,2,6,3,5,4],
  },
];

// This is a line generator. Normally, you pass the x- and y-scales in,
// see also d3-scale on github
const line = d3.line()
  // The first argument is always the datum object, the second is the index
  // Note that I use the index to determine the x coordinate of each point here
  .x((d, i) => i * 50)
  // And the datum object for the y-coordinate
  .y(d => 150 - (15 * d));
  
// The term `datum` is unrelated to date, but is the singular value of `data`.
// One datum, many data.

d3.select("body")
  .selectAll("svg")
  // Append one svg per array entry, look up the so-called enter, update, exit
  // cycle for this. It's the most complex part of d3
  .data(signalData)
  .enter()
  .append("svg")
  // Execute a custom function for each element. People who are new to d3.js
  // over-use this function, very often you don't need it!
  .each(function(d, i) {
    // I pass the current svg element, the datum object, and the index for convenience
    draw(d3.select(this), d, i);
  });

function draw(svg, data, index) {
  // Append a label, set the text to the name
  svg.append("text")
    .attr("x", 20)
    .attr("y", 20)
    .text(d => d.name);
  
  // Append a path, take the datum of the svg, pick it's `data` property,
  // which is the array of numbers, and set that as the datum of the path,
  // then call the line generator
  svg.append("path")
    .datum(d => d.data)
    .attr("d", line);
}
path {
  stroke: darkblue;
  stroke-width: 2px;
  fill: none;
}

svg {
  margin: 10px;
  border: solid 2px red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top