对于我的生活,我似乎无法找到关于如何处理这个问题的明确答案。当然,我仍然是javascript和D3的新手,但我找不到任何好的例子。
我目前正在尝试使用积分创建D3多线图。我使用平坦的JSON文件取得了相当不错的成功,但是当我的JSON数据被修改为添加额外的嵌套层时,我真的开始挣扎。
我的JSON数据文件现在看起来像这样:
{
"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"}
]
}
]
}
添加了这个额外的嵌套层,因此我可以按模型和指标进行过滤。
假设我的JSON文件中没有多个“模型”(因此完全按照上面的代码片段获取JSON)。如何针对每个指标(多线图)有效地绘制Value
和Date
?如果有人能指出我的一些工作实例,那将是一个不可思议的帮助!
答案 0 :(得分:1)
根据您的数据结构,可能的解决方案是将数据(特别是外部Data
数组)绑定到组:
var groups = svg.selectAll("foo")
.data(data.Data)
.enter()
.append("g");
使用每个内部Data
数组作为每行的数据:
var lines = groups.append("path")
.attr("d", d => lineGen(d.Data))
.attr("fill", "none")
.attr("stroke", (d, i) => colors(i));
以下是使用数据对象的演示:
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>
&#13;