Docs
Core Architecture

Core Concepts & Reactive Architecture

Understanding the internal mechanics of ngx-workflow will help you build complex interactive diagram editors efficiently.

1. Signals State Management

At the core of ngx-workflow is DiagramStateService. Instead of relying on continuous change detection cycles or heavy RxJS subscription chains for mouse movements, diagram state is modeled using Angular signal() and computed() primitives:

TypeScript
// State Architecture Overview
diagramState = {
  nodes: signal<WorkflowNode[]>([]),
  edges: signal<WorkflowEdge[]>([]),
  viewport: signal<ViewportState>({ x: 0, y: 0, zoom: 1 }),
  selectedNodeIds: signal<Set<string>>(new Set())
};
⚡ Performance Impact
Because nodes and handles consume Signal inputs directly, dragging a single node only updates that specific node component's transform without re-evaluating the rest of the diagram subtree!

2. Viewport Transform & Canvas Coordinates

The diagram viewport handles pan (translate) and zoom (scale). All node positions are maintained in absolute graph space (x, y), while the viewport transform matrix converts them to DOM client coordinates:

Formula
DOM_X = (Graph_X * Zoom) + Pan_X
DOM_Y = (Graph_Y * Zoom) + Pan_Y

When users drag nodes, ngx-workflow automatically converts mouse offset events back into graph space coordinates, taking the current zoom level and pan offset into account.

3. Handles, Ports & Connecting

Connections originate and terminate at Handles (ports). Default nodes expose top / right / bottom / left based on node.ports (0=none … 4=all).

  • Manual connect: drag from one port to another — a preview edge follows the pointer.
  • Auto-connect: drag a node near another (within [proximityThreshold]) to snap a link.
  • Limits:handleConfig[port].maxConnectionsmaxConnectionsPerPort[maxConnectionsPerHandle].
  • Handles register with HandleRegistryService for typed dataType checks and connectability.
HTML
// Manual + limited connections
<ngx-workflow-diagram
  [nodes]="nodes()"
  [edges]="edges()"
  [maxConnectionsPerHandle]="2"
  (connectStart)="..."
  (connect)="..."
  (edgesChange)="edges.set($event)"
/>

4. ELK.js Auto-Layout Engine

ngx-workflow includes AutoLayoutService which delegates layout computation to the Eclipse Layout Kernel (ELK). You can invoke auto-layout at any time:

TypeScript
import { AutoLayoutService } from 'ngx-workflow';

// Inject service in your component
private autoLayout = inject(AutoLayoutService);

async arrangeDiagram() {
  // Directions: 'TB' (Top-to-Bottom), 'LR' (Left-to-Right), 'BT', 'RL'
  await this.autoLayout.applyLayout('LR');
}