Pep*_*G-a 3 d3.js force-layout
在带有强制模块的D3 v4中,如何在初始化图形后更新模拟的参数?
更确切地说,我试图改变.forceLink和.forceManyBody力向图,当用户点击其中一个节点.
var node = svg
.append("g")
.attr("class", "gnodes")
.selectAll(".node")
.data(graph.nodes)
.enter()
.append("g")
.attr("class", "node")
.on('dblclick', connectedNodes); //calls for change in simulation parameters
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经能够通过在connectedNodes函数下复制模拟来更新它:
function connectedNodes() {
//new parameters
linkDistance = 5;
fCharge = -10;
//replicates the initial simulation code
simulation = d3.forceSimulation()
.force("link", d3.forceLink()
.id(function(d) {return d.id;})
.distance(linkDistance)
)
.force("collide", d3.forceCollide()
.radius(function(d){return d.r + 10})
.strength(1)
)
.force("charge", d3.forceManyBody()
.strength(fCharge)
)
.force("center", d3.forceCenter(width / 2, height / 2));
simulation.nodes(graph.nodes).on("tick", ticked);
simulation.force("link").links(graph.links);
Run Code Online (Sandbox Code Playgroud)
虽然这是有效的,但它非常多余.有没有一种方法可以使用新参数刷新模拟?我尝试了以下但它不起作用
function connectedNodes() {
//new parameters
linkDistance = 5;
fCharge = -10;
//restart simulation with new parameters
simulation.restart();
}
Run Code Online (Sandbox Code Playgroud)
您需要引用要更新的力.这可以使用以下两种方式之一完成:
正如Cool Blue在他们的评论中指出的那样,你可以通过调用simulation.force()刚刚传入注册力的名称来轻松获得对力的引用.据说,如果我们创建了我们的模拟,同时传递一个匿名的就地力量,如下所示:
var simulation = d3.forceSimulation()
.force("link", d3.forceLink() // "link" is the name to register the force
.id(function(d) { return d.id; })
.distance(linkDistance)
);
Run Code Online (Sandbox Code Playgroud)
稍后可以在需要时通过其名称获取力:
var forceLink = simulation.force("link"); // Get the force by its name
Run Code Online (Sandbox Code Playgroud)
就个人而言,我喜欢这种方法,并且只要有可能,我会更喜欢它,因为我不喜欢有很多引用/变量.
在创建时保持对力的引用.
var forceLink = d3.forceLink() // Keep a reference to the force
.id(function(d) { return d.id; })
.distance(linkDistance);
var simulation = d3.forceSimulation()
.force("link", forceLink ) // Pass the reference when creating the simulation
Run Code Online (Sandbox Code Playgroud)无论你选择哪种方式,你都可以通过做类似的事情来更新你的力量
linkDistance += 10;
forceLink.distance(linkDistance);
Run Code Online (Sandbox Code Playgroud)
这将在计算下一个滴答后将新值考虑在内.如果模拟已经停止或您只是想再次加热,您可以打电话
simulation.alpha(1).restart();
Run Code Online (Sandbox Code Playgroud)
我已经设置了一个示例,当您将鼠标悬停在SVG上时会显示这些实时更新.这将更新linkDistance并重新启动力布局.
| 归档时间: |
|
| 查看次数: |
1670 次 |
| 最近记录: |