/

Connection Lines

Connections are SVG paths between measured connector elements. Choose a flowing Bezier curve or an orthogonal SmoothStep path, then configure arrowheads, labels and CSS variables independently from the graph data.

BezierCubic curves driven by source and target directions.
SmoothStepHorizontal and vertical segments with rounded corners.
ArrowheadsNone, open arrow or closed arrow at the target.

Configure Connection Rendering

Connection rendering is shared by existing model edges and interactive draft creation. The connector's position input supplies the path direction.

graph-editor.component.ts

    
      provideNgDrawFlowConfigs({
  connection: {
    type: DfConnectionType.SmoothStep,
    curvature: 16,
    arrowhead: {
      type: DfArrowhead.ArrowClosed,
      width: 10,
      height: 6,
    },
  },
});
    
OptionDefaultBehavior
typeBezierSelects Bezier or SmoothStep calculation.
curvature0.25Bezier bend coefficient or SmoothStep radius in pixels.
arrowhead.typeNone Uses Arrow , ArrowClosed or no marker.
arrowhead.width / height8 / 4Target marker dimensions in pixels.

Bezier

Bezier edges are cubic curves. Their dimensionless curvature coefficient scales with connector distance, so the same value remains useful across short and long edges.

    
      
    
    
      import {AsyncPipe} from '@angular/common';
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {FormControl, ReactiveFormsModule} from '@angular/forms';
import {
    DfArrowhead,
    DfConnectionPoint,
    DfConnectionType,
    type DfDataModel,
    dfPanZoomOptionsProvider,
    NgDrawFlowComponent,
    provideNgDrawFlowConfigs,
} from '@ng-draw-flow/core';
import {TuiAddonDoc} from '@taiga-ui/addon-doc';

import {InputNodeComponent, OutputNodeComponent} from '../../../../app/modules/nodes';

@Component({
    standalone: true,
    selector: 'bezier-example',
    imports: [AsyncPipe, NgDrawFlowComponent, ReactiveFormsModule, TuiAddonDoc],
    templateUrl: './bezier-example.component.html',
    changeDetection: ChangeDetectionStrategy.OnPush,
    providers: [
        dfPanZoomOptionsProvider({
            topPosition: 50,
            leftPosition: null,
        }),
        provideNgDrawFlowConfigs({
            connection: {
                type: DfConnectionType.Bezier,
                arrowhead: {type: DfArrowhead.ArrowClosed},
                curvature: 0.25,
            },
            nodes: {
                inputNode: InputNodeComponent,
                outputNode: OutputNodeComponent,
            },
        }),
    ],
})
export default class BezierExampleComponent {
    public data: DfDataModel = {
        nodes: [
            {
                id: 'node-1',
                data: {type: 'outputNode', text: 'This base node'},
                position: {x: 0, y: 0},
            },
            {
                id: 'node-2',
                data: {type: 'inputNode', text: 'This child node 1'},
                position: {x: 20, y: 150},
            },
        ],
        connections: [
            {
                source: {
                    nodeId: 'node-1',
                    connectorType: DfConnectionPoint.Output,
                    connectorId: 'node-1-output-1',
                },
                target: {
                    nodeId: 'node-2',
                    connectorType: DfConnectionPoint.Input,
                    connectorId: 'node-2-input-3',
                },
            },
            {
                source: {
                    nodeId: 'node-1',
                    connectorType: DfConnectionPoint.Output,
                    connectorId: 'node-1-output-2',
                },
                target: {
                    nodeId: 'node-2',
                    connectorType: DfConnectionPoint.Input,
                    connectorId: 'node-2-input-1',
                },
            },
            {
                source: {
                    nodeId: 'node-1',
                    connectorType: DfConnectionPoint.Output,
                    connectorId: 'node-1-output-3',
                },
                target: {
                    nodeId: 'node-2',
                    connectorType: DfConnectionPoint.Input,
                    connectorId: 'node-2-input-4',
                },
            },
            {
                source: {
                    nodeId: 'node-1',
                    connectorType: DfConnectionPoint.Output,
                    connectorId: 'node-1-output-4',
                },
                target: {
                    nodeId: 'node-2',
                    connectorType: DfConnectionPoint.Input,
                    connectorId: 'node-2-input-2',
                },
            },
        ],
    };

    public form = new FormControl<DfDataModel>(this.data);
}

    
    
      <ng-draw-flow [formControl]="form" />

    

SmoothStep

