我一直在尝试在DOM中的多个图表中绘制topoJson文件。我提供的示例仅包括两个图表,但我想最终扩展。我的问题是,尽管两个容器中的每个容器中的Javascript代码完全相同,但topoJSON文件仅显示在第二个容器中。我相信它与D3的渲染模式有关,但我无法弄明白。这是代码和结果页面。
P.S。很抱歉JS代码中的冗余。我只是为了示例而做了
<!doctype html>
<meta charset="utf-8">
<script src="./js/d3.js"></script>
<script src="./js/topojson.js"></script>
<body>
First Map (Empty!!!)
<div id='container1'>
<script charset="utf-8">
var width=2712/9;
var height=1955/9;
var rasterBounds=[[-1.3312652841195303 , 41.964452901889715] , [1.748235284119533 , 43.59348149262565]];
var projection = d3.geo.mercator()
.scale(1)
.translate([0, 0])
var b = [projection(rasterBounds[0]), projection(rasterBounds[1])],
s = 1 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height),
t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2]
//update projection
projection
.scale(s)
.translate(t)
// geo path generator
var path = d3.geo.path()
.projection(projection)
var map = d3.select('#container1').append('svg')
.attr('width', width)
.attr('height', height)
map.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#E6E6E6");
var color = d3.scale.ordinal()
.domain(["1", "2", "3"])
.range(["#ffd633", "#aaff00" , "#267300"]);
d3.json('MapTopoFinal.json', function(error, topology) {
map.selectAll("path")
.data(topojson.feature(topology, topology.objects.Fin_Map).features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", function(d) {
return color(d.properties.DN);
})
.style("opacity", .6);
})
</script>
</div>
Second Map (OK)
<div id='container2'>
<script charset="utf-8">
var width=2712/9;
var height=1955/9;
var rasterBounds=[[-1.3312652841195303 , 41.964452901889715] , [1.748235284119533 , 43.59348149262565]];
var projection = d3.geo.mercator()
.scale(1)
.translate([0, 0])
var b = [projection(rasterBounds[0]), projection(rasterBounds[1])],
s = 1 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height),
t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2]
//update projection
projection
.scale(s)
.translate(t)
// geo path generator
var path = d3.geo.path()
.projection(projection)
var map = d3.select('#container2').append('svg')
.attr('width', width)
.attr('height', height)
map.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#E6E6E6");
var color = d3.scale.ordinal()
.domain(["1", "2", "3"])
.range(["#ffd633", "#aaff00" , "#267300"]);
d3.json('MapTopoFinal1.json', function(error, topology) {
map.selectAll("path")
.data(topojson.feature(topology, topology.objects.Fin_Map).features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", function(d) {
return color(d.properties.DN);
})
.style("opacity", .6);
})
</script>
</div>
</body>
答案 0 :(得分:0)
长话短说:在多个脚本标记中分隔您的代码不会创建不同的范围。
现在您正在使用脚本两次的几个变量。最重要的是map
。从这里更改第二张地图:
var map = d3.select('#container2').append('svg')
.attr('width', width)
.attr('height', height)
到此:
var map2 = d3.select('#container2').append('svg')
.attr('width', width)
.attr('height', height)
并将所有后续map
更改为map2
或其他任何内容。此外,更改所有其他重复变量,例如color
,projection
等。
不要将脚本分开。它们现在的方式,遍布HTML,并不是最佳实践,因为浏览器必须在继续解析HTML的其余部分之前解析每个脚本(这也可能导致其他问题)。将所有脚本放在<script></script>
末尾的单个body
内。
请注意,使用多个<script>
标记不会在JavaScript中定义不同的范围。