简体   繁体   中英

Creating a D3 Line Graph with Points using 2 Level Nested JSON

For the life of me, I can't seem to find a clear answer on how to handle this. Granted, I'm still pretty new to javascript and D3, but I can't find any good examples.

I am currently trying to create a D3 multi-line graph with points. I've had some pretty good success with a flat JSON file, but when my JSON data was modified to add an additional layer of nesting, I really began to struggle.

My JSON data file now looks something like this:

{
    "Model": "Model A", 
    "Data": [
        {
            "Metric": "Metric 1", 
            "Data": [
                    {"Date":"2017-2-25", "Value": "34"}, 
                    {"Date":"2017-2-26", "Value": "52"},
                    {"Date":"2017-2-27", "Value": "47"},
                    {"Date":"2017-2-28", "Value": "50"}
             ]
        }, 
        {
            "Metric": "Metric 2", 
            "Data": [
                    {"Date":"2017-2-25", "Value": "22"}, 
                    {"Date":"2017-2-26", "Value": "27"},
                    {"Date":"2017-2-27", "Value": "25"},
                    {"Date":"2017-2-28", "Value": "21"}
             ]
        }, 
        {
            "Metric": "Metric 3", 
            "Data": [
                    {"Date":"2017-2-25", "Value": "27"}, 
                    {"Date":"2017-2-26", "Value": "28"},
                    {"Date":"2017-2-27", "Value": "25"},
                    {"Date":"2017-2-28", "Value": "22"}
             ]
        }
    ]
} 

This extra nested layer was added so I could filter by model and metric.

Assuming I do not have multiple "Models" in my JSON file (so taking the JSON exactly as it is from the above snippet). How do I effectively plot Value and Date per metric (multi-line chart)? If anyone could point me to some working examples as well, that would be an incredible help!

Given your data structure, a possible solution is binding the data (specifically the outer Data array) to groups:

var groups = svg.selectAll("foo")
    .data(data.Data)
    .enter()
    .append("g");

And using each inner Data array as the data to each line:

var lines = groups.append("path")
    .attr("d", d => lineGen(d.Data))
    .attr("fill", "none")
    .attr("stroke", (d, i) => colors(i));

Here is a demo using your data object:

 var data = { "Model": "Model A", "Data": [{ "Metric": "Metric 1", "Data": [{ "Date": "2017-2-25", "Value": "34" }, { "Date": "2017-2-26", "Value": "52" }, { "Date": "2017-2-27", "Value": "47" }, { "Date": "2017-2-28", "Value": "50" }] }, { "Metric": "Metric 2", "Data": [{ "Date": "2017-2-25", "Value": "22" }, { "Date": "2017-2-26", "Value": "27" }, { "Date": "2017-2-27", "Value": "25" }, { "Date": "2017-2-28", "Value": "21" }] }, { "Metric": "Metric 3", "Data": [{ "Date": "2017-2-25", "Value": "27" }, { "Date": "2017-2-26", "Value": "28" }, { "Date": "2017-2-27", "Value": "25" }, { "Date": "2017-2-28", "Value": "22" }] }] }; var width = 500, height = 300; var colors = d3.scaleOrdinal(d3.schemeCategory10); var svg = d3.select("body") .append("svg") .attr("width", width) .attr("height", height); var parse = d3.timeParse("%Y-%m-%d"); var xScale = d3.scaleTime() .range([30, width - 20]) .domain(d3.extent(data.Data[0].Data, d => parse(d.Date))); var yScale = d3.scaleLinear() .range([height - 20, 20]) .domain([0, 60]); var lineGen = d3.line() .x(d => xScale(parse(d.Date))) .y(d => yScale(d.Value)); var groups = svg.selectAll("foo") .data(data.Data) .enter() .append("g"); var lines = groups.append("path") .attr("d", d => lineGen(d.Data)) .attr("fill", "none") .attr("stroke", (d, i) => colors(i)); var gX = svg.append("g").attr("transform", "translate(0," + (height - 20) + ")").call(d3.axisBottom(xScale)); var gY = svg.append("g").attr("transform", "translate(30,0)").call(d3.axisLeft(yScale)); 
 <script src="https://d3js.org/d3.v4.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM