Graph
Force-directed node/edge graph with draggable nodes, pan/zoom, hover-highlighting, and keyboard navigation.
Installation
npx dafink-ui add graphRequires: d3-force, @types/d3-force
Demo
Props
| Name | Type | Default | Description |
|---|---|---|---|
| nodes | GraphNode[] | - | Required. Array of { id, label, group? } objects. |
| edges | GraphEdge[] | - | Required. Array of { source, target } objects referencing node ids. |
| width | number | 600 | SVG width in pixels. |
| height | number | 400 | SVG height in pixels. |
| className | string | "" | Additional classes on the root wrapper div. |
| onNodeSelect | (node: GraphNode) => void | - | Called when a node is selected via click or keyboard Enter/Space. |
Accessibility
Graph uses roving tabindex over a listbox: the SVG root is a single Tab stop (role="application"), and only the selected node (role="option" inside a role="listbox") carries tabIndex=0, with every other node at tabIndex=-1. Node/edge dragging, panning, and mouse-wheel zoom are pointer-only, with no keyboard equivalent for dragging or panning specifically; a hidden aria-live="polite" status region announces the initial node/edge count and every selection change.
| Key | Function |
|---|---|
| tab | Moves focus into the graph container. |
| right arrow | Moves selection to the next node, wrapping from the last node to the first. |
| down arrow | Moves selection to the next node, wrapping from the last node to the first. |
| left arrow | Moves selection to the previous node, wrapping from the first node to the last. |
| up arrow | Moves selection to the previous node, wrapping from the first node to the last. |
| enter | Selects the focused node and fires onNodeSelect. |
| space | Selects the focused node and fires onNodeSelect. |
| escape | Clears the selection and returns focus to the graph container. |
| + | Zooms in. |
| - | Zooms out. |
| 0 | Resets zoom and pan. |