gpt4 book ai didi

javascript - D3 TOPOJSON map 加载后如何运行函数

转载 作者:行者123 更新时间:2023-11-29 19:07:16 26 4
gpt4 key购买 nike

我正在尝试运行一个函数,该函数根据数据对 TOPOJSON D3 map 的各个状态进行着色。

但是,该函数会在状态加载/出现在 SVG 中之前继续运行。构建 map 的函数在文档就绪函数中调用。我已经尝试向状态添加一个事件监听器,一个 .on 属性调用应该遮蔽状态的函数并使用了 window.load。但是遮蔽状态的函数在状态出现在屏幕上之前一直在运行,因此在尝试通过 ID 查找每个状态时返回 NULL 值

.background {
fill: none;
pointer-events: all;
}

#states {
fill: #aaa;
}

#states .active {
fill: orange;
}

#state-borders {
fill: none;
stroke: #fff;
stroke-width: 1.5px;
stroke-linejoin: round;
stroke-linecap: round;
pointer-events: none;
}

</style>

<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
function buildmap(){
var width = 960,
height = 500,
centered;

var projection = d3.geo.albersUsa()
.scale(1070)
.translate([width / 2, height / 2]);

var path = d3.geo.path()
.projection(projection);

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

svg.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height)
.on("click", clicked);

var g = svg.append("g");

d3.json("/mbostock/raw/4090846/us.json", function(error, us) {
if (error) throw error;

g.append("g")
.attr("id", "states")
.selectAll("path")
.data(topojson.feature(us, us.objects.states).features)
.enter().append("path")
.attr("d", path);

g.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
.attr("id", "state-borders")
.attr("d", path);
});
};

function colorstates(){
var mainstate = document.getElementById("texas")
mainstate.style.fill="blue"
}



$(document).ready(function((){
buildmap()
colorstates() //I have also used window.load and adding .on attribute to svg/d3

最佳答案

d3.json 是异步的。这意味着它之后的所有代码将立即运行,也就是说,代码不会等待 d3.json 完成。

使用 $(document).ready()window.load 不会有任何区别。只有在 d3.json 获取文件(顺便说一句,一个大文件)并绘制 SVG 之后,路径才会出现在 DOM 中。因此,您必须等待 d3.json 完成,以便您可以选择这些路径。

解决方案:在d3.json底部调用你的函数:

d3.json("/mbostock/raw/4090846/us.json", function(error, us) {
if (error) throw error;

g.append("g")
.attr("id", "states")
.selectAll("path")
.data(topojson.feature(us, us.objects.states).features)
.enter().append("path")
.attr("d", path);

g.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) {
return a !== b;
}))
.attr("id", "state-borders")
.attr("d", path);

//calling colorstates inside d3.json
colorstates()

function colorstates() {
var mainstate = document.getElementById("texas")
mainstate.style.fill = "blue"
}

});

这样,当您调用 colorstates 函数时,元素就会存在。

编辑:要通过 ID 选择状态(即路径),您必须先设置路径的 ID(现在,它们没有 ID):

g.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) {
return a !== b;
}))
.attr("id", d => "state" + d.id)
.attr("d", path);

topoJSON 中,d.id 是数字,ID 不能以数字开头(这就是为什么我使用 "state"+ d.id).得克萨斯州的 ID 是 48。

这是您的代码,有效:https://bl.ocks.org/anonymous/b2114787193d018fc094763a92872333

PS:您不需要在 D3 代码中使用 document.getElementById。您会发现使用 D3 选择器更容易,也更通用。

PS2:你的州边界应该有“state-borders”作为一个class,而不是一个id:你不能有相同的不同元素的 ID。 ID 是唯一的。

关于javascript - D3 TOPOJSON map 加载后如何运行函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41928617/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com