Skip to content
misoto22 design

Diagrams

DiagramCanvas

A frame that a picture larger than it can be panned and zoomed inside.

Ships from@misoto22/design/diagrams

When to reach for it

Any oversized figure — an SVG, an image, a table that will not fold. It knows nothing about nodes, which is what makes it reusable.

Examples

default

Request path4 elements and 3 relationships.EXTERNALBrowserCLOUDCloudFrontCDNSERVICEAPIFastAPIDATAPostgres

4 elements and 3 relationships.

  • Browser (external)
  • CloudFront (cloud) — CDN
  • API (backend) — FastAPI
  • Postgres (database)
  • BrowserCloudFront: HTTPS
  • CloudFrontAPI
  • APIPostgres: SQL

Drag to pan. Plus and minus zoom, zero resets, the arrow keys pan.

Notes

A frame that a picture larger than it can be moved around inside.

Pan with a drag, zoom with the controls or with ⌘/Ctrl and the wheel, and reset with a key. That is the whole of it — this is deliberately a VIEWPORT and not a diagram editor: nothing here knows what a node is, so it works for any oversized figure, an SVG, an image, a table that will not fold.

Three decisions here are not obvious.

A plain wheel scrolls the page, not the diagram. A canvas that swallows the wheel is a scroll trap: a reader flicking down an article hits the figure and the page stops moving for no reason they can see. Zooming needs the modifier — which is also the platform gesture for zoom everywhere else, and is what a trackpad pinch already sends.

The transform is on a wrapper, not on the content. The child keeps its own coordinate space, so a figure inside can still be measured, exported and read by anything that walks it. Scaling the child directly would make every getBoundingClientRect inside it a lie.

Keyboard first, and the frame is a real tab stop. + / - / 0 and the arrow keys move the view; the frame takes focus so they can be pressed at all. A canvas that only answers a drag is a canvas half the readers cannot operate.

Props

DiagramCanvas props
PropTypeDefaultDescription
childrenrequiredReactNode
classNamestring
controlsbooleantrueHides the built-in zoom controls, for a caller supplying its own.
heightstring'24rem'How tall the frame is. Anything CSS accepts.
labelstring'Diagram canvas'Names the region for assistive tech.
onViewChange(view: CanvasView) => voidTold about every view change, for a minimap or a percentage readout.
refRef<DiagramCanvasHandle>

Keyboard

DiagramCanvas keyboard interactions
KeyDoes
+=Zooms in about the centre of the frame.
-Zooms out.
0Resets the scale and the offset together.
Pans. Shift pans further per press.

Accessibility

  • The frame is a real tab stop, so the keyboard controls can be pressed at all.
  • A plain wheel scrolls the page. Zoom needs the platform modifier, so the canvas is never a scroll trap in the middle of an article.