d3 v6指针功能未针对缩放和平移进行调整 [英] d3 v6 pointer function not adjusting for scale and translate

查看:40
本文介绍了d3 v6指针功能未针对缩放和平移进行调整的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am upgrading my app from d3 v5 to v6 and am having an issue migrating the d3.mouse functionality. In my app I apply a transform to the top level svg group and use the zoom functionality to zoom and pan (scale and translate). When I double click on the screen I take the mouse position and draw a square.

现在,我将d3.mouse函数替换为d3.pointer.在双击事件中,我通过调用 d3.pointer(event)获得鼠标位置.但是,此功能不会产生相对于我的顶级svg组的位置和比例的位置.当我从顶级组中删除平移和缩放比例时,位置匹配.

Now I am replacing the d3.mouse function with d3.pointer. In my double click event I get the mouse position by calling d3.pointer(event). However this function is not producing a position that is relative to where my top level svg group is positioned and scaled. When I remove the translate and scale from the top level group, the position matches up.

在旧版本的d3中,我可以调用 d3.mouse(this.state.svg.node()),它将产生我单击的确切位置,以进行平移和缩放.这在版本6中可用吗?如果没有,是否有一种干净的方法可以对此进行调整?新的事件对象带有许多不同的位置属性:pagex,offsetx,screenx,x.这些都没有产生我点击的位置.有没有一种干净的方法可以达到这个目的?

In the older version of d3 I could call d3.mouse(this.state.svg.node()) and it would produce the exact position I clicked corrected for pan and scale. Is this available in version 6? If not, is there a clean way I can adjust for this? The new event object is coming through with a host of different position properties: pagex, offsetx, screenx, x. None of these is producing the position I clicked on. Is there a clean way to acheive this?

推荐答案

您可以指定一个容器元素,该元素将在v5及更低版本中进行缩放转换:

You could specify a container element which would factor in a zoom transform in v5 and earlier:

d3.mouse(容器)

d3.mouse(container)

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

Returns the x and y coordinates of the current event relative to the specified container. The container may be an HTML or SVG container element, such as a G element or an SVG element. The coordinates are returned as a two-element array of numbers [x, y]. (source)

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

In d3v6 you can specify this by using the second parameter of d3.pointer:

d3.pointer(event [,target])

d3.pointer(event[, target])

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

Returns a two-element array of numbers [x, y] representing the coordinates of the specified event relative to the specified target. event can be a MouseEvent, a PointerEvent, a Touch, or a custom event holding a UIEvent as event.sourceEvent. ... If the target is an SVG element, the event’s coordinates are transformed using the inverse of the screen coordinate transformation matrix. If the target is an HTML element, the event’s coordinates are translated relative to the top-left corner of the target’s bounding client rectangle. (source)

据我所知,您应该使用:

So as far as I'm aware, you should be use:

d3.pointer(event,this.state.svg.node());

代替

d3.mouse(this.state.svg.node());

这是d3v6的示例:

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");
 })

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.0.0/d3.min.js"></script>

适应此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() {
  g.attr("transform", d3.event.transform);
}

rect.call(d3.zoom().on("zoom",zoomed))
 .on("click", function() {
    var xy = d3.mouse(g.node());
    
    g.append("circle")
      .attr("r", 5)
      .attr("cx", xy[0])
      .attr("cy", xy[1])
      .attr("fill","crimson");
 })

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

这篇关于d3 v6指针功能未针对缩放和平移进行调整的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