Appearance of Nodes in Angular Diagram Component

29 Aug 202524 minutes to read

Setting default properties for nodes

The getNodeDefaults property in the Angular Diagram control allows you to define default settings that apply to all nodes based on specific conditions or requirements. This approach ensures consistency across your diagram and reduces repetitive code.

The following code example shows how to use the getNodeDefaults function to apply common styling to all nodes:

import {
    DiagramModule,
    DiagramComponent,
    NodeModel,
    ShapeStyleModel,
  } 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" [nodes]='nodes' [getNodeDefaults] ='getNodeDefaults'>
      </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None,
  })
  export class AppComponent {
    @ViewChild('diagram')
    public diagram?: DiagramComponent;
    public nodes: NodeModel[] = [
      {
        id: 'node1',
        // Position of the node
        offsetX: 250,
        offsetY: 250,
        zIndex: 2,
        annotations: [{ content: 'Node1' }],
        style: { fill: 'white', strokeColor: 'black' },
      },
      {
        id: 'node2',
        // Position of the node
        offsetX: 270,
        offsetY: 270,
        zIndex: 1,
        annotations: [{ content: 'Node2' }],
        style: { fill: 'white', strokeColor: 'black' },
      },
    ];
    public getNodeDefaults(node: NodeModel): NodeModel {
      node.height = 100;
      node.width = 100;
      ((node as NodeModel).style as ShapeStyleModel).fill = 'yellow';
      ((node as NodeModel).style as ShapeStyleModel).strokeColor = 'green';
      ((node as NodeModel).style as ShapeStyleModel).strokeWidth = 3;
      return node;
    }
  }
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

NOTE

The values set in the getNodeDefaults function have higher priority than individual node properties during rendering.

Appearance

Apply style to nodes

The appearance of a node can be customized by changing its fill color, strokeDashArray, strokeWidth, strokeColor and opacity. The visible property of the node enables or disables the visibility of the node.

The following code illustrates how to customize the appearance of nodes using style properties:

import {
    Diagram,
    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="600px" (created)='created($event)'>
      </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None,
  })
  export class AppComponent {
    @ViewChild('diagram')
    public diagram?: DiagramComponent;
    public node1: NodeModel = {
      // Position of the node
      offsetX: 250,
      offsetY: 250,
      // Size of the node
      width: 100,
      height: 100,
      visible: true,
      style: {
        fill: '#6AA8D7',
        strokeColor: 'white',
        strokeWidth: 5,
        strokeDashArray: '3',
        opacity: 0.7,
      },
      // Text(label) added to the node
    };
    public node2: NodeModel = {
      // Position of the node
      offsetX: 450,
      offsetY: 250,
      // Size of the node
      width: 100,
      height: 100,
      visible: false,
      style: {
        fill: '#6AA8D7',
        strokeColor: 'white',
        strokeWidth: 5,
        strokeDashArray: '3',
        opacity: 0.7,
      },
      // Text(label) added to the node
    };
    public created(args: Object): void {
      //Add Node
      (this.diagram as Diagram).add(this.node1);
      (this.diagram as Diagram).add(this.node2);
    }
  }
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Apply gradient style to nodes

The gradient property of the node allows you to define and apply gradient effects to create visually appealing nodes with smooth color transitions.

The gradient stop property defines the color and position where the previous color transition ends and a new color transition starts. The gradient stop’s opacity property defines the transparency level of the region.

There are two types of gradients available:

  • Linear gradient
  • Radial gradient

Linear gradient

LinearGradient defines a smooth transition between a set of colors (called stops) along a straight line. This is ideal for creating directional color effects on nodes.

A linear gradient’s x1, y1, x2, y2 properties are used to define the position (relative to the node) of the rectangular region that needs to be painted.

import {
    DiagramModule,
    DiagramComponent,
    NodeModel,
    ShapeStyleModel,
    LinearGradientModel,
  } 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]=350 [offsetY]=250 [style]='style'></e-node>
          </e-nodes>
      </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None,
  })
  export class AppComponent {
    @ViewChild('diagram')
    public diagram?: DiagramComponent;
    public style?: ShapeStyleModel;
    public linearGradient: LinearGradientModel = {
      //Start point of linear gradient
      x1: 0,
      y1: 0,
      //End point of linear gradient
      x2: 50,
      y2: 50,
      //Sets an array of stop objects
      stops: [
        {
          color: 'white',
          offset: 0,
        },
        {
          color: '#6BA5D7',
          offset: 100,
        },
      ],
      type: 'Linear',
    };
    public getNodeDefaults(node: NodeModel): NodeModel {
      node.height = 100;
      node.width = 100;
      return node;
    }
    ngOnInit(): void {
      this.style = { gradient: this.linearGradient };
    }
  }
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Radial gradient

