隐形载体?组合 d3.tile()、d3.zoom() 和 TopoJSON 向量
Invisible vectors? Combining d3.tile(), d3.zoom() and TopoJSON vectors
我使用栅格(d3.tile
和地图库)和矢量(SVG 形状中的 TopoJSON)制作了有效的 D3 地图。但是我在组合它们的时候遇到了一个错误。
我遵循了 Mike Bostock 的光栅和矢量示例,尤其是他的 "Raster & Vector III",它更改了变换和描边宽度以更新矢量的显示方式。
我的地图几乎完美无缺。但是,在加载时,只显示光栅图块;矢量是不可见的:
但是一旦我触发 d3.zoom
事件(通过平移或缩放),就会显示矢量:
我不明白这一点,因为我明确告诉浏览器,独立于缩放事件,绘制矢量。这是相关的片段:
// read in the topojson
d3.json("ausElectorates.json", function(error, mapData) {
if (error) throw error;
var electorates = topojson.feature(mapData, mapData.objects.tracts);
// apply a zoom transform equivalent to projection{scale,translate,center}
map.call(zoom)
.call(zoom.transform, d3.zoomIdentity
.translate(mapWidth / 2, mapHeight / 2)
.scale(1 << 12)
.translate(-centre[0], -centre[1]));
// draw the electorate vectors
vector.selectAll("path")
.data(electorates.features)
.enter().append("path")
.attr("class", "electorate")
.attr("d", path);
});
出于某种原因,d3.json()
函数的最后一行 -- .attr("d", path")
-- 没有可视化向量。
Click here to see the map. Click here 访问完整代码及其使用的 TopoJSON。
我很想得到这方面的建议,这让我很困惑!
(PS 为省略地图图块、D3.js 库等的版权归属而道歉 - 我只是想尽量减少此示例的代码。)
它正在绘制矢量 - 但是,你不能仅仅依靠 d3 geoProjection 缩放和平移你的矢量,因为当你缩放时你将平移和缩放应用到路径本身 - 而不是投影:
vector.selectAll("path")
.attr("transform", "translate(" + [change.x, change.y] + ")scale(" + change.k + ")")
.style("stroke-width", 1 / change.k);
由于您没有设置缩放和平移,因此在加载矢量时它们不会正确绘制。它们绘制得非常小 - 因为您的投影比例为 1/tau
,翻译为 [0,0]
。在页面加载时检查 svg 显示它们在那里,而且很小。
解决方案是在 map.call("zoom")
之前绘制矢量 - 这样您就可以在手动缩放之前在路径上应用基础变换(居中、变换和缩放):
// read in the topojson
d3.json("ausElectorates.json", function(error, mapData) {
if (error) throw error;
var electorates = topojson.feature(mapData, mapData.objects.tracts);
// draw the electorate vectors
vector.selectAll("path")
.data(electorates.features)
.enter().append("path")
.attr("class", "electorate")
.attr("d", path);
// apply a zoom transform equivalent to projection{scale,translate,center}
map.call(zoom)
.call(zoom.transform, d3.zoomIdentity
.translate(mapWidth / 2, mapHeight / 2)
.scale(1 << 12)
.translate(-centre[0], -centre[1]));
});
我使用栅格(d3.tile
和地图库)和矢量(SVG 形状中的 TopoJSON)制作了有效的 D3 地图。但是我在组合它们的时候遇到了一个错误。
我遵循了 Mike Bostock 的光栅和矢量示例,尤其是他的 "Raster & Vector III",它更改了变换和描边宽度以更新矢量的显示方式。
我的地图几乎完美无缺。但是,在加载时,只显示光栅图块;矢量是不可见的:
但是一旦我触发 d3.zoom
事件(通过平移或缩放),就会显示矢量:
我不明白这一点,因为我明确告诉浏览器,独立于缩放事件,绘制矢量。这是相关的片段:
// read in the topojson
d3.json("ausElectorates.json", function(error, mapData) {
if (error) throw error;
var electorates = topojson.feature(mapData, mapData.objects.tracts);
// apply a zoom transform equivalent to projection{scale,translate,center}
map.call(zoom)
.call(zoom.transform, d3.zoomIdentity
.translate(mapWidth / 2, mapHeight / 2)
.scale(1 << 12)
.translate(-centre[0], -centre[1]));
// draw the electorate vectors
vector.selectAll("path")
.data(electorates.features)
.enter().append("path")
.attr("class", "electorate")
.attr("d", path);
});
出于某种原因,d3.json()
函数的最后一行 -- .attr("d", path")
-- 没有可视化向量。
Click here to see the map. Click here 访问完整代码及其使用的 TopoJSON。
我很想得到这方面的建议,这让我很困惑!
(PS 为省略地图图块、D3.js 库等的版权归属而道歉 - 我只是想尽量减少此示例的代码。)
它正在绘制矢量 - 但是,你不能仅仅依靠 d3 geoProjection 缩放和平移你的矢量,因为当你缩放时你将平移和缩放应用到路径本身 - 而不是投影:
vector.selectAll("path")
.attr("transform", "translate(" + [change.x, change.y] + ")scale(" + change.k + ")")
.style("stroke-width", 1 / change.k);
由于您没有设置缩放和平移,因此在加载矢量时它们不会正确绘制。它们绘制得非常小 - 因为您的投影比例为 1/tau
,翻译为 [0,0]
。在页面加载时检查 svg 显示它们在那里,而且很小。
解决方案是在 map.call("zoom")
之前绘制矢量 - 这样您就可以在手动缩放之前在路径上应用基础变换(居中、变换和缩放):
// read in the topojson
d3.json("ausElectorates.json", function(error, mapData) {
if (error) throw error;
var electorates = topojson.feature(mapData, mapData.objects.tracts);
// draw the electorate vectors
vector.selectAll("path")
.data(electorates.features)
.enter().append("path")
.attr("class", "electorate")
.attr("d", path);
// apply a zoom transform equivalent to projection{scale,translate,center}
map.call(zoom)
.call(zoom.transform, d3.zoomIdentity
.translate(mapWidth / 2, mapHeight / 2)
.scale(1 << 12)
.translate(-centre[0], -centre[1]));
});