Skip to main content

Overlay API

Reference for overlay authoring (builder.overlay(...), OverlayBuilder) and the overlay registry.

Overlays are data-only specs (VizOverlaySpec) rendered by the overlay registry.


builder.overlay(...)

Direct form

builder.overlay(id, params, key?)
ParamTypeDescription
idstringOverlay kind (e.g. 'signal', 'rect')
paramsobjectOverlay-specific parameters
keystringStable key (recommended for animation targeting)

Built-in overlay ids are type-safe via OverlayKindRegistry.

Callback form

builder.overlay((o: OverlayBuilder) => {
o.add('grid-labels', { colLabels: { 0: '0' } }, { key: 'labels' }).add(
'signal',
{ from: 'a', to: 'b', progress: 0 },
{ key: 'sig' }
);
});

OverlayBuilder

Received as o in the callback form. Import: import { OverlayBuilder } from 'vizcraft'.

o.add(id, params, options?)

Adds an overlay spec.

ParamTypeDescription
idstringOverlay kind
paramsobjectOverlay parameters
options.keystringStable key
options.classNamestringCSS class for styling

Auto-keying: When multiple unkeyed overlays of the same id are added, keys are auto-generated (<id>#1, <id>#2, etc.).

o.remove(keyOrId)

Removes overlays by key (always) or by id (for unkeyed overlays).

o.clear()

Removes all accumulated overlay specs.

o.build()VizOverlaySpec[]

Returns a shallow copy of accumulated specs.

Primitive convenience methods

MethodEquivalent
o.rect(params, opts?)o.add('rect', params, opts)
o.circle(params, opts?)o.add('circle', params, opts)
o.text(params, opts?)o.add('text', params, opts)

o.group(params, children, options?)

Creates a group overlay for animating multiple elements as one unit or anchoring a local overlay cluster to a node.

o.group(
{ from: 'a', to: 'b', progress: 0, magnitude: 0.2 },
(g) => {
g.circle({ x: 0, y: -12, r: 5 });
g.circle({ x: 0, y: 0, r: 5 });
g.circle({ x: 0, y: 12, r: 5 });
},
{ key: 'swarm' }
);

Child coordinates are group-local (transformed by the group's translate/scale/rotate). Animatable group params: x, y, scale, rotation, opacity, progress, magnitude.

Set nodeId with optional offsetX / offsetY to anchor the group origin to a node center. When nodeId or from / to are set, x and y remain additional offsets.


Built-in overlay kinds

Primitives (no custom renderer needed)

KindParamsNotes
rect{ x, y, w, h, ... } or { nodeId, offsetX?, offsetY?, w, h, ... }Rectangle
circle{ x, y, r, ... } or { nodeId, offsetX?, offsetY?, r, ... }Circle
text{ x, y, text, ... } or { nodeId, offsetX?, offsetY?, text, ... }Text label
group{ x?, y?, children, ... }, { nodeId, offsetX?, offsetY?, x?, y?, children, ... }, or { from, to, progress?, x?, y?, children, ... }Grouped elements

When nodeId is provided, circle and text use node.centre + { offsetX, offsetY } as their position, rect centers itself on that resolved point, and group uses it as the group origin. Omitting nodeId preserves the current absolute-coordinate behavior.

Pre-registered kinds

KindParamsDescription
signal{ from, to, progress, ... } or { chain, progress, ... }Moving marker between nodes, across hop chains, along edge paths, or parked in a node
grid-labels{ colLabels, rowLabels, xOffset, yOffset }Grid axis labels
data-pointsvariesPoints attached to nodes

signal

signal interpolates between node centers by default. It can also follow a rendered edge path in flight, park inside a node after arrival, or move through a declarative multi-hop chain. See SignalOverlayParams and SignalOverlayHop for the exported types.

  • Set followEdge: true to follow the rendered edge path when there is exactly one matching from -> to edge.
  • Set edgeId to follow a specific edge when multiple edges connect the same nodes.
  • Set resting: true to keep the signal visible at to once progress >= 1.
  • Set parkAt to override the parked node, and use parkOffsetX / parkOffsetY to offset from that node's center for stacking or jitter.
  • Set color to override the default blue fill for a specific signal. Set glowColor for a separate halo effect (defaults to color).
  • Set chain to describe multiple hops inside one overlay. floor(progress) selects the active hop and the fractional part drives that hop.
  • When progress >= chain.length, chain signals park at the final hop's to node automatically.
  • If edge resolution fails or is ambiguous, the renderer falls back to straight center interpolation before arrival.
ParamTypeDescription
fromstringSingle-hop source node id. Mutually exclusive with chain
tostringSingle-hop target node id and the default parked node. Mutually exclusive with chain
chainSignalOverlayHop[]Declarative hop sequence. Each hop may also set followEdge or edgeId
progressnumberFor single-hop signals, typically 0..1. For chains, floor(progress) selects the hop and progress >= chain.length parks at the end
magnitude?numberVisual intensity used to scale the marker radius
color?stringCSS color for the ball fill; overrides the default class fill (#3b82f6)
glowColor?stringSeparate glow / halo color applied as a drop-shadow; defaults to color when omitted
followEdge?booleanFor single-hop signals, follow the only matching from -> to edge path when true
edgeId?stringFor single-hop signals, explicit edge id to follow; takes precedence over followEdge
resting?booleanFor single-hop signals, keep the signal visible at to once it arrives
parkAt?stringOverride the node used for parked placement after arrival
parkOffsetX?numberHorizontal parked offset from the parked node center
parkOffsetY?numberVertical parked offset from the parked node center
builder.overlay(
'signal',
{
chain: [
{ from: 'producer', to: 'dispatcher', edgeId: 'producer-dispatcher' },
{ from: 'dispatcher', to: 'adapter', edgeId: 'dispatcher-adapter' },
{ from: 'adapter', to: 'broker', edgeId: 'adapter-broker' },
{ from: 'broker', to: 'p2', edgeId: 'broker-p2' },
],
progress: 2.4,
magnitude: 0.8,
},
'sig'
);

Styling overlays

Via params (portable)

o.rect({
x: 10,
y: 10,
w: 200,
h: 80,
fill: '#dcfce7',
stroke: '#22c55e',
strokeWidth: 2,
});

Via CSS (themeable)

o.rect(
{ x: 10, y: 10, w: 200, h: 80 },
{ key: 'sel', className: 'viz-selection' }
);

Inject CSS at mount time:

builder.mount(container, {
css: '.viz-selection { fill: #3b82f6; fill-opacity: 0.12; stroke: #3b82f6; stroke-width: 2; }',
});

Animating overlays

Target overlays in the timeline animation system by key:

builder.animate((aBuilder) => {
aBuilder.overlay('sig');
aBuilder.to({ progress: 1 }, { duration: 900, easing: 'easeInOut' });
});

Any numeric property in spec.params can be tweened.


Custom overlay registry

Register new overlay kinds with the global registry:

import { defaultCoreOverlayRegistry } from 'vizcraft';

defaultCoreOverlayRegistry.register('selection', {
render: ({ spec }) => {
const { x, y, w, h } = spec.params;
return `<rect x="${x}" y="${y}" width="${w}" height="${h}" rx="8" />`;
},
update: ({ spec }, g) => {
// Efficient DOM patching for animations
let rect = g.querySelector('rect');
if (!rect) {
rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
g.appendChild(rect);
}
rect.setAttribute('x', String(spec.params.x));
// ... set other attributes
},
});

Type-safe custom overlays

Augment OverlayKindRegistry for TypeScript support:

declare module 'vizcraft' {
interface OverlayKindRegistry {
selection: { x: number; y: number; w: number; h: number };
}
}

Found a problem? Open an issue on GitHub.