Command Palette

Search for a command to run...

Hectal
Back to the lesson: Topic 13.5 — Force-Directed Networks
Data Visualization · Example 2 of 2

When a network goes wrong: a missing station, overlap, lonely nodes, hairballs, dragging

Each case runs in its own simulation over a fresh copy of the data. Positions are rounded to whole pixels.

A network is things (nodes) joined by connections (links). A force simulation places the nodes by pretending they are charged balls joined by springs, and lets them settle. You decide how many steps to run, and how to keep it readable when there are too many links.

Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.

Ready for more? This phase has 4 hands-on exercises with automatic checks.

Practice questions

Write the code in the editor, run it, then open the model answer to compare.

01

Add a slider-free version of the threshold: a function strongest(links, min) that keeps links with at least min trips and returns the nodes they use. Then run the simulation on that part only.

02

Make nodes draggable: add d3.drag() to the node groups so that dragging sets fx and fy, and release clears them.

Explain it without notes

01

What does each of forceLink, forceManyBody, forceCenter and forceCollide do?

02

What is alpha, and when does a simulation stop?

03

Why would you call stop() and tick() yourself?

04

What can you do when a network is a hairball?

When a network goes wrong: a missing station, overlap, lonely nodes, hairballs, dragging

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

a link to a missing station: node not found: S99
no collide force  | pairs of 7 px circles that overlap: 12
forceCollide(7)   | pairs of 7 px circles that overlap: 0
all routes: 60 routes, 20 stations | 60+ trips: 17 routes, 10 stations | 70+ trips: 5 routes, 6 stations | 80+ trips: 2 routes, 3 stations
no x/y force      | the lonely station is 429 px from the centre
forceX and forceY | the lonely station is 159 px from the centre
dragged: Quay is at 50 50 | alpha 0.25 (held up by alphaTarget 0.3)
released: Quay is at 116, 108 | alpha 0.063