d3-force directed graph (forces experiments for dummies)
By: Liron Hazan
Tags: D3, Graph, Frontend, UI, API

The need to visualize a large amount of data / data flows / entities relations in a way that our brain could face it is an interesting challenge in UX / UI and interactive graphs are in daily use, a lot of them are based on d3.

The d3-force module:

Force-directed graph layout using velocity Verlet integration.

“Verlet integration”?

OK, but my narrow world is more into frontend terms can I just stay a dummy and create my own graph? — definitely YES.

Here’s the graph I created:

(I didn’t give much effort on styling, that wasn’t my purpose).

I listed some terms and definitions that are relevant when working with the d3-force, here’s the repo.

The <defs> element is used to define SVG elements without rendering them. Combined with a ‘g’ tag, it can be used to create a template for an intricate graphic that contains many elements.

element is used to define SVG elements without rendering them. Combined with a ‘g’ tag, it can be used to create a template for an intricate graphic that contains many elements. The <marker> element defines the graphic that is to be used for drawing arrowheads or polymarkers on a given <path> , <line> , <polyline> or <polygon> element.

create a simulation for an array of nodes, and compose the desired forces.

forceSimulation: d3.forceSimulation() Creates a new simulation with the specified array of nodes and no forces. If nodes are not specified, it defaults to the empty array

A force is simply a function that modifies nodes’ positions or velocities

simulation.force : If force is specified, assigns the force for the specified name and returns this simulation.

: If force is specified, assigns the force for the specified name and returns this simulation. The “charge” force — like electrostatic charge, when negative will push nodes away, (default strength is -30) the charge force is global: every node affects every other node, even if they are on disconnected subgraphs (used with many-body().

force — like electrostatic charge, when negative will push nodes away, (default strength is -30) the charge force is global: every node affects every other node, even if they are on disconnected subgraphs (used with many-body(). The “center” force — centering force, centers all nodes at the given position ⟨x,y⟩.

force — centering force, centers all nodes at the given position ⟨x,y⟩. The “ link” force — The link force pushes linked nodes together or apart according to the desired link distance.

force The link force pushes linked nodes together or apart according to the desired link distance. forceLink : Creates a new link force with the specified links and default parameters. If links are not specified, it defaults to the empty array.

: Creates a new link force with the specified links and default parameters. If links are not specified, it defaults to the empty array. The “ many-body ” force applies mutually amongst all nodes. It can be used to simulate gravity (attraction) if the strength is a positive, or electrostatic charge (repulsion) if the strength is negative.

” force applies mutually amongst all nodes. It can be used to simulate gravity (attraction) if the strength is a positive, or electrostatic charge (repulsion) if the strength is negative. alphaTarget: Usually used on interactions such as drag-drop a node, together with restart(), it’s hard to understand — thus hard to explain what is the “alpha” concept, it plays a role in “slowing” the nodes transition, for a “smother” experience when changing the layout by dropping the node somewhere, according to the API docs: alphaTarget sets the current target alpha to the specified number in the range [0,1] and returns this simulation.

tick — The simulator starts automatically, and after the node data iteration the tick event is triggered, on its handler fn the nodes and lines get a calculated x- and y-positions.

References: