d3 line generator returning null rather than path data string

Tags: , ,



I’m using d3 v4 to create a line graph. My pathGenerator, using d3’s line() method, is returning null instead of a path data string (eg “M 100 100 L 300 100 L 200 300 z”), and therefore no lines are being drawn.

When I add in console.log()s to try to determine where the issue occurs, the passed in datum appears correctly as an object with percentLoad and efficiency keys with valid numbers as their values. Console.log()s within the .x() and .y() methods do not seem to be invoked, but I’m not sure why this would be.

const xScale = d3.scaleLinear()
    .domain([10, 100])
    .range([0, chartAreaWidth])

const yScale = d3.scaleLinear()
    .domain([0, 2])
    .range([chartAreaHeight, 0])

const pathGenerator = d3.line()
    .x(d => xScale(d.percentLoad))
    .y(d => yScale(d.efficiency))
    .curve(d3.curveCardinal);

const binGroups = chartGroup.selectAll('.binGroups')
    .data(data.bins)
    .enter().append('g')
    .attr('class', (d,i) => 'binGroups binGroup' + i)

binGroups.selectAll('.percentLoads')
    .data(d => d)
    .enter().append('path')
    .attr('class', (d,i) => 'percentLoads percentLoad' + i)
    .attr('d', d => pathGenerator(d))

Answer

d3.line generator expects an array of data to generate a line. As mentioned in the docs:

line(data): Generates a line for the given array of data.

In your case, data.bins looks like an array so take a look at a sample curve generated using pathGenerator function from your code and a few sample bins.

Snippet:

var data = {
	bins: [
  	{ percentLoad: 30, efficiency: 1.4},
  	{ percentLoad: 60, efficiency: 0.3},
  	{ percentLoad: 90, efficiency: 1}    
  ]
}

const xScale = d3.scaleLinear()
    .domain([10, 100])
    .range([0, 400])

const yScale = d3.scaleLinear()
    .domain([0, 2])
    .range([200, 0])

const pathGenerator = d3.line()
    .x(d => xScale(d.percentLoad))
    .y(d => yScale(d.efficiency))
    .curve(d3.curveCardinal);

const path = d3.select('svg').append('path').style('fill','none').style('stroke', 'steelblue')
    .attr('d', pathGenerator(data.bins));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.0.0/d3.min.js"></script>
<svg width="400" height="200"></svg>

Hope this helps.



Source: stackoverflow