2

MWEs

I tried to create the same graph with both version, here are the Bl.ocks:

These examples are adapted from one of the official examples.

Issue

Differences arises when there is more than one connected component. There are two things in particular that don't work for me in version 4:

  1. dragging one connected component makes the others to translate wildly around (I guess) the force center, in a very non-physics way;

  2. on mouse down (even without actually moving) the other connected components move away indefinitely, eventually off screen.

In short, graphs in version 3 are unbreakable, no matter how much you mess with nodes they will eventually return into a stable position.

How can I fix these two behaviors, making the simulation more similar to version 3?

Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
cYrus
  • 2,976
  • 6
  • 29
  • 47

1 Answers1

7

You don't want d3.forceCenter. If you look at the API:

The centering force 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⟩

This means that, when you move a node away from the center, the other nodes will move in the opposite direction, to compensate the movement, so the center of mass stays at the same position.

Instead, use forceX and forceY:

The x- and y-positioning forces push nodes towards a desired position along the given dimension with a configurable strength.

So, this is the simulation:

const simulation = d3.forceSimulation()
     .force('link', d3.forceLink().distance(200))
     .force('charge', d3.forceManyBody())
     .force('centerX', d3.forceX(width / 2))
     .force('centerY', d3.forceY(height / 2));

Here is an updated fiddle: https://jsfiddle.net/ahdbLL8a/

Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
  • Awesome, thank you so much, that's exactly what I was after! – cYrus Nov 19 '16 at 15:47
  • 1
    Oh my god! Gerardo! I can't tell you how thankful I am!!! I looked hours for the solution of a similar issue after upgrading to d3v4... Taking my huge codebase apart piece by piece... My issue was about the labels of fixed circles going wild in the very beginning of the simulation. The final VERY SIMPLE solution was to drop the center completely! I posted my example in a [jsfiddle](https://jsfiddle.net/dominicbosch/g95md4b4/). I would give you a hundred upvotes if I could ;) – Dominic Jan 25 '17 at 13:51
  • @Dominic No worries! Coincidentally, I just answered a similar question today: http://stackoverflow.com/questions/41843166/d3-js-pass-anonymous-function-as-parameter-to-centering-force . Apparently, there is some confusion between `forceCenter` and `forceX/Y`. – Gerardo Furtado Jan 25 '17 at 13:57
  • 1
    Yeah, after all there were quite a lot of deep changes in the new version d3v4. It forces you to go back to the specs and read them again. Which I actually appreciate since it has many nice new features and I was able to optimize quite a lot through this process. Even if it's time consuming... – Dominic Jan 27 '17 at 09:07