Constraints in Angular Diagram Component

30 Aug 202524 minutes to read

Constraints enable or disable specific behaviors of diagrams, nodes, and connectors. These constraints are implemented as flagged enumerations, allowing multiple behaviors to be controlled simultaneously using Bitwise operators (&, |, ~, <<, etc.).

To learn more about Bitwise operators, refer to the Bitwise Operations section.

Diagram Constraints

Diagram constraints control the overall behavior and functionality of the diagram canvas.

Constraints Description
None Disables all diagram functionalities.
Bridging Enables bridging support for connectors in the diagram.
Undo/redo Enables undo and redo functionality for diagram operations.
UserInteraction Enables user interaction capabilities for the diagram.
ApiUpdate Enables programmatic updates through API calls.
PageEditable Enables editing within the page boundaries.
Zoom Enables zooming functionality for the diagram.
PanX Enables horizontal panning of the diagram.
PanY Enables vertical panning of the diagram.
Pan Enables both horizontal and vertical panning.
ZoomTextEdit Enables text box zooming during text editing operations.
Tooltip Enables tooltip display for diagram elements.
Virtualization Enables virtualization support for large diagrams.
LineRouting Enables automatic line routing for connectors.
Default Enables all default constraints for the diagram.

The following example demonstrates how to disable page editing using diagram constraints:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { DiagramConstraints } from '@syncfusion/ej2-diagrams';
@Component({
  selector: "app-container",
  template: `<ejs-diagram id="diagram" width="100%" height="580px" [constraints]='diagramConstraints'></ejs-diagram>`
})
export class AppComponent {
    @ViewChild("diagram")
    public diagramConstraints: DiagramConstraints;
    ngOnInit(): void {
        this.diagramConstraints = DiagramConstraints.Default & ~DiagramConstraints.PageEditable;
    }
}

The following example shows how to enable bridging constraint along with the default constraints:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { DiagramConstraints } from '@syncfusion/ej2-diagrams';
@Component({
  selector: "app-container",
  // specifies the template string for the diagram component
  template: `<ejs-diagram id="diagram" width="100%" height="580px" [constraints]='diagramConstraints'></ejs-diagram>`
})
export class AppComponent {
    @ViewChild("diagram")
    public diagramConstraints: DiagramConstraints;
    ngOnInit(): void {
        this.diagramConstraints = DiagramConstraints.Default | DiagramConstraints.Bridging
    }
}

Multiple behaviors can be added or removed from the default constraints using Bitwise operations:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { DiagramConstraints } from '@syncfusion/ej2-diagrams';
@Component({
  selector: "app-container",
  // specifies the template string for the diagram component
  template: `<ejs-diagram id="diagram" width="100%" height="580px" [constraints]='diagramConstraints'></ejs-diagram>`
})
export class AppComponent {
    @ViewChild("diagram")
    public diagramConstraints: DiagramConstraints;
    ngOnInit(): void {
        this.diagramConstraints = DiagramConstraints.Default & ~(DiagramConstraints.PageEditable | DiagramConstraints.Zoom);
    }
}

For more information about diagram constraints, refer to DiagramConstraints.

NOTE

By default, the following constraints are enabled in the diagram:

* Zoom

* ApiUpdate

* PanX

* PanY

* Pan

* Undo/Redo

* PageEditable

* Default

Node Constraints

Node constraints control the behavior and interactions available for individual nodes within the diagram.

Constraints Description
None Disables all node constraints.
Select Enables node selection capability.
Drag Enables node dragging functionality.
Rotate Enables node rotation capability.
Shadow Enables shadow display for the node.
PointerEvents Enables pointer event handling for the node.
Delete Enables node deletion capability.
InConnect Enables incoming connections to the node.
OutConnect Enables outgoing connections from the node.
AllowDrop Enables drop operations on the node.
Individual Enables individual resize handles for the node.
ResizeNorthEast Enables resizing from the northeast corner.
ResizeEast Enables resizing from the east side.
ResizeSouthEast Enables resizing from the southeast corner.
ResizeSouth Enables resizing from the south side.
ResizeSouthWest Enables resizing from the southwest corner.
ResizeWest Enables resizing from the west side.
ResizeNorthWest Enables resizing from the northwest corner.
ResizeNorth Enables resizing from the north side.
AspectRatio Maintains aspect ratio during resize operations.
ReadOnly Enables read-only mode for node annotations.
HideThumbs Hides all resize thumbs for the node.
Tooltip Enables tooltip display for the node.
InheritTooltip Inherits tooltip settings from parent objects.
Resize Enables overall resize functionality for the node.
Inherit Inherits interaction settings from parent objects.
Expandable Enables expand/collapse functionality for the node.
AllowMovingOutsideLane Allows movement outside swim lane boundaries.
Default Enables all default constraints for the node.

