使用 D3 使用 JSON 数据填充现有 SVG 元素
populating existing SVG elements with JSON data using D3
我想要实现的是一个 SVG,它有几个独立的多边形,可以根据一组 JSON 数据进行着色。我快到了,但是在以正确的顺序将数据对象与 SVG 元素匹配时遇到了问题。
我创建了一个 SVG,它有几个多边形,例如
<polygon id="Zone2" fill="#DFECC5" stroke="#000000" stroke-miterlimit="10" points="828.815,660.425 841.261,594.05 842.82,594.422 849.014,564.644 837.769,562.306 841.108,546.883 851.945,549.118 866.75,474.55 837.799,468.253 837.254,470.748 833.572,470.097 833.982,467.844 817.591,463.942 818.746,458.473 875.479,470.067 838.604,655.601 837.24,662.395 " style="fill: rgb(244, 246, 252);"><title>Car Park South, 1230</title></polygon>
这是我正在解析的 JSON 文件:
{
"zoneData":[
{"zoneID":"Zone1","name":"Car Park South", "value":1230},
{"zoneID":"Zone2","name":"Outdoor North", "value":3453},
{"zoneID":"Zone3","name":"Outdoor West", "value":2342},
{"zoneID":"Zone4","name":"Outdoor South", "value":3453},
{"zoneID":"Zone5","name":"High St. East", "value":1023},
{"zoneID":"Zone6","name":"High St. West", "value":2322},
{"zoneID":"Zone7","name":"Car Park North", "value":4562},
{"zoneID":"Zone8","name":"Indoor North", "value":5644},
{"zoneID":"Zone9","name":"Indoor South", "value":2356}
]
}
我已经设法解析所有内容并创建合适的色标,甚至使用该色标为每个多边形设置颜色,但它们的顺序错误。脚本在这里:
d3.json("zoneAnalysisData.json", function(error, data) {
var minDataValue = d3.min(data.zoneData, function(d) { return d.value; })
var maxDataValue = d3.max(data.zoneData, function(d) { return d.value; })
var color = d3.scale.linear()
.domain([minDataValue, maxDataValue])
.range(["#ffffff", "#0038c5"]);
d3.selectAll("[id*='Zone']")
.data(data.zoneData)
.style("fill", function(d){
return color(d.value);
})
.append("title")
.text(function(d) {
return d.name + "\n" + d.value;
});
});
我查看了 selections and thinking with joins 上的文档,但无法弄清楚如何将我选择的现有元素与 JSON 数据数组元素相匹配。
问题是您需要按特定顺序选择多边形,.selectAll()
无法保证这一点。您也不能轻易地重新排序它们,因为 D3 的 .sort()
方法适用于当时尚未绑定到元素的数据。
解决此问题的一种方法是 "attach" 将一些数据手动添加到允许匹配元素和数据的元素中。那么你只需要一个关键功能:
d3.selectAll("[id*='Zone']")
.each(function() { this.__data__ = { zoneID: this.id })
.data(data.zoneData, function(d) { return d.zoneID; })
...
这里的第二行模仿 D3 内部所做的并创建 D3 在尝试查找绑定数据时查找的属性。
我想要实现的是一个 SVG,它有几个独立的多边形,可以根据一组 JSON 数据进行着色。我快到了,但是在以正确的顺序将数据对象与 SVG 元素匹配时遇到了问题。
我创建了一个 SVG,它有几个多边形,例如
<polygon id="Zone2" fill="#DFECC5" stroke="#000000" stroke-miterlimit="10" points="828.815,660.425 841.261,594.05 842.82,594.422 849.014,564.644 837.769,562.306 841.108,546.883 851.945,549.118 866.75,474.55 837.799,468.253 837.254,470.748 833.572,470.097 833.982,467.844 817.591,463.942 818.746,458.473 875.479,470.067 838.604,655.601 837.24,662.395 " style="fill: rgb(244, 246, 252);"><title>Car Park South, 1230</title></polygon>
这是我正在解析的 JSON 文件:
{
"zoneData":[
{"zoneID":"Zone1","name":"Car Park South", "value":1230},
{"zoneID":"Zone2","name":"Outdoor North", "value":3453},
{"zoneID":"Zone3","name":"Outdoor West", "value":2342},
{"zoneID":"Zone4","name":"Outdoor South", "value":3453},
{"zoneID":"Zone5","name":"High St. East", "value":1023},
{"zoneID":"Zone6","name":"High St. West", "value":2322},
{"zoneID":"Zone7","name":"Car Park North", "value":4562},
{"zoneID":"Zone8","name":"Indoor North", "value":5644},
{"zoneID":"Zone9","name":"Indoor South", "value":2356}
]
}
我已经设法解析所有内容并创建合适的色标,甚至使用该色标为每个多边形设置颜色,但它们的顺序错误。脚本在这里:
d3.json("zoneAnalysisData.json", function(error, data) {
var minDataValue = d3.min(data.zoneData, function(d) { return d.value; })
var maxDataValue = d3.max(data.zoneData, function(d) { return d.value; })
var color = d3.scale.linear()
.domain([minDataValue, maxDataValue])
.range(["#ffffff", "#0038c5"]);
d3.selectAll("[id*='Zone']")
.data(data.zoneData)
.style("fill", function(d){
return color(d.value);
})
.append("title")
.text(function(d) {
return d.name + "\n" + d.value;
});
});
我查看了 selections and thinking with joins 上的文档,但无法弄清楚如何将我选择的现有元素与 JSON 数据数组元素相匹配。
问题是您需要按特定顺序选择多边形,.selectAll()
无法保证这一点。您也不能轻易地重新排序它们,因为 D3 的 .sort()
方法适用于当时尚未绑定到元素的数据。
解决此问题的一种方法是 "attach" 将一些数据手动添加到允许匹配元素和数据的元素中。那么你只需要一个关键功能:
d3.selectAll("[id*='Zone']")
.each(function() { this.__data__ = { zoneID: this.id })
.data(data.zoneData, function(d) { return d.zoneID; })
...
这里的第二行模仿 D3 内部所做的并创建 D3 在尝试查找绑定数据时查找的属性。