如何在响应式地图中以编程方式缩放到 D3 中的元素?

How to programmatically zoom to Elements in D3 in responsive map?

我有一个使用 d3.xml 导入的 SVG,当我单击我的 SVG 中的一个省略号时,我试图放大。这几乎可以工作,尽管我缺少一些在 SVG 大小发生变化时定位元素的功能。这是我用来缩放的代码:

svg.transition().duration(750).call(
    zoom.transform,
    d3.zoomIdentity
      .translate(widthContainer/2 , heightContainer/2)
      .scale(2)
      .translate(-d3.select(this).attr('cx'), -d3.select(this).attr('cy')),
    d3.pointer(event, svg.node())
);

当浏览器的大小 window 代表创建 svg 的大小时,这有效,因为省略号的 cxcy 值可用于找到它们,尽管当我增加浏览器 window 的大小时,这当然不再起作用,因为 cxcy 值现在已经偏离了。如何居中并缩放到独立于当前上下文的元素?我猜想有一种方法可以找出父级 div 的当前比例,然后从那里计算翻译参数,但经过几个小时的尝试后我还没有找到任何东西。

我找到了我的问题的解决方案,我最大的错误是假设要使我的地图响应,我需要更新我的变量 widthContainerheightContainer(用于在我的缩放位置等代码)在页面加载和调整大小时使用当前视口宽度。这引入了一堆非常奇怪的行为,导致我花费数小时进行调试,而这本可以避免。

使具有缩放功能的地图具有响应性的解决方案是将这两个变量设置为固定值。如果您使用的 SVG 正在阅读为 xml 和 d3,则使用在 SVG 的 viewbox 属性中设置的值,例如viewBox="0 0 657.58 344.67".

然后您可以像在 css 中一样处理您的 SVG 元素所在的容器,并将宽度设置为 100% 或您喜欢的任何值,地图应该会做出响应。我完全是 d3 和 JS 的菜鸟,所以这种行为对我来说似乎不合逻辑,特别是因为关于 d3 的 zoomIdentity 的文档非常糟糕。对于普通的 d3 用户来说,这似乎是显而易见的,但我希望这能影响到其他 d3 初学者。