Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between D3 forceX/forceY and forceCenter

I have the following code :

var simulation = d3v5.forceSimulation()
      .force('link', d3v5.forceLink().id(function (d) { return d.id; }))
      .force('charge', d3v5.forceManyBody())
      .force('center', d3v5.forceCenter(width / 2, height / 2))

Here is an example codePen (see line 57): https://codepen.io/anon/pen/PdOqZK?editors=1010

The last line sets the force center. When I drag nodes around and have this center being set, the nodes seem to go out from the center. But when I have the following :

var simulation = d3v5.forceSimulation()
      .force('link', d3v5.forceLink().id(function (d) { return d.id; }))
      .force('charge', d3v5.forceManyBody())
      .force('x', d3v5.forceX(width / 2))
      .force('y', d3v5.forceY(height / 2))

Here is an example codePen (see line 57): https://codepen.io/anon/pen/gdXprR?editors=1010

It works as expected. Would be great if someone could explain what's happening.

like image 899
thatOneGuy Avatar asked Oct 25 '25 22:10

thatOneGuy


1 Answers

The behaviours of both your JSFiddles are the expected ones.

The issue here is that d3.forceCenter and d3.forceX/Y are not interchangeable or similar methods. "Centering" and "positioning" are not the same, they have very different uses and effects.

If you look at the API, you'll see that d3.forceCenter...

...translates nodes uniformly so that the mean position of all nodes (the center of mass if all nodes have equal weight) is at the given position ⟨x,y⟩. (emphasis mine)

Therefore, the important concept here is the "center of mass". When you move a node to the right hand side, for instance, the other nodes move to the left hand side, so the center of mass stays at the specified position. The effect of this behaviour is that, if you drag a node to the edge of the SVG, other nodes will disappear at the opposite side.

On the other hand, "positioning" does not affect all the nodes simultaneously. As the API states regarding d3.forceX/Y,

... while these forces can be used to position individual nodes... (emphasis mine)

like image 152
Gerardo Furtado Avatar answered Oct 28 '25 13:10

Gerardo Furtado