JamesE February 2016

D3 multi-line chart line path not displaying: d attribute missing

I am trying to create a simple multi-line chart using JSON data similar to the following:

[
    {
        sampleDate: "2014-04-14",
        shortName: "PFOA",
        pfcLevel: "0.3500000"
    },
    {
        sampleDate: "2014-05-14",
        shortName: "PFOA",
        pfcLevel: "0.3200000"
    },
    {
        sampleDate: "2014-04-14",
        shortName: "PFOS",
        pfcLevel: "2.5000000"
    },
    {
        sampleDate: "2014-05-14",
        shortName: "PFOS",
        pfcLevel: "2.4000000"
    }
]

I have basic X and Y axis showing, but the actual value lines are not displaying. Looking at the DOM the path element is not showing the d attribute.

<path class="line" style="stroke: green;"></path>

The code is below:

<script>

  var data = <?php echo $wellSamples ?>;

  console.log(data);

  // Set the dimensions of the canvas / graph
  var margin = {top: 30, right: 20, bottom: 30, left: 50},
      width = 600 - margin.left - margin.right,
      height = 270 - margin.top - margin.bottom;

  // Parse the date / time
  var parseDate = d3.time.format("%Y-%m-%d").parse;

  // Set the ranges
  var x = d3.time.scale().range([0, width]);
  var y = d3.scale.linear().range([height, 0]);

  var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom");

  var yAxis = d3.svg.axis()
      .scale(y)
      .orient("left");

  var line = d3.svg.line()
      .interpolate("basis")
      .x(function(d) { console.log(d.sampleDate); return x(d.sampleDate); })
      .y(function(d) { console.log(d.pfcLevel); return y(d.pfcLevel); });

  var svg = d3.select("#chart").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  x.domain(d3.extent(data, function(d) { return par        

Answers


Mark February 2016

Several problems here:

  1. Your data-binding is invalid. You bind the data then call .attr("d", line), this would call the line function on each point. It needs awhole array -- .attr("d", line(data))
  2. You've made no attempt to create more then one line from that data. I'm guessing you want a line per "shortName"? You need to nest the data.
  3. Your line x accessor calls .x(function(d) { return x(d.sampleDate); }), d.sampleDate has never been converted to a date though, it's still a string.

Putting this all together:

<!DOCTYPE html>
<html>

  <head>
    <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <div id="chart"></div>
    <script>

  var data = [
    {
        sampleDate: "2014-04-14",
        shortName: "PFOA",
        pfcLevel: "0.3500000"
    },
    {
        sampleDate: "2014-05-14",
        shortName: "PFOA",
        pfcLevel: "0.3200000"
    },
    {
        sampleDate: "2014-04-14",
        shortName: "PFOS",
        pfcLevel: "2.5000000"
    },
    {
        sampleDate: "2014-05-14",
        shortName: "PFOS",
        pfcLevel: "2.4000000"
    }
];

  // Parse the date / time
  var parseDate = d3.time.format("%Y-%m-%d").parse;

  // clean up data
  data.forEach(function(d){
    d.sampleDate = parseDate(d.sampleDate);
    d.pfcLevel = +d.pfcLevel;
  });

  // nest data
  var nested_data = d3.nest()
    .key(function(d) { return d.shortName; })
    .entries(data);

  // Set the dimensions of the canvas / 

Post Status

Asked in February 2016
Viewed 1,632 times
Voted 8
Answered 1 times

Search




Leave an answer