ngx-workflow

December 13, 2025 ยท View on GitHub

npm version License

A powerful, highly customizable Angular library for building interactive node-based editors, flow charts, and diagrams. Built with Angular Signals for high performance and reactivity.

Demo Screenshot

๐Ÿš€ Features

Core Features

  • Native Angular: Built from the ground up for Angular, using Signals and OnPush change detection
  • Interactive: Drag & drop nodes, zoom & pan canvas, connect edges
  • Customizable: Fully custom node and edge templates
  • Rich UI: Built-in minimap, background patterns, controls, and alignment tools
  • Layouts: Automatic layout support via Dagre and ELK
  • History: Robust Undo/Redo history stack with Ctrl+Z/Ctrl+Shift+Z
  • Theming: Explicit colorMode and CSS variables for easy styling with dark mode support
  • Smart Alignment: Visual alignment guides and drag snapping

Advanced Features

  • Snap-to-Grid: Configurable grid snapping for precise node placement
  • Space Panning: Professional canvas panning with Space + Drag
  • Export Controls: Built-in UI for PNG, SVG, and clipboard export
  • Clipboard Operations: Full copy/paste/cut support with Ctrl+C/V/X and localStorage persistence
  • Connection Validation: Prevent invalid connections with custom validators
  • Collision Detection: Optional collision prevention to stop nodes from overlapping
  • Edge Reconnection: Drag edge endpoints to reconnect them

Visuals & Motion

  • Edge Animation: SVG motion particles on edges (animated: true)
  • Node Motion: Programmatic API to animate nodes along edge paths
  • Custom Markers: Support for arrow, arrowclosed, dot, or fully custom SVG definitions via [defsTemplate]
  • Background Images: Support for custom background images via [backgroundImage]

Built-in UI Components

  • Search Bar: Press Ctrl+F to search nodes by label/id.
  • Properties Panel: Sidebar for editing node properties (auto-shows on selection).
  • Context Menu: Right-click canvas/nodes/edges for actions.
  • Layout Alignment: Auto-align selected nodes (if showLayoutControls is true).
  • Minimap: Navigable overview of complex flows.

Content Projection (Slots)

  • Node Toolbars: Show contextual buttons above selected nodes.
  • Panels: Add fixed overlays to the canvas (e.g., top-right controls).
<ngx-workflow-diagram ...>
  <!-- Shows above selected node -->
  <ngx-workflow-node-toolbar [nodeId]="selectedNodeId">
    <button (click)="deleteNode()">Delete</button>
  </ngx-workflow-node-toolbar>

  <!-- Fixed panel -->
  <ngx-workflow-panel position="top-right">
    <button>Save</button>
  </ngx-workflow-panel>
</ngx-workflow-diagram>

๐Ÿ“ฆ Installation

npm install ngx-workflow
npm install ngx-workflow

๐Ÿ Quick Start

Import NgxWorkflowModule directly into your standalone component's imports array.

import { Component } from '@angular/core';
import { NgxWorkflowModule, Node, Edge } from 'ngx-workflow';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [NgxWorkflowModule],
  template: `
    <div style="height: 100vh; width: 100%;">
      <ngx-workflow-diagram
        [nodes]="nodes"
        [edges]="edges"
        (nodeClick)="onNodeClick($event)"
        (connect)="onConnect($event)"
      ></ngx-workflow-diagram>
    </div>
  `
})
export class AppComponent {
  nodes: Node[] = [
    { id: '1', position: { x: 100, y: 100 }, label: 'Start', type: 'default' },
    { id: '2', position: { x: 300, y: 100 }, label: 'End', type: 'default' }
  ];

  edges: Edge[] = [
    { id: 'e1-2', source: '1', target: '2', sourceHandle: 'right', targetHandle: 'left', animated: true }
  ];

  onNodeClick(node: Node) {
    console.log('Clicked:', node);
  }

  onConnect(connection: any) {
    console.log('Connected:', connection);
  }
}

๐Ÿ“– API Reference

<ngx-workflow-diagram>

The main component for rendering the workflow.

Inputs

