Types
All types shown here are exported from vizcraft and can be imported as:
import type { VizScene, VizNode, VizEdge, ... } from 'vizcraft';
VizScene
Complete, serializable description of what to render.
| Field | Type | Description |
|---|---|---|
viewBox | { w: number; h: number } | SVG coordinate space |
nodes | VizNode[] | Nodes to render |
edges | VizEdge[] | Edges to render |
overlays? | VizOverlaySpec[] | Optional overlay layer |
animationSpecs? | AnimationSpec[] | Data-only timelines |
sketch? | { enabled?: boolean; seed?: number } | Global hand-drawn mode |
VizNode
A node in the scene graph.
| Field | Type | Description |
| -------------------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------- | ---------------------- | ------------------------------------------------------------------------------ |
| id | string | Unique identifier |
| pos | { x: number; y: number } | Base position |
| shape | NodeShape | Geometry (see NodeShape) |
| label? | NodeLabel | Text label |
| style? | object | fill, stroke, strokeWidth, opacity, strokeDasharray, shadow, sketch, sketchSeed |
| className? | string | CSS class |
| runtime? | VizRuntimeNodeProps | Runtime-only overrides (animation system) |
| animations? | VizAnimSpec[] | Registry/CSS animation requests |
| data? | unknown | Custom payload |
| parentId? | string | Parent container node id |
| container? | ContainerConfig | Container configuration |
| ports? | NodePort[] | Explicit connection ports | | compartments? | VizNodeCompartment[] | Horizontal sections (UML-style). See VizNodeCompartment |
| collapsed? | boolean | When true, only the first compartment is rendered (compact mode) |
| collapseIndicator? | CollapseIndicatorOptions | false | Customise or hide the collapse chevron. Pass false to hide entirely |
| collapseAnchor? | CollapseAnchor | Anchor point for collapse animation: 'top', 'center' (default), or 'bottom' |
| tooltip? | TooltipContent | Tooltip shown on hover/focus. See TooltipContent |
| badges? | VizNodeBadge[] | Text badges pinned to corners. See VizNodeBadge |
VizEdge
An edge connecting two nodes (or a dangling edge with free endpoints).
| Field | Type | Description |
|---|---|---|
id | string | Unique id (commonly "a->b") |
from? | string | Source node id |
to? | string | Target node id |
fromAt? | Vec2 | Free-endpoint for source (dangling) |
toAt? | Vec2 | Free-endpoint for target (dangling) |
fromPort? | string | Source port id |
toPort? | string | Target port id |
fromAngle? | number | Fixed perimeter angle at source (degrees) |
toAngle? | number | Fixed perimeter angle at target (degrees) |
straightLine? | boolean | 'from' | 'to' | Auto-compute perimeter angles for a straight line between nodes |
routing? | EdgeRouting | Path algorithm |
waypoints? | Vec2[] | Intermediate points |
markerEnd? | EdgeMarkerType | Target marker |
markerStart? | EdgeMarkerType | Source marker |
anchor? | 'center' | 'boundary' | Connection behavior |
labels? | EdgeLabel[] | Labels at various positions |
style? | object | stroke, strokeWidth, fill, opacity, strokeDasharray, sketch |
runtime? | VizRuntimeEdgeProps | Runtime-only overrides |
animations? | VizAnimSpec[] | Registry/CSS animation requests |
meta? | Record<string, unknown> | User metadata |
data? | unknown | Custom payload |
tooltip? | TooltipContent | Tooltip shown on hover/focus. See TooltipContent |
EdgeRouting
| Mode | Description |
|---|---|
'straight' | Direct line (default). Polyline with waypoints. |
'curved' | Smooth bezier. Catmull-Rom spline through waypoints. |
'orthogonal' | Right-angle (elbow) connectors. |
EdgeMarkerType
| Type | Description | Use case |
|---|---|---|
'none' | No marker | Plain line |
'arrow' | Filled triangle | Dependency |
'arrowOpen' | Open triangle | Inheritance (UML) |
'diamond' | Filled diamond | Composition (UML) |
'diamondOpen' | Open diamond | Aggregation (UML) |
'circle' | Filled circle | Navigable association |
'circleOpen' | Open circle | Association endpoint |
'square' | Filled square | Custom endpoint |
'bar' | Perpendicular T-line | ER cardinality |
'halfArrow' | Single-sided arrow | Directional hint |
EdgeLabel
| Property | Type | Description |
|---|---|---|
text | string | Label text |
rich? | RichText | Rich formatted label |
position | 'start' | 'mid' | 'end' | Position on path |
className? | string | CSS class |
dx? | number | Horizontal offset |
dy? | number | Vertical offset (default -10) |
fill? | string | Text color |
fontSize? | number | string | Font size |
fontWeight? | number | string | Font weight |
fontFamily? | string | Font family |
NodeShape
Supported geometries. Each variant is a discriminated union on kind:
| Kind | Key params | Description |
|---|---|---|
circle | r | Circle |
rect | w, h, rx? | Rectangle |
diamond | w, h | Rhombus |
ellipse | rx, ry | Ellipse |
hexagon | r, orientation? | Regular hexagon |
cylinder | w, h, arcHeight? | Database symbol |
triangle | w, h, direction? | Triangle |
star | points, outerR, innerR? | Multi-pointed star |
cloud | w, h | Bumpy outline |
cross | size, barWidth? | Plus sign |
cube | w, h, depth? | 3D isometric box |
arc | r, startAngle, endAngle, closed? | Arc/pie slice |
blockArrow | length, bodyWidth, headWidth, headLength, direction? | Thick arrow |
callout | w, h, pointer options | Speech bubble |
document | w, h, waveHeight? | Wavy bottom |
note | w, h, foldSize? | Folded corner |
parallelogram | w, h, skew? | Skewed rect |
trapezoid | topW, bottomW, h | Trapezoid |
path | d, w, h | Custom SVG path |
NodeLabel
| Property | Type | Description |
|---|---|---|
text | string | Label text |
rich? | RichText | Rich/mixed-format label |
className? | string | CSS class |
dx? | number | Horizontal offset |
dy? | number | Vertical offset |
fill? | string | Text color |
fontSize? | number | string | Font size |
fontWeight? | number | string | Font weight |
fontFamily? | string | Font family |
RichText
Token model for mixed-format labels.
type RichText = { kind: 'rich'; tokens: RichTextToken[] };
type RichTextToken =
| {
kind: 'span';
text: string;
bold?: boolean;
italic?: boolean;
underline?: boolean;
code?: boolean;
href?: string;
fill?: string;
fontSize?: number | string;
fontWeight?: number | string;
fontFamily?: string;
baselineShift?: 'sub' | 'super';
className?: string;
}
| { kind: 'newline' };
NodePort
| Field | Type | Description |
|---|---|---|
id | string | Port identifier (e.g. 'top', 'right') |
offset | Vec2 | Position relative to node center |
direction? | number | Outgoing angle in degrees |
Default ports
| Shape | Default ports | IDs |
|---|---|---|
rect, circle, diamond, ellipse, cylinder | 4 | top, right, bottom, left |
hexagon (pointy) | 6 | top, top-right, bottom-right, bottom, bottom-left, top-left |
hexagon (flat) | 6 | right, top-right, top-left, left, bottom-left, bottom-right |
triangle | 3–4 | varies by direction |
| Fallback | 4 | top, right, bottom, left |
Port utility functions
| Function | Signature | Description |
|---|---|---|
getDefaultPorts | (shape) => NodePort[] | Default ports for a shape |
getNodePorts | (node) => NodePort[] | Effective ports (explicit or default) |
findPort | (node, portId) => NodePort? | Lookup by id |
findPortNearest | (node, x, y) => NodePort? | Closest port to a point |
resolvePortPosition | (node, portId) => Vec2? | Absolute port position |
getEquidistantPorts | (shape, count?) => EquidistantPort[] | N equidistant perimeter points |
toNodePorts | (ports) => NodePort[] | Convert EquidistantPort to NodePort |
registerPerimeterStrategy | (strategy) => void | Register custom perimeter strategy |
EquidistantPort
| Field | Type | Description |
|---|---|---|
id | string | Location-based identifier |
angle | number | Angle from center (degrees) |
t | number | Parametric proportion [0, 1) |
x | number | X offset from center |
y | number | Y offset from center |
ContainerConfig
| Field | Type | Default | Description |
|---|---|---|---|
layout? | 'free' | 'vertical' | 'horizontal' | 'free' | Child layout |
padding? | { top, right, bottom, left } | — | Interior padding |
autoSize? | boolean | — | Auto-resize to fit children |
headerHeight? | number | — | Header band height |
VizNodeCompartment
A horizontal section inside a compartmented node (e.g. UML class box name/attributes/methods).
| Field | Type | Description |
|---|---|---|
id | string | Unique id within the node (e.g. 'name', 'methods') |
y | number | Y offset from the node's top edge (computed at build) |
height | number | Height in pixels |
label? | NodeLabel | Optional label rendered inside the compartment |
entries? | CompartmentEntry[] | Per-line interactive entries (mutually exclusive with label) |
onClick? | (ctx: CompartmentClickContext) => void | Click handler receiving context with toggle() helper. See CompartmentClickContext |
Compartments are auto-sized when no explicit height is given — the builder estimates height from the label's line count and font size, or from the number of entries.
CompartmentClickContext
Context passed to a compartment's onClick handler, providing collapse control.
| Field | Type | Description |
|---|---|---|
nodeId | string | The node's id |
compartmentId | string | The compartment's id |
collapsed | boolean | Current collapsed state (before toggling) |
collapseAnchor | CollapseAnchor | Current collapse anchor of the node ('center' when unset) |
toggle | (opts?: { animate?: number; anchor?: CollapseAnchor }) => void | Toggle collapse; optional animate duration in ms, optional anchor override |
CollapseIndicatorOptions
Options for customising the collapse indicator (chevron) on compartmented nodes.
| Field | Type | Description |
|---|---|---|
color? | string | Fill colour of the default triangle. Defaults to the node's stroke colour |
visible? | boolean | Set to false to hide the indicator. Defaults to true when a compartment has an onClick handler |
render? | (collapsed: boolean) => string | Return a custom SVG string to replace the default triangle. Receives the current collapsed state |
Pass false instead of an options object to hide the indicator entirely:
.collapseIndicator(false)
CollapseAnchor
The anchor point from which a node collapses/expands:
| Value | Description |
|---|---|
'top' | Top edge stays fixed; the node shrinks/grows downward |
'center' | The node shrinks/grows symmetrically (default) |
'bottom' | Bottom edge stays fixed; the node shrinks/grows upward |
type CollapseAnchor = 'top' | 'center' | 'bottom';
CompartmentEntry
A single interactive line inside a compartment. Each entry has its own hit region, optional click handler, tooltip, and styling.
| Field | Type | Description |
|---|---|---|
id | string | Unique id within the compartment |
y | number | Y offset within the compartment (computed) |
height | number | Height in pixels (computed, includes padding) |
text | string | Display text |
label? | NodeLabel | Resolved label with styles |
onClick? | () => void | Click handler for this entry |
tooltip? | TooltipContent | Tooltip shown on hover |
className? | string | Custom CSS class applied to the entry element |
paddingTop? | number | Top padding in pixels (default 0) |
paddingBottom? | number | Bottom padding in pixels (default 0) |
EntryStyle
Per-entry text styling options.
| Field | Type | Description |
|---|---|---|
fill? | string | Text color |
fontSize? | number | string | Font size |
fontWeight? | number | string | Font weight |
fontStyle? | string | Font style (e.g. 'italic') |
fontFamily? | string | Font family |
EntryOptions
Options passed to .entry(id, text, opts?) on the CompartmentBuilder.
| Field | Type | Description |
|---|---|---|
onClick? | () => void | Click handler |
style? | EntryStyle | Per-entry text styling |
tooltip? | TooltipContent | Tooltip shown on hover |
maxWidth? | number | Max text width in pixels |
overflow? | 'clip' | 'ellipsis' | Text overflow behavior |
padding? | number | { top?: number; bottom?: number } | Vertical padding around entry text. A single number applies equally to top and bottom. |
className? | string | Custom CSS class applied to the entry element |
TooltipContent
Tooltip content attached to a node or edge. Shown on hover or keyboard focus.
Can be a plain string or a structured object with optional title and labelled sections.
type TooltipContent = string | { title?: string; sections: TooltipSection[] };
TooltipSection
| Field | Type | Description |
|---|---|---|
label | string | Key / label text |
value | string | Value / info text |
VizNodeBadge
A small text indicator pinned to a corner of a node shape.
| Field | Type | Description |
|---|---|---|
text | string | 1–2 character badge text |
position | BadgePosition | Corner: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' |
fill? | string | Text color |
background? | string | Optional pill background color |
fontSize? | number | Font size in px (default 10) |
BadgePosition
type BadgePosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
VizPlugin
type VizPlugin<Options = any> = (
builder: VizBuilder,
options?: Options
) => void;
NodeOptions
Declarative options for builder.node(id, opts). See Builder API.
EdgeOptions
Declarative options for builder.edge(from, to, opts). See Builder API.
Animation types
AnimationSpec
{ version: 'viz-anim/1'; tweens: TweenSpec[] }
TweenSpec
{ kind: 'tween'; target: AnimationTarget; property: AnimProperty; to: number; duration: number; delay?: number; easing?: Ease; from?: number }
AnimationTarget
node:<id>— targets a nodeedge:<id>— targets an edgeoverlay:<key>— targets an overlay
AnimProperty / CoreAnimProperty
Core: x, y, opacity, scale, rotation (nodes); opacity, strokeDashoffset (edges). Custom properties via extendAdapter.
AnimatableProps
Property bag for aBuilder.to(props, opts). Typed for core properties, accepts arbitrary numeric keys.
TweenOptions
{ duration: number; easing?: Ease; from?: Record<string, number> }
Ease
'linear' | 'easeIn' | 'easeOut' | 'easeInOut'
PlaybackController
{ play(): void; pause(): void; stop(): void; seek(ms: number): void }
ExtendAdapter
(adapter: AnimationHostAdapter & Partial<RegistrableAdapter>) => void
VizRuntimeNodeProps
| Field | Type |
|---|---|
x? | number |
y? | number |
opacity? | number |
scale? | number |
rotation? | number |
VizRuntimeEdgeProps
| Field | Type |
|---|---|
strokeDashoffset? | number |
opacity? | number |
EdgePathResult
Low-level path computation result returned by computeEdgePath and computeSelfLoop.
| Field | Type | Description |
|---|---|---|
d | string | SVG path d attribute |
mid | Vec2 | Approximate midpoint along the path |
start | Vec2 | Position near the source (~15% along the path) |
end | Vec2 | Position near the target (~85% along the path) |
ResolvedEdgeGeometry
Returned by resolveEdgeGeometry. Extends EdgePathResult with convenience fields.
| Field | Type | Description |
|---|---|---|
d | string | SVG path d attribute |
mid | Vec2 | Approximate midpoint along the path |
start | Vec2 | Position near the source (~15% along the path) — same as startLabel |
end | Vec2 | Position near the target (~85% along the path) — same as endLabel |
startAnchor | Vec2 | True boundary/port position where the edge exits the source node |
endAnchor | Vec2 | True boundary/port position where the edge enters the target node |
startLabel | Vec2 | Label position ~15% along the path (alias of start) |
endLabel | Vec2 | Label position ~85% along the path (alias of end) |
waypoints | Vec2[] | Waypoints used for the path (empty array when none) |
isSelfLoop | boolean | Whether this edge is a self-loop |
Layout Types
LayoutGraph
Input graph structure passed to layout algorithms.
| Field | Type | Description |
|---|---|---|
nodes | VizNode[] | All nodes |
edges | VizEdge[] | All edges |
LayoutResult
Result returned by a layout algorithm.
| Field | Type | Description |
|---|---|---|
nodes | Record<string, { x: number; y: number }> | Computed node positions |
edges? | Record<string, { waypoints?: Vec2[] }> | Optional edge routing waypoints |
LayoutAlgorithm
A function that computes node positions. May return synchronously or as a Promise for async engines.
// Sync-only variant (for .layout())
type SyncLayoutAlgorithm<Options = any> = (
graph: LayoutGraph,
options?: Options
) => LayoutResult;
// Sync or async variant (for .layoutAsync())
type LayoutAlgorithm<Options = any> = (
graph: LayoutGraph,
options?: Options
) => LayoutResult | Promise<LayoutResult>;
Utilities
getNodeBoundingBox(shape)
Computes the tight axis-aligned bounding-box size for a given NodeShape.
import { getNodeBoundingBox } from 'vizcraft';
const { width, height } = getNodeBoundingBox({ kind: 'circle', r: 25 });
// → { width: 50, height: 50 }
Supports every NodeShape variant (circle, rect, diamond, ellipse, hexagon, star, trapezoid, callout, blockArrow, etc.) and accounts for orientation, direction, pointer height, and other shape-specific parameters.
Found a problem? Open an issue on GitHub.