Edit: 看起来主要问题只是投影的更新
使用恒定投影
这里的主要问题是您要根据缩放来更改投影并从中计算边界框。
放大后,你会看到这一行:
projection.scale...
看起来您正在尝试根据缩放来更新投影,但是平移和缩放已经由transform
svg 元素的属性。
相反,投影用于将球面地理坐标转换为二维空间。它用于计算一个国家/地区的边界,如果它发生变化,边界就会移动,这可能是无意的。删除此投影更新可以让您顺利完成大部分工作。
另一个大问题是,您将点击处理程序中的比例限制为远低于您需要的值(例如,您将比例限制为最大值 8,但初始比例为 4096)。
移除夹子和投影更新应该可以让您点击缩放国家/地区。但我们还没有完成!
另一个问题是你的reset
功能不会重置为原始视图,这会使其缩小到远处。使用初始缩放设置而不是d3.zoomIdentity
解决问题。
这些编辑的结果如下:https://jsfiddle.net/m7cn0p47/99/ https://jsfiddle.net/m7cn0p47/99/
可选:合并转换
更改许多 DOM 节点通常效率很低。在这种情况下,您将更改中的每个路径向量zoomed
。将变换应用到一个g
元素(在本例中为g
带有 id 的元素vector
) 相反通常更有效。
代替:
vector.selectAll("path")
.attr("transform", "translate(" + [transform.x, transform.y] + ")scale(" + transform.k + ")")
.style("stroke-width", 1 / transform.k);
您可以将其更改为简单的:
vector
.attr("transform", "translate(" + [transform.x, transform.y] + ")scale(" + transform.k + ")")
.style("stroke-width", 1 / transform.k);
您还必须删除stroke-width
来自 CSS 中的路径,因为它会覆盖它。
以下是这些更改和更正的更新:https://jsfiddle.net/m7cn0p47/96/ https://jsfiddle.net/m7cn0p47/96/