我正在尝试编写一个通用地图,以便任何新的csv都会改变数据可视化。我能够绘制地图,将csv与geojson连接,甚至在鼠标悬停时打印csv数据。但是,当我尝试使用此数据将颜色应用于地图时,我一直undefined
- 我想是由于 js 的异步性质。如何最有效地解决这个问题?
这是我的代码:
// Community colors
var comm_colors = [ "red", "blue", "green", "yellow", "purple" ];
// CSV
function parse_add_csv(cts){
var new_cts = cts
console.log('parsing csv');
d3.csv("data/communities.csv", function(comms)
{ csv = comms.map(function(d)
{
return {"community": d.community, "label": d.BoroCT2010} ;
})
csv.forEach(function(d, i) {
new_cts.forEach(function(e, j) {
if (d.label === e.properties.BoroCT2010) {
e.properties.community = parseInt(d.community)
}
})
})
})
return new_cts
}
d3.json("data/nyct2010_17a3_topo.json", function(error, nyb) {
console.log('tracts uploaded, v3')
var ctss = topojson.feature(nyb, nyb.objects.nyct2010_17a3).features;
ctss = parse_add_csv(ctss); // match data from csv by BoroCT2010
cts.selectAll(".tract")
.data(ctss)
.enter().append("path")
.attr("class", "tract")
.attr("d", path)
.attr("id", function(d) {
return d.properties.BoroCT2010;})
.attr("nhd_name", function(d) {
return d.properties.NTAName;})
.style('fill', function(d){
console.log(comm_colors[d.properties.community])
return comm_colors[d.properties.community];})
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut)
.style('fill', function(d) {return
comm_colors[d.properties.community]});
})
在这里,我正在尝试将csv中的社区列与geojson匹配,然后使用它从列表中选择一种颜色。当我在鼠标悬停事件中打印颜色时,它可以完美运行,但在链中不起作用:
.style('fill', function(d){
console.log(comm_colors[d.properties.community])
return comm_colors[d.properties.community];})
你的猜测只是部分正确:
我一直未定义 - 我想是由于 js 的异步性质。
没有"js的异步性质"。JavaScript 始终是同步和单线程的。但是,AJAX 调用和 D3 函数(如 d3.json
和 d3.csv
(是异步的。
话虽如此,有几个解决方案。您可以使用 d3.queue。但是,最简单的解决方案是简单地嵌套异步函数:
d3.json("data/nyct2010_17a3_topo.json", function(error, nyb){
d3.csv("data/communities.csv", function(comms){
//here goes all code that uses both 'nyb' and 'comms'
})
})
嵌套它们后,将所有处理 GeoJSON 和 CSV 的代码放在内部回调中。