RadialGradient defines a smooth transition between stops that radiates from a central point in a circular pattern. This creates a spotlight or glow effect on nodes.

A radial gradient’s cx, cy, fx, fy properties are used to define the position (relative to the node) of the outermost or innermost circle of the radial gradient.

import {
    DiagramModule,
    DiagramComponent,
    NodeModel,
    ShapeStyleModel,
    RadialGradientModel,
  } 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]=350 [offsetY]=250 [style]='style'></e-node>
          </e-nodes>
      </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None,
  })
  export class AppComponent {
    @ViewChild('diagram')
    public diagram?: DiagramComponent;
    public style?: ShapeStyleModel;
    public radialGradient: RadialGradientModel = {
      //Center point of outer circle
      cx: 50,
      cy: 50,
      //Center point of inner circle
      fx: 25,
      fy: 25,
      //Radius of a radial gradient
      r: 50,
      //Sets an array of stop objects
      stops: [
        {
          color: 'white',
          offset: 0,
        },
        {
          color: '#6BA5D7',
          offset: 100,
        },
      ],
      type: 'Radial',
    };
    public getNodeDefaults(node: NodeModel): NodeModel {
      node.height = 100;
      node.width = 100;
      return node;
    }
    ngOnInit(): void {
      this.style = { gradient: this.radialGradient };
    }
  }
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Customize the style of node selector

Customize the style of main node selector indicator

In the diagram, multiple nodes can be selected simultaneously. When selecting multiple nodes, a highlighter renders to indicate the selection of each node. The border style of the first node in the multiple selection can be customized using the CSS class name e-diagram-first-selection-indicator.

Use the following CSS to customize the style of the main node during multiple selection:

.e-diagram-first-selection-indicator {
   stroke-width: 5px;
   stroke: red;
   stroke-dasharray: 1,1;
}

Apply rotate angle and corner radius to nodes

Node appearance can be enhanced using rotation and corner radius properties:

  • Rotate angle: The rotateAngle property allows you to rotate nodes within the diagram. This is particularly useful when you want to represent nodes from different perspectives or angles to match your design requirements.

  • Corner radius: The cornerRadius property allows you to round the corners of rectangular nodes in the diagram. It adds a visual styling effect to the nodes, making them appear softer and more polished.

The following code shows how to set the rotate angle and corner radius for nodes:

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" [getNodeDefaults] ='getNodeDefaults'>
        <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 getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        node.rotateAngle = 45;
        (node.shape as any).cornerRadius = 15;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Apply shadow effect to nodes

Diagram provides support to add shadow effects to nodes, which is disabled by default. Shadow effects can be enabled using the constraints property of the node to create depth and visual hierarchy in your diagrams.