NameTypeDefaultDescription
nodesNode[][]Array of nodes to display (Signal-based sync).
edgesEdge[][]Array of edges to display.
initialViewportViewportundefinedInitial viewport state { x, y, zoom }.
showZoomControlsbooleantrueWhether to show the zoom control buttons (bottom-left).
minZoomnumber0.1Minimum zoom level.
maxZoomnumber4Maximum zoom level.
showMinimapbooleantrueWhether to show the minimap (bottom-right).
showBackgroundbooleantrueWhether to show the background pattern.
backgroundVariant'dots' | 'lines' | 'cross''dots'The pattern style of the background.
backgroundImagestring | nullnullURL for a custom background image.
backgroundGapnumber20Gap between background pattern elements.
backgroundSizenumber1Size of background pattern elements.
backgroundColorstring'#81818a'Color of the background pattern dots/lines.
backgroundBgColorstring'#f0f0f0'Background color of the canvas itself.
fitViewbooleanfalseAutomatically fit all nodes in view on load.
connectionValidator(source: string, target: string) => booleanundefinedCustom function to validate connections globally.
nodesResizablebooleantrueGlobal toggle to enable/disable node resizing.
snapToGridbooleanfalseEnable snap-to-grid for node positioning.
gridSizenumber20Grid size in pixels for snap-to-grid.
showExportControlsbooleanfalseShow export controls UI (PNG, SVG, Clipboard).
showUndoRedoControlsbooleantrueShow history controls UI.
showLayoutControlsbooleanfalseShow auto-layout controls.
colorMode'light' | 'dark''light'Color theme mode.
zIndexMode'default' | 'layered''default'Strategy for node z-indexing.
preventNodeOverlapbooleanfalseEnable collision detection to prevent partial overlaps.
nodeSpacingnumber10Minimum spacing between nodes when preventNodeOverlap is true.
edgeReconnectionbooleanfalseAllow dragging edge endpoints to reconnect them.
autoSavebooleanfalseEnable auto-saving of diagram state to localStorage.
autoSaveIntervalnumber1000throttled auto-save interval in ms.
autoPanOnNodeDragbooleantruePan canvas automatically when dragging node near edge.
autoPanOnConnectbooleantruePan canvas automatically when connecting edges near boundary.
autoPanSpeednumber15Pixels per frame for auto-pan.
autoPanEdgeThresholdnumber50Distance in pixels from edge to trigger auto-pan.
defsTemplateTemplateRef<any>undefinedAngular template containing SVG <defs> (markers, etc).
edgeTemplateTemplateRef<any>undefinedCustom template for rendering edges.
maxConnectionsPerHandlenumberundefinedGlobal limit for connections per handle.

Methods

You can access these methods via @ViewChild(DiagramComponent):

MethodReturnDescription
fitView()voidFits all nodes within the viewport.
zoomIn()voidIncreases zoom level by 20%.
zoomOut()voidDecreases zoom level by 20%.
resetZoom()voidResets zoom to 100%.
exportToPNG(filename, options)voidExport canvas as PNG.
exportToSVG(filename, options)voidExport canvas as SVG.
copyToClipboard(options)voidCopy diagram image to clipboard.

Outputs

NameTypeDescription
nodeClickEventEmitter<Node>Emitted when a node is clicked.
nodeDoubleClickEventEmitter<Node>Emitted when a node is double-clicked.
edgeClickEventEmitter<Edge>Emitted when an edge is clicked.
connectEventEmitter<Connection>Emitted when a new connection is created.
nodesChangeEventEmitter<Node[]>Emitted when the nodes array changes (move, add, delete).
edgesChangeEventEmitter<Edge[]>Emitted when the edges array changes.
paneClickEventEmitter<MouseEvent>Emitted when the empty canvas is clicked.
contextMenuEventEmitter<Event>Emitted on right-click.
beforeDeleteEventEmitter<{nodes, edges, cancel}>cancellable event before deletion.
nodeMouseEnterEventEmitter<Node>Emitted when mouse enters a node.
nodeMouseLeaveEventEmitter<Node>Emitted when mouse leaves a node.
edgeMouseEnterEventEmitter<Edge>Emitted when mouse enters an edge.
edgeMouseLeaveEventEmitter<Edge>Emitted when mouse leaves an edge.

Interfaces

Node

interface Node {
  id: string;              // Unique identifier
  position: { x: number; y: number }; // Position on canvas
  label?: string;          // Default label
  data?: any;              // Custom data passed to your custom node component
  type?: string;           // 'default', 'group', or your custom type
  width?: number;          // Width in pixels (default: 170)
  height?: number;         // Height in pixels (default: 60)
  draggable?: boolean;     // Is the node draggable? (default: true)
  selectable?: boolean;    // Is the node selectable? (default: true)
  connectable?: boolean;   // Can edges be connected? (default: true)
  resizable?: boolean;     // Is this specific node resizable? (default: true)
  zIndex?: number;         // Manual Z-Index
  class?: string;          // Custom CSS class
  style?: object;          // Custom inline styles
  
