Node Interaction Events in Angular Diagram Component
29 Aug 202520 minutes to read
The Angular Diagram component provides comprehensive event support for node interactions, allowing developers to respond to user actions and customize behavior during various interaction scenarios. These events are triggered when users interact with nodes through clicking, dragging, resizing, rotating, and other operations.
Click Event
Triggered when a user clicks on a node. This event provides access to the clicked node and mouse event details, enabling custom click handling and node-specific actions.
The following code example demonstrates how to handle the click event in the diagram:
import {
Connector,
DiagramModule,
IClickEventArgs,
PointModel,
DiagramComponent,
Node,
NodeModel,
} from '@syncfusion/ej2-angular-diagrams';
import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
@Component({
imports: [DiagramModule],
providers: [],
standalone: true,
selector: 'app-container',
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults' (click)="click($event)">
<e-nodes>
<e-node id='node1' [offsetX]=350 [offsetY]=250>
</e-node>
</e-nodes>
<e-connectors>
<e-connector id='connector' type='Straight' sourceID='node1' [targetPoint]='targetPoint'>
</e-connector>
</e-connectors>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
@ViewChild('diagram')
public diagram?: DiagramComponent;
public targetPoint?: PointModel;
ngOnInit(): void {
this.targetPoint = { x: 350, y: 500 };
}
public click(args: IClickEventArgs): void {
if (args.actualObject instanceof Node) {
alert('Node is clicked');
} else if (args.actualObject instanceof Connector) {
alert('Connector is clicked');
}
}
public getNodeDefaults(node: NodeModel): NodeModel {
node.height = 100;
node.width = 100;
return node;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Selection Change Event
Triggered when a node’s selection state changes, either when selected or deselected. This event fires during both the selection process and completion, providing control over selection behavior.
The following code example shows how to handle the selectionChange event:
import {
DiagramModule,
ISelectionChangeEventArgs,
DiagramComponent,
NodeModel,
} from '@syncfusion/ej2-angular-diagrams';
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
@Component({
imports: [DiagramModule],
providers: [],
standalone: true,
selector: 'app-container',
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults' (selectionChange)="selectionChange($event)">
<e-nodes>
<e-node id='node1' [offsetX]=350 [offsetY]=250>
</e-node>
</e-nodes>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
@ViewChild('diagram')
public diagram?: DiagramComponent;
public selectionChange(args: ISelectionChangeEventArgs): void {
if (args.state === 'Changed') {
console.log('Selection Change');
}
}
public getNodeDefaults(node: NodeModel): NodeModel {
node.height = 100;
node.width = 100;
return node;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Selection can be prevented by setting the cancel property of SelectionChangeEventArgs to true, as shown in the following code:
public selectionChange(args: ISelectionChangeEventArgs): void {
if (args.state === 'Changing') {
// Prevents node selection
args.cancel = true;
}
}Position Change Event
Triggered during node dragging operations, providing real-time position updates as users move nodes. This event enables position validation, snap-to-grid functionality, and custom drag behavior.
The following code example demonstrates how to handle the positionChange event:
import {
DiagramModule,
IDraggingEventArgs,
DiagramComponent,
NodeModel,
} from '@syncfusion/ej2-angular-diagrams';
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
@Component({
imports: [DiagramModule],
providers: [],
standalone: true,
selector: 'app-container',
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults' (positionChange)="positionChange($event)">
<e-nodes>
<e-node id='node1' [offsetX]=350 [offsetY]=250>
</e-node>
</e-nodes>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
@ViewChild('diagram')
public diagram?: DiagramComponent;
public positionChange(args: IDraggingEventArgs): void {
if (args.state === 'Completed') {
console.log('Position Change');
}
}
public getNodeDefaults(node: NodeModel): NodeModel {
node.height = 100;
node.width = 100;
return node;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Dragging can be prevented by setting the cancel property of DraggingEventArgs to true:
public positionChange(args: IDraggingEventArgs): void {
if (args.state === 'Progress') {
// Prevents node dragging
args.cancel = true;
}
}Size Change Event
Triggered during node resizing operations when users interact with resize handles. This event provides access to the new dimensions and allows for size constraints and validation.
The following code example shows how to handle the sizeChange event:
import {
DiagramModule,
ISizeChangeEventArgs,
DiagramComponent,
NodeModel,
} from '@syncfusion/ej2-angular-diagrams';
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
@Component({
imports: [DiagramModule],
providers: [],
standalone: true,
selector: 'app-container',
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults' (sizeChange)="sizeChange($event)">
<e-nodes>
<e-node id='node1' [offsetX]=350 [offsetY]=250>
</e-node>
</e-nodes>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
@ViewChild('diagram')
public diagram?: DiagramComponent;
public sizeChange(args: ISizeChangeEventArgs): void {
if (args.state === 'Completed') {
console.log('Size Change');
}
}
public getNodeDefaults(node: NodeModel): NodeModel {
node.height = 100;
node.width = 100;
return node;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Resizing can be prevented by setting the cancel property of SizeChangeEventArgs to true:
public sizeChange(args: ISizeChangeEventArgs): void {
if (args.state === 'Progress') {
// Prevents node resizing
args.cancel = true;
}
}Rotate Change Event
Triggered during node rotation operations when users interact with the rotation handle. This event enables rotation constraints and custom rotation behavior.
The following code example demonstrates how to handle the rotateChange event:
import {
DiagramModule,
IRotationEventArgs,
DiagramComponent,
NodeModel,
} from '@syncfusion/ej2-angular-diagrams';
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
@Component({
imports: [DiagramModule],
providers: [],
standalone: true,
selector: 'app-container',
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults' (rotateChange)="rotateChange($event)">
<e-nodes>
<e-node id='node1' [offsetX]=350 [offsetY]=250>
</e-node>
</e-nodes>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
@ViewChild('diagram')
public diagram?: DiagramComponent;
public rotateChange(args: IRotationEventArgs): void {
if (args.state === 'Completed') {
console.log('Rotate Change');
}
}
public getNodeDefaults(node: NodeModel): NodeModel {
node.height = 100;
node.width = 100;
return node;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Rotation can be prevented by setting the cancel property of RotationEventArgs to true:
public rotateChange(args: IRotationEventArgs): void {
if (args.state === 'Progress') {
// Prevents node rotation
args.cancel = true;
}
}Property Change Event
Triggered when any property of a node is modified programmatically or through user interaction. This event is useful for tracking changes and implementing custom validation logic.
The following code example shows how to handle the propertyChange event:
import {
DiagramModule,
IPropertyChangeEventArgs,
DiagramComponent,
NodeModel,
} from '@syncfusion/ej2-angular-diagrams';
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
@Component({
imports: [DiagramModule],
providers: [],
standalone: true,
selector: 'app-container',
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults' (propertyChange)="propertyChange($event)">
<e-nodes>
<e-node id='node1' [offsetX]=350 [offsetY]=250>
</e-node>
</e-nodes>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
@ViewChild('diagram')
public diagram?: DiagramComponent;
public propertyChange(args: IPropertyChangeEventArgs): void {
console.log(args.newValue);
}
public getNodeDefaults(node: NodeModel): NodeModel {
node.height = 100;
node.width = 100;
return node;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Collection Change Event
Triggered when nodes are added to or removed from the diagram dynamically. This event provides control over diagram modifications and enables validation before collection changes occur.
The following code example demonstrates how to handle the collectionChange event:
import {
DiagramModule,
ICollectionChangeEventArgs,
DiagramComponent,
NodeModel,
} from '@syncfusion/ej2-angular-diagrams';
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
@Component({
imports: [DiagramModule],
providers: [],
standalone: true,
selector: 'app-container',
template: `<button (click)= 'add()'>Add</button>
<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults' (collectionChange)="collectionChange($event)">
<e-nodes>
<e-node id='node1' [offsetX]=350 [offsetY]=250>
</e-node>
</e-nodes>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
@ViewChild('diagram')
public diagram?: DiagramComponent;
public node: NodeModel = {
// Position of the node
offsetX: 500,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
style: {
fill: 'skyblue',
},
};
public collectionChange(args: ICollectionChangeEventArgs): void {
if (args.state === 'Changed') {
console.log('Collection Change');
}
}
public add() {
(this.diagram as any).add(this.node);
}
public getNodeDefaults(node: NodeModel): NodeModel {
node.height = 100;
node.width = 100;
return node;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Collection changes can be prevented by setting the cancel property of CollectionChangeEventArgs to true:
public collectionChange(args: ICollectionChangeEventArgs): void {
if (args.state === 'Changing') {
// Prevents adding or removing nodes from the diagram
args.cancel = true;
}
}Mouse Events
The diagram component provides mouse interaction events that trigger when users hover over or move the mouse cursor in relation to node surfaces.
Mouse Enter Event
The mouseEnter event is triggered when the mouse cursor enters a node’s boundary area.
Mouse Over Event
The mouseOver event is triggered when the mouse cursor hovers over a node’s surface area.
Mouse Leave Event
The mouseLeave event is triggered when the mouse cursor leaves a node’s boundary area.
The following code example demonstrates how to handle these mouse events and implement visual feedback by changing node colors based on mouse interactions:
import {
DiagramModule,
IMouseEventArgs,
DiagramComponent,
NodeModel,
} from '@syncfusion/ej2-angular-diagrams';
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
@Component({
imports: [DiagramModule],
providers: [],
standalone: true,
selector: 'app-container',
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults' (mouseEnter)="mouseEnter($event)" (mouseLeave)="mouseLeave($event)" (mouseOver)="mouseOver($event)">
<e-nodes>
<e-node id='node1' [offsetX]=350 [offsetY]=250>
</e-node>
</e-nodes>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
@ViewChild('diagram')
public diagram?: DiagramComponent;
public mouseEnter(args: IMouseEventArgs): void {
(args.actualObject as any).style.fill = 'red';
(this.diagram as any).dataBind();
}
public mouseLeave(args: IMouseEventArgs): void {
(args.element as any).style.fill = 'skyblue';
(this.diagram as any).dataBind();
}
public mouseOver(args: IMouseEventArgs): void {
//Customize
}
public getNodeDefaults(node: NodeModel): NodeModel {
node.height = 100;
node.width = 100;
return node;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));