去年,我使用Mapnik library(服务器端,位图/平铺)在网络地图上进行了几次实验。现在我试图使用d3.js的载体,客户端方法复制相同的实验。
我有一张地图(~680个形状),其中zoom
很慢而pan
缓慢(迈克博斯托克的this example效果很好)。我怀疑问题出在zoommove
回调中,selectAll("path").attr("d", path)
需要太长时间。
function zoommove() {
projection.translate(d3.event.translate).scale(d3.event.scale);
mapa.selectAll("path").attr("d", path);
console.log('zoommove fired...');
}
问题:
地图就是这个(jsfiddle here):
数据源采用topojson格式。它被简化了,可能已经太多了,因为有些形状没有关闭:
[UPDATE]
看起来即使在没有简化标志的情况下运行topojson时也会出现打开几何的问题,我还在调查。我很感激这里的任何线索,文档不是很详细。
答案 0 :(得分:11)
(我不太清楚这里发生了什么,这可能是完全错误的)。
mapa.selectAll("path").attr("d", path);
从头开始重绘地图。这适用于50个州,但开始变得相当缓慢,600多个形状。如果你把路径留在原地并且只是改变了整个svg,你可能会有更好的运气:
function zoommove() {
svg.attr("transform",
"translate("+d3.event.translate+")"
+ " scale("+d3.event.scale+")");
}
我曾经用它创建一个美国county level map(约500个形状),可以平滑地缩放和平移。
答案 1 :(得分:2)
在这里回答我自己的问题,如果你觉得这很有帮助,那么请提升亚当的答案,值得信赖。
对我有用的是什么:
var bg = svg.append('g')
.call(zoom);
var map = bg.append("g")
.attr("transform", "translate(0,0) scale(1)");
...
function zoommove() {
var t1 = projection.translate(),
t2 = d3.event.translate,
t = [t2[0]-t1[0], t2[1]-t1[1]];
map.attr("transform",
"translate("+t+") " +
"scale("+(d3.event.scale/s)+")"
);
console.log(map.attr("transform"));
}
一些提示:
projection.translate()
不是[0,0],则必须将其考虑在内,否则在您第一次尝试平移/缩放时会出现大的凹凸(仅限第一次)。projection.scale()
不是1,则必须将其考虑在内。.call(zoom)
必须位于地图父元素中,否则平移/缩放会变得颠簸。答案 2 :(得分:1)
我遇到过类似的问题,并且重新缩放不适合我的解决方案,因为我不希望svg元素本身被缩放。我做的是优化它,使得可见区域之外的元素不会重新计算。这意味着当所有元素都在视图中时,性能仍然很差,但是当你放大它时会更好。
ode样本:
clippedArea.selectAll("circle")
.style("visibility", d => pointInDomain(d, domain) ? "visible" : "hidden")
.filter(d => pointInDomain(d, domain))
.attr("cx", d => xz(d.x));