转换后获取 D3 节点的屏幕位置 [英] Getting Screen Positions of D3 Nodes After Transform

查看:47
本文介绍了转换后获取 D3 节点的屏幕位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在布局被 d3.behavior.zoom() 转换后获取节点的屏幕位置,但我运气不佳.在平移和缩放布局后,我该如何获取节点在窗口中的实际位置?

I'm trying to get the screen position of a node after the layout has been transformed by d3.behavior.zoom() but I'm not having much luck. How might I go about getting a node's actual position in the window after translating and scaling the layout?

mouseOver = function(node) {
  screenX = magic(node.x); // Need a magic function to transform node
  screenY = magic(node.y); // positions into screen coordinates.
};

任何指导将不胜感激.

上面的节点"是一个力布局节点,因此它的 x 和 y 属性由模拟设置,并在模拟停止后保持不变,无论应用何种类型的变换.

'node' above is a force layout node, so it's x and y properties are set by the simulation and remain constant after the simulation comes to rest, regardless of what type of transform is applied.

我用来转换 SVG 的策略来自 d3 的缩放行为,这里概述:SVG 几何缩放.

The strategy I'm using to transform the SVG comes from d3's zoom behavior, which is outlined here: SVG Geometric Zooming.

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
  .append("g");

svg.append("rect")
    .attr("class", "overlay")
    .attr("width", width)
    .attr("height", height);

svg.selectAll("circle")
    .data(data)
  .enter().append("circle")
    .attr("r", 2.5)
    .attr("transform", function(d) { return "translate(" + d + ")"; });

function zoom() {
  svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}

这很简单.d3 的缩放行为将平移和缩放事件传递给处理程序,该处理程序通过转换属性将转换应用于容器元素.

It's pretty straightforward. d3's zoom behavior delivers pan and zoom events to a handler, which applies the transforms to the container element by way of the transform attribute.

我正在通过使用鼠标坐标而不是节点坐标来解决这个问题,因为我对用鼠标指针悬停在节点上时的节点位置感兴趣.这不完全是我所追求的行为,但它在大多数情况下都有效,并且总比没有好.

I'm working around the issue by using mouse coordinates instead of node coordinates, since I'm interested in the node position when the node is hovered over with the mouse pointer. It's not exactly the behavior I'm after, but it works for the most part, and is better than nothing.

解决方案是使用 element.getCTM() 获取 svg 元素的当前变换矩阵,然后使用它来将 x 和 y 坐标偏移到屏幕相对状态.见下文.

The solution was to get the current transformation matrix of the svg element with element.getCTM() and then use it to offset the x and y coordinates to a screen-relative state. See below.

推荐答案

您可以尝试 node.getBBox() 以获取任何 transform 已被应用.请参阅此处了解更多信息:链接.

You can try node.getBBox() to get the pixel positions of a tight bounding box around the node shapes after any transform has been applied. See here for more: link.

getBBox 和我想的不太一样.由于矩形是根据变换后的坐标空间定义的,它总是相对于父,因此对于包含的形状总是相同的.

getBBox doesn't work quite the way I thought. Since the rectangle is defined in terms of the transformed coordinate space it is always relative to the parent <g> and will therefore always be the same for contained shapes.

还有一个名为 element.getBoundingClientRect 的函数,看起来相当得到广泛支持,它以相对于浏览器视口左上角的像素位置返回其矩形.这可能会让您更接近您想要的东西,而无需直接弄乱变换矩阵.

There is another function called element.getBoundingClientRect that appears to be quite widely supported and it returns its rectangle in pixel position relative to the top left of the browser view port. That might get you closer to what you want without needing to mess with the transform matrix directly.

这篇关于转换后获取 D3 节点的屏幕位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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