  // Styling
  shadow?: boolean | string;   // Drop shadow
  borderStyle?: 'solid' | 'dashed' | 'dotted' | 'none';
  borderColor?: string;
  borderWidth?: number;

  // Behavior
  ports?: 1 | 2 | 3 | 4;   // Default handle configuration (1=Top, 4=All)
  easyConnect?: boolean;   // Drag from node body to connect
  
  // Visuals
  badges?: Array<{
    content: string;
    color?: string;
    backgroundColor?: string;
    position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
  }>;
}

Edge

interface Edge {
  id: string;
  source: string;          // ID of source node
  target: string;          // ID of target node
  sourceHandle?: string;   // ID of source handle (optional)
  targetHandle?: string;   // ID of target handle (optional)
  label?: string;          // Label text displayed on the edge
  type?: 'bezier' | 'straight' | 'step'; // Path type (default: 'bezier')
  animated?: boolean;      // Show animation (dashed moving line)?
  markerStart?: string;    // Start marker ID (e.g., 'arrow', 'dot')
  markerEnd?: string;      // End marker ID
  style?: object;          // SVG styles (stroke, stroke-width, etc.)
}

Handle (Component)

Use <ngx-workflow-handle> inside your custom nodes.

<ngx-workflow-handle
    type="source"
    position="right"
    [isConnectable]="true"
    [isValidConnection]="validateConnectionFn"
></ngx-workflow-handle>
InputTypeDescription
type'source' | 'target'Type of handle.
position'top' | 'right' | 'bottom' | 'left'Position on the node boundary.
isValidConnection(connection) => booleanFunction to validate connections for this specific handle.

Custom Edges

Similar to nodes, you can register custom edge types.

  1. Create Edge Component: It must extend BaseEdge.
  2. Register Token:
    import { NGX_WORKFLOW_EDGE_TYPES } from 'ngx-workflow';
    providers: [
      { provide: NGX_WORKFLOW_EDGE_TYPES, useValue: { 'my-edge': CustomEdgeComponent } }
    ]
    

๐ŸŽจ Custom Customization

Edge Markers

To use custom SVG markers, pass a template to [defsTemplate]:

<ng-template #defs>
  <svg:marker id="my-marker" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="5" markerHeight="5">
    <circle cx="5" cy="5" r="5" fill="red" />
  </svg:marker>
</ng-template>

<ngx-workflow-diagram [defsTemplate]="defs" ...></ngx-workflow-diagram>

Then use it in your edge: { id: 'e1', ..., markerEnd: 'my-marker' }.

Styling

ngx-workflow uses CSS variables for easy theming. Override these in your global styles:

:root {
  --ngx-workflow-primary: #3b82f6;
  --ngx-workflow-bg: #f8fafc;
  --ngx-workflow-grid-color: #e2e8f0;
  --ngx-workflow-node-bg: #ffffff;
  --ngx-workflow-node-border: #cbd5e1;
  --ngx-workflow-handle-color: #3b82f6;
  --ngx-workflow-edge-stroke: #64748b;
  --ngx-workflow-selection-stroke: #3b82f6;
}

โŒจ๏ธ Keyboard Shortcuts

ShortcutAction
Space + DragPan canvas
Shift + DragLasso selection
Ctrl + ClickMulti-select
Mouse WheelZoom in/out

Editing

ShortcutAction
Delete / BackspaceDelete selected nodes/edges
Ctrl + ZUndo
Ctrl + Shift + Z / Ctrl + YRedo

Clipboard Operations

ShortcutAction
Ctrl + CCopy selected nodes
Ctrl + VPaste copied nodes
Ctrl + XCut selected nodes
Ctrl + DDuplicate selected nodes

Export

ShortcutAction
Ctrl + Shift + EExport as PNG
Ctrl + Shift + SExport as SVG
Ctrl + Shift + CCopy to clipboard

Grouping

ShortcutAction
Ctrl + GGroup selected nodes
Ctrl + Shift + GUngroup selected group

๐Ÿค Contributing

Contributions are welcome! Please read our Contributing Guide for details.

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


See ADVANCED_FEATURES.md for details on Space Panning, Exports, Grid Snapping, and more.