0

I'm new with d3js and am trying to plot a line from an array nested in a JSON. Few questions on the topic have already been asked but their solutions don't work for my specific problem (maybe it's just me being a total novice though).

The JSON file (json_data.json) in question is this:

{"Test": 1, 
 "Name": "SampleA", 
 "Voltage": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], 
 "Current": [-0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5]}

"Voltage" and "Current" are the x and y values I want to plot with this js:

var margin = {top: 50, right: 50, bottom: 50, left: 50},
    width = 800 - margin.left - margin.right,
    height = 600 - margin.top - margin.bottom;

var xScale = d3.scaleLinear().range([0, width]);
var yScale = d3.scaleLinear().range([height, 0]);

var xAxis = d3.axisBottom().scale(xScale);
var yAxis = d3.axisLeft().scale(yScale);

var line = d3.line()
    .x(function(d,i){return d.Voltage[i]; } )
    .y(function(d,i){return d.Current[i]; } );

var svg = d3.select("body")
    .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 + ")");

d3.json("json_data.json", function(data) {

xScale.domain(d3.extent(data.Voltage));
yScale.domain(d3.extent(data.Current));

svg.append("path")     
    .attr("d", line(data))

svg.append("g")       
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

svg.append("g")        
    .attr("class", "y axis")
    .call(yAxis);

});

The problem is that for some reason the line chart is not displayed. The axes are shown with the correct scale which makes me think there must be an issue with the line() generator. The JSON and the nested arrays show up when I run console.log.

I'd really appreciate your help! And if you have any suggestions on how to improve my code or JSON structure I'm listening :) Thanks a lot!

1 Answer 1

1

d3.line "generates a line for the given array of data" (https://github.com/d3/d3-shape#_line).

So I would create an array of points, such as:

let lineData = []
let lineDataLength = data.Voltage.length;

for (var i = 0; i < lineDataLength; i++) {
      let point = {};
      point.x = data.Voltage[i];
      point.y = data.Current[i];
      lineData.push(point);
};

Then for the line generator simplify to:

var line = d3.line()
    .x(function(d,i){return xScale(d.x); } )
    .y(function(d,i){return yScale(d.y); } );
Sign up to request clarification or add additional context in comments.

2 Comments

This fixed it for me, thanks a lot! My plan was to build a larger JSON file with many samples, in which case I'd need to plot multiple lines in the same graph. Would you create an array of points for each line or would you structure the JSON array in a different way?
There's more considerations that what would be desirable in a Stackoverflow comment. For me, the less I can do client side the better, especially once datasets grow large

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.