import { OrbitDiagram } from "semiotic"
OrbitDiagram arranges hierarchical data as orbital rings — children revolve around their parent node. It's an animated alternative to tree layouts that emphasizes the relationship between parent and children rather than the structure.
Quick Start
import { OrbitDiagram } from "semiotic" const frameProps = { /* --- Data --- */ data: { name: "CEO", children: [ { name: "Engineering", children: [...] }, { name: "Design", children: [...] }, { name: "Sales", children: [...] }, ] }, childrenAccessor: "children", /* --- Size --- */ width: 500, height: 500, /* --- Process --- */ nodeIdAccessor: "name", /* --- Customize --- */ colorByDepth: true, showLabels: true } export default () => { return <OrbitDiagram {...frameProps} /> }
Examples
Solar Mode
orbitMode="solar" places one child per ring, creating a solar system effect. Combined with eccentricity for elliptical orbits and revolution for depth-based speed.
import { OrbitDiagram } from "semiotic" const frameProps = { /* --- Data --- */ data: solarSystem, childrenAccessor: "children", /* --- Size --- */ width: 500, height: 500, /* --- Layout --- */ orbitMode: "solar", eccentricity: 0.7, revolution: (n) => 1 / (n.depth + 1), /* --- Process --- */ nodeIdAccessor: "name", /* --- Customize --- */ colorByDepth: true, nodeRadius: (n) => n.depth === 0 ? 16 : n.data?.children ? 8 : 4, showLabels: true, speed: 0.4 } export default () => { return <OrbitDiagram {...frameProps} /> }
Atomic Mode
orbitMode="atomic" uses electron shell capacities [2, 8] — the first ring holds 2 nodes, subsequent rings hold 8.
JSX
<OrbitDiagram data={moleculeData} childrenAccessor="children" nodeIdAccessor="name" orbitMode="atomic" speed={0.3} colorByDepth />
Static (No Animation)
Set animated={false} for a static orbital layout without the revolving animation.
import { OrbitDiagram } from "semiotic" const frameProps = { /* --- Data --- */ data: orgData, childrenAccessor: "children", /* --- Size --- */ width: 500, height: 500, /* --- Process --- */ nodeIdAccessor: "name", /* --- Customize --- */ colorByDepth: true, showLabels: true, animated: false } export default () => { return <OrbitDiagram {...frameProps} /> }
Props
| Prop | Type | Required | Default | Description |
|---|
data | object | Yes | — | Root of the hierarchy with children |
childrenAccessor | string | function | — | "children" | How to access children |
nodeIdAccessor | string | function | — | "name" | How to identify nodes |
orbitMode | "flat" | "solar" | "atomic" | number[] | — | "flat" | Ring capacity pattern |
orbitSize | number | function | — | 2.95 | Ring size divisor per depth |
speed | number | — | 0.25 | Rotation speed (degrees/frame) |
revolution | function | — | (n) => 1/(depth+1) | Per-node speed modifier (overrides revolutionStyle) |
revolutionStyle | "locked" | "decay" | "alternate" | — | "locked" | Preset revolution pattern |
eccentricity | number | function | — | 1 | Vertical squash (1=circle, 0.5=ellipse) |
showRings | boolean | — | true | Draw orbital ring paths |
nodeRadius | number | function | — | 6 | Node circle radius |
showLabels | boolean | — | false | Show node name labels |
animated | boolean | — | true | Enable orbital animation |
colorBy | string | function | — | — | Field for node colors |
colorByDepth | boolean | — | false | Color by hierarchy depth |
tooltip | function | — | default | Custom tooltip (static mode only — disabled during animation) |
Orbit Modes
| Mode | Capacity Pattern | Use Case |
|---|
"flat" | [9999] — all in one ring | Org charts, simple hierarchies |
"solar" | [1] — one per ring | Solar systems, sequential depth |
"atomic" | [2, 8] — electron shells | Atomic models, tiered capacity |
[3, 6, 12] | Custom capacities (last repeats) | Custom ring patterns |
Revolution Styles
The revolutionStyle prop controls how child nodes move relative to their parents. You can also pass a custom revolution function for full control.
| Style | Behavior | Use Case |
|---|
"locked" | Children rotate with parent, speed = 1/(depth+1) | Default, natural hierarchy feel |
"decay" | Each depth level exponentially slower | Winding down, outer rings nearly still |
"alternate" | Odd-depth rings reverse direction | Counter-rotating, mechanical feel |
Tooltips are only available when the chart is static (animated={false}). During animation, tooltips are automatically disabled because nodes continuously move under the cursor, causing flicker. Setanimated={false} to enable hover and tooltip interactions.