The following code illustrates how to apply shadow effects to nodes:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramModule, DiagramComponent, NodeModel, NodeConstraints } 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'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [constraints]='constraints'></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;
    }
    public constraints?: NodeConstraints;
    ngOnInit(): void {
        this.constraints = NodeConstraints.Default | NodeConstraints.Shadow;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Customizing shadow effects

The angle, distance, and opacity of the shadow can be customized using the shadow property of the node. These properties allow you to control the direction, positioning, and transparency of the shadow effect.

The following code example illustrates how to customize shadow properties:

import { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramModule, DiagramComponent, NodeModel, NodeConstraints, ShadowModel } 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'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [constraints]='constraints' [shadow]='shadow'></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;
    }
    public constraints?: NodeConstraints;
    public shadow?: ShadowModel;
    ngOnInit(): void {
        this.constraints = NodeConstraints.Default | NodeConstraints.Shadow;
        this.shadow = {
            angle: 50,
            opacity: 0.8,
            distance: 9
        }
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Provide additional information to nodes

The addInfo property of the node allows you to maintain additional information with the node. You can specify either object or string values to store custom data that can be retrieved and used in your application logic.

The following code shows how to set the addInfo value:

export class AppComponent {
    @ViewChild("diagram")
    public diagram: DiagramComponent;
    public addInfo = { type: 'Node', info: 'Rectangle Node' };
    public nodes: NodeModel[] = [
        {
            // Position of the node
            offsetX: 400,
            offsetY: 250,
            // Additional information about the node
            addInfo: this.addInfo,
            // Size of the node
            width: 100,
            height: 100,
        },
    ];
}

Constraints

The constraints property of the node allows you to enable or disable certain behaviors of the node. This provides fine-grained control over node interactions and capabilities. For more information about node constraints, refer to the Node Constraints documentation.

Stack order

The zIndex property of nodes specifies the stack order of the node. A node with a greater stack order is always rendered in front of a node with a lower stack order, allowing you to control the layering of overlapping elements.

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>`,
    encapsulation: ViewEncapsulation.None,
  })
  export class AppComponent {
    @ViewChild('diagram')
    public diagram?: DiagramComponent;
    public nodes: NodeModel[] = [
      {
        id: 'node1',
        // Position of the node
        offsetX: 250,
        offsetY: 250,
        zIndex: 2,
        annotations: [{ content: 'Node1' }],
        style: { fill: 'white', strokeColor: 'black' },
      },
      {
        id: 'node2',
        // Position of the node
        offsetX: 270,
        offsetY: 270,
        zIndex: 1,
        annotations: [{ content: 'Node2' }],
        style: { fill: 'white', strokeColor: 'black' },
      },
    ];
  }
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

NOTE

By default, the zIndex is generated automatically based on the order in which diagram elements are added to the diagram. The default value is Number.MIN_VALUE.

Pivot

Node rotation angle is based on Pivot values which range from 0 to 1, similar to offset values. By default, the pivot values are set to X = 0.5 and Y = 0.5, meaning rotation occurs around the center of the node.

The following table illustrates how pivot relates to offset values with node boundaries:

Pivot Offset
(0.5,0.5) offsetX and offsetY values are considered as the node’s center point.
(0,0) offsetX and offsetY values are considered as the top-left corner of the node.
(1,1) offsetX and offsetY values are considered as the bottom-right corner of the node.

The following code illustrates how to change the pivot value:

import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { DiagramModule, DiagramComponent, Diagram, NodeModel, PointModel } 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)'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [pivot]='pivot'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public pivot?: PointModel;
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
    ngOnInit(): void {
        this.pivot = { x: 0, y: 0 };
    }
    public created(args: Object): void {
        //Add Node
        (this.diagram as Diagram).select([(this.diagram as Diagram).nodes[0]]);
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Get connected connectors from node

Node has the inEdges and outEdges read-only properties. These properties allow you to identify all connectors that are connected to the node. You can then retrieve these connectors using the getObject method in the diagram.

@Component({
    imports: [
        DiagramModule
    ],
    providers: [],
    standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="600px" [getNodeDefaults]='getNodeDefaults' (created)='created($event)'>
            <e-nodes>
                <e-node id='node1' [offsetX]=450 [offsetY]=100>
                    <e-node-annotations>
                        <e-node-annotation content="Node1">
                        </e-node-annotation>
                    </e-node-annotations>
                </e-node>
                <e-node id='node2' [offsetX]=350 [offsetY]=200>
                    <e-node-annotations>
                        <e-node-annotation content="Node2">
                        </e-node-annotation>
                    </e-node-annotations>
                </e-node>
                <e-node id='node3' [offsetX]=450 [offsetY]=200>
                    <e-node-annotations>
                        <e-node-annotation content="Node3">
                        </e-node-annotation>
                    </e-node-annotations>
                </e-node>
                <e-node id='node4' [offsetX]=550 [offsetY]=200>
                    <e-node-annotations>
                        <e-node-annotation content="Node4">
                        </e-node-annotation>
                    </e-node-annotations>
                </e-node>
            </e-nodes>
            <e-connectors>
                <e-connector id='connector1' type='Orthogonal' sourceID='node1' targetID='node2'>
                </e-connector>
                <e-connector id='connector2' type='Orthogonal' sourceID='node1' targetID='node3'>
                </e-connector>
                <e-connector id='connector3' type='Orthogonal' sourceID='node1' targetID='node4'>
                </e-connector>
            </e-connectors>
        </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 80;
        node.width = 50;
        (node.style as ShapeStyleModel).fill = "#6BA5D7";
        (node.style as ShapeStyleModel).strokeColor = "White";
        return node;
    }
    
    public created(args: Object): void {
        // Access outgoing connectors from node1
        const outConnectors = ((this.diagram as DiagramComponent).getObject('node1') as any).outEdges;
        console.log('Connected outgoing connectors:', outConnectors);
    }
}