API Reference
Component inputs, outputs, models, and services in ngx-workflow. For the full tables with examples, see Inputs and Outputs. For generated class/API docs (Compodoc), open /compodoc/.
Connection limits
Limit how many edges can attach to a port. Resolution order (first wins):
node.handleConfig[port].maxConnectionsnode.maxConnectionsPerPort on the diagram[maxConnectionsPerHandle]
<ngx-workflow-diagram
[nodes]="nodes()"
[edges]="edges()"
[maxConnectionsPerHandle]="2"
(nodesChange)="nodes.set($event)"
(edgesChange)="edges.set($event)"
(connect)="onConnect($event)"
/>
nodes = signal<Node[]>([
{
id: 'a',
label: 'Source',
position: { x: 80, y: 100 },
ports: 4,
maxConnectionsPerPort: 1,
handleConfig: {
bottom: { maxConnections: 3 } // override one port
}
},
{
id: 'b',
label: 'Target',
position: { x: 360, y: 100 },
ports: 4
}
]); In the sandbox / properties sidebar you can edit Max connections / port and Per-port limits when a node is selected. The same sidebar exposes RGBA pickers for node and edge colors, plus edge animation type/speed and markers. If you mount <ngx-workflow-properties-sidebar> yourself, bind (nodeChange) (not (change)) and (edgeChange).
Key Diagram Inputs
| Property | Type | Default | Description |
|---|---|---|---|
[nodes] | Node[] | [] | Controlled nodes array. |
[edges] | Edge[] | undefined | undefined | Controlled edges; pass [] after deleting the last edge. |
[maxConnectionsPerHandle] | number | undefined | Global max edges per port (unlimited if unset). |
[proximityThreshold] | number | 200 | Auto-connect distance when dragging nodes. |
[connectionValidator] | (s, t) => boolean | undefined | Custom global connection validator. |
[validateConnection] | (connection) => boolean | undefined | Validator with handle ids. |
[edgeReconnectable] | boolean | false | Drag edge endpoints to reconnect. |
[showPropertiesSidebar] | boolean | false | Enable/disable built-in properties editing sidebar on double-click. |
[showSearchControls] | boolean | true | Show floating Ctrl+F search controls. |
[showBackground] | boolean | true | Render background pattern. |
[backgroundVariant] | 'dots' | 'lines' | 'cross' | 'dots' | Background pattern style. |
[showMinimap] | boolean | true | Show minimap overlay. |
[showZoomControls] | boolean | true | Show zoom / fit controls. |
[zoomControlsConfig] | ZoomControlsConfig | undefined | Custom slots, positions (bottom-left, top-right, etc.), actions, and icons for zoom controls. |
[showUndoRedoControls] | boolean | true | Show undo / redo controls. |
[snapToGrid] | boolean | false | Snap nodes while dragging. |
[nodeTypes] | Record<string, Type> | {} | Custom node type → component map. |
[optimization] | FlowOptimization | { virtualization: true, … } | Lazy load + large-graph culling (spatial index, adaptive buffer, maxRenderedNodes, edgeVirtualization). |
Large-graph optimization
Off-screen nodes are culled with a cached spatial hash (rebuild on graph changes, query on pan/zoom). Selected nodes stay mounted; adaptive buffer scales with zoom; optional maxRenderedNodes soft-caps density. See Compodoc for FlowOptimization and SpatialIndex.
<ngx-workflow-diagram
[nodes]="nodes()"
[edges]="edges()"
[optimization]="{
lazyLoadTrigger: 'viewport',
virtualization: true,
adaptiveBuffer: true,
keepSelectedVisible: true,
maxRenderedNodes: 400,
edgeVirtualization: 'any-endpoint',
virtualizationBuffer: 500
}"
/>Key Diagram Outputs
| Event | Payload | Description |
|---|---|---|
(nodesChange) | Node[] | Nodes moved, added, deleted, or edited. |
(edgesChange) | Edge[] | Edges added, reconnected, or deleted. |
(nodeClick) | Node | Emitted when a node is clicked. |
(nodeDoubleClick) | Node | Emitted when a node is double-clicked. |
(edgeClick) | Edge | Emitted when an edge is clicked. |
(edgeDoubleClick) | Edge | Emitted when an edge is double-clicked. |
(connect) | { source, target, sourceHandle?, targetHandle? } | New port-to-port connection created. |
(connectStart) / (connectEnd) | { nodeId, handleId? } | Connection drag lifecycle. |
(edgeDrop) | { sourceNodeId, sourceHandleId, position } | Connection dropped on empty canvas. |
(beforeDelete) | { nodes, edges, cancel } | Cancellable delete. |
(importError) | { message, error? } | JSON import failure. |
(paneClick) | { event, position } | Empty canvas click. |
(contextMenu) | { type, item?, event } | Right-click on canvas / node / edge. |
Overlay Components
Project custom floating toolbars and anchored panels inside <ngx-workflow-diagram>.
| Component | Input / Prop | Type | Description |
|---|---|---|---|
<ngx-workflow-panel> | [position] | PanelPosition | 9 anchor presets: 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' (default: 'top-left'). |
<ngx-workflow-panel> | [style] | string | Record | Inline dynamic CSS styles (dimensions, background colors, drop shadows, z-index). |
<ngx-workflow-panel> | [className] | string | Custom CSS class applied to the panel container. |
<ngx-workflow-node-toolbar> | [nodeId] | string | Target node ID to attach toolbar above/below. |
<ngx-workflow-node-toolbar> | [position] | 'top' | 'bottom' | 'left' | 'right' | Placement relative to the node boundary (default: 'top'). |
Core TypeScript Models
Node
export interface Node {
id: string;
label?: string;
type?: string;
position: { x: number; y: number };
data?: Record<string, any>;
width?: number;
height?: number;
selected?: boolean;
/** Colors: hex / rgb() / rgba() — backgroundColor, color, borderColor */
style?: Record<string, string>;
borderColor?: string;
borderWidth?: number;
/** 0=None, 1=Top, 2=Top/Bottom, 3=Left/Right, 4=All */
ports?: 0 | 1 | 2 | 3 | 4;
/** Default max edges for every port on this node */
maxConnectionsPerPort?: number;
handleConfig?: {
[handleId: string]: {
isConnectable?: boolean | number | ((node: Node, edges: Edge[]) => boolean);
maxConnections?: number;
};
};
easyConnect?: boolean;
}Edge
export interface Edge {
id: string;
source: string;
target: string;
/** Handle side: 'top' | 'right' | 'bottom' | 'left' — drives bezier/step direction */
sourceHandle?: string;
targetHandle?: string;
type?: 'bezier' | 'step' | 'smoothstep' | 'straight' | 'smart' | 'dashed';
animated?: boolean; // defaults animationType to 'flow' when unset
animationType?: 'flow' | 'dot' | 'both';
animationDuration?: string; // e.g. '1s'
animationStyle?: { fill?: string }; // moving-dot color (rgba ok)
markerStart?: 'arrow' | 'arrowclosed' | 'dot' | string;
markerEnd?: 'arrow' | 'arrowclosed' | 'dot' | string; // built-ins match stroke
label?: string; // legacy center label
edgeLabels?: { start?: string | EdgeLabel; center?: string | EdgeLabel; end?: string | EdgeLabel };
labelStyle?: Record<string, string>;
style?: Record<string, string>; // stroke, strokeWidth, strokeDasharray
}Injectable Services
DiagramStateService— nodes, edges, selection, viewport.HandleRegistryService— port registration and typed connect rules.AutoLayoutService— ELK.js layout (applyLayout('TB' | 'LR')).ExportService— PNG / SVG / JSON export.UndoRedoService— history stack.