我目前正在使用zoom函数制作一个强制d3图。用户可以选择在图上创建新节点。这是通过双击图上的事件来获得创建新节点的坐标。
在用户的日常工作中,双击图形,然后缩放到另一个区域和/或更改缩放比例,然后完成节点的创建(设置属性),这是可能的,也是很常见的。在这种情况下,节点应该在图形的可见区域中创建。
对于这个场景,我编写了一个函数,它接受要创建的节点和svg元素,并在必要时改变节点的坐标,使其位于可见区域的中心:
moveNodeIntoViewPort(node: NodeInterface, svgElement: any): NodeInterface {
let svg = svgElement._groups[0][0];
let minX: number = parseInt(svg.attributes.viewBox.nodeValue.split(" ")[0]);
let minY: number = parseInt(svg.attributes.viewBox.nodeValue.split(" ")[1]);
let width: number = parseInt(
svg.attributes.viewBox.nodeValue.split(" ")[1].split(" ")[0]
);
let height: number = parseInt(
svg.attributes.viewBox.nodeValue.split(" ")[1].split(" ")[1]
);
let zoomX: number = parseInt(svg.__zoom.x) * -1;
let zoomY: number = parseInt(svg.__zoom.y) * -1;
let zoomK: number = parseFloat(svg.__zoom.k.toFixed(2));
node.x =
node.x < minX + zoomX || node.x > minX + width + zoomX
? (minX + zoomX + width / 2) / zoomK
: node.x;
node.y =
node.y < minY + zoomY || node.y > minY + height + zoomY
? (minY + zoomY + height / 2) / zoomK
: node.y;
return node;
}
虽然这段代码能按预期工作,但我对代码本身并不满意,我想知道D3是否提供了更好的现成解决方案。我在official D3 documentation中找不到任何关于如何:
- 如果节点在缩放区域中可见,请检查
- 如何获取缩放图形的当前中心坐标
我们非常感谢您的任何意见。
1条答案
按热度按时间h7appiyu1#
经过一些研究(并在一些帮助下),我们使用DOMMatrix通过以下代码实现了相同的结果:
viewportRef
是<svg>
元素的<g class="viewport>
子元素的d3选择。虽然没有比原来的函数更短,但是我们可以避免使用字符串操作,并且可以提取部分函数用于其他进程。