d3 v6 指针功能未针对缩放和平移进行调整

afr*_*111 7 d3.js

我正在将我的应用程序从 d3 v5 升级到 v6,并且在迁移 d3.mouse 功能时遇到了问题。在我的应用程序中,我将变换应用于顶级 svg 组并使用缩放功能进行缩放和平移(缩放和平移)。当我双击屏幕时,我会占据鼠标位置并绘制一个正方形。

现在我用 d3.pointer 替换 d3.mouse 函数。在我的双击事件中,我通过调用d3.pointer(event). 但是,此函数不会产生与我的顶级 svg 组的定位和缩放位置相关的位置。当我从顶级组中删除翻译和缩放时,位置匹配。

在旧版本的 d3 中,我可以调用d3.mouse(this.state.svg.node())它,它会产生我点击的准确位置,并针对平移和缩放进行了校正。这在版本 6 中可用吗?如果没有,是否有一种干净的方法可以对此进行调整?新的事件对象带有许多不同的位置属性:pagex、offsetx、screenx、x。这些都没有产生我点击的位置。有没有一种干净的方法来实现这一目标?

And*_*eid 10

您可以指定一个容器元素,该元素会影响 v5 及更早版本中的缩放变换:

d3.鼠标(容器)

返回当前事件相对于指定容器的 x 和 y 坐标。容器可以是HTML或SVG容器元素,例如G元素或SVG元素。坐标以数字 [x, y] 的二元素数组形式返回。(来源

在 d3v6 中,您可以使用 d3.pointer 的第二个参数来指定它:

d3.pointer(事件[, 目标])

返回一个由数字组成的二元素数组 [x, y],表示指定事件相对于指定目标的坐标。事件可以是 MouseEvent、PointerEvent、Touch 或将 UIEvent 保存为 event.sourceEvent 的自定义事件。... 如果目标是 SVG 元素,则使用屏幕坐标变换矩阵的逆变换事件的坐标。如果目标是 HTML 元素,则事件的坐标将相对于目标边界客户端矩形的左上角进行转换。(来源

所以据我所知,你应该使用:

d3.pointer(event,this.state.svg.node());
Run Code Online (Sandbox Code Playgroud)

代替

d3.mouse(this.state.svg.node());
Run Code Online (Sandbox Code Playgroud)

这是一个 d3v6 示例:

d3.pointer(event,this.state.svg.node());
Run Code Online (Sandbox Code Playgroud)
d3.mouse(this.state.svg.node());
Run Code Online (Sandbox Code Playgroud)

调整此 v5 示例:

var svg = d3.select("body")
  .append("svg")
  .attr("width", 500)
  .attr("height", 200);
  
var rect = svg.append("rect")
 .attr("width",500)
 .attr("height",200)
 .attr("fill", "#eee")
 
var g = svg.append("g");
  
var zoomed = function(event) {
  g.attr("transform", event.transform);
}

rect.call(d3.zoom().on("zoom",zoomed))
 .on("click", function(event) {
    var xy = d3.pointer(event,g.node());
    
    g.append("circle")
      .attr("r", 5)
      .attr("cx", xy[0])
      .attr("cy", xy[1])
      .attr("fill","crimson");
 })
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.0.0/d3.min.js"></script>
Run Code Online (Sandbox Code Playgroud)