作为序言,我仔细研究了所有其他有关将节点添加到力布局中的问题,尽管我的回答几乎奏效了(出现了节点),但是缺少了一些东西。我正在使用d3v4。
问题:在某些事件触发上,我想将节点平滑地添加到我的强制控制布局中。
当前问题:我有一个按钮,当单击该按钮时,确实可以将节点添加到我的强制布局中。但是,新节点的位置与现有节点不一样,并且它们不是以静态方式连接的(我更喜欢enter()
上的那种移动效果。
根据当前的进度,我已经创建了一个相当裸露的骨骼block available here。
我相信我的问题必须在.merge()
更新的情况下在强制节点上错误地使用.on('tick', ...)
来解决,但是我无法从文档中看到我想要的东西。
这是我的相关代码(请参见上面的块)
// initital data
let sampleData = d3.range(2).map((d,i) => ({r: 40 - i * 0.5}));
function changeNetwork() {
d3.selectAll('.force1')
.attr('cx', d => d.x)
.attr('cy', d => d.y)
};
function force1(data) {
const manyBody = d3.forceManyBody().strength(2)
const center = d3.forceCenter().x((width/2)).y((height/2))
// define force
let force = d3.forceSimulation()
.force('charge', manyBody)
.force('center', center)
.force('collision', d3.forceCollide(d => d.r + 2))
.velocityDecay(.48);
force
.nodes(data)
.on('tick', changeNetwork);
svg.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('class', 'force1')
.style('fill', 'coral')
.attr('r', d => d.r)
return force
}
function clickButton() {
// generate random data point
let ranNum = Math.round(Math.random() * 20);
let newDataPoint = {r: 40 - ranNum * 0.5}
// update datasource
sampleData = sampleData.concat(newDataPoint);
let nodes = svg.selectAll('circle.force1')
.data(sampleData);
let nodeEnter = nodes.enter()
.append('circle')
.attr('class', 'force1')
.style('fill', 'blue')
.attr('r', d => d.r / 2)
nodes = nodeEnter.merge(nodes)
.on('tick', changeNetwork)
f1.nodes(sampleData);
f1.alpha(1).restart()
}
感谢您的帮助!