The following example demonstrates how to disable rotation using node constraints:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { NodeConstraints } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-nodes>
            <e-node id='node1' [height]=60 [width]=100 [offsetX]=300 [offsetY]=80 [constraints]='nodeConstraints'>
            </e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public nodeConstraints: NodeConstraints;
    ngOnInit(): void {
        this.nodeConstraints = NodeConstraints.Default & ~NodeConstraints.Rotate;
    }
}

The following example shows how to add shadow constraint to the default node constraints:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { NodeConstraints } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-nodes>
            <e-node id='node1' [height]=60 [width]=100 [offsetX]=300 [offsetY]=80 [constraints]='nodeConstraints'>
            </e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public nodeConstraints: NodeConstraints;
    ngOnInit(): void {
        this.nodeConstraints = NodeConstraints.Default | NodeConstraints.Shadow;
    }
}

The following code example shows how to enable tooltip for a node:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { NodeConstraints, DiagramTooltipModel } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-nodes>
            <e-node id='node1' [height]=60 [width]=100 [offsetX]=300 [offsetY]=80 [constraints]='nodeConstraints' [tooltip]='tooltip'>
            </e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public nodeConstraints: NodeConstraints;
    public tooltip: DiagramTooltipModel;
    ngOnInit(): void {
        this.nodeConstraints = NodeConstraints.Default | NodeConstraints.Tooltip;
        this.tooltip = { content: 'Node' };
    }
}

Multiple behaviors can be added or removed from the default constraints using Bitwise operations:

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-nodes>
            <e-node id='node1' [height]=60 [width]=100 [offsetX]=300 [offsetY]=80 [constraints]='nodeConstraints'>
            </e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public nodeConstraints: NodeConstraints;
    ngOnInit(): void {
        this.nodeConstraints = NodeConstraints.Default & ~(NodeConstraints.Rotate | NodeConstraints.Resize);
    }
}

Refer sample below

import {
    DiagramModule,
    NodeConstraints, 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' [getNodeDefaults] ='getNodeDefaults'>
      </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None,
  })
  export class AppComponent {
    @ViewChild('diagram')
    public diagram?: DiagramComponent;
    public nodes: NodeModel[] = [
      {
        id: 'node1',
        offsetX: 200,
        offsetY: 100,
        annotations: [{ content: 'Select disabled' }],
        constraints: NodeConstraints.Default & ~NodeConstraints.Select,
      },
      {
        id: 'node2',
        offsetX: 500,
        offsetY: 100,
        annotations: [{ content: 'Rotate disabled' }],
        constraints: NodeConstraints.Default & ~NodeConstraints.Rotate,
      },
      {
        id: 'node3',
        offsetX: 200,
        offsetY: 400,
        annotations: [{ content: 'Resize disabled' }],
        constraints: NodeConstraints.Default & ~NodeConstraints.Resize,
      },
      {
        id: 'node4',
        offsetX: 500,
        offsetY: 400,
        annotations: [{ content: 'Drag disabled' }],
        constraints: NodeConstraints.Default & ~NodeConstraints.Drag,
      },
      {
        id: 'node5',
        offsetX: 350,
        offsetY: 250,
        annotations: [{ content: 'Tooltip disabled' }],
        constraints: NodeConstraints.Default & ~NodeConstraints.Tooltip,
        tooltip: { content: 'Node Tooltip', relativeMode: 'Object' },
      },
    ];
  
    public getNodeDefaults(node: NodeModel): NodeModel {
      node.height = 100;
      node.width = 100;
      node.pivot = { x: 0, y: 0 };
      return node;
    }
  }
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

For more information about node constraints, refer to NodeConstraints.

NOTE

By default, the following constraints are enabled for nodes:

* Select

* Drag

* Resize

* Rotate

* InConnect