SmoothStep edges use horizontal and vertical segments joined by rounded bends. Their curvature value is the corner radius in pixels, making them suitable for tree and process layouts.

    
      
    
    
      import {AsyncPipe} from '@angular/common';
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {FormControl, ReactiveFormsModule} from '@angular/forms';
import {
    DfArrowhead,
    DfConnectionPoint,
    DfConnectionType,
    type DfDataModel,
    dfPanZoomOptionsProvider,
    NgDrawFlowComponent,
    provideNgDrawFlowConfigs,
} from '@ng-draw-flow/core';
import {TuiAddonDoc} from '@taiga-ui/addon-doc';

import {InputNodeComponent, OutputNodeComponent} from '../../../../app/modules/nodes';

@Component({
    standalone: true,
    selector: 'smooth-step-example',
    imports: [AsyncPipe, NgDrawFlowComponent, ReactiveFormsModule, TuiAddonDoc],
    templateUrl: './smooth-step-example.component.html',
    changeDetection: ChangeDetectionStrategy.OnPush,
    providers: [
        dfPanZoomOptionsProvider({
            topPosition: 50,
            leftPosition: null,
        }),
        provideNgDrawFlowConfigs({
            connection: {
                type: DfConnectionType.SmoothStep,
                arrowhead: {type: DfArrowhead.ArrowClosed},
                curvature: 10,
            },
            nodes: {
                inputNode: InputNodeComponent,
                outputNode: OutputNodeComponent,
            },
        }),
    ],
})
export default class SmoothStepExampleComponent {
    public data: DfDataModel = {
        nodes: [
            {
                id: 'node-1',
                data: {type: 'outputNode', text: 'This base node'},
                position: {x: 0, y: 0},
            },
            {
                id: 'node-2',
                data: {type: 'inputNode', text: 'This child node 1'},
                position: {x: 20, y: 150},
            },
        ],
        connections: [
            {
                source: {
                    nodeId: 'node-1',
                    connectorType: DfConnectionPoint.Output,
                    connectorId: 'node-1-output-1',
                },
                target: {
                    nodeId: 'node-2',
                    connectorType: DfConnectionPoint.Input,
                    connectorId: 'node-2-input-3',
                },
            },
            {
                source: {
                    nodeId: 'node-1',
                    connectorType: DfConnectionPoint.Output,
                    connectorId: 'node-1-output-2',
                },
                target: {
                    nodeId: 'node-2',
                    connectorType: DfConnectionPoint.Input,
                    connectorId: 'node-2-input-1',
                },
            },
            {
                source: {
                    nodeId: 'node-1',
                    connectorType: DfConnectionPoint.Output,
                    connectorId: 'node-1-output-3',
                },
                target: {
                    nodeId: 'node-2',
                    connectorType: DfConnectionPoint.Input,
                    connectorId: 'node-2-input-4',
                },
            },
            {
                source: {
                    nodeId: 'node-1',
                    connectorType: DfConnectionPoint.Output,
                    connectorId: 'node-1-output-4',
                },
                target: {
                    nodeId: 'node-2',
                    connectorType: DfConnectionPoint.Input,
                    connectorId: 'node-2-input-2',
                },
            },
        ],
    };

    public form = new FormControl<DfDataModel>(this.data);
}

    
    
      <ng-draw-flow [formControl]="form" />

    

Selection and Deletion

Selecting a node distinguishes both directions: incoming edges use the input highlight palette and outgoing edges use the output palette. Selecting an edge applies the active connection color. Delete or Backspace removes the selected edge when connectionsDeletable is enabled.

Programmatic deletion is available through removeConnection() on NgDrawFlowComponent and NgDrawFlowStoreService . The source and target endpoints identify the matching connection.

Connection Theming

Style the visible path, larger selectable hit area, active edge, directional node highlights and labels with CSS variables on ng-draw-flow . The hit area width does not change the visible stroke.

styles.less

    
      ng-draw-flow {
  --df-connection-color: #428bf9;
  --df-connection-color-hover: #155eef;
  --df-connection-color-active: #004eeb;
  --df-connection-stroke-width: 0.125rem;
  --df-connection-selectable-area-stroke-width: 0.75rem;
  --df-connection-selected-node-input-color: #156ed4;
  --df-connection-selected-node-output-color: #f97316;
  --df-connection-label-background: #fff;
  --df-connection-label-border-color: #b1b1b7;
  --df-connection-label-border-radius: 0.25rem;
  --df-connection-label-padding: 0.25rem 0.375rem;
}