Skip to content

Custom Edges

When ngDiagram’s default edge customizations are not sufficient, you can create custom edges that provide more precise control over edge rendering, including routing.

You can create a custom edge by extending NgDiagramBaseEdgeComponent and implementing NgDiagramEdgeTemplate

import { Component, computed, input } from '@angular/core';
import {
NgDiagramBaseEdgeComponent,
type Edge,
type NgDiagramEdgeTemplate,
} from 'ng-diagram';
@Component({
selector: 'custom-edge',
template: `<ng-diagram-base-edge
[edge]="customEdge()"
stroke="var(--ngd-default-edge-stroke)"
/>`,
imports: [NgDiagramBaseEdgeComponent],
})
export class CustomEdgeComponent implements NgDiagramEdgeTemplate {
edge = input.required<Edge>();
customEdge = computed(() => {
const edge = this.edge();
const { sourcePosition, targetPosition } = edge;
if (!sourcePosition || !targetPosition) {
return edge;
}
// Create custom points for the edge path
const points = [
{ x: sourcePosition.x, y: sourcePosition.y },
{ x: targetPosition.x, y: targetPosition.y },
];
return {
...edge,
points,
routing: 'polyline',
routingMode: 'manual' as const,
};
});
}

Custom edge types need to be registered in the edgeTemplateMap and passed to the ngDiagram component.

After registering the custom edge, you can use it in your diagram model by specifying the type property of the edge.

@Component({
imports: [NgDiagramComponent, NgDiagramBackgroundComponent],
providers: [provideNgDiagram()],
template: `
<div class="not-content diagram">
<ng-diagram [model]="model" [edgeTemplateMap]="edgeTemplateMap">
<ng-diagram-background />
</ng-diagram>
</div>
`,
7 collapsed lines
styles: `
.diagram {
display: flex;
height: var(--ng-diagram-height);
border: var(--ng-diagram-border);
}
`,
})
export class DiagramComponent {
edgeTemplateMap = new NgDiagramEdgeTemplateMap([
['custom', CustomEdgeComponent],
]);
26 collapsed lines
model = initializeModel({
metadata: {
viewport: { x: 0, y: 0, scale: 0.88 },
},
nodes: [
{
id: '1',
position: { x: 150, y: 150 },
data: { label: 'Node 1' },
rotatable: true,
},
{ id: '2', position: { x: 500, y: 150 }, data: { label: 'Node 2' } },
],
edges: [
{
id: '1',
source: '1',
sourcePort: 'port-right',
targetPort: 'port-left',
target: '2',
type: 'custom',
data: {},
},
],
});
}

Custom edges can be styled using CSS variables that the NgDiagramBaseEdgeComponent exposes. This approach provides a clean way to customize edge appearance without breaking encapsulation.

  • --edge-stroke - Stroke color
  • --edge-stroke-width - Stroke width
  • --edge-stroke-opacity - Stroke opacity
  • --edge-stroke-dasharray - Stroke dash pattern (e.g., 5 5 for dashed line)
  • --edge-stroke-transition - Transition for stroke changes (e.g., stroke 0.1s ease-in-out)
ng-diagram-base-edge {
--edge-stroke: #334155;
--edge-stroke-width: 2;
--edge-stroke-dasharray: 5 5; // Dashed line
}
ng-diagram-base-edge.selected {
--edge-stroke: #3b82f6;
--edge-stroke-width: 3;
--edge-stroke-dasharray: 8 4; // Different dash pattern when selected
}
ng-diagram-base-edge:hover:not(.selected) {
--edge-stroke: #64748b;
}

You can also pass styling properties directly to the NgDiagramBaseEdgeComponent:

@Component({
selector: 'custom-edge',
template: `<ng-diagram-base-edge
[edge]="edge()"
stroke="#334155"
[strokeWidth]="3"
strokeDasharray="5 5"
[strokeOpacity]="0.8"
/>`,
imports: [NgDiagramBaseEdgeComponent],
})
export class CustomEdgeComponent implements NgDiagramEdgeTemplate {
edge = input.required<Edge>();
}

Custom routing is an extensible mechanism that allows you to create sophisticated edge paths tailored to your specific needs. You can implement custom routing algorithms, create dynamic paths based on node positions, or define manual waypoints for precise control.

Routing →

To add labels to your custom edges, integrate the NgDiagramBaseEdgeLabelComponent within your custom edge component.
Here’s an implementation example:


import { Component, input } from '@angular/core';
import {
NgDiagramBaseEdgeComponent,
NgDiagramBaseEdgeLabelComponent,
type Edge,
type NgDiagramEdgeTemplate,
} from 'ng-diagram';
@Component({
selector: 'labeled-edge',
template: `<ng-diagram-base-edge
[edge]="edge()"
stroke="var(--ngd-default-edge-stroke)"
>
<ng-diagram-base-edge-label [id]="'test-label'" [positionOnEdge]="0.5">
<div class="custom-label">Label</div>
</ng-diagram-base-edge-label>
</ng-diagram-base-edge>`,
styleUrl: './labeled-edge.component.scss',
imports: [NgDiagramBaseEdgeComponent, NgDiagramBaseEdgeLabelComponent],
})
export class LabeledEdgeComponent implements NgDiagramEdgeTemplate {
edge = input.required<Edge>();
}

Edge Labels →