3
votes

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.

1
Have a look at my explanation here: stackoverflow.com/a/51841404/5768908 - Gerardo Furtado
@GerardoFurtado I get that it gives you the center of the force, but whats the reason for it moving outwards ? Is it just because I hadnt set the force x and y ? - thatOneGuy
No, it's because the centre of mass says at the same position, not the individual nodes. That's why dragging one node makes other nodes moving outwards. - Gerardo Furtado

1 Answers

3
votes

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)