Tools in React Diagram Component
21 Oct 202524 minutes to read
The React Diagram component provides a comprehensive set of interactive tools that enable users to create, modify, and navigate diagrams efficiently. These tools facilitate real-time interaction with diagram elements through mouse and keyboard operations.
Overview
The diagram control offers three primary tool categories:
- Select: Choose and manipulate specific elements within the diagram.
- Pan: Navigate the diagram view to different areas without modifying elements.
- Draw: Create new shapes, connectors, and freehand drawings on the diagram surface.
These tools are essential for building complex diagrams and provide the foundation for user interaction within the diagram environment.
Drawing Tools
Drawing tools enable real-time creation of diagram elements by clicking and dragging on the diagram canvas. All drawing operations are configured through the drawingObject property and activated using the tool property.
Draw Nodes
To draw shapes during runtime, configure the JSON representation of the desired shape in the drawingObject property and set the tool to drawing mode. The following example demonstrates how to draw a rectangle shape:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramTools, DiagramComponent } from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
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 {
BasicShapeModel,
NodeModel,
DiagramTools,
DiagramComponent,
} from '@syncfusion/ej2-react-diagrams';
let diagramInstance: DiagramComponent;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
//JSON to create a rectangle
let drawingshape: BasicShapeModel = {
type: 'Basic',
shape: 'Rectangle',
};
let node: NodeModel = {
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 />);Path shapes can be drawn using the same approach with custom path data. The following example shows how to draw a path shape:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
DiagramTools,
DiagramComponent,
} from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
let node = {
id: "Path",
style: {
fill: "#fbe172"
},
annotations: [{
content: "Path"
}],
shape: {
type: 'Path',
data: 'M13.560 67.524 L 21.941 41.731 L 0.000 25.790 L 27.120 25.790 L 35.501 0.000 L 43.882 25.790 L 71.000 25.790 L 49.061 41.731 L 57.441 67.524 L 35.501 51.583 z'
}
};
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 {
NodeModel,
DiagramTools,
DiagramComponent,
} from '@syncfusion/ej2-react-diagrams';
let diagramInstance: DiagramComponent;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
let node: NodeModel = {
id: "Path",
style: {
fill: "#fbe172"
},
annotations: [{
content: "Path"
}],
shape: {
type: 'Path',
data: 'M13.560 67.524 L 21.941 41.731 L 0.000 25.790 L 27.120 25.790 L 35.501 0.000 L 43.882 25.790 L 71.000 25.790 L 49.061 41.731 L 57.441 67.524 L 35.501 51.583 z'
}
};
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 />);Text Nodes
Similarly, you can draw a text node by setting the type of shape as ‘Text’ in the drawingObject property. The text node includes a content property that defines the displayed text. Users can add or modify the content after completing the drawing operation:
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
DiagramTools,
DiagramComponent
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
//JSON to create a text
let node = {
shape: {
type: 'Text',
}
};
diagramInstance.drawingObject = node;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.DrawOnce;
diagramInstance.dataBind();
}}
//customize the appearance of the shape
getNodeDefaults={(obj, diagramInstance) => {
obj.borderWidth = 1;
obj.style = {
fill: '#6BA5D7',
strokeWidth: 2,
strokeColor: '#6BA5D7',
};
return obj;
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
TextModel,
NodeModel,
DiagramTools,
DiagramComponent
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
//JSON to create a text
let node: NodeModel = {
shape: {
type: 'Text',
} as TextModel
};
diagramInstance.drawingObject = node;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.DrawOnce;
diagramInstance.dataBind();
}}
//customize the appearance of the shape
getNodeDefaults={(obj, diagramInstance) => {
obj.borderWidth = 1;
obj.style = {
fill: '#6BA5D7',
strokeWidth: 2,
strokeColor: '#6BA5D7',
};
return obj;
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Draw Connectors
Connectors are drawn by defining the connector configuration in the drawingObject property. The drawing tool supports various connector types including straight, orthogonal, and bezier connectors:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
DiagramTools,
DiagramComponent,
} from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
//JSON to create a Connector
let connectors = {
id: 'connector1',
type: 'Straight',
segments: [
{
type: 'polyline',
},
],
};
diagramInstance.drawingObject = connectors;
//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 {
ConnectorModel,
DiagramTools,
DiagramComponent,
} from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
//JSON to create a Connector
let connectors: ConnectorModel = {
id: 'connector1',
type: 'Straight',
segments: [
{
type: 'polyline',
},
],
};
diagramInstance.drawingObject = connectors;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.ContinuousDraw;
diagramInstance.dataBind();
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);Polygon Shapes
The diagram supports interactive polygon creation through point-and-click interaction. Users can define custom shapes with multiple sides by specifying vertices directly on the diagram canvas. To enable polygon drawing, set the drawingObject type as Polygon:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
DiagramTools,
DiagramComponent,
} from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
let drawingshape = {
type: 'Basic',
shape: 'Polygon',
};
//JSON to create a polygon
let node = {
shape: drawingshape,
};
diagramInstance.drawingObject = node;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.DrawOnce;
diagramInstance.dataBind();
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
Polyline Connectors
Polyline connectors enable creation of multi-segment connections with straight lines and angled vertices. Users can interactively add control points by clicking on the diagram canvas. To draw polyline connectors, set the drawingObject type as Polyline:
The following code illustrates how to draw a polyline connector.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
DiagramTools,
DiagramComponent,
} from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
let connector = {
id: 'connector1',
type: 'Polyline',
};
diagramInstance.drawingObject = connector;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.DrawOnce;
diagramInstance.dataBind();
}}
//customize the appearance of the shape
getNodeDefaults={(obj, diagramInstance) => {
obj.borderWidth = 1;
obj.style = {
fill: '#6BA5D7',
strokeWidth: 2,
strokeColor: '#6BA5D7',
};
return obj;
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
ConnectorModel,
DiagramTools,
DiagramComponent
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created = {
() => {
let connector: ConnectorModel = {
id: 'connector1',
type: 'Polyline'
};
diagramInstance.drawingObject = connector;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.DrawOnce;
diagramInstance.dataBind();
}
}
//customize the appearance of the shape
getNodeDefaults={(obj, diagramInstance) => {
obj.borderWidth = 1;
obj.style = {
fill: '#6BA5D7',
strokeWidth: 2,
strokeColor: '#6BA5D7',
};
return obj;
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);The segments of a polyline connector can be adjusted at runtime by dragging the segment thumb, as shown in the image below. To enable segment editing, you should set the DragSegmentThumb constraint for the connector.

NOTE
To make the segment thumb visible, inject the
ConnectorEditingmodule into the diagram.
Freehand Drawing
The diagram supports free-hand drawing, allowing users to draw anything independently on the diagram page. Free-hand drawing is enabled by setting the type of the drawingObject property to ‘Freehand’.
The following code illustrates how to perform freehand drawing:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramTools, DiagramComponent } from '@syncfusion/ej2-react-diagrams';
let diagramInstance;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
//JSON to create a Connector
let connectors = {
id: 'connector1',
type: 'Freehand',
};
diagramInstance.drawingObject = connectors;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.DrawOnce;
diagramInstance.dataBind();
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
ConnectorModel,
DiagramTools,
DiagramComponent
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
//JSON to create a Connector
let connectors: ConnectorModel = {
id: 'connector1',
type: 'Freehand',
};
diagramInstance.drawingObject = connectors;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.DrawOnce;
diagramInstance.dataBind();
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);The segments of a freehand connector can be adjusted at runtime by dragging the segment thumb, as shown in the image below. To enable segment editing, you should set the DragSegmentThumb constraint for the connector.

Tool Selection and Precedence
The diagram supports multiple tool configurations that can be combined for different interaction scenarios. When multiple tools are enabled simultaneously, the system follows a specific precedence order to determine which tool takes priority:
Tool Precedence Hierarchy
The following table shows the precedence order from highest to lowest priority:
| Precedence | Tool | Description |
|---|---|---|
| 1st | ContinuesDraw | Enables continuous drawing mode. Once activated, prevents all other interactions until deactivated. |
| 2nd | DrawOnce | Allows drawing a single element. After completion, automatically enables SingleSelect and MultipleSelect tools. |
| 3rd | ZoomPan | Enables diagram panning. When combined with SingleSelect, panning activates when cursor hovers over empty diagram areas. |
| 4th | MultipleSelect | Enables selection of multiple elements. When combined with ZoomPan, selection takes priority over panning when hovering over elements. |
| 5th | SingleSelect | Enables selection of individual elements. |
| 6th | None | Disables all interactive tools. |
These tools provide flexibility and functionality for creating and interacting with elements within the diagram interface.
Zoom Pan Tool
The pan tool enables users to navigate large diagrams by dragging the view area. To activate panning mode, set the tool property to ZoomPan:
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
DiagramComponent,
DiagramTools,
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
let nodes = [{
id: 'Start',
width: 140,
height: 50,
offsetX: 300,
offsetY: 50,
annotations: [{
id: 'label1',
content: 'Start'
}],
shape: {
type: 'Flow',
shape: 'Terminator'
}
},
{
id: 'Init',
width: 140,
height: 50,
offsetX: 300,
offsetY: 140,
annotations: [{
id: 'label2',
content: 'End'
}],
shape: {
type: 'Flow',
shape: 'Process'
},
annotations: [{
content: 'var i = 0;'
}]
}
];
let connectors = [{
// Name of the connector
id: "connector1",
style: {
strokeColor: '#6BA5D7',
fill: '#6BA5D7',
strokeWidth: 2
},
targetDecorator: {
style: {
fill: '#6BA5D7',
strokeColor: '#6BA5D7'
}
},
// ID of the source and target nodes
sourceID: "Start",
targetID: "Init",
connectorSpacing: 7,
type: 'Orthogonal'
}];
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
nodes={nodes}
connectors={connectors}
tool={DiagramTools.DrawOnce | DiagramTools.ZoomPan}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
DiagramComponent,
DiagramTools,
ConnectorModel,
NodeModel,
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
let nodes: NodeModel[] = [{
id: 'Start',
width: 140,
height: 50,
offsetX: 300,
offsetY: 50,
annotations: [{
id: 'label1',
content: 'Start'
}],
shape: {
type: 'Flow',
shape: 'Terminator'
}
},
{
id: 'Init',
width: 140,
height: 50,
offsetX: 300,
offsetY: 140,
annotations: [{
id: 'label2',
content: 'End'
}],
shape: {
type: 'Flow',
shape: 'Process'
},
annotations: [{
content: 'var i = 0;'
}]
}
];
let connectors: ConnectorModel[] = [{
// Name of the connector
id: "connector1",
style: {
strokeColor: '#6BA5D7',
fill: '#6BA5D7',
strokeWidth: 2
},
targetDecorator: {
style: {
fill: '#6BA5D7',
strokeColor: '#6BA5D7'
}
},
// ID of the source and target nodes
sourceID: "Start",
targetID: "Init",
connectorSpacing: 7,
type: 'Orthogonal'
}];
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
nodes={nodes}
connectors={connectors}
tool={DiagramTools.DrawOnce | DiagramTools.ZoomPan}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);NOTE
Please note that panning the diagram is not possible when ‘multiplePage’ is set to false if any diagram object (node or connector) is outside the defined page break area.
Events
The elementDraw event triggers whenever users create nodes or connectors using drawing tools. This event provides access to the newly created element and enables custom logic during the drawing process:
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
DiagramComponent,
DiagramTools
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
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.DrawOnce;
diagramInstance.dataBind();
}}
elementDraw={(args) => {
if(args.state === 'Completed'){
alert('Element Draw Rectangle');
}
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);import * as React from "react";
import * as ReactDOM from "react-dom";
import {
NodeModel,
DiagramTools,
DiagramComponent,
BasicShapeModel,
IElementDrawEventArgs
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
function App() {
return (
<DiagramComponent
id="container"
ref={(diagram) => (diagramInstance = diagram)}
width={700}
height={700}
created={() => {
//JSON to create a rectangle
let drawingshape: BasicShapeModel = {
type: 'Basic',
shape: 'Rectangle',
};
let node: NodeModel = {
shape: drawingshape,
};
diagramInstance.drawingObject = node;
//To draw an object once, activate draw once
diagramInstance.tool = DiagramTools.DrawOnce;
diagramInstance.dataBind();
}}
elementDraw={(args: IElementDrawEventArgs) => {
if(args.state === 'Completed'){
alert('Element Draw Rectangle');
}
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);