Connectors in React Diagram component

27 Oct 202424 minutes to read

Connectors are objects used to create link between two points, nodes or ports to represent the relationships between them.

Create connector

Connector can be created by defining the source and target point of the connector. 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

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

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.

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.

The following code example illustrates how to add connectors in palette.

import * as React from "react";
import * as ReactDOM from "react-dom/client";
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 (
    <>
      <SymbolPaletteComponent
        id="symbolpalette"
        expandMode="Multiple"
        palettes={[
          {
            id: "flow",
            expanded: true,
            symbols: connectorSymbols,
            title: "Connectors",
          },
        ]}
      />
      <DiagramComponent
        id="diagram"
        width="100%"
        height="700px"
      />
    </>
  );
};

// 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/client";
import { DiagramComponent, SymbolPaletteComponent,ConnetorModel } from "@syncfusion/ej2-react-diagrams";

// Define connector symbols
let connectorSymbols:ConnetorModel[] = [
  {
    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 (
    <>
      <SymbolPaletteComponent
        id="symbolpalette"
        expandMode="Multiple"
        palettes={[
          {
            id: "flow",
            expanded: true,
            symbols: connectorSymbols,
            title: "Connectors",
          },
        ]}
      />
      <DiagramComponent
        id="diagram"
        width="100%"
        height="700px"
      />
    </>
  );
};

// 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 the diagram surface.

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/client";
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/client";
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 />);

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.

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.

The following code example illustrates how to clone a connector

import * as React from "react";
import { createRoot } from 'react-dom/client';
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 = createRoot(document.getElementById('diagram') );
root.render(<App />);
import * as React from "react";
import { createRoot } from 'react-dom/client';
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 = createRoot(document.getElementById('diagram') );
root.render(<App />);

Get Connector defaults

Get Connector defaults helps to define default properties of the connector. It is triggered when the diagram is initialized. In this event, you can customize the connector properties.

The following code example explains how to customize the connector 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 sourceID and targetID properties allow to define the nodes to be connected.

  • 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 InConnect from Default, the node accepts only an outgoing connection to dock in it. Similarly, when you remove NodeConstraints OutConnect from 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 connector to establish connection in 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 to create connections between some specific points of source/target 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 to OutConnect, 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 the diagram connectors. 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.

  • Dependency LineRouting module should be injected to the application as the following code snippet.

       import { Diagram,  LineRouting } from "@syncfusion/ej2-react-diagrams";
       /**
       * Injecting the automatic line routing module.
        */
       Diagram.Inject(LineRouting);
  • Now, the line routing constraints must be included to the default diagram constraints to enable automatic line routing support like below.

       /**
       *  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/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-diagrams/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.2.2/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.

LineRouting GIF

  • 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 constraints property 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/27.2.2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.2.2/ej2-diagrams/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.2.2/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>

See Also