Nodes in React Diagram Component
21 Oct 202524 minutes to read
Nodes are graphical objects that visually represent entities, processes, data flow, or any business logic within diagrams. They serve as the fundamental building blocks for creating flowcharts, organizational charts, network diagrams, and other visual representations. Each node can be customized with different shapes, sizes, colors, and interactive behaviors to suit specific diagram requirements.

Node Fundamentals
Before creating nodes, understanding their core properties helps in effective diagram development:
-
Position: Defined by
offsetXandoffsetYproperties for precise placement. -
Size: Controlled through
widthandheightproperties. -
Identification: Each node requires a unique
idfor runtime operations. - Stacking: Nodes are layered from bottom to top based on addition order.
Creating Nodes
Add Nodes through Nodes Collection
To create a node, define the node object and add it to the nodes collection of the diagram model. The id property serves as the unique identifier for runtime operations and customization.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
// A node is created and stored in nodes array.
let node = [{
// Position of the node
offsetX: 250,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
style: {
fill: '#6BA5D7',
strokeColor: 'white'
},
// Text(label) added to the node
}];
// initialize Diagram component
function App() {
return (<DiagramComponent id="container" width={'100%'} height={'600px'}
// Add node
nodes={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
} from "@syncfusion/ej2-react-diagrams";
// A node is created and stored in nodes array.
let node: NodeModel[] = [{
// Position of the node
offsetX: 250,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
style: {
fill: '#6BA5D7',
strokeColor: 'white'
},
// Text(label) added to the node
}];
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
// Add node
nodes={node}
// render initialized Diagram
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);NOTE
Node id should not begin with numbers(should begin with a letter). Node Id should be unique for all the shapes and connectors.
Create Node from Data Source
Nodes can be generated automatically using the dataSource property. Default properties for these nodes are retrieved from(getNodeDefaults) settings. For detailed information about data binding, refer to DataBinding.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
DiagramComponent,
Inject,
DataBinding,
} from '@syncfusion/ej2-react-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';
let diagramInstance;
let data = [
{
id: 'data1',
parent: null,
},
];
let items = new DataManager(data, new Query().take(7));
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'100%'}
height={'700px'}
getNodeDefaults={(node) => {
node.height = 100;
node.width = 100;
node.offsetX = 300;
node.offsetY = 200;
node.style = { fill: 'yellow', strokeColor: 'yellow' };
return node;
}}
dataSourceSettings=
>
<Inject services={[DataBinding]} />
</DiagramComponent>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
DiagramComponent,
Inject,
DataBinding,
} from '@syncfusion/ej2-react-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';
let diagramInstance: DiagramComponent;
let data: any = [
{
id: 'data1',
parent: null,
},
];
let items: any = new DataManager(data, new Query().take(7));
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'100%'}
height={'700px'}
getNodeDefaults={(node) => {
node.height = 100;
node.width = 100;
node.offsetX = 300;
node.offsetY = 200;
node.style = { fill: 'yellow', strokeColor: 'yellow' };
return node;
}}
dataSourceSettings=
>
<Inject services={[DataBinding]} />
</DiagramComponent>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Add Nodes from Symbol Palette
Nodes can be predefined in a symbol palette and dragged into the diagram as needed. This approach provides users with a library of reusable components. For comprehensive guidance on symbol palette integration, refer to Symbol Palette.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, SymbolPalette,
SymbolPaletteComponent, } from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
let node = [
{
// Position of the node
offsetX: 250,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
},
];
export function getBasicShapes() {
let basicShapes = [
{
id: "Rectangle",
shape: {
type: "Basic",
shape: "Rectangle",
},
height: 100,
width: 100
},
];
return basicShapes;
}
// initialize Diagram component
function App() {
return (
<div style={{width:'100%'}}>
<div style={{float: 'left', width:'30%'}}>
<SymbolPaletteComponent id="palette" width={'100%'} height={"700px"}
palettes={[
{
id: 'basic',
title: 'Basic Shapes',
symbols: getBasicShapes(),
},
]}
//Specifies the size of the symbol
symbolHeight={80} symbolWidth={80}
//Sets the space to be left around a symbol
symbolMargin={{
left: 15,
right: 15,
top: 0,
bottom: 15,
}} />
</div>
<div style={{float: 'right', width:'70%'}}>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'70%'}
height={'700px'}
nodes={node}
/>
</div>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent,
SymbolPaletteComponent, NodeModel } from '@syncfusion/ej2-react-diagrams';
let diagramInstance: DiagramComponent;
let node: NodeModel[] = [
{
// Position of the node
offsetX: 250,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
},
];
export function getBasicShapes() {
let basicShapes = [
{
id: "Rectangle",
shape: {
type: "Basic",
shape: "Rectangle",
},
height: 100,
width: 100
},
];
return basicShapes;
}
// initialize Diagram component
function App() {
return (
<div style={{width:'100%'}}>
<div style={{float: 'left', width:'30%'}}>
<SymbolPaletteComponent id="palette" width={'100%'} height={"700px"}
palettes={[
{
id: 'basic',
title: 'Basic Shapes',
symbols: getBasicShapes(),
},
]}
//Specifies the size of the symbol
symbolHeight={80} symbolWidth={80}
//Sets the space to be left around a symbol
symbolMargin={{
left: 15,
right: 15,
top: 0,
bottom: 15,
}} />
</div>
<div style={{float: 'right', width:'70%'}}>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'70%'}
height={'700px'}
nodes={node}
/>
</div>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Draw Nodes Interactively
To enable interactive node drawing, activate the drawing tool by setting DrawOnce or ContinuousDraw to the tool property and configure the node template using the drawingObject property.
The following code example illustrates how to draw a rectangle at runtime.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, DiagramTools } from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'100%'}
height={'700px'}
created={() => {
//JSON to create a rectangle
let drawingshape = {
type: 'Basic',
shape: 'Rectangle',
};
let node = {
shape: drawingshape,
};
diagramInstance.drawingObject = node;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.ContinuousDraw;
diagramInstance.dataBind();
}}
/>
);
}
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';
let diagramInstance: DiagramComponent;
// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'100%'}
height={'700px'}
created={() => {
//JSON to create a rectangle
let drawingshape = {
type: 'Basic',
shape: 'Rectangle',
};
let node = {
shape: drawingshape,
};
diagramInstance.drawingObject = node;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.ContinuousDraw;
diagramInstance.dataBind();
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Runtime Node Operations
Add and Remove Individual Nodes
Nodes can be dynamically added using the add method and removed using the remove method. Both operations trigger the collectionChange event, allowing for custom handling of diagram modifications.
The following code illustrates how to add a node.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent } from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
let node = [
{
// Position of the node
offsetX: 250,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
},
];
// initialize Diagram component
function App() {
const add = () => {
diagramInstance.add(node[0]);
};
const remove = () => {
diagramInstance.remove(diagramInstance.nodes[0]);
};
return (
<div>
<button onClick={add}>Add Node</button>
<button onClick={remove}>Remove Node</button>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'100%'}
height={'600px'}
/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, NodeModel } from '@syncfusion/ej2-react-diagrams';
let diagramInstance: DiagramComponent;
let node: NodeModel[] = [
{
// Position of the node
offsetX: 250,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
},
];
// initialize Diagram component
function App() {
const add = () => {
diagramInstance.add(node[0]);
};
const remove = () => {
diagramInstance.remove(diagramInstance.nodes[0]);
};
return (
<div>
<button onClick={add}>Add Node</button>
<button onClick={remove}>Remove Node</button>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'100%'}
height={'600px'}
/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Add Multiple Nodes Simultaneously
Collections of nodes can be efficiently added using theaddElements method. This approach is optimal for bulk operations and triggers the collectionChange event for each added element.
The following code illustrates how to add nodes collection at run time.
import * as React from "react";
import * as ReactDOM from "react-dom";
import {DiagramComponent }from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// initialize nodes collection
var node = [
{ id: 'node1', offsetX: 140, offsetY: 250 ,annotations: [{ content: 'node1' }]},
{ id: 'node2', offsetX: 250, offsetY: 250 ,annotations: [{ content: 'node2' }]},
{ id: 'node3', offsetX: 360, offsetY: 250 ,annotations: [{ content: 'node3' }]}
];
// initialize Diagram component
function App() {
return (<DiagramComponent id="container" ref={(diagram) => (diagramInstance = diagram)} width={'1500px'} height={'600px'}
getNodeDefaults={(node) => {
node.height = 100;
node.width = 100;
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}}
created={() => {
// Add collection of nodes
diagramInstance.addElements(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} from "@syncfusion/ej2-react-diagrams";
let diagramInstance:DiagramComponent;
//initialize node collection
var node:NodeModel= [
{ id: 'node1', offsetX: 35, offsetY: 260 ,annotations: [{ content: 'node1' }]},
{ id: 'node2', offsetX: 140, offsetY: 260 ,annotations: [{ content: 'node2' }]},
{ id: 'node3', offsetX: 240, offsetY: 260 ,annotations: [{ content: 'node3' }]}
];// initialize Diagram component
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={'1500px'}
height={'600px'}
getNodeDefaults={(node: NodeModel) => {
node.height = 100;
node.width = 100;
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}}
created={() => {
// Add collection of nodes
diagramInstance.addElements(node);
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Update Node Properties
Node properties can be modified at runtime with immediate visual updates. Changes take effect instantly, allowing for dynamic diagram manipulation based on user interactions or data updates.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent } from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
let node = [
{
// Position of the node
offsetX: 250,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
style: { fill: '#6AA8D7',strokeWidth:1},
},
];
// initialize Diagram component
function App() {
const color = () => {
if(diagramInstance.nodes[0].style.fill === '#6AA8D7'){
diagramInstance.nodes[0].style.fill = 'orange';
}
else{
diagramInstance.nodes[0].style.fill = '#6AA8D7';
}
};
const size = () => {
if(diagramInstance.nodes[0].width === 100){
diagramInstance.nodes[0].width = 200;
}
else{
diagramInstance.nodes[0].width =100;
}
};
return (
<div>
<button onClick={color}>Change Color</button>
<button onClick={size}>Change Size</button>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
nodes={node}
width={'100%'}
height={'600px'}
/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, NodeModel } from '@syncfusion/ej2-react-diagrams';
let diagramInstance: DiagramComponent;
let node: NodeModel[] = [
{
// Position of the node
offsetX: 250,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
style: { fill: '#6AA8D7',strokeWidth:1},
},
];
// initialize Diagram component
function App() {
const color = () => {
if(diagramInstance.nodes[0].style.fill === '#6AA8D7'){
diagramInstance.nodes[0].style.fill = 'orange';
}
else{
diagramInstance.nodes[0].style.fill = '#6AA8D7';
}
};
const size = () => {
if(diagramInstance.nodes[0].width === 100){
diagramInstance.nodes[0].width = 200;
}
else{
diagramInstance.nodes[0].width =100;
}
};
return (
<div>
<button onClick={color}>Change Color</button>
<button onClick={size}>Change Size</button>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
nodes={node}
width={'100%'}
height={'600px'}
/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);NOTE
Call the
dataBinddataBindmethod after property updates to ensure immediate reflection of changes.
Clone Node at Runtime
Node cloning creates new instances with identical properties and attributes. Use the copy and paste methods to duplicate existing nodes programmatically.
The following code example illustrates how to clone node at runtime
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent } from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
let node = [
{
// Position of the node
offsetX: 250,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
style: { fill: '#6AA8D7', strokeWidth: 1 },
},
];
// initialize Diagram component
function App() {
const clone = () => {
let selectedNode =
diagramInstance.selectedItems.nodes.length > 0
? diagramInstance.selectedItems.nodes[0]
: diagramInstance.nodes[0];
diagramInstance.select([selectedNode]);
diagramInstance.copy();
diagramInstance.paste();
};
return (
<div>
<button onClick={clone}>Clone Node</button>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
nodes={node}
width={'100%'}
height={'600px'}
/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, NodeModel } from '@syncfusion/ej2-react-diagrams';
let diagramInstance: DiagramComponent;
let node: NodeModel[] = [
{
// Position of the node
offsetX: 250,
offsetY: 250,
// Size of the node
width: 100,
height: 100,
style: { fill: '#6AA8D7',strokeWidth:1},
},
];
// initialize Diagram component
function App() {
const clone = () => {
let selectedNode =
diagramInstance.selectedItems.nodes.length > 0
? diagramInstance.selectedItems.nodes[0]
: diagramInstance.nodes[0];
diagramInstance.select([selectedNode]);
diagramInstance.copy();
diagramInstance.paste();
};
return (
<div>
<button onClick={clone}>Clone Node</button>
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
nodes={node}
width={'100%'}
height={'600px'}
/>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Advanced Node Integration
Import Nodes from External Components
Custom dragEnter functionality enables conversion of elements from other components, such as tree views, into diagram nodes based on the dragged element’s data properties.