Skip to content

Arrowheads

Arrowheads in NgDiagram are visual markers that indicate the start or end of the edge. They are implemented using SVG markers and can be applied to either the source end (sourceArrowhead) or target end (targetArrowhead) of an edge.

NgDiagram provides a built-in arrowhead called ng-diagram-arrow that can be used out of the box. This default arrowhead is a simple triangular arrow that adapts to the edge’s stroke color.

To use the default arrowhead, specify it in your edge configuration:

edges: [
{
targetArrowhead: 'ng-diagram-arrow',
7 collapsed lines
id: '1',
source: '1',
sourcePort: 'port-right',
target: '2',
targetPort: 'port-left',
data: {},
routing: 'straight',
},
{
sourceArrowhead: 'ng-diagram-arrow',
targetArrowhead: 'ng-diagram-arrow',
7 collapsed lines
id: '2',
source: '3',
sourcePort: 'port-right',
target: '4',
targetPort: 'port-left',
data: {},
routing: 'straight',
},
],
});

You can create custom arrowheads by defining SVG markers with unique IDs. Custom arrowheads allow you to create distinctive visual styles that match your application’s design requirements.

Custom arrowheads need to be defined as SVG <marker> elements within a <defs> section. Each marker needs a unique ID that you’ll reference in your edge configuration:

@Component({
selector: 'custom-arrowheads',
template: `
<svg height="0" width="0">
<defs>
<!-- Square Arrowhead -->
<marker
id="square-arrowhead"
markerWidth="10"
markerHeight="10"
refX="8"
refY="5"
orient="auto"
>
<rect
x="1"
y="1"
width="8"
height="8"
fill="context-stroke"
stroke="context-stroke"
/>
</marker>
<!-- Open Arrow Arrowhead -->
<marker
id="open-arrow"
markerWidth="10"
markerHeight="10"
refX="8"
refY="5"
orient="auto"
>
<path
d="M 2 2 L 8 5 L 2 8"
fill="none"
stroke="context-stroke"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</marker>
<!-- Circle Arrowhead -->
<marker
id="circle-arrowhead"
markerWidth="8"
markerHeight="8"
refX="6"
refY="4"
orient="auto"
>
<circle cx="4" cy="4" r="3" fill="context-stroke" />
</marker>
</defs>
</svg>
`,
})
export class CustomArrowheadsComponent {}

When marker is defined in the SVG <defs> section, it can be referenced in your edge configuration to apply the custom arrowhead to the edge.

@Component({
imports: [NgDiagramComponent, CustomArrowheadsComponent],
providers: [provideNgDiagram()],
template: `
<ng-diagram [model]="model" />
<custom-arrowheads />
`,
7 collapsed lines
styles: `
:host {
flex: 1;
display: flex;
height: 100%;
}
`,
})
export class CustomArrowheadDiagram {
model = initializeModel({
35 collapsed lines
metadata: {
viewport: { x: 100, y: 0, scale: 0.8 },
},
nodes: [
{
id: 'square',
position: { x: 50, y: 50 },
data: { label: 'Square' },
},
{
id: 'square-target',
position: { x: 400, y: 50 },
data: { label: 'Target' },
},
{
id: 'open-arrow',
position: { x: 50, y: 150 },
data: { label: 'Open Arrow' },
},
{
id: 'open-arrow-target',
position: { x: 400, y: 150 },
data: { label: 'Target' },
},
{
id: 'circle',
position: { x: 50, y: 250 },
data: { label: 'Circle' },
},
{
id: 'circle-target',
position: { x: 400, y: 250 },
data: { label: 'Target' },
},
],
edges: [
{
targetArrowhead: 'square-arrowhead',
6 collapsed lines
id: '1',
source: 'square',
target: 'square-target',
sourcePort: 'port-right',
targetPort: 'port-left',
data: {},
},
{
targetArrowhead: 'open-arrow',
6 collapsed lines
id: '2',
source: 'open-arrow',
target: 'open-arrow-target',
sourcePort: 'port-right',
targetPort: 'port-left',
data: {},
},
{
targetArrowhead: 'circle-arrowhead',
6 collapsed lines
id: '3',
source: 'circle',
target: 'circle-target',
sourcePort: 'port-right',
targetPort: 'port-left',
data: {},
},
],
});
}

See <marker> documentation on MDN for more details.

When implementing custom edges, you can override the default arrowhead with a custom one by specifying the sourceArrowhead and targetArrowhead inputs of NgDiagramBaseEdgeComponent. Thanks to it you don’t have to specify the arrowhead in the data of each edge.