I am trying to dynamically update nodes on a d3js force chart, but the collision stops working at some point. It seems the issue is caused by a node which gets placed exactly at the center of the svg canvas, but I can't figure out why. Collision should be able to solve this, right? Any ideas?
I'll attach a minimal reproduction
var width = 400,
height = 200;
var svg = d3.select("svg");
svg.attr("viewBox", [-width / 2, -height / 2, width, height]);
var nodes = [{
radius: 20
}];
var simulation = d3
.forceSimulation(nodes)
.force("charge", d3.forceManyBody().strength(-50))
.force(
"collision",
d3.forceCollide().radius(function(d) {
return d.radius;
})
)
.on("tick", ticked);
function ticked() {
var u = d3.select("svg").selectAll("circle").data(nodes);
u.enter()
.append("circle")
.attr("r", function(d) {
return d.radius;
})
.merge(u)
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
u.exit().remove();
}
function update() {
nodes.push({
radius: Math.random() * (20 - 5) + 5
});
node = svg.selectAll("circle").data(nodes);
node
.enter()
.append("circle")
.attr("r", (d) => d.radius);
simulation.nodes(nodes);
}
setInterval(update, 100);
svg {
background: blue
}
circle {
fill: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="200" />