拖动节点时调整 viewBox 的大小

Resize viewBox when dragging a node

我在我的项目中创建了基于 d3.v2 库的力布局图。 它在几乎所有部分都运行良好,但有一件事我想改变。因此,当我之后将节点拖出图形块时,我无法到达它。为了解决这个问题,我为我的图形添加了 viewBox 属性并更改了很少的 "tick" 事件,所以现在它看起来像

force.on("tick", function() {
    link.attr("x1", function(d) {
            return d.source.x;
        })
        .attr("y1", function(d) {
            return d.source.y;
        })
        .attr("x2", function(d) {
            return d.target.x;
        })
        .attr("y2", function(d) {
            return d.target.y;
        });

    node.attr("transform", function(d) {
        if (d.fixed != true) {
            return "translate(" + d.x + "," + d.y + ")";
        } else {
            return "translate(" + d.px + "," + d.py + ")";
        }

        // here is what I tried to do
        if (d.x < 960 && d.y < 600) {
            vis.attr("viewBox", "0 0 960 600");
        } else if (d.x > 960 && d.y < 600) {
            vis.attr("viewBox", "0 0 " + d.x + " 600");
        } else if (d.x < 960 && d.y > 600) {
            vis.attr("viewBox", "0 0 960 " + d.y);
        } else {
            vis.attr("viewBox", "0 0 " + d.x + " " + d.y)
        }
    });
});

但是viewBox只有在我拖动节点时才会改变,这取决于节点数组中的最后一个元素。 所以我想知道在拖动任何节点时是否有任何方法可以更改 viewBox 的大小。 感谢您的任何回答或建议!

只有last节点可以改变viewBox的原因很简单。让我们检查一下您的代码。

您的所有 if...else 语句都在 node 选择的 attr 的回调中:

node.attr("transform", function (d) {

因此,将针对选择中的 每个 节点评估基准 (d)。所以,如果将节点B拖到图表的边框,即使它的值大于300,节点C的值(小于300 ), 评估时,将覆盖它并将 viewBox 设置回 "0 0 300 200".

解决方法:

让我们计算每个节点的最大值值:

  var maxX = d3.max(node.data().map(d => d.x));
  var maxY = d3.max(node.data().map(d => d.y));

然后,您可以使用 if...else 语句(顺便说一句,可以改进)处理 maxXmaxY.

这是更新后的 fiddle:https://jsfiddle.net/fc5myafx/