Nodes in Angular Diagram component

20 Oct 202422 minutes to read

Nodes are graphical objects used to visually represent the geometrical information, process flow, internal business procedure, entity, or any other kind of data.

Node

Create node

A node can be created and added to the diagram either programmatically or interactively. The id property of a node is used to define its unique identifier and can later be used to find the node at runtime for customization. Nodes are stacked on the diagram area from bottom to top in the order they are added.

NOTE

Note: There should not be any white-spaces in the ID string while setting the ID.

Add node through nodes collection

To create a node, define the node object and add that to nodes collection of the diagram model. The following code example illustrates how to add a node to the diagram.

import {
    DiagramModule,
    DiagramComponent,
    NodeModel,
    ShapeStyleModel,
  } 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'>
          <e-nodes>
              <e-node id='node1' [offsetX]=150 [offsetY]=150></e-node>
          </e-nodes>
      </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None,
  })
  export class AppComponent {
    @ViewChild('diagram')
    public diagram?: DiagramComponent;
    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));

Note: Node id should not begin with numbers(should begin with a letter).Node Id should be unique for all the shapes and connectors.

Add/Remove node at runtime

Nodes can be added at runtime by using public method, add and can be removed at runtime by using public method, remove. On adding/removing node at runtime, the nodes collection is changed and the collectionChange event will trigger.

  • The node’s ID property is used to define the name of the node and its further used to find the node at runtime and do any customization.

The following code illustrates how to add a node.

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { DiagramModule } from '@syncfusion/ej2-angular-diagrams'



import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, 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)'>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public node: NodeModel = {
        // Position of the node
        offsetX: 250,
        offsetY: 250,
        // Size of the node
        width: 100,
        height: 100,
        style: {
            fill: '#6BA5D7',
            strokeColor: 'white'
        },
    };
    public created(args: Object): void {
        //Add Node
        (this.diagram as Diagram).add(this.node);
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Add collection of nodes at runtime

  • The collection of nodes can be dynamically added using addElements method.Each time an element is added to the diagram canvas, the collectionChange event will be triggered.

The following code illustrates how to add nodes at runtime.

import { DiagramModule, DiagramComponent, Diagram, 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" (created)='created($event)'>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public node: NodeModel =[
        { id: 'node16', offsetX: 35, offsetY: 260 },
        { id: 'node17', offsetX: 140, offsetY: 260 },
        { id: 'node18', offsetX: 240, offsetY: 260 }] as NodeModel;
        public created(args: Object): void {
            //Add Nodes collection
            (this.diagram as Diagram).addElements(this.node as any);
        }
    }
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Add node from palette

Nodes can be predefined and added to the palette, and can be dropped into the diagram when needed. For more information about adding nodes from symbol palette, refer to Symbol Palette.

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import {
  DiagramComponent,
  DiagramModule,
  ShapeStyleModel,
  SymbolPaletteModule,
  NodeModel,
  PaletteModel,
} from '@syncfusion/ej2-angular-diagrams';
@Component({
  imports: [DiagramModule, SymbolPaletteModule],
  providers: [],
  standalone: true,
  selector: 'app-container',
  template: `
      <ejs-symbolpalette id="symbolpalette"width="10%" height="700px" [palettes]="palettes" [symbolHeight]=80 [symbolWidth]=80 >
      </ejs-symbolpalette>
      <ejs-diagram #diagram id="diagram" width="74%" height="700px" [getNodeDefaults] ='getNodeDefaults'>
          <e-nodes>
              <e-node id='node1' [offsetX]=150 [offsetY]=150></e-node>
          </e-nodes>
      </ejs-diagram>`,
  encapsulation: ViewEncapsulation.None,
  styles: [
    `
      ejs-symbolpalette {
      float: left;
    }
  `,
  ],
})
export class AppComponent {
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public getNodeDefaults(node: NodeModel): NodeModel {
    node.height = 100;
    node.width = 100;
    return node;
  }
  public palettes?: PaletteModel[];
  public getBasicShapes(): NodeModel[] {
    let basicShapes: NodeModel[] = [
      {
        id: 'Rectangle',
        shape: {
          type: 'Basic',
          shape: 'Rectangle',
        },
        style: { fill: '#6BA5D7' },
      },
    ];
    return basicShapes;
  }

