Interactive Port Features in React Diagram Component
Ports in React Diagram components support various interactive features that enhance user workflow and diagram creation efficiency. This guide covers drawing connectors from ports, drag functionality, automatic port creation, tooltips, and event handling.
Draw Connector from Port
Ports can serve as connection points for creating connectors dynamically. Enable the Draw constraint on the constraints property to allow users to draw connectors directly from ports. The default connector segment type is Orthogonal, providing structured, right-angled connections suitable for flowcharts and organizational diagrams.
The following code explains how to draw the connector by using the port constraints.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, PortVisibility, PortConstraints } from "@syncfusion/ej2-react-diagrams";
let nodes = [
{
id: 'node1',
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
ports: [
{
offset: { x: 1, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
],
},
];
let connectors = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 300, y: 120 },
type: 'Orthogonal',
ports: [
{
offset: 0.5,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
],
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent id="container" width={'100%'} height={'600px'} nodes={nodes} 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, PortVisibility, PortConstraints, NodeModel, ConnectorModel } from "@syncfusion/ej2-react-diagrams";
let nodes: NodeModel[]= [
{
id: 'node1',
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
ports: [
{
offset: { x: 1, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
],
},
];
let connectors: ConnectorModel[] = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 300, y: 120 },
type: 'Orthogonal',
ports: [
{
offset: 0.5,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
],
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent id="container" width={'100%'} height={'600px'} nodes={nodes} connectors={connectors} />);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Draw Different Connector Types from Port
The default connector type can be customized when drawing from ports by configuring connector defaults. This flexibility allows creation of various connector styles to match different diagram requirements:
- Straight: Direct linear connections for simple relationships.
- Bezier: Curved connections for organic, flowing designs.
- Orthogonal: Right-angled connections for structured layouts.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, PortVisibility, PortConstraints} from "@syncfusion/ej2-react-diagrams";
let nodes = [
{
id: 'node1',
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
ports: [
{
offset: { x: 1, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
],
},
];
let connectors = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 300, y: 120 },
type: 'Orthogonal',
ports: [
{
offset: 0.5,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
],
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
connectors={connectors}
getConnectorDefaults={function (connector) {
connector.type = 'Bezier';
return connector;
}}
/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, PortVisibility, PortConstraints,NodeModel, ConnectorModel } from "@syncfusion/ej2-react-diagrams";
let nodes: NodeModel[] = [
{
id: 'node1',
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
ports: [
{
offset: { x: 1, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
],
},
];
let connectors: ConnectorModel[] = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 300, y: 120 },
type: 'Orthogonal',
ports: [
{
offset: 0.5,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
],
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
connectors={connectors}
getConnectorDefaults={function (connector) {
connector.type = 'Bezier';
return connector;
}}
/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Port Drag
Port drag functionality enables users to reposition ports by clicking and dragging with the mouse. This feature enhances diagram flexibility by allowing dynamic port placement adjustments. Enable this capability by setting the port constraints to Drag.
The following code explains how to enable port drag.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, PortVisibility, PortConstraints } from "@syncfusion/ej2-react-diagrams";
let nodes = [
{
id: 'node1',
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
annotations: [{ content: 'Click and drag the port' }],
ports: [
{
offset: { x: 1, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Drag,
},
],
},
];
let connectors = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 300, y: 120 },
type: 'Orthogonal',
ports: [
{
offset: 0.5,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Drag,
},
],
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
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, PortVisibility, PortConstraints, NodeModel, ConnectorModel } from "@syncfusion/ej2-react-diagrams";
let nodes: NodeModel[] = [
{
id: 'node1',
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
annotations: [{ content: 'Click and drag the port' }],
ports: [
{
offset: { x: 1, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Drag,
},
],
},
];
let connectors: ConnectorModel[] = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 300, y: 120 },
type: 'Orthogonal',
ports: [
{
offset: 0.5,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Drag,
},
],
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
connectors={connectors}
/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Automatic Port Creation
The Diagram component supports dynamic port creation through user interaction. Users can create ports on nodes or connectors by clicking and dragging while holding the Control (Ctrl) key. This feature is disabled by default and requires enabling the DiagramConstraints.AutomaticPortCreation constraint.
Ports can also be removed using the same Ctrl + Click interaction, provided the port is not connected to any connector. This prevents accidental disconnection of active connections.
The following example shows how to enable automatic port creation:
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, NodeConstraints, DiagramConstraints, SnapConstraints } from "@syncfusion/ej2-react-diagrams";
const nodes = [
{
id: 'node1', width: 100, height: 100, offsetX: 150, offsetY: 200, style: { fill: 'cornflowerblue' },
constraints: NodeConstraints.Default &
~(NodeConstraints.InConnect | NodeConstraints.OutConnect)
},
{
id: 'node2', width: 100, height: 100, offsetX: 400, offsetY: 200, style: { fill: 'cornflowerblue' },
constraints: NodeConstraints.Default &
~(NodeConstraints.InConnect | NodeConstraints.OutConnect)
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'} height={'500px'}
nodes={nodes} snapSettings=
constraints={
DiagramConstraints.Default |
DiagramConstraints.AutomaticPortCreation
}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, NodeModel, NodeConstraints, DiagramConstraints, SnapConstraints } from "@syncfusion/ej2-react-diagrams";
const nodes: NodeModel[] = [
{
id: 'node1', width: 100, height: 100, offsetX: 150, offsetY: 200, style: { fill: 'cornflowerblue' },
constraints: NodeConstraints.Default &
~(NodeConstraints.InConnect | NodeConstraints.OutConnect)
},
{
id: 'node2', width: 100, height: 100, offsetX: 400, offsetY: 200, style: { fill: 'cornflowerblue' },
constraints: NodeConstraints.Default &
~(NodeConstraints.InConnect | NodeConstraints.OutConnect)
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'} height={'500px'}
nodes={nodes} snapSettings=
constraints={
DiagramConstraints.Default |
DiagramConstraints.AutomaticPortCreation
}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Port Tooltip
Port tooltips provide contextual information when users hover over ports, improving usability and user guidance. Enable this feature by setting the port constraints to Tooltip.
The following code explains how to enable port tooltip.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, PortVisibility, PortConstraints } from "@syncfusion/ej2-react-diagrams";
let nodes = [
{
id: 'node1',
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
annotations: [{ content: 'Hover over port to see tooltip'}],
ports: [
{
offset: { x: 1, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.ToolTip,
tooltip: { content: 'node port tooltip' },
},
],
},
];
let connectors = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 300, y: 120 },
type: 'Orthogonal',
ports: [
{
offset: 0.5,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.ToolTip,
tooltip: { content: 'connector port tooltip' },
},
],
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
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, PortVisibility, PortConstraints, NodeModel, ConnectorModel } from "@syncfusion/ej2-react-diagrams";
let nodes: NodeModel[] = [
{
id: 'node1',
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
annotations: [{ content: 'Hover over port to see tooltip'}],
ports: [
{
offset: { x: 1, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.ToolTip,
tooltip: { content: 'node port tooltip' },
},
],
},
];
let connectors: ConnectorModel[] = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 300, y: 120 },
type: 'Orthogonal',
ports: [
{
offset: 0.5,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.ToolTip,
tooltip: { content: 'connector port tooltip' },
},
],
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
connectors={connectors}
/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Events
Port interactions trigger specific events that enable custom handling and application logic. These events provide hooks for implementing validation, logging, or custom behaviors during port operations.
| Event | Description |
|---|---|
Click |
Triggers when the port is clicked. |
Element Draw |
Triggers when drawing a connector from the port. |
Position Change |
Triggers when the port is dragged. |
Connection Change |
Triggers when a connector is connected or disconnected from the port |
The following example shows how to get these events in diagram.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, PortVisibility, PortConstraints, Connector } from "@syncfusion/ej2-react-diagrams";
let nodes = [
{
id: 'node1',
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
annotations: [
{ content: 'draw port', offset: { x: 0, y: 0.7 } },
{ content: 'drag port', offset: { x: 1, y: 0.7 } },
],
ports: [
{
id: 'p1',
offset: { x: 0, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
{
id: 'p2',
offset: { x: 1, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Drag,
},
],
},
];
let connectors = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 300, y: 120 },
type: 'Orthogonal',
annotations: [
{
content: 'draw port',
alignment: 'After',
displacement: { x: 0, y: 10 },
},
{
content: 'drag port',
alignment: 'After',
offset: 0.7,
displacement: { x: 0, y: 10 },
},
],
ports: [
{
id: 'p1',
offset: 0.5,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
{
id: 'p2',
offset: 0.8,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Drag,
},
],
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
connectors={connectors}
click={(args) => {
console.log('clicked')
}}
positionChange={(args) => {
console.log('PositionChange')
}}
connectionChange={(args) => {
console.log('connectionChange')
}}
elementDraw={(args) => {
//Prevents connector drawn from connector port
if (args.state === 'Start' && args.source instanceof Connector) {
args.cancel = true;
}
}}
/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent, PortVisibility, PortConstraints, Connector, NodeModel, ConnectorModel, IConnectionChangeEventArgs,IDraggingEventArgs, IElementDrawEventArgs, IClickEventArgs } from "@syncfusion/ej2-react-diagrams";
let nodes: NodeModel[] = [
{
id: 'node1',
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
annotations: [
{ content: 'draw port', offset: { x: 0, y: 0.7 } },
{ content: 'drag port', offset: { x: 1, y: 0.7 } },
],
ports: [
{
id: 'p1',
offset: { x: 0, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
{
id: 'p2',
offset: { x: 1, y: 0.5 },
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Drag,
},
],
},
];
let connectors: ConnectorModel[] = [
{
id: 'connector1',
sourcePoint: { x: 100, y: 100 },
targetPoint: { x: 300, y: 120 },
type: 'Orthogonal',
annotations: [
{
content: 'draw port',
alignment: 'After',
displacement: { x: 0, y: 10 },
},
{
content: 'drag port',
alignment: 'After',
offset: 0.7,
displacement: { x: 0, y: 10 },
},
],
ports: [
{
id: 'p1',
offset: 0.5,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Draw,
},
{
id: 'p2',
offset: 0.8,
visibility: PortVisibility.Visible,
constraints: PortConstraints.Default | PortConstraints.Drag,
},
],
},
];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
connectors={connectors}
click={(args: IClickEventArgs ) => {
console.log('clicked')
}}
positionChange={(args: IDraggingEventArgs) => {
console.log('PositionChange')
}}
connectionChange={(args: IConnectionChangeEventArgs) => {
console.log('connectionChange')
}}
elementDraw={(args: IElementDrawEventArgs) => {
//Prevents connector drawn from connector port
if (args.state === 'Start' && args.source instanceof Connector) {
args.cancel = true;
}
}}
/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);