Skip to main content

Declarative Specs (fromSpec)

Overview

fromSpec lets you describe a VizCraft scene as a plain JSON object, then get back a fully hydrated VizBuilder you can chain, mount, or build like normal.

import { fromSpec } from 'vizcraft';

const builder = fromSpec({ view: ..., nodes: [...], edges: [...] });
builder.mount(container);

Use it when:

  • An LLM is generating scenes. Plain JSON is schema-validatable and round-trips cleanly through structured outputs.
  • Scenes come from a database or API. Store a VizSpec object; hydrate it back into a live builder at render time.
  • You prefer a data-first workflow. Build the data, inspect it, then render — no method-chaining required.

Mental model

fromSpec is a translation layer, not a sealed format. It calls the same fluent builder methods you would write by hand. The result is an ordinary VizBuilder — you can keep chaining after fromSpec returns:

const builder = fromSpec(spec)
.node('extra')
.at(900, 180)
.rect(120, 40)
.label('Extra')
.done()
.edge('lb', 'extra')
.done();

builder.mount(container);

Quick start


API reference

fromSpec(spec: VizSpec): VizBuilder

Translates the spec and returns a VizBuilder. Throws if spec.view is missing required fields, but is otherwise lenient — unknown fields are silently ignored.


VizSpec

FieldTypeRequiredDescription
view{ width; height }Viewport dimensions in scene units
nodesNodeSpec[]Scene nodes
edgesEdgeSpec[]Edges between nodes
overlaysStaticOverlaySpec[]Static rect / circle / text annotations
autoSignalsAutoSignalSpec[]Self-animating signals (future feature)
stepsVizStepSpec[]Step-through walkthrough (future feature)

NodeSpec

FieldTypeDefaultDescription
idstringUnique id. Referenced by edges, overlays, and signals
labelstring | string[]Display text. Array → multi-line (joined with \n)
shapeNodeSpecShape'rect'Shape name (see table below)
xnumberCentre X in scene coordinates
ynumberCentre Y in scene coordinates
widthnumberper-shapeWidth. For circle: diameter; for ellipse: full width
heightnumberper-shapeHeight. Ignored for circle and hexagon
fillstringFill colour
strokestringStroke colour
strokeWidthnumberStroke width
opacitynumberOpacity 0–1
dashedbooleanDashed border
dottedbooleanDotted border
classstringCSS class on the node's root SVG element
tooltipobject{ title, sections? } tooltip on hover

Node shape defaults

shapeDefault widthDefault heightNotes
rect12040
circle40width = diameter; radius = width / 2
cylinder10050
diamond8060
hexagon8060radius = min(width, height) / 2
ellipse12040semi-axes = width/2, height/2
cloud12040
document12040
parallelogram12040
triangle12040
note12040

EdgeSpec

FieldTypeDefaultDescription
fromstringSource node id
tostringTarget node id
idstringfrom-toExplicit edge id for overlay anchoring
labelstringEdge label
styleEdgeStyleSpec'straight''straight' | 'curved' | 'orthogonal'
arrowArrowModeSpec'end''end' | 'start' | 'both' | false
animate'flow' | false'flow' adds a marching-ants CSS animation
strokestringStroke colour
strokeWidthnumberStroke width
dashedbooleanDashed stroke
dottedbooleanDotted stroke
opacitynumberOpacity 0–1
classstringCSS class

StaticOverlaySpec

Discriminated union on type. All types share the positioning fields:

FieldTypeDescription
typestring'rect', 'circle', or 'text'
keystringOptional stable key for runtime patching
nodeIdstringWhen present, x/y are offsets from the node centre
xnumberAbsolute x, or x-offset from nodeId centre when nodeId is set
ynumberAbsolute y, or y-offset from nodeId centre when nodeId is set
opacitynumberOpacity 0–1

See the Overlay API for the complete field listings per type.


AutoSignalSpec (future)

The autoSignals field is accepted and stored but produces no rendering behaviour until the internal-signal-animation feature is activated.

FieldTypeDefaultDescription
idstringUnique id. Must be stable across re-renders
chainstring[]Ordered node ids. Minimum 2 entries
durationPerHopnumber800ms per hop
totalDurationnumberAlternative: total ms across all hops
loopbooleanfalseRestart after reaching the final node
loopDelaynumber0Pause in ms before restarting when loop: true
keepFinalbooleanfalsePark the dot at the final node when loop: false
colorstringDot fill colour
glowColorstringSeparate glow / halo colour
magnitudenumber1Visual scale of the signal dot (0–1)

Notes

  • fromSpec calls the same builder methods as hand-authored code — there is no separate render path.
  • The returned VizBuilder can be further chained after fromSpec.
  • autoSignals and steps are silently ignored at build/mount time until the corresponding features are activated. No error is thrown.
  • Overlay x/y are offsets (not absolute coords) when nodeId is present, matching the semantics of nodeId + offsetX/offsetY in the internal overlay system.