首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在D3.js 4.x Force Simulation中将选择矩形与缩放+平移相结合

在D3.js 4.x Force Simulation中将选择矩形与缩放+平移相结合
EN

Stack Overflow用户
提问于 2017-01-18 16:45:46
回答 1查看 671关注 0票数 1

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

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

这一切都很好,但当我将缩放行为应用到等式中时,整个事情就会变得不太对劲。我已经将问题定位到d3.event.transform应用于包含节点的g容器的scale值。

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

代码语言:javascript
复制
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 (scale)重新计算矩形x和y时,问题就出现了。如果刻度为1(起始值),则重新计算是正确的。如果不是这样,实际的选择矩形将不再与屏幕上绘制的矩形匹配。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-19 00:01:41

如果一切都设置正确,你应该能够apply变换到点,

代码语言:javascript
复制
var upperRight = [lx, ly];
var lowerLeft = [lx + lw, ly + lh];

if (!!currentZoom) {
  upperRight = currentZoom.apply(upperRight);
  lowerLeft = currentZoom.apply(lowerLeft);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41714805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档