javascript - 在 D3.js 4.x 力模拟中将选择矩形与缩放和平移相结合

标签 javascript svg d3.js

我在 D3.js 4.4 中构建了一个力模拟,它使用内置的缩放 + 平移函数 (d3.zoom()),并结合用于选择节点的选择矩形(例如herehere )。

拖动/平移视口(viewport)是默认行为,但在按住 Shift 键时会被过滤掉。然后另一个拖动处理程序接管并从起点绘制一个矩形。在鼠标按下时,代码使矩形与屏幕上的节点相交并选择它们。

这一切都工作得很好,但是当我将缩放行为应用于方程时,整个事情就出现了偏差。我已将问题定位到适用于包含节点的 g 容器的 scaled3.event.transform

由于这个项目的性质(以及我们正在工作的无互联网开发环境),我无法在网络上复制/粘贴工作代码。所以这里是导致问题的删节部分(我不得不从另一个显示器重新输入这些部分)。

var currentZoom = null;

var zoom = d3.zoom()
    .scaleExtent([0.5, 10])
    .filter(function() {
        return !d3.event.shiftKey // Don't zoom/pan when shift is pressed
    })
    .on("zoom", zoomed);

function zoomed() {
    currentZoom = d3.event.transform;

    d3.select("g.links").attr("transform", d3.event.transform);
    d3.select("g.nodes").attr("transform", d3.event.transform);
}

// This fires on mouseup after dragging the rectangle (svg rect)
function intersectSelectionRect() {
    var rect = svg.select("rect.selection-rect");

    // Intersect rectangle with nodes
    var lx = parseInt(rect.attr("x"));
    var ly = parseInt(rect.attr("y"));
    var lw = parseInt(rect.attr("width"));
    var lh = parseInt(rect.attr("height"));

    // Account for zoom
    if (!!currentZoom) {
        // Recalculate for pan
        lx -= currentZoom.x;
        ly -= currentZoom.y;

        // Recalculate for zoom (scale)
        // currentZoom.k ???????????????
    }

    // Rectangle corners
    var upperRight = [lx + lw, ly];
    var lowerLeft = [lx + ly + lh];

    nodes.forEach(function(item, index) {
        if ((item.x < upperRight[0] && item.x > lowerLeft[0]) &&
            (item.y > upperRight[1] && item.y < lowerLeft[1])) {
            item.selected = true;
        }
    });
}

正如您(希望)可以看出的那样,当使用缩放 k(比例)重新计算矩形 x 和 y 时,就会出现问题。如果比例为 1(起始值),则重新计算是正确的。如果不是这样,则实际选择矩形不再与屏幕上绘制的矩形匹配。

最佳答案

如果一切设置正确,您应该能够apply转换为点,

var upperRight = [lx, ly];
var lowerLeft = [lx + lw, ly + lh];

if (!!currentZoom) {
  upperRight = currentZoom.apply(upperRight);
  lowerLeft = currentZoom.apply(lowerLeft);
}

关于javascript - 在 D3.js 4.x 力模拟中将选择矩形与缩放和平移相结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41714805/

相关文章:

javascript - 如何在jmeter中执行javascript生成一些在后续请求中使用的sessionID

javascript - 如何获取 id 包含特殊字符的输入元素的值?

javascript - 创建不规则边框

javascript - 如何在 javascript 中隐藏 IE 中的空 <span>。 (注意在其他浏览器中工作正常)

SVG 过滤器相对于可能为零长度边的边界框,calc() 替代方案?

javascript - 使用新数据重新渲染 D3 强制定向布局

javascript - 查找平行或偏移 SVG 路径

javascript - chop svg 文本以适应矩形

javascript - 获取 d3 中的质心坐标

javascript - 使用 D3.js 将 SVG 元素附加到 HTML 表格单元格