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.