请查看this codepen demo;我要求您单击svg对象以查看实例化的模拟标记,因此会发生转换。我使用一个简单的函数来执行此操作:
function transitionTo() {
simulation
.on("tick", ticked);
}
但是,您可以从演示中看到“补间”不存在。要查看我建议的补间示例,请参阅here!
我哪里出错了? ticked()
函数知道我的节点在哪里吗?我是否需要为模拟而不是节点指定我的位置?
密钥代码(包含在上面的演示链接中):
var data = {
nodes:d3.range(0, range).map(function(d){ return {label: "l"+d ,r: config.radius,color: d3.scaleOrdinal(d3.schemeCategory10)}})
}
svg
.attr("width", config.canvas.width)
.attr("height", config.canvas.height)
.attr("id", "canvas")
.style("border", "1px solid black")
.attr("onclick", "transitionTo()");
}
var simulation = d3.forceSimulation()
.force("collide",d3.forceCollide( function(d){return d.r + 1 }).iterations(15) )
.force("charge", d3.forceManyBody().strength(1))
.force("center", d3.forceCenter(config.canvas.width / 2, config.canvas.height / 2))
.force("y", d3.forceY(0))
.force("x", d3.forceX(0));
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(data.nodes)
.enter().append("circle")
.attr("r", function(d){ return d.r })
.attr('cx', function(d, i) { return i % 10 * (config.canvas.width - config.margin.x*2) / 10 + config.radius + config.margin.x; })
.attr('cy', function(d, i) {return (Math.floor(i/10) * (config.canvas.height - config.margin.y*2) / 10) + config.margin.y + config.radius});
var ticked = function() {
node
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
simulation
.nodes(data.nodes);
function transitionTo() {
simulation
.on("tick", ticked);
}
我更喜欢d3 v4的答案,但任何想法都会非常受欢迎!感谢这个d3 noob。
答案 0 :(得分:0)
我认为您没有看到任何补间的原因是解决方案正在快速收敛 - 即“勾选”函数的第一次迭代计算x和y非常接近最终解决方案。你可以看到模拟结束时点点闪烁,因为它们找到了最终的位置。
是的 - 勾选确实知道节点的位置(通过d.x和d.y),你不必指定它们在模拟中的位置。
要查看节点从初始位置到最终解决方案的动画,一个选项是将模拟设置调整为效率较低的设置。
e.g。我添加了一个velocityDecay并将forceCollide迭代更改为1.
var simulation = d3.forceSimulation()
.velocityDecay(0.05)
.force("collide",d3.forceCollide( function(d){return d.r + 1 }).iterations(1) )
.force("charge", d3.forceManyBody().strength(1))
.force("center", d3.forceCenter(config.canvas.width / 2, config.canvas.height / 2))
.force("y", d3.forceY(0))
.force("x", d3.forceX(0));
使用d3.transition()可能有一个更清洁的解决方案。