Interfaces I–L
Import these from @grafloria/engine.
Interfaces
ILayoutAlgorithm
tsinterface ILayoutAlgorithm
Members
getName(): string— Get the name of the layout algorithmgetType(): 'grid' | 'force-directed' | 'hierarchical' | 'hybrid'— Get the type of the layout algorithmcalculatePlacement(options: PlacementOptions): PlacementResult— Calculate position for a single new node
This is called when a node is added to the diagram. The algorithm should return a position that:
- Doesn't overlap with existing nodes
- Follows the layout strategy
- Fits within the viewport (or is close to existing content)
reLayout(diagram: DiagramModel, config?: LayoutConfiguration): Map<string, Point>— Re-layout all nodes in the diagram
This is called when the user explicitly requests a re-layout (e.g., clicks "Re-Arrange" button). The algorithm should calculate new positions for ALL nodes.
configure(config: LayoutConfiguration): void— Configure the layout algorithmgetConfiguration(): LayoutConfiguration— Get current configurationcanApply(diagram: DiagramModel): { valid: boolean; reason?: string }— Validate if this algorithm can be applied to the given diagram
For example:
- Hierarchical layout requires a DAG (no cycles)
- Force-directed works better with connected nodes
onActivate?(): void— Called when the algorithm is activated Use this to initialize any state or cachesonDeactivate?(): void— Called when the algorithm is deactivated Use this to clean up state or caches
IncrementalLayoutOptions
Options for incremental layout
tsinterface IncrementalLayoutOptions
Properties
| Name | Type | Default | Description |
|---|---|---|---|
strategy? | IncrementalLayoutStrategy | 'pin-existing' | Strategy to use for incremental layout |
newNodeIds? | string[] | Nodes that are new (to be laid out) If not provided, nodes without valid positions are considered new | |
anchorNodeIds? | string[] | Anchor nodes that should never move (in addition to strategy constraints) These have highest priority | |
maxShift? | number | Maximum distance a non-anchor node can move (pixels) Only applies to 'minimal-shift' strategy | |
proximityRadius? | number | 200 | Radius around new nodes where existing nodes can be adjusted (pixels) Only applies to 'proximity-aware' strategy |
allowMinorAdjustments? | boolean | false | Whether to allow slight adjustments to improve layout quality |
customConstraints? | LayoutConstraints | Custom constraints to apply in addition to incremental constraints |
IncrementalLayoutResult
Result of incremental layout operation
tsinterface IncrementalLayoutResult
Properties
| Name | Type | Default | Description |
|---|---|---|---|
movedNodeIds | string[] | IDs of nodes that were moved during layout | |
pinnedNodeIds | string[] | IDs of nodes that were pinned/fixed | |
newlyLaidOutNodeIds | string[] | IDs of nodes that were newly laid out | |
maxMovement | number | Maximum distance any node moved (pixels) | |
avgMovement | number | Average distance nodes moved (pixels) | |
strategy | IncrementalLayoutStrategy | Strategy that was used | |
autoConstraintCount | number | Number of constraints that were auto-generated |
LabelBox
The box an edge label needs. Layout's job is to reserve it; not to place it.
tsinterface LabelBox
Properties
| Name | Type | Default | Description |
|---|---|---|---|
id | string | The label this box belongs to. | |
linkId | string | The link the label rides on. | |
text | string | ||
width | number | ||
height | number |
LabelClearanceResult
tsinterface LabelClearanceResult
Properties
| Name | Type | Default | Description |
|---|---|---|---|
overlaps | number | Label boxes that land on top of a node. | |
judged | number | Labelled links that could be judged. | |
score | number | 100 = no label box collides with any node. | |
collidingLinks | string[] | Which links' labels collided, for the report. |
LayeringEstimate
Longest-path layering estimate for a DAG — the two numbers that predict which hierarchical engine will choke (measured, not guessed; see the perf spec):
• dagre's pathology is DEPTH: a 2,000-rank chain never returns, while a 2,000-node, ~1,000-wide tree takes ~700ms. • our layered (Sugiyama) engine's pathology is WIDTH: crossing minimisation over a ~1,000-node rank runs for tens of seconds, while a 45-wide, 90-deep mesh takes ~480ms and a width-1, 2,000-deep chain ~130ms.
O(n + m) via Kahn's algorithm. Only meaningful when the graph is acyclic; nodes left unranked by a cycle default to rank 0.
tsinterface LayeringEstimate
Properties
| Name | Type | Default | Description |
|---|---|---|---|
depth | number | Number of layers a longest-path layering would produce. | |
maxWidth | number | Node count of the widest layer. |
LayoutAdapter
Interface that all layout adapters must implement
tsinterface LayoutAdapter
Properties
| Name | Type | Default | Description |
|---|---|---|---|
name | string | Name of the layout adapter (e.g., 'dagre', 'elk') |
Members
apply( nodes: NodeModel[], links: LinkModel[], options?: Partial<LayoutOptions> ): Promise<LayoutResult>— Apply layout to nodes and linksapplyIncremental( nodes: NodeModel[], links: LinkModel[], incrementalOptions: IncrementalLayoutOptions, layoutOptions?: Partial<LayoutOptions> ): Promise<LayoutResult & { incremental: IncrementalLayoutResult }>— Apply incremental layout - layout new nodes while preserving existing positionsvalidateOptions(options: Partial<LayoutOptions>): boolean— Validate that options are valid for this adapter
LayoutCandidate
tsinterface LayoutCandidate
Properties
| Name | Type | Default | Description |
|---|---|---|---|
name | string | Registered layout name to run. | |
options | UnifiedLayoutOptions | Options to run it with. | |
id | string | A stable id for this candidate — name + tuning. Ties break on this. | |
portAware | boolean | Is this engine able to honour port sides? |
LayoutConfiguration
Configuration for layout algorithms
tsinterface LayoutConfiguration
Properties
| Name | Type | Default | Description |
|---|---|---|---|
type? | LayoutAlgorithmType | Algorithm type (optional when passed to reLayout, as it uses current algorithm) | |
options? | GridLayoutOptions | ForceDirectedOptions | HierarchicalOptions | HybridOptions | Algorithm-specific options | |
animate? | boolean | Whether to animate layout changes | |
animationDuration? | number | Animation duration in ms | |
viewport? | Rectangle | Viewport for viewport-aware layout | |
margins? | number | Margins around content | |
direction? | 'TB' | 'BT' | 'LR' | 'RL' | Shorthand for hierarchical direction |
LayoutConstraints
Collection of layout constraints to apply
tsinterface LayoutConstraints
Properties
| Name | Type | Default | Description |
|---|---|---|---|
constraints | NodeConstraint[] | Array of node constraints | |
conflictResolution? | 'priority' | 'first' | 'last' | Strategy for handling conflicting constraints - 'priority': Use constraint priority to resolve conflicts - 'first': First constraint wins - 'last': Last constraint wins |
LayoutErrorMessage
tsinterface LayoutErrorMessage
Properties
| Name | Type | Default | Description |
|---|---|---|---|
seq | number | ||
kind | 'error' | ||
message | string |
LayoutGraph
A whole graph, structured-clone-safe: no functions, no class instances.
tsinterface LayoutGraph
Properties
| Name | Type | Default | Description |
|---|---|---|---|
nodes | LayoutGraphNode[] | ||
links | LayoutGraphLink[] |
LayoutGraphLink
A link, as it crosses the boundary.
tsinterface LayoutGraphLink
Properties
| Name | Type | Default | Description |
|---|---|---|---|
id | string | ||
sourceNodeId? | string | ||
targetNodeId? | string | ||
sourcePortId? | string | ||
targetPortId? | string |
LayoutGraphNode
A node, as it crosses the boundary: geometry + topology only.
tsinterface LayoutGraphNode
Properties
| Name | Type | Default | Description |
|---|---|---|---|
id | string | ||
type | string | ||
position | { x: number; y: number } | ||
size | { width: number; height: number } | ||
parentId? | string | Container membership — the nested-layout card needs it; harmless otherwise. | |
positionMode? | 'absolute' | 'relative' | 'layout' | How position relates to the parent. Absent on pre-v3 payloads, which meant summation — i.e. 'relative'; the consumer below applies exactly that default. | |
ports? | LayoutGraphPort[] |
LayoutGraphPort
A port, as it crosses the boundary. Ids are preserved — see above.
tsinterface LayoutGraphPort
Properties
| Name | Type | Default | Description |
|---|---|---|---|
id | string | ||
type | 'input' | 'output' | 'bi' | ||
side? | 'left' | 'right' | 'top' | 'bottom' | ||
index? | number | Order within a side — carried so multi-port sides revive in the same order. | |
position? | { x: number; y: number } |
LayoutHistoryOptions
Options for layout history management
tsinterface LayoutHistoryOptions
Properties
| Name | Type | Default | Description |
|---|---|---|---|
maxHistorySize? | number | Maximum number of history entries to keep | |
autoSnapshot? | boolean | Whether to automatically create snapshots | |
minSnapshotInterval? | number | Minimum time between auto-snapshots (ms) |
LayoutPort
The message-port surface the host needs — a real Worker satisfies it.
tsinterface LayoutPort
Properties
| Name | Type | Default | Description |
|---|---|---|---|
onmessage | ((ev: { data: LayoutResponse }) => void) | null |
Members
postMessage(msg: LayoutRequest): void
LayoutPreset
Layout preset configuration
tsinterface LayoutPreset
Properties
| Name | Type | Default | Description |
|---|---|---|---|
id | string | Unique identifier for the preset | |
name | string | Human-readable name | |
description | string | Description of when to use this preset | |
adapter | 'dagre' | 'elk' | Which adapter to use | |
options | Partial<DagreLayoutOptions> | Partial<ELKLayoutOptions> | Layout options for the adapter | |
constraints? | LayoutConstraints | Optional pre-configured constraints | |
incrementalOptions? | Partial<IncrementalLayoutOptions> | Optional incremental layout settings | |
tags? | string[] | Tags for categorization |
LayoutPresetCategory
Category of layout presets
tsinterface LayoutPresetCategory
Properties
| Name | Type | Default | Description |
|---|---|---|---|
name | string | Category name | |
description | string | Category description | |
presets | LayoutPreset[] | Presets in this category |
LayoutProgress
tsinterface LayoutProgress
Properties
| Name | Type | Default | Description |
|---|---|---|---|
progress | number | 0..1. | |
phase | string | ||
iteration | number | ||
totalIterations | number |
LayoutProgressMessage
tsinterface LayoutProgressMessage
Properties
| Name | Type | Default | Description |
|---|---|---|---|
seq | number | ||
kind | 'progress' | ||
progress | number | 0..1. Monotonic. | |
phase | string | ||
iteration | number | ||
totalIterations | number |
LayoutQualityResult
Overall layout quality assessment
tsinterface LayoutQualityResult
Properties
| Name | Type | Default | Description |
|---|---|---|---|
overallScore | number | Overall quality score (0-100) | |
grade | 'A' | 'B' | 'C' | 'D' | 'F' | Quality grade (A, B, C, D, F) | |
metrics | { edgeCrossings: QualityMetric; nodeOverlap: QualityMetric; edgeLength: QualityMetric; nodeDistribution: QualityMetric; symmetry: QualityMetric; aspectRatio: QualityMetric; } | Individual metrics | |
topSuggestions | string[] | Top suggestions for improvement | |
timestamp | number | Timestamp of assessment |
LayoutRequestCancel
tsinterface LayoutRequestCancel
Properties
| Name | Type | Default | Description |
|---|---|---|---|
seq | number | ||
kind | 'cancel' | ||
target | number | The seq of the run to cancel. |
LayoutRequestRun
tsinterface LayoutRequestRun
Properties
| Name | Type | Default | Description |
|---|---|---|---|
seq | number | ||
kind | 'run' | ||
algorithm | string | ||
graph | LayoutGraph | ||
options | LayoutWireOptions | ||
timeBudgetMs? | number | Stop and return the best-so-far once this many ms have elapsed. | |
sliceMs? | number | How long to compute before surrendering the thread so cancel can land. | |
stopAfterIteration? | number | Stop after exactly N iterations — a DETERMINISTIC pre-emption. |
LayoutResult
Result of applying a layout algorithm
tsinterface LayoutResult
Properties
| Name | Type | Default | Description |
|---|---|---|---|
nodePositions | Map<string, { x: number; y: number }> | Map of node IDs to their new positions | |
bounds | { x: number; y: number; width: number; height: number; } | Bounding box of the laid-out graph | |
metadata? | { algorithm: string; executionTime: number; [key: string]: any; } | Additional metadata about the layout execution | |
quality? | LayoutQualityResult | Quality assessment of the layout (if calculateQuality was true) | |
portAware? | PortAwareLayoutResult | Port-aware layout result (if portAware was enabled) | |
subgraph? | SubgraphLayoutResult | Subgraph layout result (if subgraph was enabled) | |
edgeBundling? | EdgeBundlingResult | Edge bundling result (if edgeBundling was enabled) | |
routing? | LayoutRoutingHints | The port positions and edge routes the layout engine computed. Present when the engine produces them (ELK does); previously computed and discarded. |
LayoutResultMessage
tsinterface LayoutResultMessage
Properties
| Name | Type | Default | Description |
|---|---|---|---|
seq | number | ||
kind | 'result' | ||
algorithm | string | ||
positions | Array<[string, { x: number; y: number }]> | ||
bounds | { x: number; y: number; width: number; height: number } | ||
partial | boolean | True when the run stopped early — the answer is the best-so-far, not the end. | |
reason? | LayoutStopReason | ||
iteration | number | ||
totalIterations | number | ||
metadata? | LayoutResult['metadata'] | Everything else the adapter reported, carried verbatim. | |
quality? | LayoutResult['quality'] | ||
portAware? | LayoutResult['portAware'] | ||
subgraph? | LayoutResult['subgraph'] | ||
edgeBundling? | LayoutResult['edgeBundling'] |
LayoutRng
A seeded, deterministic source of randomness.
tsinterface LayoutRng
Properties
| Name | Type | Default | Description |
|---|---|---|---|
seed | number | The seed this generator was created with (so a result can report it). |
Members
next(): number— Uniform in [0, 1).between(min: number, max: number): number— Uniform in [min, max).
LayoutRoutingHints
What the layout engine worked out about EDGES and PORTS, which until now was computed and then thrown in the bin.
ELK does genuine port-aware layered layout with orthogonal edge routing. The
old adapter read back child.x / child.y and NOTHING else — every port
position and every edge section ELK produced was discarded. These are those
results.
They are HINTS, deliberately. Layout's job is to place nodes so a good route EXISTS and to say where it thinks that route runs — not to draw it.
tsinterface LayoutRoutingHints
Properties
| Name | Type | Default | Description |
|---|---|---|---|
portPositions | Map<string, { x: number; y: number; side: PortSide }> | Absolute position of each declared port, as the layout engine placed it. | |
edgeRoutes | Map<string, { start: Point; end: Point; bends: Point[] }> | The route the layout engine found for each link: endpoints + bend points. | |
labelSpace | Map<string, { width: number; height: number }> | The box reserved for each labelled link (keyed by link id). | |
orthogonal | boolean | Whether the engine routed orthogonally. |
Was this page helpful?