编辑:根据下面的答案,以供将来参考,原始资料由palewire World Choropleth
我试图通过将数据源从CSV切换到JSON来重用Mike的例子。
原始数据源是通过CSV文件加载的,如下所示:
// Load external data and boot
d3.queue()
.defer(d3.json, "http://enjalot.github.io/wwsd/data/world/world-110m.geojson")
.defer(d3.csv, "mooc-countries.csv", function(d) { data.set(d.code, +d.total); })
.await(ready);
function ready(error, topo) {
if (error) throw error;
// Draw the map
svg.append("g")
.attr("class", "countries")
.selectAll("path")
.data(topo.features)
.enter().append("path")
.attr("fill", function (d){
// Pull data for this country
d.total = data.get(d.id) || 0;
// Set the color
return colorScale(d.total);
})
.attr("d", path);
}
但是我正在尝试更改第二个.defer来从JSON文件中获取数据,到目前为止,我发现它应该与此接近:
.defer(d3.json, "data.json", function(error, data) {
data.forEach(function(d) {
return {
d.code,
d.total;
};
});
})
JSON源:
[
{
"name" : "Burkina Faso",
"total" : 5,
"percent" : 0.3,
"code" : "BFA"
},
{
"name" : "Democratic Republic of the Congo",
"total" : 4,
"percent" : 0.3,
"code" : "COD"
},
{
"name" : "Haiti",
"total" : 8,
"percent" : 0.3,
"code" : "HTI"
}
]
答案 0 :(得分:1)
您未包含指向原始块的任何链接,但进行了谷歌搜索,我认为您指的是World Choropleth py浅线。将其移植为使用d3.json()
需要一些额外的步骤。
有一个全局变量data
,它是一个d3.map
:
var data = d3.map();
此词典包含从CSV提取的code
→total
映射,稍后在确定fill
时使用。如果要保留代码的一般结构,则需要从JSON输入中填写相同的值。这直接将我们引向下一个问题。
在原始代码中,此行的函数填充了地图:
.defer(d3.csv, "mooc-countries.csv", function(d) { data.set(d.code, +d.total); })
但是,重要的是要了解此功能不是处理接收到的数据集的回调。该回调是隐藏的,并由队列隐式提供。相反,这是行转换函数,它按CSV的每一行执行。这使用.set()
将每一行放入地图。遵循D3的命名约定,该函数的参数表示为d
,它引用的是单个数据而不是整个数据集。
d3.json()
不具有行转换功能,因为JSON数据本质上是分层的,而不是像CSV那样基于行的。您可以将该逻辑放在传递到.await()
的回调中:
d3.queue()
.defer(d3.json, "http://enjalot.github.io/wwsd/data/world/world-110m.geojson")
.defer(d3.json, "data.json") // No callback, just loading.
.await(ready);
function ready(error, topo, json) {
if (error) throw error;
var data = d3.map(); // Can be moved here, no need to pollute the global scope.
json.forEach(function(d) { data.set(d.code, +d.total); }); // Populate the map.
// ...business as usual
}
其余代码(例如,迁移到D3 v5和ES6)仍有很大的改进空间,但是上述操作可能是最不侵入的方式,并且将使大多数原始代码保持不变。
答案 1 :(得分:0)
您可能正在寻找的是使用所选键返回一个新数组。 forEach
内部的退货是当前的问题。也许您想退货
map
将对象数组转换为其他格式,然后返回到延迟函数
.defer(d3.json, "data.json", function(error, data) {
return data.map(function(d) {
return {
id: d.code,
total: d.total;
};
});
})