block by harrystevens 2d8d15a34c637cba6a85c6eb039ce072

Five Forces

Full Screen

In a D3.js force layout, you can apply distinct forces to nodes based on attributes of the underlying data. Suppose you want to create six “buckets” of nodes. You can think of each bucket as being placed in one cell of a 2x3 grid:

The letters a through f represent the six options of the underlying data by which we will group our nodes. The columns are labeled x1, x2 and x3 and the rows, y1 and y2. Each of these labels can also be thought of as a distinct force. The x1 force, for example, will apply to groups a and d, dragging their horizontal center to the left side of the screen. The y2 force will apply to groups d, e and f and will drag their vertical center to the bottom half of the screen. And so on.

In a D3 force simulation, you can name your forces whatever you want. I have named my five forces according to the labels:

.force("y1", isolate(d3.forceY(-height / 8), function(d){ return d.class == "a" || d.class == "b" || d.class == "c"; })) // applies to a, b & c
.force("y2", isolate(d3.forceY(height / 8), function(d){ return d.class == "d" || d.class == "e" || d.class == "f"; })) // applies to d, e & f
.force("x1", isolate(d3.forceX(-width / 6), function(d) { return d.class === "a" || d.class == "d"; })) // applies to a & d
.force("x2", isolate(d3.forceX(), function(d) { return d.class === "b" || d.class == "e"; })) // applies to b & e
.force("x3", isolate(d3.forceX(width / 6), function(d) { return d.class === "c" || d.class == "f"; })) // applies to c & f

The isolate() function was taken from this block by Mike Bostock. It can also be seen in action in this block by Manas Sharma (who, incidentally, helped me understand how to do this). Both of those blocks use Canvas rather than SVG, which is necessary if you have a lot of nodes. The drawback to that is that Canvas is a pain to use, particularly if you want to add interactivity like tooltips to your nodes. If you have fewer than 1,000 nodes, you should be okay with SVG – after that, your browser will start to suffer.

index.html