gpt4 book ai didi

d3.js - 如何停止 d3 力图布局模拟?

转载 作者:行者123 更新时间:2023-12-02 01:32:56 25 4
gpt4 key购买 nike

一旦您在 D3 中 d3.layout.force()....start() 进行力布局模拟,它就会继续伴随一个事件事件。

我想设置 5 秒的超时,让图形强制布局模拟成形并停止(调用 .stop() 或 alpha(0))。这可以停止,但是一旦我拖动节点,模拟就会停止重新开始。

下面的代码,也可以从jsfiddle轻松测试,在最后一行处显示将发出stop()并且模拟立即停止,但是一旦您拖动任何节点,模拟再次开始。我认为这是在强制拖动中硬编码的。有没有办法禁用/取消注册这个?

var svgContainer = d3.select("#svgContainer");

var element0a = svgContainer.append("g").attr("class","node").attr("transform","translate(100,100)");
var element0b = element0a.append("rect").attr("x",0).attr("y",0).attr("width",20).attr("height",10).attr("fill","red");

var element1a = svgContainer.append("g").attr("class","node").attr("transform","translate(100,200)");
var element1b = element1a.append("rect").attr("x",0).attr("y",0).attr("width",20).attr("height",10).attr("fill","green");

var element2a = svgContainer.append("g").attr("class","node").attr("transform","translate(100,300)");
var element2b = element2a.append("rect").attr("x",0).attr("y",0).attr("width",20).attr("height",10).attr("fill","blue");

var nodeArray = new Array();
nodeArray[0] = { id : "000", label : "label 000", ui : element0a };
nodeArray[1] = { id : "001", label : "label 001", ui : element1a };
nodeArray[2] = { id : "002", label : "label 002", ui : element2a };

var linkArray = new Array();

var force = self.force = d3.layout.force()
.nodes(nodeArray)
.links(linkArray)
.gravity(.05)
.distance(80)
.charge(-100)
.size([600, 600])
.start();

var node = svgContainer.selectAll("g.node")
.data(nodeArray)
.call(force.drag);


force.on("tick", function() {
node.attr("transform", function(d) {return "translate(" + d.x + "," + d.y + ")";});
});

// HERE !!!! Without the stop() the simulation goes fine. With the stop() the simulation will immediately stop, but will continue as soon as you drap something. I want the simulation to never start again.

force.stop();

这是示例的屏幕截图:

enter image description here

最佳答案

在内部拖动节点时调用的函数中重新启动模拟。但是您可以覆盖此行为。事件名称为“drag.force”,您可以通过 force.drag 访问它。您可以直接修改坐标,而不需要重新启动模拟,而不是通常的行为,如下所示:

var node...
.call(force.drag().on("drag.force", function() {
d3.select(this).attr("transform", "translate(" + d3.event.x + "," + d3.event.y + ")");
}));

这对应于正常的拖动行为。在执行此操作之前,建议停止模拟以防止拖动事件和强制刻度线干扰。只需在修改后的事件处理程序的开头调用 force.stop() 即可。

最后,您需要重置拖动事件的原点,否则您会注意到,当您再次拖动被拖动的元素时,它们会“跳”回其原始位置。这以与修改事件处理程序类似的方式完成。您只需获取当前翻译并以预期格式返回坐标即可。

var node...
.call(force.drag().origin(function() {
var t = d3.transform(d3.select(this).attr("transform")).translate;
return {x: t[0], y: t[1]};
}));

完整代码在更新后的jsfiddle here .

关于d3.js - 如何停止 d3 力图布局模拟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16112108/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com