Connectors in React Diagram Component
21 Oct 202524 minutes to read
Connectors are objects used to create links between two points, nodes, or ports to represent relationships between them. They provide visual connections that help illustrate data flow, process sequences, hierarchical relationships, and other logical connections in diagrams.
Create Connector
Connectors can be created by defining the source and target points. The path to be drawn can be defined with a collection of segments. To explore the properties of a connector, refer to Connector Properties. The id property of a connector is used to define its unique identifier and can later be used to find the connector at runtime for customization.
let connectors = [{
// id of the connector
id: "connector1",
sourcePoint: {x: 100, y: 100 },
targetPoint: { x: 200,y: 200 }
}];NOTE
When setting a Connector’s ID, ensure that it does not contain white spaces, does not start with numbers or special characters, and does not include special characters like underscores (_) or spaces.
Add connectors through Connectors Collection
The sourcePoint and targetPoint properties of connector allow you to define the end points of a connector.
The following code example illustrates how to add a connector through connector collection.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let connectors = [{
// Name of the connector
id: "connector1",
// Sets source and target points
sourcePoint: {
x: 100,
y: 100
},
targetPoint: {
x: 200,
y: 200
}
}];
function App() {
return (<DiagramComponent id="container" width={'100%'} height={'600px'} connectors={connectors}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
DiagramComponent,
ConnectorModel
} from "@syncfusion/ej2-react-diagrams";
let connectors: ConnectorModel[] = [{
// Name of the connector
id: "connector1",
// Sets source and target points
sourcePoint: {
x: 100,
y: 100
},
targetPoint: {
x: 200,
y: 200
}
}];
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
connectors={connectors}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Add/Remove Connector at Runtime
Connectors can be added at runtime by using public method, add and can be removed at runtime by using public method, remove.These methods are useful when you need to dynamically modify diagram structure based on user interactions or data changes.
The following code example illustrates how to add connector at runtime.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
let connectors = [{
id: 'connector1',
sourcePoint: {
x: 100,
y: 100
},
targetPoint: {
x: 200,
y: 200
}
}];
function App() {
const add = () => {
diagramInstance.add(connectors[0])
}
const remove = () => {
diagramInstance.remove(connectors[0])
}
return (
<div>
<button onClick={add}>Add</button>
<button onClick={remove}>Remove</button>
<DiagramComponent id="container" ref={(diagram) => (diagramInstance = diagram)} width={'100%'} height={'600px'} created={() => {
// Adds to the Diagram
diagramInstance.add(connectors[0]);
// Remove from the diagram
diagramInstance.remove(connectors[0]);
}}/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
DiagramComponent,
ConnectorModel
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
let connectors: ConnectorModel[] = [{
id: 'connector1',
sourcePoint: {
x: 100,
y: 100
},
targetPoint: {
x: 200,
y: 200
}
}];
function App() {
const add = () => {
diagramInstance.add(connectors[0])
}
const remove = () => {
diagramInstance.remove(connectors[0])
}
return (
<div>
<button onClick={add}>Add</button>
<button onClick={remove}>Remove</button>
<DiagramComponent id="container" ref={(diagram) => (diagramInstance = diagram)} width={'100%'} height={'600px'} created={() => {
// Adds to the Diagram
diagramInstance.add(connectors[0]);
// Remove from the diagram
diagramInstance.remove(connectors[0]);
}}/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Add Collection of Connectors at Runtime
The collection of connectors 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 connectors collection at runtime.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
//initialize connector collection
let collectorCollection = [
{ id: 'connector1', sourcePoint: { x: 80, y: 80 }, targetPoint: { x: 150, y: 150 } },
{id: 'connector2', type: 'Orthogonal', sourcePoint: { x: 170, y: 170 }, targetPoint: { x: 300, y: 300 }},
{ id: 'connector3', type: 'Bezier', sourcePoint: { x: 320, y: 320 }, targetPoint: { x: 400, y: 400 } }
];
function App() {
return (<DiagramComponent id="container" ref={(diagram) => (diagramInstance = diagram)} width={'1500px'} height={'600px'} created={() => {
//Add collection of connectors
diagramInstance.addElements(collectorCollection);
}}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, ConnectorModel} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
//initialize connector collection
var collectorCollection:ConnectorModel[] = [
{ id: 'connector1', sourcePoint: { x: 80, y: 80 }, targetPoint: { x: 150, y: 150 } },
{id: 'connector2', type: 'Orthogonal', sourcePoint: { x: 170, y: 170 }, targetPoint: { x: 300, y: 300 }},
{ id: 'connector3', type: 'Bezier', sourcePoint: { x: 320, y: 320 }, targetPoint: { x: 400, y: 400 } }
];
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'1500px'}
height={'600px'}
created={() => {
//Add collection of connectors
diagramInstance.addElements(collectorCollection);
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Add Connectors from Palette
Connectors can be predefined and added to the symbol palette. You can drop those connectors into the diagram, when required. This approach is useful for creating reusable connector templates that users can easily drag and drop into their diagrams.
The following code example illustrates how to add connectors in palette.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, SymbolPaletteComponent } from "@syncfusion/ej2-react-diagrams";
// Define connector symbols
let connectorSymbols = [
{
id: 'Link1',
type: 'Orthogonal',
sourcePoint: { x: 0, y: 0 },
targetPoint: { x: 40, y: 40 }
},
{
id: 'Link2',
type: 'Orthogonal',
sourcePoint: { x: 0, y: 0 },
targetPoint: { x: 40, y: 40 },
style: {strokeDashArray: '4 4' },
},
{
id: 'Link3',
type: 'Straight',
sourcePoint: { x: 0, y: 0 },
targetPoint: { x: 40, y: 40 },
},
{
id: 'Link4',
type: 'Bezier',
sourcePoint: { x: 0, y: 0 },
targetPoint: { x: 40, y: 40 },
},
];
// App component
let App = () => {
return (
<div>
<SymbolPaletteComponent
id="symbolpalette"
expandMode="Multiple"
palettes={[
{
id: "flow",
expanded: true,
symbols: connectorSymbols,
title: "Connectors",
},
]}
/>
<DiagramComponent
id="diagram"
width="100%"
height="700px"
/>
</div>
);
};
// Render the App component
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, SymbolPaletteComponent,ConnectorModel } from "@syncfusion/ej2-react-diagrams";
// Define connector symbols
let connectorSymbols:ConnectorModel[] = [
{
id: 'Link1',
type: 'Orthogonal',
sourcePoint: { x: 0, y: 0 },
targetPoint: { x: 40, y: 40 }
},
{
id: 'Link2',
type: 'Orthogonal',
sourcePoint: { x: 0, y: 0 },
targetPoint: { x: 40, y: 40 },
style: {strokeDashArray: '4 4' },
},
{
id: 'Link3',
type: 'Straight',
sourcePoint: { x: 0, y: 0 },
targetPoint: { x: 40, y: 40 },
},
{
id: 'Link4',
type: 'Bezier',
sourcePoint: { x: 0, y: 0 },
targetPoint: { x: 40, y: 40 },
},
];
// App component
let App = () => {
return (
<div>
<SymbolPaletteComponent
id="symbolpalette"
expandMode="Multiple"
palettes={[
{
id: "flow",
expanded: true,
symbols: connectorSymbols,
title: "Connectors",
},
]}
/>
<DiagramComponent
id="diagram"
width="100%"
height="700px"
/>
</div>
);
};
// Render the App component
const root = ReactDOM.createRoot(document.getElementById('diagram') as HTMLElement);
root.render(<App />);Draw Connectors
Connectors can be interactively drawn by clicking and dragging on the diagram surface. This feature enables users to create connections dynamically during diagram creation or editing.
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 connector object by using the drawingObject property.
The following code example illustrates how to draw a connector at runtime.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, DiagramTools } from "@syncfusion/ej2-react-diagrams";
const drawingObject = { type: 'Orthogonal' };
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
tool={DiagramTools.ContinuousDraw}
drawingObject={drawingObject}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, DiagramTools } from "@syncfusion/ej2-react-diagrams";
const drawingObject = { type: 'Orthogonal' };
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
tool={DiagramTools.ContinuousDraw}
drawingObject={drawingObject}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram') as HTMLElement);
root.render(<App />);For more information about drawing connectors, refer to Draw Connectors.
Update Connector at Runtime
Various connector properties such as sourcePoint, targetPoint, style, sourcePortID, targetPortID, etc., can be updated at the runtime.
The following code example illustrates how to update a connector’s source point, target point, styles properties at runtime.This flexibility allows for dynamic modification of connector appearance and behavior based on application logic or user interactions.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let connectors = [{
id: "connector1",
sourcePoint: {
x: 100,
y: 100
},
targetPoint: {
x: 200,
y: 200
}
}];
let diagramInstance;
function App() {
const update = () =>{
// Update the connector properties at the run time
diagramInstance.connectors[0].style.strokeColor = '#6BA5D7';
diagramInstance.connectors[0].style.fill = '#6BA5D7';
diagramInstance.connectors[0].style.strokeWidth = 2;
diagramInstance.connectors[0].targetDecorator.style.fill = '#6BA5D7';
diagramInstance.connectors[0].targetDecorator.style.strokeColor =
'#6BA5D7';
diagramInstance.connectors[0].sourcePoint.x = 150;
diagramInstance.connectors[0].targetPoint.x = 150;
diagramInstance.dataBind();
}
return (
<div>
<button onClick={update}>update</button>
<DiagramComponent id="container" ref={(diagram) => (diagramInstance = diagram)} width={'100%'} height={'600px'} connectors={connectors}
/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
DiagramComponent,
ConnectorModel
} from "@syncfusion/ej2-react-diagrams";
let connectors: ConnectorModel[] = [{
id: "connector1",
sourcePoint: {
x: 100,
y: 100
},
targetPoint: {
x: 200,
y: 200
}
}];
let diagramInstance: DiagramComponent;
function App() {
const update = () =>{
// Update the connector properties at the run time
diagramInstance.connectors[0].style.strokeColor = '#6BA5D7';
diagramInstance.connectors[0].style.fill = '#6BA5D7';
diagramInstance.connectors[0].style.strokeWidth = 2;
diagramInstance.connectors[0].targetDecorator.style.fill = '#6BA5D7';
diagramInstance.connectors[0].targetDecorator.style.strokeColor =
'#6BA5D7';
diagramInstance.connectors[0].sourcePoint.x = 150;
diagramInstance.connectors[0].targetPoint.x = 150;
diagramInstance.dataBind();
}
return (
<div>
<button onClick={update}>update</button>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'100%'}
height={'600px'}
connectors={connectors}
/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Clone Connector at Runtime
Cloning a connector creates a new connector instance with identical properties and attributes. This feature is useful when you need to duplicate existing connectors while maintaining their configuration.
The following code example illustrates how to clone a connector.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// Define initial connectors
let connectors = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 200, y: 200 }
}
];
// App component
const App = () => {
// Function to handle clone button click
const handleCloneClick = () => {
diagramInstance.select([diagramInstance.selectedItems.connectors[0]]);
diagramInstance.copy();
diagramInstance.paste();
};
return (
<div>
<button onClick={handleCloneClick}>handleCloneClick</button>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'100%'}
height={'600px'}
connectors={connectors}
/>
</div>
);
};
// Render the App component
const root = ReactDOM.createRoot(document.getElementById('diagram') );
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent,ConnectorModel } from "@syncfusion/ej2-react-diagrams";
let diagramInstance:DiagramComponent;
// Define initial connectors
let connectors: ConnectorModel[] = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 200, y: 200 }
}
];
// App component
const App = () => {
// Function to handle clone button click
const handleCloneClick = () => {
diagramInstance.select([diagramInstance.selectedItems.connectors[0]]);
diagramInstance.copy();
diagramInstance.paste();
};
return (
<div>
<button onClick={handleCloneClick}>handleCloneClick</button>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'100%'}
height={'600px'}
connectors={connectors}
/>
</div>
);
};
// Render the App component
const root = ReactDOM.createRoot(document.getElementById('diagram') );
root.render(<App />);Configure Default Connector Properties
The connector defaults functionality allows you to define default properties for all connectors in the diagram. This is triggered when the diagram is initialized, providing an opportunity to customize connector properties globally rather than setting them individually for each connector.
The following code example explains how to customize connector defaults using getConnectorDefaults.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
var connectors = [
{
id: 'connector1',
type: 'Straight',
sourcePoint: {
x: 100,
y: 100,
},
targetPoint: {
x: 200,
y: 200,
},
},
{
id: 'connector2',
type: 'Straight',
sourcePoint: {
x: 300,
y: 100,
},
targetPoint: {
x: 400,
y: 200,
},
},
];
function App() {
return (<DiagramComponent id="container" width={'100%'} height={'600px'} connectors={connectors}
// Defines the default properties for the connector
getConnectorDefaults={(connector) => {
connector.style.strokeColor = 'red';
connector.sourceDecorator.shape = 'Circle';
connector.targetDecorator.style.fill = '#6BA5D7'
connector.targetDecorator.style.strokeColor = '#6BA5D7'
connector.style.strokeWidth = 2;
}}
/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, ConnectorModel } from "@syncfusion/ej2-react-diagrams";
var connectors:ConnectorModel[] = [
{
id: 'connector1',
type: 'Straight',
sourcePoint: {
x: 100,
y: 100,
},
targetPoint: {
x: 200,
y: 200,
},
},
{
id: 'connector2',
type: 'Straight',
sourcePoint: {
x: 300,
y: 100,
},
targetPoint: {
x: 400,
y: 200,
},
},
];
function App() {
return (<DiagramComponent id="container" width={'100%'} height={'600px'} connectors={connectors}
// Defines the default properties for the connector
getConnectorDefaults={(connector: ConnectorModel) => {
connector.style.strokeColor = 'red';
connector.sourceDecorator.shape = 'Circle';
connector.targetDecorator.style.fill = '#6BA5D7'
connector.targetDecorator.style.strokeColor = '#6BA5D7'
connector.style.strokeWidth = 2;
}}
/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Connections
Connection with Nodes
- The
sourceIDandtargetIDproperties allow you to define the nodes to be connected. When these properties are set, the connector will automatically attach to the specified nodes and move with them when the nodes are repositioned.
The following code example illustrates how to connect two nodes.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, } from "@syncfusion/ej2-react-diagrams";
let nodes = [{
id: 'Start',
width: 140,
height: 50,
offsetX: 100,
offsetY: 100,
annotations: [{
id: 'label1',
content: 'Start'
}],
shape: {
type: 'Flow',
shape: 'Terminator'
}
},
{
id: 'Init',
width: 140,
height: 50,
offsetX: 300,
offsetY: 300,
shape: {
type: 'Flow',
shape: 'Process'
},
annotations: [{
content: 'var i = 0;'
}]
}
];
let connectors = [{
// Name of the connector
id: "connector1",
// ID of the source and target nodes
sourceID: "Start",
targetID: "Init",
type: 'Orthogonal'
}];
function App() {
return (<DiagramComponent id="container" width={'100%'} height={'600px'} nodes={nodes} connectors={connectors}
// Defines the default properties for the node
getNodeDefaults={(node) => {
node.height = 100;
node.width = 100;
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}} />);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
DiagramComponent,
NodeModel,
ConnectorModel,
} from "@syncfusion/ej2-react-diagrams";
let nodes: NodeModel[] = [{
id: 'Start',
width: 140,
height: 50,
offsetX: 100,
offsetY: 100,
annotations: [{
id: 'label1',
content: 'Start'
}],
shape: {
type: 'Flow',
shape: 'Terminator'
}
},
{
id: 'Init',
width: 140,
height: 50,
offsetX: 300,
offsetY: 300,
shape: {
type: 'Flow',
shape: 'Process'
},
annotations: [{
content: 'var i = 0;'
}]
}
];
let connectors: ConnectorModel[] = [{
// Name of the connector
id: "connector1",
// ID of the source and target nodes
sourceID: "Start",
targetID: "Init",
type: 'Orthogonal'
}];
function App() {
return (
<DiagramComponent id="container"
width={
'100%'
}
height={
'600px'
}
nodes={
nodes
}
connectors={
connectors
}
// Defines the default properties for the node
getNodeDefaults={
(node: NodeModel) => {
node.height = 100;
node.width = 100;
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}
}
/>
)
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);- When you remove NodeConstraints
InConnectfrom Default, the node accepts only an outgoing connection to dock in it. Similarly, when you remove NodeConstraintsOutConnectfrom Default, the node accepts only an incoming connection to dock in it.
When you remove both InConnect and OutConnect NodeConstraints from Default, the node restricts connectors from establishing connections to it.
The following code illustrates how to disable InConnect constraints.
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
Diagram,
DiagramComponent,
NodeModel,
ConnectorModel
} from "@syncfusion/ej2-react-diagrams";
let nodes: NodeModel[] = [{
id: 'Start',
width: 140,
height: 50,
offsetX: 300,
offsetY: 100,
//Disable InConnect constraints
constraints: NodeConstraints.Default & ~NodeConstraints.InConnect,
}
];
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Connections with Ports
The sourcePortID and targetPortID properties allow you to create connections between specific points of source and target nodes. This provides more precise control over where connectors attach to nodes.
The following code example illustrates how to create port to port connections.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, PortVisibility } from "@syncfusion/ej2-react-diagrams";
let port1 = {
id:'port1',
style: {
strokeColor: '#366F8C',
fill: '#366F8C'
},
shape:'Circle',
visibility: PortVisibility.Visible,
offset:{
x: 1, y: 0.5
}
};
let port2 = {
id:'port2',
style: {
strokeColor: '#366F8C',
fill: '#366F8C'
},
shape:'Circle',
visibility: PortVisibility.Visible,
offset:{
x: 0, y: 0
}
};
let port3 = {
id:'ports3',
style: {
strokeColor: '#366F8C',
fill: '#366F8C'
},
shape:'Square',
visibility: PortVisibility.Visible,
offset:{
x: 0, y: 1
}
};
let nodes = [{
id: 'node',
width: 100,
height: 100,
offsetX: 100,
offsetY: 100,
ports: [port1]
},
{
id: 'node1',
width: 100,
height: 100,
offsetX: 300,
offsetY: 100,
ports: [port2,port3]
},
];
let connectors = [{
id: "connector1",
type:'Orthogonal',
sourceID: 'node',
targetID: 'node1',
sourcePortID: 'port1',
targetPortID: 'port2'
}];
function App() {
return (<DiagramComponent id="container" width={900} height={900} nodes={nodes} connectors={connectors} getNodeDefaults={(node) => {
node.height = 100;
node.width = 100;
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
ConnectorModel,
NodeModel,
PointPortModel,
DiagramComponent,
PortVisibility
} from "@syncfusion/ej2-react-diagrams";
let port1: PointPortModel = {
id:'port1',
style: {
strokeColor: '#366F8C',
fill: '#366F8C'
},
shape:'Circle',
visibility: PortVisibility.Visible,
offset:{
x: 1, y: 0.5
}
};
let port2: PointPortModel = {
id:'port2',
style: {
strokeColor: '#366F8C',
fill: '#366F8C'
},
shape:'Circle',
visibility: PortVisibility.Visible,
offset:{
x: 0, y: 0
}
};
let port3: PointPortModel = {
id:'ports3',
style: {
strokeColor: '#366F8C',
fill: '#366F8C'
},
shape:'Square',
visibility: PortVisibility.Visible,
offset:{
x: 0, y: 1
}
};
let nodes: NodeModel[] = [{
id: 'node',
width: 100,
height: 100,
offsetX: 100,
offsetY: 100,
ports: [port1]
},
{
id: 'node1',
width: 100,
height: 100,
offsetX: 300,
offsetY: 100,
ports: [port2,port3]
},
];
let connectors: ConnectorModel[] = [{
id: "connector1",
sourceID: 'node',
targetID: 'node1',
sourcePortID: 'port1',
targetPortID: 'port2'
}];
function App() {
return (
<DiagramComponent
id="container"
width={900}
height={900}
nodes={nodes}
connectors={connectors}
getNodeDefaults={(node: NodeModel) => {
node.height = 100;
node.width = 100;
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Similarly, the sourcePortID or targetPortID can be changed at the runtime by changing the port sourcePortID or targetPortID.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, PortVisibility, } from '@syncfusion/ej2-react-diagrams';
let port1 = {
style: {
strokeColor: '#366F8C',
fill: '#366F8C',
},
shape : 'Circle',
id :'port',
visibility : PortVisibility.Visible,
offset : {
x: 1,
y: 1,
}
};
let port2 = {
style: {
strokeColor: '#366F8C',
fill: '#366F8C',
},
shape : 'Circle',
id :'port1',
visibility : PortVisibility.Visible,
offset : {
x: 0.5,
y: 1,
}
};
let port3 = {
style: {
strokeColor: '#366F8C',
fill: '#366F8C',
},
shape : 'Circle',
id :'port2',
visibility : PortVisibility.Visible,
offset : {
x: 1,
y: 0.5,
}
}
let port4 = {
style: {
strokeColor: '#366F8C',
fill: '#366F8C',
},
shape : 'Circle',
id :'port2',
visibility : PortVisibility.Visible,
offset : {
x: 1,
y: 0.5,
}
}
let nodes = [
{
id: 'node',
width: 100,
height: 100,
offsetX: 100,
offsetY: 100,
ports: [port1,port4],
},
{
id: 'node1',
width: 100,
height: 100,
offsetX: 300,
offsetY: 100,
ports: [port2, port3],
},
];
let diagramInstance;
let connectors = [
{
id: 'connector1',
sourcePoint: {
x: 100,
y: 100,
},
type: 'Orthogonal',
targetPoint: {
x: 200,
y: 200,
},
sourceID: 'node',
targetID: 'node1',
sourcePortID: 'port',
targetPortID: 'port1',
},
];
function App() {
// Update the target portID at the run time
const handleCloneClick = () => {
diagramInstance.connectors[0].sourcePortID = 'port4';
diagramInstance.connectors[0].targetPortID = 'port2';
}
return (
<div>
<button onClick={handleCloneClick}>update</button>
<DiagramComponent id="container" ref={(diagram) => (diagramInstance = diagram)} width={900} height={900} nodes={nodes} connectors={connectors} getNodeDefaults={(node) => {
node.height = 100;
node.width = 100;
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}}/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
ConnectorModel,
NodeModel,
BasicShapeModel,
PointPortModel,
Diagram,
DiagramComponent,
PortVisibility,
} from '@syncfusion/ej2-react-diagrams';
let port1: PointPortModel = {
style: {
strokeColor: '#366F8C',
fill: '#366F8C',
},
shape : 'Circle',
id :'port',
visibility : PortVisibility.Visible,
offset : {
x: 1,
y: 1,
}
};
let port2: PointPortModel = {
style: {
strokeColor: '#366F8C',
fill: '#366F8C',
},
shape : 'Circle',
id :'port1',
visibility : PortVisibility.Visible,
offset : {
x: 0.5,
y: 1,
}
};
let port3: PointPortModel = {
style: {
strokeColor: '#366F8C',
fill: '#366F8C',
},
shape : 'Circle',
id :'port2',
visibility : PortVisibility.Visible,
offset : {
x: 1,
y: 0.5,
}
};
let port4: PointPortModel = {
style: {
strokeColor: '#366F8C',
fill: '#366F8C',
},
shape : 'Circle',
id :'port2',
visibility : PortVisibility.Visible,
offset : {
x: 1,
y: 0.5,
}
};
let nodes: NodeModel[] = [
{
id: 'node',
width: 100,
height: 100,
offsetX: 100,
offsetY: 100,
ports: [port1,port4],
},
{
id: 'node1',
width: 100,
height: 100,
offsetX: 300,
offsetY: 100,
ports: [port2, port3],
},
];
let diagramInstance: DiagramComponent;
let connectors: ConnectorModel[] = [
{
id: 'connector1',
sourcePoint: {
x: 100,
y: 100,
},
type: 'Orthogonal',
targetPoint: {
x: 200,
y: 200,
},
sourceID: 'node',
targetID: 'node1',
sourcePortID: 'port',
targetPortID: 'port1',
},
];
function App() {
// Update the target portID at the run time
const handleCloneClick = () => {
diagramInstance.connectors[0].sourcePortID = 'port4';
diagramInstance.connectors[0].targetPortID = 'port2';
}
return (
<div>
<button onClick={handleCloneClick}>update</button>
<DiagramComponent id="container" ref={(diagram) => (diagramInstance = diagram)} width={900} height={900} nodes={nodes} connectors={connectors}
getNodeDefaults={(node: NodeModel) => {
node.height = 100;
node.width = 100;
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}}/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);-
When you set PortConstraints to
InConnect, the port accepts only an incoming connection to dock in it. Similarly, when you set PortConstraints toOutConnect, the port accepts only an outgoing connection to dock in it. -
When you set PortConstraints to None, the port restricts connector to establish connection in it.
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
ConnectorModel,
NodeModel,
BasicShapeModel,
PointPortModel,
Diagram,
DiagramComponent,
PortVisibility
} from "@syncfusion/ej2-react-diagrams";
let port1: PointPortModel = {
style: {
strokeColor: '#366F8C',
fill: '#366F8C'
}
}
port1.shape = 'Circle';
port1.id = 'nodeportnew';
//Enable portConstraints Inconnect
port1.constraints = PortConstraints.InConnect;
let nodes: NodeModel[] = [{
id: 'node',
width: 100,
height: 100,
offsetX: 100,
offsetY: 150,
ports: [port1]
},
];
function App() {
return (
<DiagramComponent id="container" width={900} height={900} nodes={nodes} />
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Automatic Line Routing
Diagram provides additional flexibility to re-route diagram connectors automatically. A connector will frequently re-route itself when a shape moves next to it. Routing adjusts the geometry of connectors to prevent them from overlapping with any nearby nodes in their path. This feature can be activated by adding the LineRouting constraints property to the diagram.
The LineRouting module should be injected to the application as shown in the following code snippet.
```ts
import { Diagram, LineRouting } from "@syncfusion/ej2-react-diagrams";
/**
* Injecting the automatic line routing module.
*/
Diagram.Inject(LineRouting); ```
The line routing constraints must be included in the default diagram constraints to enable automatic line routing support as shown below.
```ts
/**
* Initialize the Diagram
*/
<DiagramComponent constraints={DiagramConstraints.Default | DiagramConstraints.LineRouting} />
```
- The following code block shows how to create the diagram with specifying nodes, connectors, constraints, and necessary modules for line routing.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Diagram, DiagramComponent, LineRouting, DiagramConstraints } from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(LineRouting);
/**
* Diagram Default sample
*/
//Initializes the nodes for the diagram
let nodes = [
{ id: 'shape1', offsetX: 100, offsetY: 100, width: 120, height: 50 },
{ id: 'shape2', offsetX: 300, offsetY: 300, width: 120, height: 50 },
{ id: 'shape3', offsetX: 150, offsetY: 200, width: 120, height: 50 }
];
//Initializes the connector for the diagram
let connectors = [
{ id: 'connector', sourceID: 'shape1', targetID: 'shape2', type: 'Orthogonal' }
];
function App() {
return (<DiagramComponent id="container" width={'100%'} height={'700px'} nodes={nodes} connectors={connectors} //Sets the default values of a node
constraints={DiagramConstraints.Default | DiagramConstraints.LineRouting} getNodeDefaults={(node) => {
node = { style: { strokeColor: '#6BA5D7', fill: '#6BA5D7' } };
return node;
}}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
Diagram, DiagramComponent, NodeModel, SnapConstraints, LineRouting, DiagramConstraints, NodeModel, ConnectorModel, ConnectorConstraints
} from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(LineRouting);
/**
* Diagram Default sample
*/
//Initializes the nodes for the diagram
let nodes = [
{ id: 'shape1', offsetX: 100, offsetY: 100, width: 120, height: 50 },
{ id: 'shape2', offsetX: 300, offsetY: 300, width: 120, height: 50 },
{ id: 'shape3', offsetX: 150, offsetY: 200, width: 120, height: 50 }
];
//Initializes the connector for the diagram
let connectors = [
{ id: 'connector', sourceID: 'shape1', targetID: 'shape2', type: 'Orthogonal' }
];
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'700px'}
nodes={nodes}
connectors={connectors} //Sets the default values of a node
constraints={DiagramConstraints.Default | DiagramConstraints.LineRouting}
getNodeDefaults={(node) => {
node = { style: { strokeColor: '#6BA5D7', fill: '#6BA5D7' } };
return node;
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion® React Chart-DataLabel</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-diagrams/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-navigations/styles/fabric.css" rel="stylesheet" />
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
#diagram {
display: block;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='diagram'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>The following image illustrates how the connector automatically re-routes the segments.

- In some situations, automatic line routing enabled diagram needs to ignore a specific connector from automatic line routing. So, in this case, auto routing feature can be disabled to the specific connector using the
constraintsproperty of the connector like the following code snippet.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Diagram, DiagramComponent, LineRouting, DiagramConstraints, ConnectorConstraints } from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(LineRouting);
/**
* Diagram Default sample
*/
//Initializes the nodes for the diagram
let nodes = [
{ id: 'shape1', offsetX: 100, offsetY: 100, width: 120, height: 50 },
{ id: 'shape2', offsetX: 350, offsetY: 300, width: 120, height: 50 },
{ id: 'shape3', offsetX: 150, offsetY: 200, width: 120, height: 50 },
{ id: 'shape4', offsetX: 300, offsetY: 200, width: 120, height: 50 }
];
//Initializes the connector for the diagram
let connectors = [
{ id: 'connector', sourceID: 'shape1', targetID: 'shape2', type: 'Orthogonal', annotations: [{ offset: .7, content: ' Routing \n enabled', style: { fill: "white" } }] },
{ id: 'connector2', sourceID: 'shape1', targetID: 'shape2', annotations: [{ offset: .6, content: ' Routing \n disabled', style: { fill: "white" } }], type: 'Orthogonal', constraints: ConnectorConstraints.Default & ~ConnectorConstraints.InheritLineRouting }
];
function App() {
return (<DiagramComponent id="container" width={'100%'} height={'700px'} nodes={nodes} connectors={connectors} //Sets the default values of a node
constraints={DiagramConstraints.Default | DiagramConstraints.LineRouting} getNodeDefaults={(node) => {
node = { style: { strokeColor: '#6BA5D7', fill: '#6BA5D7' } };
return node;
}}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
Diagram, DiagramComponent, LineRouting, DiagramConstraints, NodeModel, ConnectorModel, ConnectorConstraints
} from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(LineRouting);
/**
* Diagram Default sample
*/
//Initializes the nodes for the diagram
let nodes:NodeModel[] = [
{ id: 'shape1', offsetX: 100, offsetY: 100, width: 120, height: 50 },
{ id: 'shape2', offsetX: 350, offsetY: 300, width: 120, height: 50 },
{ id: 'shape3', offsetX: 150, offsetY: 200, width: 120, height: 50 },
{ id: 'shape4', offsetX: 300, offsetY: 200, width: 120, height: 50 }
];
//Initializes the connector for the diagram
let connectors:ConnectorModel[] = [
{ id: 'connector', sourceID: 'shape1', targetID: 'shape2', type: 'Orthogonal', annotations: [{ offset: .7, content: ' Routing \n enabled', style: { fill: "white" } }] },
{ id: 'connector2', sourceID: 'shape1', targetID: 'shape2', annotations: [{ offset: .6, content: ' Routing \n disabled', style: { fill: "white" } }], type: 'Orthogonal', constraints: ConnectorConstraints.Default & ~ConnectorConstraints.InheritLineRouting }
];
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'700px'}
nodes={nodes}
connectors={connectors} //Sets the default values of a node
constraints={DiagramConstraints.Default | DiagramConstraints.LineRouting}
getNodeDefaults={(node) => {
node = { style: { strokeColor: '#6BA5D7', fill: '#6BA5D7' } };
return node;
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion® React Chart-DataLabel</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-diagrams/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-navigations/styles/fabric.css" rel="stylesheet" />
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
#diagram {
display: block;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='diagram'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Avoid Line Overlapping
The diagram provides flexibility to prevent connectors from overlapping, ensuring better clarity and readability. This feature intelligently adjusts connector paths to avoid stacking orthogonal connectors on top of each other, reducing visual clutter and enhancing diagram structure. It is especially useful in complex diagrams with multiple orthogonal connectors, where overlapping lines can make interpretation difficult.
To enable this feature, inject the AvoidLineOverlapping module and add its constraints to the diagram.
-
Inject both the
LineRoutingandAvoidLineOverlappingmodules into the application.import { Diagram, LineRouting, AvoidLineOverlapping } from "@syncfusion/ej2-react-diagrams"; /** * Injecting the line routing and avoid line overlapping module. */ Diagram.Inject(LineRouting, AvoidLineOverlapping); -
Add
LineRoutingandAvoidLineOverlappingconstraints to the diagram constraints to enable line routing with avoid line overlapping support./** * Initialize the Diagram */ <DiagramComponent constraints={DiagramConstraints.Default | DiagramConstraints.LineRouting | DiagramConstraints.AvoidLineOverlapping} />

The following example demonstrates how to enable the AvoidLineOverlapping feature in the diagram.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Diagram, DiagramComponent, LineRouting, AvoidLineOverlapping, Snapping, DiagramConstraints, PortVisibility } from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(LineRouting, AvoidLineOverlapping, Snapping);
let orData = 'M21.7,76.5L21.7,76.5c6.4-18.1,6.4-37.8,0-55.9l0-0.1h1.6c21.5,0,41.7,10.4,54.2,28l0,0l0,0 c-12.5,17.6-32.7,28-54.2,28H21.7z M99.5,48.5l-22,0 M0,31.5h25 M0,65.5h25';
let andData = 'M21.5,20.5h28a28,28,0,0,1,28,28v0a28,28,0,0,1-28,28h-28a0,0,0,0,1,0,0v-56a0,0,0,0,1,0,0Z M78,48.5 L 100,48.5Z M0,32.5 L 21.4,32.5Z M0,65.5 L 21.4,65.5Z';
let notData = 'M75.5,50.5l-52,28v-56L75.5,50.5z M81.5,50.5h18 M1.5,50.5h22 M78.5,47.5c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3 S80.2,47.5,78.5,47.5z';
let orPort = [
{ id: 'Or_port1', offset: { x: 0.01, y: 0.1963 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }, { id: 'Or_port2', offset: { x: 0.26, y: 0.5 } },
{ id: 'Or_port3', offset: { x: 0.01, y: 0.805 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }, { id: 'Or_port4', offset: { x: 0.99, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }
];
let andPort = [
{ id: 'And_port1', offset: { x: 0.01, y: 0.215 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }, { id: 'And_port2', offset: { x: 0.22, y: 0.5 } },
{ id: 'And_port3', offset: { x: 0.01, y: 0.805 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }, { id: 'And_port4', offset: { x: 0.99, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }
];
let notPort = [
{ id: 'Not_port1', offset: { x: 0.01, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }, { id: 'Not_port2', offset: { x: 0.99, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }
];
let nodes = [
{ id: 'switch', offsetX: 80, offsetY: 50, width: 50, height: 50, ports: [{ id: 'port1', offset: { x: 1, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }], annotations: [{ content: 'A' }] },
{ id: 'Push', offsetX: 80, offsetY: 150, width: 50, height: 50, ports: [{ id: 'port1', offset: { x: 1, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }], annotations: [{ content: 'B' }] },
{ id: 'clock', offsetX: 80, offsetY: 250, width: 50, height: 50, ports: [{ id: 'port1', offset: { x: 1, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }], annotations: [{ content: 'C' }] },
{ id: 'switch2', offsetX: 80, offsetY: 350, width: 50, height: 50, ports: [{ id: 'port1', offset: { x: 1, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }], annotations: [{ content: 'D' }] },
{ id: 'AND21', offsetX: 200, offsetY: 100, width: 60, height: 40, shape: { type: 'Path', data: andData }, ports: andPort },
{ id: 'OR22', offsetX: 200, offsetY: 200, width: 60, height: 40, shape: { type: 'Path', data: orData }, ports: orPort },
{ id: 'AND23', offsetX: 200, offsetY: 300, width: 60, height: 40, shape: { type: 'Path', data: andData }, ports: andPort },
{ id: 'AND31', offsetX: 300, offsetY: 250, width: 60, height: 40, shape: { type: 'Path', data: andData }, ports: andPort },
{ id: 'OR41', offsetX: 400, offsetY: 150, width: 60, height: 40, shape: { type: 'Path', data: orData }, ports: orPort },
{ id: 'NOT42', offsetX: 400, offsetY: 350, width: 60, height: 40, shape: { type: 'Path', data: notData }, ports: notPort },
{
id: 'Exor5', ports: orPort, offsetX: 500, offsetY: 250, width: 60, height: 40,
shape: {
type: 'Path', data: 'M21.7,76.5L21.7,76.5c6.4-18.1,6.4-37.8,0-55.9l0-0.1h1.6c21.5,0,41.7,10.4,54.2,28l0,0l0,0 c-12.5,17.6-32.7,28-54.2,28H21.7z M73.4,48.5L73.4,48.5 M17.5,76.8L17.5,76.8c6.7-18.2,6.7-38.1,0-56.3l0-0.1 M77.5,48.5h22 M0,32.5h21 M0,65.5h21'
},
},
{ id: 'bulb', offsetX: 600, offsetY: 150, width: 50, height: 50, ports: [{ id: 'bulbPort', offset: { x: 0.5, y: 1 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }], annotations: [{ content: 'Out' }] }
];
let connectors = [
{ id: 'ExOr-Output', sourceID: 'Exor5', targetID: 'bulb', sourcePortID: 'Or_port4', targetPortID: 'bulbPort', type: 'Orthogonal' },
{ id: '4-ExOr1', sourceID: 'OR41', targetID: 'Exor5', sourcePortID: 'Or_port4', targetPortID: 'Or_port1', type: 'Orthogonal' },
{ id: '4-ExOr2', sourceID: 'NOT42', targetID: 'Exor5', sourcePortID: 'Not_port2', targetPortID: 'Or_port3', type: 'Orthogonal' },
{ id: '3-AND-OR', sourceID: 'AND31', targetID: 'OR41', sourcePortID: 'And_port4', targetPortID: 'Or_port3', type: 'Orthogonal' },
{ id: '2AND1-4AND1', sourceID: 'AND21', targetID: 'OR41', sourcePortID: 'And_port4', targetPortID: 'Or_port1', type: 'Orthogonal' },
{ id: '2OR2-3AND', sourceID: 'OR22', targetID: 'AND31', sourcePortID: 'Or_port4', targetPortID: 'And_port1', type: 'Orthogonal' },
{ id: '2AND3-3AND', sourceID: 'AND23', targetID: 'AND31', sourcePortID: 'And_port4', targetPortID: 'And_port3', type: 'Orthogonal' },
{ id: 'switch-Not42', sourceID: 'switch', targetID: 'NOT42', sourcePortID: 'port1', targetPortID: 'Not_port1', type: 'Orthogonal' },
{ id: 'Push-AND21', sourceID: 'Push', targetID: 'AND21', sourcePortID: 'port1', targetPortID: 'And_port3', type: 'Orthogonal' },
{ id: 'Push-OR22', sourceID: 'Push', targetID: 'OR22', sourcePortID: 'port1', targetPortID: 'Or_port1', type: 'Orthogonal' },
{ id: 'Push-AND23', sourceID: 'Push', targetID: 'AND23', sourcePortID: 'port1', targetPortID: 'And_port1', type: 'Orthogonal' },
{ id: 'clock-OR22', sourceID: 'clock', targetID: 'OR22', sourcePortID: 'port1', targetPortID: 'Or_port3', type: 'Orthogonal' },
{ id: 'clock-AND23', sourceID: 'clock', targetID: 'AND23', sourcePortID: 'port1', targetPortID: 'And_port3', type: 'Orthogonal' },
{ id: 'switch2-And21', sourceID: 'switch2', targetID: 'AND21', sourcePortID: 'port1', targetPortID: 'And_port1', type: 'Orthogonal' },
];
function App() {
return (<DiagramComponent id="diagram" width={'100%'} height={'700px'} nodes={nodes} connectors={connectors} rulerSettings=
constraints={DiagramConstraints.Default | DiagramConstraints.LineRouting | DiagramConstraints.AvoidLineOverlapping}
getConnectorDefaults={(connector) => {
connector.cornerRadius = 5; return connector;
}} />);
}
const root = ReactDOM.createRoot(document.getElementById('container'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import { Diagram, DiagramComponent, LineRouting, AvoidLineOverlapping, Snapping, NodeModel, ConnectorModel, DiagramConstraints, PortVisibility, PointPortModel } from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(LineRouting, AvoidLineOverlapping, Snapping);
let orData: string = 'M21.7,76.5L21.7,76.5c6.4-18.1,6.4-37.8,0-55.9l0-0.1h1.6c21.5,0,41.7,10.4,54.2,28l0,0l0,0 c-12.5,17.6-32.7,28-54.2,28H21.7z M99.5,48.5l-22,0 M0,31.5h25 M0,65.5h25';
let andData: string = 'M21.5,20.5h28a28,28,0,0,1,28,28v0a28,28,0,0,1-28,28h-28a0,0,0,0,1,0,0v-56a0,0,0,0,1,0,0Z M78,48.5 L 100,48.5Z M0,32.5 L 21.4,32.5Z M0,65.5 L 21.4,65.5Z';
let notData: string = 'M75.5,50.5l-52,28v-56L75.5,50.5z M81.5,50.5h18 M1.5,50.5h22 M78.5,47.5c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3 S80.2,47.5,78.5,47.5z';
let orPort: PointPortModel[] = [
{ id: 'Or_port1', offset: { x: 0.01, y: 0.1963 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }, { id: 'Or_port2', offset: { x: 0.26, y: 0.5 } },
{ id: 'Or_port3', offset: { x: 0.01, y: 0.805 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }, { id: 'Or_port4', offset: { x: 0.99, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }
];
let andPort: PointPortModel[] = [
{ id: 'And_port1', offset: { x: 0.01, y: 0.215 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }, { id: 'And_port2', offset: { x: 0.22, y: 0.5 } },
{ id: 'And_port3', offset: { x: 0.01, y: 0.805 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }, { id: 'And_port4', offset: { x: 0.99, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }
];
let notPort: PointPortModel[] = [
{ id: 'Not_port1', offset: { x: 0.01, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }, { id: 'Not_port2', offset: { x: 0.99, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }
];
let nodes: NodeModel[] = [
{ id: 'switch', offsetX: 80, offsetY: 50, width: 50, height: 50, ports: [{ id: 'port1', offset: { x: 1, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }], annotations: [{ content: 'A' }] },
{ id: 'Push', offsetX: 80, offsetY: 150, width: 50, height: 50, ports: [{ id: 'port1', offset: { x: 1, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }], annotations: [{ content: 'B' }] },
{ id: 'clock', offsetX: 80, offsetY: 250, width: 50, height: 50, ports: [{ id: 'port1', offset: { x: 1, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }], annotations: [{ content: 'C' }] },
{ id: 'switch2', offsetX: 80, offsetY: 350, width: 50, height: 50, ports: [{ id: 'port1', offset: { x: 1, y: 0.5 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }], annotations: [{ content: 'D' }] },
{ id: 'AND21', offsetX: 200, offsetY: 100, width: 60, height: 40, shape: { type: 'Path', data: andData }, ports: andPort },
{ id: 'OR22', offsetX: 200, offsetY: 200, width: 60, height: 40, shape: { type: 'Path', data: orData }, ports: orPort },
{ id: 'AND23', offsetX: 200, offsetY: 300, width: 60, height: 40, shape: { type: 'Path', data: andData }, ports: andPort },
{ id: 'AND31', offsetX: 300, offsetY: 250, width: 60, height: 40, shape: { type: 'Path', data: andData }, ports: andPort },
{ id: 'OR41', offsetX: 400, offsetY: 150, width: 60, height: 40, shape: { type: 'Path', data: orData }, ports: orPort },
{ id: 'NOT42', offsetX: 400, offsetY: 350, width: 60, height: 40, shape: { type: 'Path', data: notData }, ports: notPort },
{
id: 'Exor5', ports: orPort, offsetX: 500, offsetY: 250, width: 60, height: 40,
shape: {
type: 'Path', data: 'M21.7,76.5L21.7,76.5c6.4-18.1,6.4-37.8,0-55.9l0-0.1h1.6c21.5,0,41.7,10.4,54.2,28l0,0l0,0 c-12.5,17.6-32.7,28-54.2,28H21.7z M73.4,48.5L73.4,48.5 M17.5,76.8L17.5,76.8c6.7-18.2,6.7-38.1,0-56.3l0-0.1 M77.5,48.5h22 M0,32.5h21 M0,65.5h21'
},
},
{ id: 'bulb', offsetX: 600, offsetY: 150, width: 50, height: 50, ports: [{ id: 'bulbPort', offset: { x: 0.5, y: 1 }, visibility: PortVisibility.Visible, style: { fill: 'black' }, shape: 'Circle' }], annotations: [{ content: 'Out' }] }
];
let connectors: ConnectorModel[] = [
{ id: 'ExOr-Output', sourceID: 'Exor5', targetID: 'bulb', sourcePortID: 'Or_port4', targetPortID: 'bulbPort', type: 'Orthogonal' },
{ id: '4-ExOr1', sourceID: 'OR41', targetID: 'Exor5', sourcePortID: 'Or_port4', targetPortID: 'Or_port1', type: 'Orthogonal' },
{ id: '4-ExOr2', sourceID: 'NOT42', targetID: 'Exor5', sourcePortID: 'Not_port2', targetPortID: 'Or_port3', type: 'Orthogonal' },
{ id: '3-AND-OR', sourceID: 'AND31', targetID: 'OR41', sourcePortID: 'And_port4', targetPortID: 'Or_port3', type: 'Orthogonal' },
{ id: '2AND1-4AND1', sourceID: 'AND21', targetID: 'OR41', sourcePortID: 'And_port4', targetPortID: 'Or_port1', type: 'Orthogonal' },
{ id: '2OR2-3AND', sourceID: 'OR22', targetID: 'AND31', sourcePortID: 'Or_port4', targetPortID: 'And_port1', type: 'Orthogonal' },
{ id: '2AND3-3AND', sourceID: 'AND23', targetID: 'AND31', sourcePortID: 'And_port4', targetPortID: 'And_port3', type: 'Orthogonal' },
{ id: 'switch-Not42', sourceID: 'switch', targetID: 'NOT42', sourcePortID: 'port1', targetPortID: 'Not_port1', type: 'Orthogonal' },
{ id: 'Push-AND21', sourceID: 'Push', targetID: 'AND21', sourcePortID: 'port1', targetPortID: 'And_port3', type: 'Orthogonal' },
{ id: 'Push-OR22', sourceID: 'Push', targetID: 'OR22', sourcePortID: 'port1', targetPortID: 'Or_port1', type: 'Orthogonal' },
{ id: 'Push-AND23', sourceID: 'Push', targetID: 'AND23', sourcePortID: 'port1', targetPortID: 'And_port1', type: 'Orthogonal' },
{ id: 'clock-OR22', sourceID: 'clock', targetID: 'OR22', sourcePortID: 'port1', targetPortID: 'Or_port3', type: 'Orthogonal' },
{ id: 'clock-AND23', sourceID: 'clock', targetID: 'AND23', sourcePortID: 'port1', targetPortID: 'And_port3', type: 'Orthogonal' },
{ id: 'switch2-And21', sourceID: 'switch2', targetID: 'AND21', sourcePortID: 'port1', targetPortID: 'And_port1', type: 'Orthogonal' },
];
function App() {
return (<DiagramComponent id="diagram" width={'100%'} height={'700px'} nodes={nodes} connectors={connectors} rulerSettings=
constraints={DiagramConstraints.Default | DiagramConstraints.LineRouting | DiagramConstraints.AvoidLineOverlapping}
getConnectorDefaults={(connector: ConnectorModel): ConnectorModel => {
connector.cornerRadius = 5; return connector;
}} />);
}
const root = ReactDOM.createRoot(document.getElementById('container'));
root.render(<App />);<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion® React Chart-DataLabel</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-diagrams/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-navigations/styles/fabric.css" rel="stylesheet" />
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
#diagram {
display: block;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='container'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>NOTE
The
AvoidLineOverlappingfeature applies only to orthogonal connectors and requires theLineRoutingmodule to be injected with its constraints enabled.