Skip to content

Labels

Labels are visual elements attached to edges that can display text, buttons, or any custom content. They automatically position themselves along the edge path and follow the edge as it moves or changes shape.

To display a label on an edge, use the BaseEdgeLabelComponent in the implementation of your edge component:

@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, BaseEdgeLabelComponent],
})
export class LabeledEdgeComponent implements NgDiagramEdgeTemplate {
edge = input.required<Edge>();
}

The positionOnEdge property determines where the label appears along the edge path. It can be set to any value from 0 to 1, where 0.5 is the center of the edge. Labels automatically follow the edge path, regardless of the used routing algorithm.

Labels can be added and modified dynamically. One way to achieve this is by using diagram’s model. The ModifiableLabelEdgeComponent shows how to map such data into an actual label implementation.

Click on an edge to select it in the example below. Then fill the label’s name and click “Set Label”. It’ll modify selected edge’s data to include a new element in a measuredLabels property.

Edge component

@Component({
selector: 'multi-label-edge',
template: `<ng-diagram-base-edge
[edge]="edge()"
[stroke]="selected() ? 'rebeccapurple' : 'var(--ngd-default-edge-stroke)'"
>
@if (label()) {
<ng-diagram-base-edge-label
[id]="label().id"
[positionOnEdge]="label().positionOnEdge"
class="label"
>
{{ label().content }}
</ng-diagram-base-edge-label>
}
</ng-diagram-base-edge>`,
8 collapsed lines
styleUrl: './modifiable-label-edge.component.scss',
imports: [NgDiagramBaseEdgeComponent, BaseEdgeLabelComponent],
})
export class ModifiableLabelEdgeComponent
implements NgDiagramEdgeTemplate<MultiLabelEdgeData>
{
edge = input.required<Edge<MultiLabelEdgeData>>();
selected = computed(() => this.edge().selected);
label = computed(() => {
const { label } = this.edge().data;
if (!label) {
return;
}
if (!Array.isArray(label)) {
return { id: 'label', positionOnEdge: 0.5, content: label };
}
});
}
type MultiLabelEdgeData = {
label: string;
};

Label Panel

@Component({
selector: 'label-panel',
imports: [FormsModule],
template: `
@if (isEdgeSelected()) {
<input [(ngModel)]="label" />
} @else {
Select an edge
}
<button (click)="onSetLabel()">Set Label</button>
`,
19 collapsed lines
styles: `
:host {
z-index: 1;
background: #222;
position: absolute;
width: 8rem;
right: 0;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1rem;
input {
width: calc(100% - 2rem);
}
}
`,
})
export class LabelPanel {
private modelService: NgDiagramModelService = inject(NgDiagramModelService);
edges = computed(() => this.modelService.getModel().getEdges());
4 collapsed lines
selectedEdge = computed(() => this.edges().find((edge) => edge.selected));
isEdgeSelected = computed(() => !!this.selectedEdge());
label = '';
onSetLabel() {
const edgeToUpdate = this.edges().find((edge) => edge.selected);
if (!edgeToUpdate) {
return;
}
this.modelService.updateEdgeData(edgeToUpdate.id, {
label: this.label,
});
}
}

When adding interactive elements like inputs to edge labels, dragging on these elements might trigger unwanted diagram behaviors. You can control this using special data attributes:

  • data-no-pan="true" - Prevents the diagram canvas from panning when the user clicks and drags on the element
  • data-no-drag="true" - Prevents nodes from being dragged when the user clicks and drags on the element
<!-- Input in edge label that won't trigger diagram interactions -->
<input type="text" data-no-pan="true" data-no-drag="true" placeholder="Type here" />

NgDiagram supports multiple labels and they can be used to display images, shapes, or any other content. The example below demonstrates how to add multiple labels to an edge to create a flow animation.

const LABEL_COUNT = 10;
const ANIMATION_DURATION = 0.5;
@Component({
selector: 'multi-label-edge',
template: `<ng-diagram-base-edge
[edge]="edge()"
[stroke]="selected() ? 'rebeccapurple' : 'var(--ngd-default-edge-stroke)'"
>
@for (label of animatedLabels(); track label.id) {
<ng-diagram-base-edge-label
class="label"
[id]="label.id"
[positionOnEdge]="label.positionOnEdge"
[style]="label.style"
>
</ng-diagram-base-edge-label>
}
</ng-diagram-base-edge>`,
styles: `
@keyframes label-animation {
0% {
background: aliceblue;
}
100% {
background: rebeccapurple;
}
}
.label {
width: 1rem;
height: 1rem;
border-radius: 100%;
background: aliceblue;
animation: label-animation ${ANIMATION_DURATION}s ease-in-out infinite;
}
`,
imports: [NgDiagramBaseEdgeComponent, BaseEdgeLabelComponent],
})
export class MultipleLabelsEdgeComponent
implements NgDiagramEdgeTemplate<MultiLabelEdgeData>
{
edge = input.required<Edge<MultiLabelEdgeData>>();
selected = computed(() => this.edge().selected);
animatedLabels = computed(() => {
return Array.from({ length: LABEL_COUNT }, (_, i) => ({
id: `label-${i}`,
positionOnEdge: (i + 1) / (LABEL_COUNT + 1),
style: {
animationDelay: `${(ANIMATION_DURATION / LABEL_COUNT) * i}s`,
},
}));
});