Medium Pool · every medium your app could speak
$npx skills add funclosure/medium-pool

Visualization

A picture computed from data
messageThe whole is visible before the parts.
instance Force graphNodes, links, emphasis

Visualization is the medium where the picture is computed from data. Node-link graphs, timelines, charts, maps. Nobody draws it; the app lays it out, and the person explores it by dragging, hovering, zooming, and selecting.

It shares a canvas with Drawing and nothing else. The concerns are layout (a force simulation here), hit testing, a camera, and emphasis: making the part that matters right now stand out from the rest.

Reach for it when

  • the content is a structure: relations, sequences, positions, quantities
  • people need to see the whole and then find their part of it
  • the picture must update as the data changes
direction
out (the app shows it)
substrate
2D canvas or WebGL · layout simulation · hit testing and camera

Kinds of this medium

  • Map: The Earth’s surface as the data. Own skill, because its concerns diverge from the medium's.

Where it bites

  • Keep the simulation and the drawing separate. Layout mutates positions; draw reads them. Mixing them makes every feature a physics bug.
  • Hit testing in screen space, not data space. Apply the camera transform in both directions or dragging drifts.
  • Emphasis is a set, not a single selected node. Most real questions light up a subgraph.
  • Damp the simulation and let it settle, or the page never stops burning CPU. Stop the loop entirely when it has converged.
  • Labels are the accessibility story. A canvas is a bitmap to a screen reader, so mirror the node list in the DOM or an aria description.

Instances of this medium

Each is one way to build it. None of them is the medium.

Force graphin the pool

Nodes, links, emphasis. reference/ForceGraph.ts

mindgraphside project

A force-directed concept graph on one 2D canvas, with layout, hit testing, camera, and emphasis all hand-rolled.

D3open source

The toolkit for data-driven documents: forces, scales, shapes, and the vocabulary everyone else borrows.

Cytoscape.jsopen source

Graph theory library with layouts and analysis for node-link views.

sigma.jsopen source

WebGL renderer for graphs too large for a 2D canvas.

$npx skills add funclosure/medium-pool --skill medium-visualization
skills/medium-visualization/SKILL.md
---
name: medium-visualization
description: "Build data-driven graphs, charts, and spatial views on the web with a 2D canvas: layout simulation, hit testing, camera, and emphasis. Use when adding node-link graphs, concept maps, timelines, or explorable charts."
---

# Visualization as a medium

## What this medium does to the person
Visualization shows the whole before the parts. People see structure first, then find their place in it. The app becomes a map of something that had no shape before.

## When to reach for this medium
Choose visualization when the picture is computed from data and people explore it rather than draw it. Structure, relations, and quantities are the content.

## Core browser APIs
- 2D canvas with a `devicePixelRatio`-scaled backing store and a translate/scale camera
- `requestAnimationFrame` loop that runs a layout step then a draw step
- Pointer Events for drag, hover, and select, with hit testing in screen space
- `ResizeObserver` so the view refits when its container changes

## UX rules that always apply
- Something readable in the first frame: seed positions on a circle, never all at the origin.
- Hover highlights, drag moves, click selects. Keep those three consistent everywhere.
- Emphasis is a set of ids; dim everything outside it rather than hiding it.
- Mirror labels in the DOM for screen readers and search.

## Reference instances
Each is one way to speak this medium, cited as evidence. None of them is the medium.

`reference/ForceGraph.ts` — force-directed layout (repulsion, springs, centering, damping), drag and hover hit testing, weighted nodes, a `setEmphasis(ids)` API, add and shake helpers. The same module is composed by `skills/compose-reading-graph`. It uses a few layout class names from the pool's stylesheet (`row`, `btn`, `status`, `frame`); without that stylesheet the logic still runs and the controls are unstyled.

## Gotchas
- Separate simulation from drawing.
- Transform pointer coordinates through the camera before hit testing.
- Stop the loop once the layout settles.