我正在尝试运行一个功能,根据数据调整TOPOJSON D3地图的各个状态。
但是,该功能在状态加载/出现在SVG之前一直运行。构建映射的函数在文档就绪函数中调用。我已经尝试向状态添加一个事件监听器,一个.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
答案 0 :(得分:3)
d3.json
是异步的。这意味着它之后的所有代码都将立即运行 ,即代码不会等待 d3.json
完成。
使用$(document).ready()
或window.load
不会产生任何影响。只有在d3.json
获取文件(btw,一个大文件)并绘制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选择状态(即路径),您必须设置路径&#39; 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
的原因)。德州&#39; id是48。
以下是您的代码:https://bl.ocks.org/anonymous/b2114787193d018fc094763a92872333
PS:您不需要在D3代码中使用document.getElementById
。您会发现使用D3选择器更容易,更通用。
PS2:你的州边界应该有&#34;州边界&#34;作为class
而不是id
:不能具有相同的ID,用于不同的元素。 ID是唯一的。