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

查看:654
本文介绍了获取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.
};

任何指导将不胜感激。

编辑:上面的'node'是一个强制布局节点,所以它的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 Geometric Zooming

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的缩放行为将pan和zoom事件传递给处理程序,通过transform属性将变换应用到容器元素。

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.

编辑:解决方案是获得当前的转换矩阵的svg元素与element.getCTM(),然后使用它来将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()在应用任何变换之后,获取节点形状周围的紧密边界框的像素位置。请参阅这里了解详情:链接

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.

EDIT:

getBBox 无法正常工作。由于矩形是根据变换的坐标空间定义的,它总是相对于父< g> ,因此对于包含的形状总是相同的。

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天全站免登陆