* OutConnect

* PointerEvents

* ResizeNorthEast

* ResizeEast

* ResizeSouthEast

* ResizeSouth

* ResizeSouthWest

* ResizeWest

* ResizeNorthWest

* ResizeNorth

* Inherit

* Expandable

* Individual

* InheritTooltip

* Default

Connector Constraints

Connector constraints control the behavior and interactions available for connectors within the diagram.

Constraints Description
None Disables all connector constraints.
Select Enables connector selection capability.
Delete Enables connector deletion capability.
Drag Enables connector dragging functionality.
DragSourceEnd Enables dragging of the connector’s source endpoint.
DragTargetEnd Enables dragging of the connector’s target endpoint.
DragSegmentThumb Enables dragging of segment control points.
Interaction Enables general interaction capabilities for the connector.
AllowDrop Enables drop operations on the connector.
Bridging Enables bridging functionality for the connector.
InheritBridging Inherits bridging settings from parent objects.
BridgeObstacle Enables the connector to act as a bridge obstacle.
PointerEvents Enables pointer event handling for the connector.
ConnectToNearByNode Enables automatic connection to nearby nodes.
ConnectToNearByPort Enables automatic connection to nearby ports.
Tooltip Enables tooltip display for the connector.
LineRouting Enables line routing functionality for the connector.
InheritLineRouting Inherits line routing settings from parent objects.
InheritTooltip Inherits tooltip settings from parent objects.
ConnectToNearByElement Enables automatic connection to nearby elements.
InheritSegmentThumbShape Inherits segment thumb shape from parent objects.
ReadOnly Enables read-only mode for the connector.
Default Enables all default constraints for the connector.

The following code demonstrates how to disable selection using connector constraints:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { ConnectorConstraints, PointModel } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-connectors>
            <e-connector id='connector' type='Straight' [sourcePoint]='sourcePoint' [targetPoint]='targetPoint' [constraints]='connectorConstraints'>
            </e-connector>
        </e-connectors>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public connectorConstraints: ConnectorConstraints;
    public sourcePoint: PointModel;
    public targetPoint: PointModel;
    ngOnInit(): void {
        this.sourcePoint = { x: 100, y: 100 };
        this.targetPoint = { x: 200, y: 200 };
        this.connectorConstraints = ConnectorConstraints.Default & ~ConnectorConstraints.Select;
    }
}

The following example shows how to add bridging constraint to the default connector constraints:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { ConnectorConstraints, PointModel } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-connectors>
            <e-connector id='connector' type='Straight' [sourcePoint]='sourcePoint' [targetPoint]='targetPoint' [constraints]='connectorConstraints'>
            </e-connector>
        </e-connectors>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public connectorConstraints: ConnectorConstraints;
    public sourcePoint: PointModel;
    public targetPoint: PointModel;
    ngOnInit(): void {
        this.sourcePoint = { x: 100, y: 100 };
        this.targetPoint = { x: 200, y: 200 };
        this.connectorConstraints = ConnectorConstraints.Default | ConnectorConstraints.Bridging;
    }
}

NOTE

To visualize connector bridging, inject the ConnectorBridging module.

The following example shows how to enable tooltip for connectors:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { ConnectorConstraints, DiagramTooltipModel, PointModel } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-connectors>
            <e-connector id='connector' type='Straight' [sourcePoint]='sourcePoint' [targetPoint]='targetPoint' [constraints]='connectorConstraints' [tooltip]='tooltip'>
            </e-connector>
        </e-connectors>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public connectorConstraints: ConnectorConstraints;
    public sourcePoint: PointModel;
    public targetPoint: PointModel;
    public tooltip: DiagramTooltipModel;
    ngOnInit(): void {
        this.sourcePoint = { x: 100, y: 100 };
        this.targetPoint = { x: 200, y: 200 };
        this.connectorConstraints = ConnectorConstraints.Default | ConnectorConstraints.Tooltip;
        this.tooltip = { content: 'Connector' };
    }
}