  ngOnInit(): void {
    this.palettes = [
      {
        id: 'basic',
        expanded: true,
        symbols: this.getBasicShapes(),
        title: 'Basic Shapes',
        iconCss: 'e-ddb-icons e-basic',
      },
    ];
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Create node through data source

Nodes can be generated automatically with the information provided through dataSource property. The default properties for these nodes are fetched from default settings (getNodeDefaults). For more information about data source, refer to  DataBinding.

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import {
  DataSourceModel,
  DiagramComponent,
  DiagramModule,
  Diagram,
  NodeModel,
  DataBinding,
} from '@syncfusion/ej2-angular-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';

Diagram.Inject(DataBinding);

@Component({
  imports: [DiagramModule],

  providers: [],
  standalone: true,
  selector: 'app-container',
  template: `<ejs-diagram #diagram id="diagram" width="100%" height="1000px" [getNodeDefaults] ='getNodeDefaults' [dataSourceSettings]="dataSourceSettings">
      </ejs-diagram>`,
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public dataSourceSettings?: DataSourceModel;
  public items?: DataManager;
  public data: Object[] = [
    {
      id: 'Steve-Ceo',
      parent: null,
    },
  ];
  public getNodeDefaults(node: NodeModel): NodeModel {
    node.height = 100;
    node.width = 100;
    node.offsetX = 300;
    node.offsetY = 200;
    node.style = { fill: 'yellow', strokeColor: 'yellow' };
    return node;
  }
  ngOnInit(): void {
    this.items = new DataManager(this.data as JSON[], new Query().take(7));
    this.dataSourceSettings = {
      id: 'id',
      parentId: 'parent',
      dataSource: this.items,
    };
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Draw nodes

To draw a shape, you have to activate the drawing tool by setting DrawOnce or ContinuousDraw to the tool property and you need to set the node object by using the drawingObject property. The following code example illustrates how to draw a rectangle at runtime.

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import {
  DiagramModule,
  DiagramComponent,
  Diagram,
  NodeModel,
  BasicShapeModel,
  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 drawingshape?: BasicShapeModel;
  public node?: NodeModel;
  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.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));

Update node at runtime

You can modify any node properties at runtime, and the changes will be instantly reflected. For example, here you can change the size and color of the node.

import {
  DiagramModule,
  ShapeStyleModel,
  DiagramComponent,
  Diagram,
  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" [nodes]="nodes" >
    </ejs-diagram>
    <button (click) = "ChangeColor()">Change Color</button>
    <button (click) = "ChangeSize()">Change Size</button>`,
  styles: [
    `button {
      margin-left: 10px;
    }`,
  ],
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  public nodes: NodeModel[] = [
    {
      id: 'node1',
      offsetX: 420,
      offsetY: 270,
      height: 100,
      width: 100,
      style: { fill: '#6AA8D7', strokeWidth: 1 },
    },
  ];
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  ChangeColor() {
    if (
      ((this.diagram as Diagram).nodes[0].style as ShapeStyleModel).fill ==
      'orange'
    ) {
      ((this.diagram as Diagram).nodes[0].style as ShapeStyleModel).fill =
        '#6AA8D7';
    } else {
      ((this.diagram as Diagram).nodes[0].style as ShapeStyleModel).fill =
        'orange';
    }
  }
  ChangeSize() {
    if (
      (this.diagram as Diagram).nodes[0].width == 200 &&
      (this.diagram as Diagram).nodes[0].height == 200
    ) {
      (this.diagram as Diagram).nodes[0].width = 100;
      (this.diagram as Diagram).nodes[0].height = 100;
    } else {
      (this.diagram as Diagram).nodes[0].width = 200;
      (this.diagram as Diagram).nodes[0].height = 200;
    }
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

NOTE

Once the property is updated, you should call the dataBind to reflect the changes instantly.

Clone node at runtime

Cloning a node creates a new node instance with identical properties and attributes. You can clone a node using the copy and paste public methods of the diagram model.

import {
  DiagramModule,
  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" [nodes]="nodes" >
    </ejs-diagram>
    <button (click) = "CloneNode()">Clone Node</button>`,
  styles: [
    `button {
      margin-left: 10px;
    }`,
  ],
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  public nodes: NodeModel[] = [
    {
      id: 'node1',
      offsetX: 420,
      offsetY: 270,
      height: 100,
      width: 100,
      style: { fill: '#6AA8D7', strokeWidth: 1 },
    },
  ];
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public selectedNode?: NodeModel;
  CloneNode() {
    this.selectedNode =
      ((this.diagram as DiagramComponent).selectedItems.nodes
        ?.length as number) > 0
        ? (
            (this.diagram as DiagramComponent).selectedItems
              .nodes as NodeModel[]
          )[0]
        : (this.diagram as DiagramComponent).nodes[0];
    (this.diagram as DiagramComponent).select([this.selectedNode]);
    (this.diagram as DiagramComponent).copy();
    (this.diagram as DiagramComponent).paste();
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Add nodes from tree view

By customizing the dragEnter functionality, we can allow elements from other components, such as the tree view, to be converted into nodes based on the data of the dragged element.

See Also