Pirs - 3 years ago 231

Javascript Question

I'm trying to do a container with balls inside, attracted to the floor like gravity. I'm close to doing it well but the balls eventually melt into each other then don't preserve their visibility.

See the demo here

I think the problem comes from the gravity function itself because the radius of each node isn't into account:

`var gravity = function() {`

return function(d) {

d.y += (d.cy - d.y);

d.x += (d.cx - d.x);

};

}

or from the bounding function in the simulation animation (tick), for the same problem above

`d3.selectAll("circle.node")`

.attr("cx", function(d,i){ return Math.max(radius, Math.min(width - radius, d.x)); })

.attr("cy", function(d,i){ return Math.max(radius, Math.min(height - radius, d.y)); });

How can I separate each ball distinctly in this case?

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

Ok, i finally read the docs and understood the problem !

All is about the collide between each node, to integrate it correctly in the forceSimulation, and the bound calculation in the tick function:

```
...
// Change values below to modify the physic
var simulation = d3.forceSimulation()
.velocityDecay(0.3)
.force("y", d3.forceY(height).strength(.035)) // gravity at bottom
.force("collide", d3.forceCollide().radius(radius).strength(1.5).iterations(10))
.nodes(nodes)
.on('tick', tick);
function tick() {
// bound
node.attr('cx', function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
.attr('cy', function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });
}
```

Recommended from our users: **Dynamic Network Monitoring from WhatsUp Gold from IPSwitch**. ** Free Download**