拖动节点时调整 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
语句(顺便说一句,可以改进)处理 maxX
和 maxY
.
这是更新后的 fiddle:https://jsfiddle.net/fc5myafx/
我在我的项目中创建了基于 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
语句(顺便说一句,可以改进)处理 maxX
和 maxY
.
这是更新后的 fiddle:https://jsfiddle.net/fc5myafx/