Multiple behaviors can be added or removed from the default constraints using Bitwise operations:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { ConnectorConstraints, PointModel } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-connectors>
            <e-connector id='connector' type='Straight' [sourcePoint]='sourcePoint' [targetPoint]='targetPoint' [constraints]='connectorConstraints'>
            </e-connector>
        </e-connectors>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public connectorConstraints: ConnectorConstraints;
    public sourcePoint: PointModel;
    public targetPoint: PointModel;
    ngOnInit(): void {
        this.sourcePoint = { x: 100, y: 100 };
        this.targetPoint = { x: 200, y: 200 };
        // Removing multiple constraints from default
        this.connectorConstraints = ConnectorConstraints.Default & ~(ConnectorConstraints.DragSourceEnd | ConnectorConstraints.DragTargetEnd);
    }
}

Refer sample below

import {
  ConnectorConstraints,
  ConnectorModel,
    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" [connectors]='connectors' [getNodeDefaults] ='getNodeDefaults'>
      </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None,
  })
  export class AppComponent {
    @ViewChild('diagram')
    public diagram?: DiagramComponent;
    public connectors: ConnectorModel[] = [
      {
          id: 'connector1',
          sourcePoint: { x: 100, y: 100 },
          targetPoint: { x: 200, y: 200 },
          type: 'Orthogonal',
          constraints: ConnectorConstraints.Default &~ ConnectorConstraints.Select,
          annotations: [{ content: 'Select disabled', alignment: 'After' }],
        },
        {
          id: 'connector2',
          sourcePoint: { x: 250, y: 100 },
          targetPoint: { x: 350, y: 200 },
          type: 'Orthogonal',
          constraints:
            ConnectorConstraints.Default &~ ConnectorConstraints.Drag,
          annotations: [{ content: 'Drag disabled', alignment: 'After' }],
        },
        {
          id: 'connector3',
          sourcePoint: { x: 400, y: 100 },
          targetPoint: { x: 500, y: 200 },
          type: 'Orthogonal',
          constraints: ConnectorConstraints.Default &~ ConnectorConstraints.DragSourceEnd,
          annotations: [{ content: 'Source end disabled', alignment: 'After' }],
        },
        {
          id: 'connector4',
          sourcePoint: { x: 550, y: 100 },
          targetPoint: { x: 650, y: 200 },
          type: 'Orthogonal',
          constraints: ConnectorConstraints.Default &~ ConnectorConstraints.DragTargetEnd,
          annotations: [{ content: 'Target end disabled', alignment: 'After' }],
        },
        {
          id: 'connector5',
          sourcePoint: { x: 700, y: 100 },
          targetPoint: { x: 800, y: 200 },
          type: 'Orthogonal',
          constraints: ConnectorConstraints.Default &~ ConnectorConstraints.Delete,
          annotations: [{ content: 'Delete disabled', alignment: 'After' }],
        },
    ];
  
    public getNodeDefaults(node: NodeModel): NodeModel {
      node.height = 100;
      node.width = 100;
      node.pivot = { x: 0, y: 0 };
      return node;
    }
  }
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

For more information about connector constraints, refer to ConnectorConstraints.

NOTE

By default, the following constraints are enabled for connectors:

* Select

* Delete

* Drag

* Interaction

* ConnectToNearByNode

* ConnectToNearByPort

* ConnectToNearByElement

* BridgeObstacle

* InheritBridging

* PointerEvents

* InheritLineRouting

* InheritTooltip

* InheritSegmentThumbShape

* Default

Port Constraints

Port constraints control the behavior and connection capabilities of ports attached to nodes.

Constraints Description
None Disables all port constraints.
Draw Enables connection creation when hovering over the port.
Drag Enables port dragging functionality.
InConnect Enables incoming connections to the port only.
OutConnect Enables outgoing connections from the port only.
ToolTip Enables tooltip display for the port.
InheritTooltip Inherits tooltip settings from parent objects.
Default Enables all default constraints for the port.

The following code demonstrates how to disable connection creation with a port:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { PointPortModel, PortConstraints } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-nodes>
            <e-node id='node1' [height]=60 [width]=100 [offsetX]=300 [offsetY]=80 [ports]='port1'>
            </e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public port1: PointPortModel[];
    ngOnInit(): void {
        this.port1 = [{
            id: 'port1',
            shape: 'Circle',
            offset: { x: 0, y: 0.5 },
            text: 'In - 1',
            constraints: PortConstraints.None
        }];
    }
}

