Home > OS >  d3.v5.min.js:2 Error: <path> attribute d: Expected moveto path command ('M' or '
d3.v5.min.js:2 Error: <path> attribute d: Expected moveto path command ('M' or '

Time:06-26

I am trying to plot a multi-line graph with d3.js but I am getting this error:

Error: attribute d: Expected moveto path command ('M' or 'm'), "function t(t){va…".

I have been stuck at it a while now and tried everything I could think of, to help you in your reflections, Find the code that I use below.

// set the dimensions and margins of the graph
var margin = {top: 10, right: 30, bottom: 30, left: 60},
width = 460 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;

const dateParser = d3.timeFormat("%Y-%m-%d %H:%M:%S");

data.forEach(function(d) {
    d.ts = dateParser(new Date(d.ts));
    d.value = parseFloat(d.value)
});


// append the svg object to the body of the page
var svg = d3.select("#graph")
.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   ")");

//Read the data

  // group the data: I want to draw one line per group
  var sumstat = d3.nest() // nest function allows to group the calculation per level of a factor
.key(function(d) { return d.key;})
.entries(data);

 // Add X axis --> it is a date format
  var x = d3.scaleLinear()
.domain(d3.extent(data, function(d) { return d.ts; }))
.range([ 0, width ]);
  svg.append("g")
.attr("transform", "translate(0,"   height   ")")
.call(d3.axisBottom(x).ticks(5));

 // Add Y axis
 var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return  d.value; })])
.range([ height, 0 ]);
 svg.append("g")
.call(d3.axisLeft(y));

// color palette
var res = sumstat.map(function(d){ return d.key }) // list of group names
var color = d3.scaleOrdinal()
.domain(res).range(['#e41a1c','#377eb8','#4daf4a','#984ea3','#ff7f00','#ffff33','#a65628','#f781bf','#999999'])

 // Draw the line
 svg.selectAll(".line")
  .data(sumstat)
  .enter()
  .append("path")
    .attr("fill", "none")
    .attr("stroke", function(d){ return color(d.key) })
    .attr("stroke-width", 1.5)
    .attr("d", function(d){
      return d3.line()
        .x(function(d) { return x(d.ts); })
        .y(function(d) { return y(d.value); })
    })

I cannot figure what I am doing wrong, in case the example I am looking at is this link. I am fairly new to d3 and it is not an easy library to use

CodePudding user response:

When you set the d attribute, you return the line generator itself from the data linking function, but you fail to execute it. Configuring the generator and executing it is a two-step process:

  • first, contruct and configure the generator (line is a function)

    var line = d3.line()
      .x(function(d) { return x(d.ts); })
      .y(function(d) { return y(d.value); })
    
  • then, pass the function to attr(), so it will be executed as line(d)

    svg.selectAll(".line")
      .data(sumstat)
      .enter()
      .append("path")
        .attr("fill", "none")
        .attr("stroke", function(d){ return color(d.key) })
        .attr("stroke-width", 1.5)
        .attr("d", line)
    
  • Related