Tools in Angular Diagram Component

25 Aug 202524 minutes to read

The Angular Diagram component provides a comprehensive set of interactive tools that enable users to create, modify, and navigate diagrams efficiently. These tools facilitate real-time interaction with diagram elements through mouse and keyboard operations.

Overview

The diagram control offers three primary tool categories:

  • Select: Choose and manipulate specific elements within the diagram
  • Pan: Navigate the diagram view to different areas without modifying elements
  • Draw: Create new shapes, connectors, and freehand drawings on the diagram surface

These tools are essential for building complex diagrams and provide the foundation for user interaction within the diagram environment.

Drawing tools

Drawing tools enable real-time creation of diagram elements by clicking and dragging on the diagram canvas. All drawing operations are configured through the drawingObject property and activated using the tool property.

Draw nodes

To draw shapes during runtime, configure the JSON representation of the desired shape in the drawingObject property and set the tool to drawing mode. The following example demonstrates how to draw a rectangle shape:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import {
  DiagramModule,
  DiagramComponent,
  Diagram,
  ConnectorModel,
  DiagramTools,
} from '@syncfusion/ej2-angular-diagrams';

@Component({
  imports: [DiagramModule],

  providers: [],
  standalone: true,
  selector: 'app-container',
  template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" (created)='created($event)'>
    </ejs-diagram>`,
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public connectors?: ConnectorModel;
  public created(args: Object): void {
    //JSON to create a path
    (this.diagram as Diagram).drawingObject = { shape: { type: 'Basic', shape: 'Rectangle' } };
    //To draw an object once, activate draw once
    (this.diagram as Diagram).tool = DiagramTools.ContinuousDraw;
    (this.diagram as Diagram).dataBind();
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Path shapes can be drawn using the same approach with custom path data. The following example shows how to draw a path shape:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramModule, DiagramComponent, Diagram, NodeModel, PathModel, DiagramTools, ShapeStyleModel } from '@syncfusion/ej2-angular-diagrams';

@Component({
imports: [
         DiagramModule
    ],

providers: [ ],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" (created)='created($event)'>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public node?: NodeModel;
    public created(args: Object): void {
        //JSON to create a path
        this.node = {
            id: "Path",
            style: { fill: "#fbe172" },
            annotations: [{
                content: "Path"
            }],
            shape: {
                type:'Path',
                data: 'M13.560 67.524 L 21.941 41.731 L 0.000 25.790 L 27.120 25.790 L 35.501 0.000 L 43.882 25.790 L 71.000 25.790 L 49.061 41.731 L 57.441 67.524 L 35.501 51.583 z',
            } as PathModel
        };
        (this.diagram as Diagram).drawingObject = this.node;
        //To draw an object once, activate draw once
        (this.diagram as Diagram).tool = DiagramTools.ContinuousDraw;
        (this.diagram as Diagram).dataBind();
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Text nodes

Text nodes are created by setting the shape type as ‘Text’ in the drawingObject property. The text node includes a content property that defines the displayed text. Users can add or modify the content after completing the drawing operation:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramModule, DiagramComponent, Diagram, NodeModel, TextModel, DiagramTools, ShapeStyleModel } from '@syncfusion/ej2-angular-diagrams';

@Component({
imports: [
         DiagramModule
    ],

providers: [ ],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" (created)='created($event)'>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public node?: NodeModel;
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
    public created(args: Object): void {
        //JSON to create a path
        this.node = {
            shape: {
                type:'Text',
            } as TextModel
        };
        (this.diagram as Diagram).drawingObject = this.node;
        //To draw an object once, activate draw once
        (this.diagram as Diagram).tool = DiagramTools.ContinuousDraw;
        (this.diagram as Diagram).dataBind();
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Draw connectors

Connectors are drawn by defining the connector configuration in the drawingObject property. The drawing tool supports various connector types including straight, orthogonal, and bezier connectors:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, ConnectorModel, DiagramTools, NodeModel, DiagramModule } from '@syncfusion/ej2-angular-diagrams';

@Component({
imports: [
         DiagramModule
    ],

providers: [ ],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" (created)='created($event)'>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public connectors?: ConnectorModel;
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
    public created(args: Object): void {
        //JSON to create a path
        this.connectors = {
            id: 'connector1',
            type: 'Straight',
            segments: [{ type: "polyline" }]
        } as any as ConnectorModel;
        (this.diagram as Diagram).drawingObject = this.connectors;
        //To draw an object once, activate draw once
        (this.diagram as Diagram).tool = DiagramTools.ContinuousDraw;
        (this.diagram as Diagram).dataBind();
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Polygon shapes

The diagram supports interactive polygon creation through point-and-click interaction. Users can define custom shapes with multiple sides by specifying vertices directly on the diagram canvas. To enable polygon drawing, set the drawingObject type as ‘Polygon’:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramModule, DiagramComponent, Diagram, NodeModel, BasicShapeModel, DiagramTools, ShapeStyleModel } from '@syncfusion/ej2-angular-diagrams';

@Component({
imports: [
         DiagramModule
    ],

providers: [ ],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" (created)='created($event)'>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public drawingshape?: BasicShapeModel;
    public node?: NodeModel;
    public getNodeDefaults(node: NodeModel): NodeModel {
        ((node as NodeModel).style as ShapeStyleModel).strokeColor = "Black";
        return node;
    }
    public created(args: Object): void {
        //JSON to create a rectangle
        this.drawingshape = { type: 'Basic', shape: 'Polygon' };
        this.node = {
            shape: this.drawingshape
        };
        (this.diagram as Diagram).drawingObject = this.node;
        //To draw an object once, activate draw once
        (this.diagram as Diagram).tool = DiagramTools.DrawOnce;
        (this.diagram as Diagram).dataBind();
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Polyline connectors

Polyline connectors enable creation of multi-segment connections with straight lines and angled vertices. Users can interactively add control points by clicking on the diagram canvas. To draw polyline connectors, set the drawingObject type as ‘Polyline’:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramModule, DiagramComponent, Diagram, ConnectorModel, DiagramTools, BasicShapeModel } from '@syncfusion/ej2-angular-diagrams';

@Component({
imports: [
         DiagramModule
    ],

providers: [ ],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" (created)='created($event)'>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public drawingshape?: BasicShapeModel;
    public connector?: ConnectorModel;
    public created(args: Object): void {
        //JSON to create a rectangle
        this.connector = { id: 'connector1', type: 'Polyline' };
        (this.diagram as Diagram).drawingObject = this.connector;
        //To draw an object once, activate draw once
        (this.diagram as Diagram).tool = DiagramTools.DrawOnce;
        (this.diagram as Diagram).dataBind();
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Freehand drawing

Freehand drawing allows users to create custom paths and sketches by dragging the mouse freely across the diagram canvas. This tool is ideal for creating organic shapes, annotations, or rough sketches. Enable freehand drawing by setting the drawingObject type to ‘Freehand’:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import {
  DiagramComponent,
  Diagram,
  DiagramModule,
  ConnectorModel,
  DiagramTools,
  BasicShapeModel,
} from '@syncfusion/ej2-angular-diagrams';

@Component({
  imports: [DiagramModule],

  providers: [],
  standalone: true,
  selector: 'app-container',
  template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" (created)='created($event)'>
    </ejs-diagram>`,
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public drawingshape?: BasicShapeModel;
  public connector?: ConnectorModel;
  public created(args: Object): void {
    //JSON to create a rectangle
    this.connector = { id: 'connector1', type: 'Freehand' };
    (this.diagram as Diagram).drawingObject = this.connector;
    //To draw an object once, activate draw once
    (this.diagram as Diagram).tool = DiagramTools.DrawOnce;
    (this.diagram as Diagram).dataBind();
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Freehand connector segments can be adjusted after creation by dragging the segment thumbs. To enable this functionality, apply the DragSegmentThumb constraint to the connector:

Freehand connector drawing

Tool selection and precedence

The diagram supports multiple tool configurations that can be combined for different interaction scenarios. When multiple tools are enabled simultaneously, the system follows a specific precedence order to determine which tool takes priority:

Tool precedence hierarchy

The following table shows the precedence order from highest to lowest priority:

Precedence Tool Description
1st ContinuesDraw Enables continuous drawing mode. Once activated, prevents all other interactions until deactivated.
2nd DrawOnce Allows drawing a single element. After completion, automatically enables SingleSelect and MultipleSelect tools.
3rd ZoomPan Enables diagram panning. When combined with SingleSelect, panning activates when cursor hovers over empty diagram areas.
4th MultipleSelect Enables selection of multiple elements. When combined with ZoomPan, selection takes priority over panning when hovering over elements.
5th SingleSelect Enables selection of individual elements.
6th None Disables all interactive tools.

These tools provide flexibility and functionality for creating and interacting with elements within the diagram interface.

Pan tool

The pan tool enables users to navigate large diagrams by dragging the view area. To activate panning mode, set the tool property to ZoomPan:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import {
  DiagramComponent,
  Diagram,
  ConnectorModel,
  DiagramTools,
  BasicShapeModel,
  DiagramModule,
  NodeModel,
} from '@syncfusion/ej2-angular-diagrams';

@Component({
  imports: [DiagramModule],

  providers: [],
  standalone: true,
  selector: 'app-container',
  template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" (created)='created($event)' [nodes]='nodes' [connectors]='connector'>
    </ejs-diagram>`,
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public drawingshape?: BasicShapeModel;
  public nodes: NodeModel[] = [
    {
      id: 'Start',
      width: 140,
      height: 50,
      offsetX: 200,
      offsetY: 200,
      annotations: [
        {
          id: 'label1',
          content: 'Start',
        },
      ],
      shape: {
        type: 'Flow',
        shape: 'Terminator',
      },
    },
    {
      id: 'Init',
      width: 140,
      height: 50,
      offsetX: 400,
      offsetY: 400,
      annotations: [
        {
          id: 'label2',
          content: 'End',
        },
      ],
      shape: {
        type: 'Flow',
        shape: 'Process',
      },
    },
  ];
  public connector: ConnectorModel[] = [
    {
      // Name of the connector
      id: 'connector1',
      style: {
        strokeColor: '#6BA5D7',
        fill: '#6BA5D7',
        strokeWidth: 2,
      },
      targetDecorator: {
        style: {
          fill: '#6BA5D7',
          strokeColor: '#6BA5D7',
        },
      },
      // ID of the source and target nodes
      sourceID: 'Start',
      targetID: 'Init',
      type: 'Orthogonal',
    },
  ];
  public created(args: Object): void {
    (this.diagram as Diagram).tool = DiagramTools.ZoomPan;
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

NOTE

Panning is disabled when ‘multiplePage’ is set to false and diagram objects exist outside the defined page boundaries.

Events

The elementDraw event triggers whenever users create nodes or connectors using drawing tools. This event provides access to the newly created element and enables custom logic during the drawing process:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramModule, IElementDrawEventArgs, DiagramComponent, Diagram, NodeModel, BasicShapeModel, DiagramTools, ShapeStyleModel } from '@syncfusion/ej2-angular-diagrams';

@Component({
    imports: [
        DiagramModule
    ],

    providers: [],
    standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" (created)='created($event)' (elementDraw)='elementDraw($event)'>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public drawingshape?: BasicShapeModel;
    public node?: NodeModel;
    public elementDraw(args: IElementDrawEventArgs) {
        if (args.state === 'Completed') {
            // Example of alerting when a rectangle is drawn
            alert('Element draw - Rectangle');
        }
    }

    public created(args: Object): void {
        //JSON to create a rectangle
        this.drawingshape = { type: 'Basic', shape: 'Rectangle' };
        this.node = {
            shape: this.drawingshape
        };
        (this.diagram as Diagram).drawingObject = this.node;
        //To draw an object once, activate draw once
        (this.diagram as Diagram).tool = DiagramTools.ContinuousDraw;
        (this.diagram as Diagram).dataBind();
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));