Interfaces A–O
Import these from @grafloria/renderer.
Interfaces
AutoSizeOptions
tsinterface AutoSizeOptions
Properties
| Name | Type | Default | Description |
|---|---|---|---|
fontSize? | number | ||
lineHeight? | number | ||
floorWidth? | number | Global resizer minimums, applied only where the node declares no per-node min. Keeps auto-size and the interactive resizer on the same floor. | |
floorHeight? | number | ||
reserve? | { top?: number; bottom?: number; width?: number } | Extra content a composite panel reserves around the label. top stacks above the label (header band + image), width widens the content box to fit a horizontal row (icon + label + badge). |
ClampOptions
tsinterface ClampOptions
Properties
| Name | Type | Default | Description |
|---|---|---|---|
floorWidth? | number | Global floor applied when the node declares no minWidth/minHeight. | |
floorHeight? | number |
ContentSize
The intrinsic content box a node needs (before shape-inset expansion).
tsinterface ContentSize
Properties
| Name | Type | Default | Description |
|---|---|---|---|
width | number | ||
height | number |
EdgeOptimizerOptions
tsinterface EdgeOptimizerOptions
Properties
| Name | Type | Default | Description |
|---|---|---|---|
jumpOwnership? | 'both' | 'single' | . Who draws the arc when two jump-drawing links cross: 'both' — legacy: each link bridges the other (a double bridge). 'single' — exactly ONE deterministic owner per intersection: the link whose crossing segment is HORIZONTAL arcs over the vertical (the classic drafting convention); when neither or both are horizontal, the smaller link id owns. | |
cellSize? | number | Uniform-grid cell size (world px) for the link broad phase. Should be on the order of a typical node — too small and long links occupy hundreds of cells, too large and the broad phase stops filtering. | |
labelSearchSteps? | number | How far out the label search pushes, in steps of labelStep. | |
labelStep? | number | Distance between successive label candidates (px). |
FanoutPoint
Parallel-link auto-separation and self-loop routing. PURE GEOMETRY: no engine models, no DOM, no framework — points in, points out — so every rule below is unit-testable on its own and the SVG renderer only has to decide WHEN to call it, not HOW the shape is built.
Why this is the biggest structural edge gap Grafloria had: • Two links between the same pair of nodes were drawn on the same centre line, one exactly on top of the other. ERD (two FKs between the same tables), BPMN (a flow and its compensation) and state machines (a→b and b→a) all produce that shape constantly. • A link whose source node IS its target node was handed to the router as an ordinary A→B route. The router excludes the link's own nodes from its obstacle set, so the "route" was a degenerate stub inside the node body.
The output of both routines is a POLYLINE, not a path string. That is
deliberate: the renderer's existing path emitters already turn a polyline into
the right shape per path type (rounded corners for orthogonal, a Catmull-Rom
spline for smooth/bezier, straight segments for direct), and hit
testing, jump-point detection, label placement and the edge toolbar all read
the same polyline. One geometry, every consumer.
tsinterface FanoutPoint
Properties
| Name | Type | Default | Description |
|---|---|---|---|
x | number | ||
y | number |
FanoutRect
tsinterface FanoutRect
Properties
| Name | Type | Default | Description |
|---|---|---|---|
x | number | ||
y | number | ||
width | number | ||
height | number |
FrameCoverage
What one live render() pass actually drew, in world coordinates — the
contract behind the host's camera fast path (see CAMERA_OVERSCAN).
rect is the node-cull rectangle INCLUDING overscan: every node, group,
stroke and comment intersecting it was rendered (links got LINK_CULL_MARGIN
of extra slack beyond it). While a new viewBox of the same size and zoom
stays inside rect, the DOM already contains everything that viewBox can
show, and the camera may move by rewriting the viewBox attribute alone.
total — every node and link in the diagram was admitted and no optional
layer (groups, ink, comment pins) exists, so containment is moot: ANY camera
position at this zoom shows a complete picture. This is what makes panning a
fit-to-content scene free.
Null when there is no diagram, or when the mount gate deferred anything (a progressive mount in flight, frozen entities): the drawn set is then smaller than the culled set and the coverage claim would be a lie.
tsinterface FrameCoverage
Properties
| Name | Type | Default | Description |
|---|---|---|---|
rect | Rectangle | ||
zoom | number | ||
viewBoxWidth | number | ||
viewBoxHeight | number | ||
total | boolean |
HtmlContentNode
A single node in the structured, sanitized rich-content tree.
tsinterface HtmlContentNode
Properties
| Name | Type | Default | Description |
|---|---|---|---|
tag | string | Element tag — validated against {@link ALLOWED_TAGS}. | |
text? | string | Text content, emitted via textContent (never innerHTML). | |
style? | Record<string, string | number> | Inline style (object form); values are sanitized. | |
className? | string | ||
attrs? | Record<string, string> | Extra attributes — filtered against {@link ALLOWED_ATTRS} + sanitized. | |
children? | HtmlContentNode[] |
HtmlLabelOptions
tsinterface HtmlLabelOptions
Properties
| Name | Type | Default | Description |
|---|---|---|---|
id | string | Stable id: becomes part of the VNode key. | |
html | string | Raw HTML. Injected verbatim via innerHTML — the author owns its safety. | |
anchor | Point | Centre of the label box in world coordinates. | |
width | number | ||
height | number | ||
className? | string | Extra class on the XHTML wrapper div. |
HtmlNodeContent
The HTML-node body spec, stored at node.metadata.html.
tsinterface HtmlNodeContent
Properties
| Name | Type | Default | Description |
|---|---|---|---|
text? | string | Plain-text body (safe: rendered through textContent). | |
content? | HtmlContentNode | Structured, sanitized rich content. | |
style? | Record<string, string | number> | Inline style for the root container (object form; values sanitized). | |
className? | string | ||
padding? | number | Inner padding (px). Default 4. | |
interactive? | boolean | Let the HTML capture pointer events (forms / links). Default false, so the shape background beneath receives clicks and the node stays draggable / selectable like any shape. |
InnerRect
A shape's inner label box in LOCAL coordinates (0,0 = node top-left). The node label engine wraps + clips text to this rect. Curved / slanted shapes (diamond, ellipse, triangle, cylinder …) inset it so text stays inside the visible silhouette. See {@link getInnerRect}.
tsinterface InnerRect
Properties
| Name | Type | Default | Description |
|---|---|---|---|
x | number | ||
y | number | ||
w | number | ||
h | number |
Intersection
Intersection information
tsinterface Intersection
Properties
| Name | Type | Default | Description |
|---|---|---|---|
point | Point | ||
angle | number | ||
t1 | number | ||
t2 | number | ||
linkId? | string | ||
segmentIndex? | number |
LabelRenderContext
Extra, per-frame context — none of it belongs on the persisted model.
tsinterface LabelRenderContext
Properties
| Name | Type | Default | Description |
|---|---|---|---|
offset? | Point | The offset the edge optimizer settled on. Overrides label.offset when present (it IS label.offset for any label that did not opt into autoOffset). | |
theme? | Theme | ||
path? | ReadonlyArray<Point> | The line AS PAINTED, when that is not link.points: a hand-bent right-angle line stores its bends and is drawn with the jogs between them, so a label placed on the stored points sat off the drawn line. The renderer passes the painted polyline; the label is placed (and turned) along it. |
LabelTemplateContext
What a LABEL template is given.
tsinterface LabelTemplateContext
Properties
| Name | Type | Default | Description |
|---|---|---|---|
label | LinkLabel | ||
link | LinkModel | ||
anchor | Point | World-space anchor the label resolved to (position/slot + offset + optimizer). | |
rotation? | number | Rotation in degrees the default renderer would have applied, if any. | |
theme | Theme |
LineSegment
Line segment defined by start and end points
tsinterface LineSegment
Properties
| Name | Type | Default | Description |
|---|---|---|---|
start | Point | ||
end | Point |
LinkHitLabel
A label placement, expressed independently of the model.
tsinterface LinkHitLabel
Properties
| Name | Type | Default | Description |
|---|---|---|---|
position | number | Position along the path in [0, 1] (the label's on-path anchor). | |
offset? | Point | Offset of the label box centre from its on-path anchor. | |
width? | number | Label box width in world units (falls back to {@link DEFAULT_LABEL_WIDTH}). | |
height? | number | Label box height in world units (falls back to {@link DEFAULT_LABEL_HEIGHT}). |
LinkHitResult
Result of a part-aware link hit-test.
tsinterface LinkHitResult
Properties
| Name | Type | Default | Description |
|---|---|---|---|
part | LinkPart | Which sub-part of the link was hit. | |
labelIndex? | number | Index into the supplied labels array — present only for part === 'label'. | |
t? | number | Position along the whole path in [0, 1] where the body was hit — present only for part === 'body'. Useful for inserting waypoints / positioning an edge toolbar on the segment under the cursor. | |
distance? | number | Distance from the query to the winning part's own metric (handle centre, body path; 0 for inside a label box). For ranking hits ACROSS links. | |
bodyDistance? | number | Distance from the query to this link's BODY path, present whenever the link has >= 2 points — even when a handle or label won the part. This is the cross-link tiebreaker: at a shared fan-out anchor every sibling's endpoint handle is equidistant, but only the link actually under the cursor has body distance ~0. |
LinkHitTestOptions
Inputs describing a single link's geometry for hit-testing.
tsinterface LinkHitTestOptions
Properties
| Name | Type | Default | Description |
|---|---|---|---|
points | Point[] | Routed points of the link, in world coordinates (>= 2 for a body). | |
labels? | LinkHitLabel[] | Label placements, in render order (later entries drawn on top). | |
sourceEndpoint? | Point | null | Source endpoint anchor (defaults to points[0]). Pass null to disable. | |
targetEndpoint? | Point | null | Target endpoint anchor (defaults to last point). Pass null to disable. | |
sourceArrow? | Point | null | Source arrowhead anchor. Omit / null when there is no source arrow. | |
targetArrow? | Point | null | Target arrowhead anchor. Omit / null when there is no target arrow. | |
endpointRadius? | number | Grab radius around endpoint anchors (default {@link DEFAULT_ENDPOINT_RADIUS}). | |
arrowRadius? | number | Grab radius around arrowhead anchors (default {@link DEFAULT_ARROW_RADIUS}). | |
defaultLabelWidth? | number | Fallback label box width when a label omits one. | |
defaultLabelHeight? | number | Fallback label box height when a label omits one. |
LinkTemplateContext
What a LINK template is given. Everything it needs; nothing it can corrupt.
tsinterface LinkTemplateContext
Properties
| Name | Type | Default | Description |
|---|---|---|---|
link | LinkModel | ||
points | Point[] | The ROUTED polyline for this frame — not the model's stale segments. | |
pathData | string | The SVG path string the default renderer would have drawn (jumps included). | |
styles | Record<string, unknown> | Resolved link styles (stroke, strokeWidth, className, …) for this state. | |
theme | Theme | ||
lod | string | Current level-of-detail tier, so a template can drop detail when zoomed out. | |
selected | boolean | True when the link is selected — templates usually want to react to this. |
LinkWithPoints
Link with points for intersection detection
tsinterface LinkWithPoints
Properties
| Name | Type | Default | Description |
|---|---|---|---|
id? | string | ||
points | Point[] |
MarkerContext
What a custom MARKER is given.
tsinterface MarkerContext
Properties
| Name | Type | Default | Description |
|---|---|---|---|
style | ArrowStyle | ||
size | number | Normalised size (never negative). | |
color | string | Resolved colour (the marker's own, else the link's stroke). | |
width | number | Stroke width for outlined markers. | |
transform | string | The SVG transform placing the marker: translate(x, y) rotate(deg). The marker draws in its LOCAL frame — origin at the anchor, +x along the direction of travel — and MUST put this on its root element. | |
backgroundColor | string | Theme background — the fill for hollow markers, so they don't glare on dark. | |
end | 'source' | 'target' | Which end this marker sits on. |
MarkerDefinition
tsinterface MarkerDefinition
Properties
| Name | Type | Default | Description |
|---|---|---|---|
render | (ctx: MarkerContext) => VNode | null | ||
tipOffset? | number | ((style: ArrowStyle) => number) | Distance from the marker's local origin to its visual TIP along +x. The renderer pulls the marker back from the path endpoint by exactly this, so the tip lands ON the port. A triangle drawn from 0 to size has tipOffset size; a dot centred on the origin has size / 2; a bar has 0. |
MeasureLabelOptions
tsinterface MeasureLabelOptions
Properties
| Name | Type | Default | Description |
|---|---|---|---|
fontSize? | number | ||
lineHeight? | number | Line-height multiplier. Default 1.2. | |
wrapWidth? | number | Wrap the label to this content width; omit to measure it on one line. |
NodeSizing
Sizing constraints for a single node. Every field is optional; an absent field means "no constraint" (the global resizer minimum still applies as a safety floor).
tsinterface NodeSizing
Properties
| Name | Type | Default | Description |
|---|---|---|---|
auto? | boolean | Content-aware auto-sizing: the node grows to fit its label + panel. | |
minWidth? | number | ||
minHeight? | number | ||
maxWidth? | number | ||
maxHeight? | number | ||
aspectLock? | boolean | number | Aspect lock. true locks to the node's CURRENT width/height ratio; a number locks to that explicit width÷height ratio. Honored during a resize gesture even without the Shift modifier. | |
padding? | number | Content padding (px) reserved around the label when auto-sizing. |
NodeToolbarConfig
Per-node tool visibility. Every field is optional; an absent field means "use
the controller's global default". halo: true → all actions, an array → only
those actions, false → no halo.
tsinterface NodeToolbarConfig
Properties
| Name | Type | Default | Description |
|---|---|---|---|
resize? | boolean | ||
rotate? | boolean | ||
remove? | boolean | ||
halo? | boolean | ToolbarHaloAction[] |
OptimizerFrame
tsinterface OptimizerFrame
Properties
| Name | Type | Default | Description |
|---|---|---|---|
nodes | OptimizerNode[] | ||
links | OptimizerLink[] |
Was this page helpful?