The following code example shows how to configure port constraints to accept only incoming connections:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { PointPortModel, PortConstraints } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-nodes>
            <e-node id='node1' [height]=60 [width]=100 [offsetX]=300 [offsetY]=80 [ports]='port1'>
            </e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public port1: PointPortModel[];
    ngOnInit(): void {
        this.port1 = [{
            id: 'port1',
            shape: 'Circle',
            offset: { x: 0, y: 0.5 },
            text: 'In - 1',
            constraints: PortConstraints.InConnect
        }];
    }
}

Multiple behaviors can be combined using Bitwise operations:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { PointPortModel, PortConstraints } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-nodes>
            <e-node id='node1' [height]=60 [width]=100 [offsetX]=300 [offsetY]=80 [ports]='port1'>
            </e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public port1: PointPortModel[];
    ngOnInit(): void {
        this.port1 = [{
            id: 'port1',
            shape: 'Circle',
            offset: { x: 0, y: 0.5 },
            text: 'In - 1',
            constraints: PortConstraints.Default | PortConstraints.Draw
        }];
    }
}

Refer sample below

import {
  DiagramModule,
PortConstraints,
PortVisibility,
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' [getNodeDefaults] ='getNodeDefaults'>
    </ejs-diagram>`,
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public nodes: NodeModel[] = [
    {
        id: 'Node1',
        offsetX: 200,
        offsetY: 200,
        annotations: [
          { content: 'tooltip enabled', offset: { x: 0.5, y: 0.1 } },
          { content: 'draw enabled', offset: { x: 0.2, y: 0.5 } },
          { content: 'drg enabled', offset: { x: 0.8, y: 0.5 } },
          { content: 'InConnect disabled', offset: { x: 0.2, y: 0.9 } },
          { content: 'OutConnect disabled', offset: { x: 0.8, y: 0.9 } },
        ],
        ports: [
          {
            id: 'left',
            offset: { x: 0, y: 0.5 },
            visibility: PortVisibility.Visible,
            constraints:
              PortConstraints.Default |
              PortConstraints.Draw,
          },
          {
            id: 'right',
            offset: { x: 1, y: 0.5 },
            visibility: PortVisibility.Visible,
            constraints:
              PortConstraints.Default |
              PortConstraints.Drag,
          },
          {
            id: 'top',
            offset: { x: 0.5, y: 0 },
            visibility: PortVisibility.Visible,
            constraints:
              PortConstraints.Default |
              PortConstraints.ToolTip,
            tooltip: { content: 'Port tooltip' },
          },
          {
            id: 'bottomLeft',
            offset: { x: 0.2, y: 1 },
            visibility: PortVisibility.Visible,
            constraints:PortConstraints.Default &
              ~PortConstraints.InConnect,
          },
          {
            id: 'bottomRight',
            offset: { x: 0.8, y: 1 },
            visibility: PortVisibility.Visible,
            constraints: PortConstraints.Default &
              ~PortConstraints.OutConnect,
          },
        ],
      },
  ];

  public getNodeDefaults(node: NodeModel): NodeModel {
    node.height = 200;
    node.width = 300;
    node.pivot = { x: 0, y: 0 };
    return node;
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

For more information about port constraints, refer to PortConstraints.

NOTE

By default, the following constraints are enabled for ports:

* InConnect

* OutConnect

Annotation Constraints

Annotation constraints control the behavior and edit ability of text annotations on nodes and connectors.

Constraints Description
ReadOnly Enables read-only mode for the annotation.
InheritReadOnly Inherits read-only settings from parent objects.
Select Enables selection capability for the annotation.
Drag Enables dragging functionality for the annotation.
Resize Enables resize capability for the annotation.
Rotate Enables rotation capability for the annotation.
Interaction Enables general interaction capabilities for the annotation.
None Disables all constraints for the annotation.

The following code demonstrates how to enable read-only mode for annotations:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { AnnotationConstraints } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-nodes>
            <e-node id='node1' [height]=60 [width]=100 [offsetX]=300 [offsetY]=80>
                <e-node-annotations>
                    <e-node-annotation content='Start' [constraints]='annotationConstraints'></e-node-annotation>
                </e-node-annotations>
            </e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public annotationConstraints: AnnotationConstraints;
    ngOnInit(): void {
        this.annotationConstraints = AnnotationConstraints.ReadOnly;
    }
}

The following example shows how to enable multiple interactions for annotations:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { AnnotationConstraints } from "@syncfusion/ej2-angular-diagrams";

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px">
        <e-nodes>
            <e-node id='node1' [height]=60 [width]=100 [offsetX]=300 [offsetY]=80>
                <e-node-annotations>
                    <e-node-annotation content='Start' [constraints]='annotationConstraints'></e-node-annotation>
                </e-node-annotations>
            </e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public annotationConstraints: AnnotationConstraints;
    ngOnInit(): void {
        this.annotationConstraints = AnnotationConstraints.Select | AnnotationConstraints.Drag | AnnotationConstraints.Resize | AnnotationConstraints.Rotate;
    }
}

Refer sample below

import {
  AnnotationConstraints,
  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' [getNodeDefaults] ='getNodeDefaults'>
          </ejs-diagram>`,
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public nodes: NodeModel[] = [
    {
      id: 'Node1',
      offsetX: 200,
      offsetY: 200,
      annotations: [
        {
          content: 'Interaction enabled',
          offset: { x: 0.5, y: 0.1 },
          constraints: AnnotationConstraints.Interaction,
        },
        {
          content: 'ReadOnly enabled',
          offset: { x: 0.2, y: 0.5 },
          constraints: AnnotationConstraints.ReadOnly,
        },
        {
          content: 'Select and drag enabled',
          offset: { x: 0.8, y: 0.5 },
          constraints:
            AnnotationConstraints.Select |
            AnnotationConstraints.Drag,
        },
        {
          content: 'Select and rotate enabled',
          offset: { x: 0.5, y: 0.9 },
          constraints:
            AnnotationConstraints.Select |
            AnnotationConstraints.Rotate,
        },
      ],
    },
  ];

  public getNodeDefaults(node: NodeModel): NodeModel {
    node.height = 200;
    node.width = 300;
    node.pivot = { x: 0, y: 0 };
    return node;
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

For more details about annotation constraints, refer to AnnotationConstraints.

Selector Constraints

Selector constraints control the visibility and behavior of selection handles and thumbs that appear when elements are selected.

Constraints Description
None Hides all selector elements.
ConnectorSourceThumb Shows or hides the connector’s source thumb.
ConnectorTargetThumb Shows or hides the connector’s target thumb.
ResizeSouthEast Shows or hides the bottom-right resize handle.
ResizeSouthWest Shows or hides the bottom-left resize handle.
ResizeNorthEast Shows or hides the top-right resize handle.
ResizeNorthWest Shows or hides the top-left resize handle.
ResizeEast Shows or hides the middle-right resize handle.
ResizeWest Shows or hides the middle-left resize handle.
ResizeSouth Shows or hides the bottom-center resize handle.
ResizeNorth Shows or hides the top-center resize handle.
Rotate Shows or hides the rotation handle.
UserHandle Shows or hides custom user handles.
ToolTip Shows or hides tooltips during drag, resize, and rotate operations.
ResizeAll Shows or hides all resize handles.
All Shows all available handles.

The following code demonstrates how to hide the rotation handle:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { SelectorModel, SelectorConstraints } from '@syncfusion/ej2-diagrams';
@Component({
  selector: "app-container",
  template: `<ejs-diagram id="diagram" width="100%" height="580px" [selectedItems]='selectedItems'></ejs-diagram>`
})
export class AppComponent {
    @ViewChild("diagram")
    public selectedItems: SelectorModel;
    ngOnInit(): void {
        this.selectedItems = { constraints: SelectorConstraints.All & ~SelectorConstraints.Rotate };
    }
}

The following code shows how to hide the default tooltip during drag, resize, and rotate operations:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { SelectorModel, SelectorConstraints } from '@syncfusion/ej2-diagrams';
@Component({
  selector: "app-container",
  template: `<ejs-diagram id="diagram" width="100%" height="580px" [selectedItems]='selectedItems'></ejs-diagram>`
})
export class AppComponent {
    @ViewChild("diagram")
    public selectedItems: SelectorModel;
    ngOnInit(): void {
        this.selectedItems = { constraints: SelectorConstraints.All & ~SelectorConstraints.Tooltip };
    }
}

The following code example shows how to disable user handle functionality:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { SelectorModel, SelectorConstraints } from '@syncfusion/ej2-diagrams';
@Component({
  selector: "app-container",
  template: `<ejs-diagram id="diagram" width="100%" height="580px" [selectedItems]='selectedItems'></ejs-diagram>`
})
export class AppComponent {
    @ViewChild("diagram")
    public selectedItems: SelectorModel;
    ngOnInit(): void {
        this.selectedItems = { constraints: SelectorConstraints.All & ~SelectorConstraints.UserHandle };
    }
}

Refer sample below

import {
  DiagramModule,
  SelectorConstraints,
  SelectorModel, 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' [getNodeDefaults] ='getNodeDefaults' [selectedItems]='selectedItems'>
        </ejs-diagram>`,
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public selectedItems?: SelectorModel;
  public nodes: NodeModel[] = [
    {
      id: 'Node1',
      offsetX: 200,
      offsetY: 200,
      annotations: [
        { content: 'Resize handle disabled in selector constraints' },
      ],
    },
  ];
  ngOnInit(): void {
    this.selectedItems = {
      constraints: SelectorConstraints.All & ~SelectorConstraints.ResizeAll,
    };
  }
  public getNodeDefaults(node: NodeModel): NodeModel {
    node.height = 100;
    node.width = 100;
    node.pivot = { x: 0, y: 0 };
    return node;
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

For more information about selector constraints, refer to SelectorConstraints.

NOTE

By default, the following constraints are enabled for selected items:

* Rotate

* UserHandle

* ResizeAll

* All

* ToolTip

Snap Constraints

Snap constraints control the visibility of gridlines and enable or disable snapping functionality for precise element positioning.

Constraints Description
None Disables snapping for all diagram elements.
ShowHorizontalLines Displays horizontal gridlines in the diagram.
ShowVerticalLines Displays vertical gridlines in the diagram.
ShowLines Displays both horizontal and vertical gridlines.
SnapToHorizontalLines Enables snapping to horizontal gridlines only.
SnapToVerticalLines Enables snapping to vertical gridlines only.
SnapToLines Enables snapping to both horizontal and vertical gridlines.
SnapToObject Enables snapping to other objects in the diagram.
All Shows gridlines and enables all snapping functionality.

The following code demonstrates how to show only horizontal gridlines:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { SnapSettingsModel, SnapConstraints } from '@syncfusion/ej2-diagrams';
@Component({
  selector: "app-container",
  template: `<ejs-diagram id="diagram" width="100%" height="580px" [snapSettings]='snapSettings'></ejs-diagram>`
})
export class AppComponent {
    @ViewChild("diagram")
    public snapSettings: SnapSettingsModel;
    ngOnInit(): void {
        this.snapSettings = {
            constraints: SnapConstraints.ShowHorizontalLines
        };
    }
}

Multiple snap behaviors can be combined using Bitwise operations:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { SnapSettingsModel, SnapConstraints } from '@syncfusion/ej2-diagrams';
@Component({
  selector: "app-container",
  template: `<ejs-diagram id="diagram" width="100%" height="580px" [snapSettings]='snapSettings'></ejs-diagram>`
})
export class AppComponent {
    @ViewChild("diagram")
    public snapSettings: SnapSettingsModel;
    ngOnInit(): void {
        this.snapSettings = {
            constraints: SnapConstraints.ShowHorizontalLines | SnapConstraints.ShowVerticalLines
        };
    }
}

Refer sample below

import {
  DiagramModule,
  SnapConstraints,
  SnapSettingsModel,
  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' [getNodeDefaults] ='getNodeDefaults' [snapSettings]='snapSettings'>
        </ejs-diagram>`,
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public snapSettings?: SnapSettingsModel;
  ngOnInit(): void {
    this.snapSettings = {
      constraints: SnapConstraints.ShowHorizontalLines | SnapConstraints.SnapToObject
    };
  }
  public nodes: NodeModel[] = [
    {
      id: 'Node1',
      offsetX: 200,
      offsetY: 200,
      annotations: [{ content: 'Node 1' }],
    },
    {
      id: 'Node2',
      offsetX: 400,
      offsetY: 200,
      annotations: [{ content: 'Node 2' }],
    },
  ];
  public getNodeDefaults(node: NodeModel): NodeModel {
    node.height = 100;
    node.width = 100;
    node.pivot = { x: 0, y: 0 };
    return node;
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

For more information about snap constraints, refer to SnapConstraints.

NOTE

By default, the following constraints are enabled for snap functionality:

* ShowLines

* ShowVerticalLines

* ShowHorizontalLines

* SnapToLines

* SnapToHorizontalLines

* SnapToVerticalLines

* SnapToObject

* All

Boundary Constraints

Boundary constraints define the interaction boundaries for diagram elements, controlling where users can perform operations.

Constraints Description
Infinity Allows interactions at infinite height and width.
Diagram Limits interactions within the diagram’s height and width.
Page Limits interactions within the page boundaries.

The following code demonstrates how to limit interactions within page boundaries:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { PageSettingsModel, BoundaryConstraints } from '@syncfusion/ej2-diagrams';
@Component({
  selector: "app-container",
  template: `<ejs-diagram id="diagram" width="100%" height="580px" [pageSettings]='pageSettings'></ejs-diagram>`
})
export class AppComponent {
    @ViewChild("diagram")
    public pageSettings: PageSettingsModel;
    ngOnInit(): void {
        this.pageSettings = {
            boundaryConstraints: 'Page'
        };
    }
}

Refer sample below

import {
  DiagramModule,
  PageSettingsModel, 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' [getNodeDefaults] ='getNodeDefaults' [pageSettings]='pageSettings'>
        </ejs-diagram>`,
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  @ViewChild('diagram')
  public diagram?: DiagramComponent;
  public pageSettings?: PageSettingsModel;
  ngOnInit(): void {
    this.pageSettings = {
      boundaryConstraints: 'Page',
      width: 500,
      height: 500,
      showPageBreaks: true,
      background: { color: 'grey' },
    };
  }
  public nodes: NodeModel[] = [
    {
      id: 'Node1',
      offsetX: 200,
      offsetY: 200,
      annotations: [{ content: 'Node 1' }],
    }
  ];
  public getNodeDefaults(node: NodeModel): NodeModel {
    node.height = 100;
    node.width = 100;
    node.pivot = { x: 0, y: 0 };
    return node;
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

For more information about boundary constraints, refer to BoundaryConstraints.

Inherit Behaviors

When behaviors are defined at both the specific object level (node/connector) and diagram level, inheritance options determine the actual behavior applied.

The following code example demonstrates how to inherit line bridging behavior from the diagram model:

import { Component, ViewEncapsulation, ViewChild } from "@angular/core";
import { DiagramConstraints, ConnectorBridging, ConnectorConstraints, PointModel } from "@syncfusion/ej2-angular-diagrams";
Diagram.Inject(ConnectorBridging);

@Component({
    selector: "app-container",
    template: `<ejs-diagram id="diagram" width="100%" height="580px" [constraints]='diagramConstraints'>
        <e-connectors>
            <e-connector id='connector' type='Straight' [sourcePoint]='sourcePoint' [targetPoint]='targetPoint' [constraints]='connectorConstraints'>
            </e-connector>
        </e-connectors>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagramConstraints: DiagramConstraints;
    public connectorConstraints: ConnectorConstraints;
    public sourcePoint: PointModel;
    public targetPoint: PointModel;
    ngOnInit(): void {
        this.diagramConstraints = DiagramConstraints.Default | DiagramConstraints.Bridging;
        this.sourcePoint = { x: 100, y: 100 };
        this.targetPoint = { x: 200, y: 200 };
        this.connectorConstraints = ConnectorConstraints.Default | ConnectorConstraints.InheritBridging;
    }
}

Bitwise Operations

Bitwise operations manipulate flagged enumerations to enable precise control over multiple constraint behaviors simultaneously.

Add operation

Use the Bitwise | (OR) operator to add or enable multiple values:

node.constraints = NodeConstraints.Select | NodeConstraints.Rotate;

This example enables both selection and rotation operations for the node.

Remove operation

Use the Bitwise &~ (XOR) operator to remove or disable specific values:

node.constraints = node.constraints & ~(NodeConstraints.Rotate);

This example disables rotation while maintaining other enabled constraints.

Check operation

Use the Bitwise & (AND) operator to verify if specific values are enabled:

if ((node.constraints & (NodeConstraints.Rotate)) == (NodeConstraints.Rotate));

This example checks whether rotation constraints are enabled for a node. When the node has rotation constraints enabled, the expression returns the rotate constraint value.