Bezier Connectors in EJ2 React Diagram control
6 Dec 202424 minutes to read
Bezier segments are used to create curve segments and the curves are configurable either with the control points or with vectors.
To create a bezier segment, the segment.type
is set as bezier
and need to specify type
for the connector.
The following code example illustrates how to create a default bezier segment.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let connectors = [{
id: 'connector1',
type: 'Bezier',
segments: [{
// Defines the type of the segment
type: 'Bezier',
}],
sourcePoint: {
x: 50,
y: 100
},
targetPoint: {
x: 150,
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[] = [{
id: 'connector1',
type: 'Bezier',
segments: [{
// Defines the type of the segment
type: 'Bezier',
}],
sourcePoint: {
x: 50,
y: 100
},
targetPoint: {
x: 150,
y: 200
},
}];
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
connectors={connectors}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
Bezier segment editing
- A segment control point of the Bezier connector is used to change the bezier vectors and points of the connector.
Control Points
-
Bezier control points can be positioned in two ways.
- When setting control point positions using the The
point1
andpoint2
properties, the control point remains fixed in its set position while dragging connector end points. - When setting control point positions using the
vector1
andvector2
properties, the control point dynamically adjusts to maintain the angle and distance originally set while moving the connector end points.
Point
The point1
and point2
properties of bezier segment enable you to set the control points. The following code example illustrates how to configure the bezier segments with control points.
import * as React from "react";
import * as ReactDOM from "react-dom";
import {DiagramComponent, Diagram, ConnectorEditing } from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(ConnectorEditing)
let connectors = [
{
id: 'connector3',
type: 'Bezier',
segments: [{
type: 'Bezier',
// First control point: an absolute position from the page origin
point1: {
x: 100,
y: 100
},
// Second control point: an absolute position from the page origin
point2: {
x: 200,
y: 200
}
}],
sourcePoint: {
x: 100,
y: 200
},
targetPoint: {
x: 200,
y: 100
},
}
];
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 {
Diagram,
DiagramComponent,
ConnectorModel, ConnectorEditing
} from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(ConnectorEditing)
let connectors: ConnectorModel[] = [
{
id: 'connector3',
type: 'Bezier',
segments: [{
type: 'Bezier',
// First control point: an absolute position from the page origin
point1: {
x: 100,
y: 100
},
// Second control point: an absolute position from the page origin
point2: {
x: 200,
y: 200
}
}],
sourcePoint: {
x: 100,
y: 200
},
targetPoint: {
x: 200,
y: 100
},
}
];
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
connectors={connectors}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
Vector
The vector1
and vector2
properties of bezier segment enable you to define the vectors. The following code illustrates how to configure a bezier curve with vectors.
import * as React from "react";
import * as ReactDOM from "react-dom";
import {DiagramComponent, Diagram, ConnectorEditing } from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(ConnectorEditing)
let connectors = [{
id: 'connector2',
// Defines the type of the segment
type: 'Bezier',
segments: [{
type: 'Bezier',
// Length and angle between the source point and the first control point
vector1: {
distance: 100,
angle: 90
},
// Length and angle between the target point and the second control point
vector2: {
distance: 45,
angle: 270
}
}],
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 {
Diagram,
DiagramComponent,
ConnectorModel,ConnectorEditing
} from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(ConnectorEditing)
let connectors: ConnectorModel[] = [{
id: 'connector2',
// Defines the type of the segment
type: 'Bezier',
segments: [{
type: 'Bezier',
// Length and angle between the source point and the first control point
vector1: {
distance: 100,
angle: 90
},
// Length and angle between the target point and the second control point
vector2: {
distance: 45,
angle: 270
}
}],
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 />);
Avoid overlapping with bezier
By default, when there are no segments defined for a bezier connector, the bezier segments will be created automatically and routed in such a way that avoids overlapping with the source and target nodes.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Diagram, DiagramComponent, ConnectorEditing, ConnectorConstraints } from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(ConnectorEditing);
let nodes = [{
id: 'Start',
offsetX: 250,
offsetY: 150,
annotations: [{ content: 'Start' }],
},
{
id: 'End',
offsetX: 450,
offsetY: 200,
annotations: [{ content: 'End' }],
}];
let connectors = [{
id: "connector1",
style: {
strokeColor: '#6BA5D7',
fill: '#6BA5D7',
strokeWidth: 2
},
targetDecorator: { shape: 'None' },
// ID of the source and target nodes
sourceID: "Start",
targetID: "End",
type: 'Bezier',
}];
function App() {
return (<DiagramComponent id="container" width={'100%'} height={'600px'} nodes={nodes} connectors={connectors} getNodeDefaults={(node) => {
node.height = 100;
node.width = 100;
node.shape = { type: 'Basic', shape: 'Rectangle' };
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}} getConnectorDefaults={(connector) => {
connector.constraints =
ConnectorConstraints.Default | ConnectorConstraints.DragSegmentThumb;
}}/>);
}
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, ConnectorModel, ConnectorEditing, ConnectorConstraints,
} from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(ConnectorEditing);
let nodes: NodeModel[] = [{
id: 'Start',
offsetX: 250,
offsetY: 150,
annotations: [{ content: 'Start' }],
},
{
id: 'End',
offsetX: 450,
offsetY: 200,
annotations: [{ content: 'End' }],
}];
let connectors: ConnectorModel[] = [{
id: "connector1",
style: {
strokeColor: '#6BA5D7',
fill: '#6BA5D7',
strokeWidth: 2
},
targetDecorator: { shape: 'None' },
// ID of the source and target nodes
sourceID: "Start",
targetID: "End",
type: 'Bezier',
}];
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
connectors={connectors}
getNodeDefaults={(node: NodeModel) => {
node.height = 100;
node.width = 100;
node.shape = { type: 'Basic', shape: 'Rectangle' };
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}}
getConnectorDefaults={(connector: ConnectorModel) => {
connector.constraints =
ConnectorConstraints.Default | ConnectorConstraints.DragSegmentThumb;
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
Allow segment reset.
This feature allows users to choose whether to reset the control points of bezier segments when moving the source or target node. This decision empowers users to maintain control over the positioning of bezier curves, enhancing flexibility and precision in diagram editing.
With allow segment reset as true.
With allow segment reset as false.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Diagram, DiagramComponent, ConnectorEditing, ConnectorConstraints } from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(ConnectorEditing);
let nodes = [{
id: 'Start',
offsetX: 250,
offsetY: 150,
annotations: [{ content: 'Start' }],
},
{
id: 'End',
offsetX: 450,
offsetY: 300,
annotations: [{ content: 'End' }],
}];
let connectors = [{
id: "connector1",
segments: [
{
type: 'Bezier',
point1: { x: 450, y: 150 },
point2: { x: 250, y: 250 },
},
],
//Prevent segment reset whil moving source or target node.
bezierSettings: { allowSegmentsReset: false },
targetDecorator: { shape: 'None' },
// ID of the source and target nodes
sourceID: "Start",
targetID: "End",
type: 'Bezier',
}];
function App() {
return (<DiagramComponent id="container" width={'100%'} height={'600px'} nodes={nodes} connectors={connectors} getNodeDefaults={(node) => {
node.height = 100;
node.width = 100;
node.shape = { type: 'Basic', shape: 'Rectangle' };
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}} getConnectorDefaults={(connector) => {
connector.constraints =
ConnectorConstraints.Default | ConnectorConstraints.DragSegmentThumb;
}}/>);
}
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,ConnectorModel,ConnectorEditing,ConnectorConstraints,PortVisibility,ControlPointsVisibility
} from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(ConnectorEditing);
let nodes: NodeModel[] = [ {
id: 'Start',
offsetX: 250,
offsetY: 150,
annotations: [{ content: 'Start' }],
},
{
id: 'End',
offsetX: 450,
offsetY: 300,
annotations: [{ content: 'End' }],
}];
let connectors: ConnectorModel[] = [{
id: "connector1",
segments: [
{
type: 'Bezier',
point1: { x: 450, y: 150 },
point2: { x: 250, y: 250 },
},
],
//Prevent segment reset whil moving source or target node.
bezierSettings: { allowSegmentsReset: false },
targetDecorator: { shape: 'None' },
// ID of the source and target nodes
sourceID: "Start",
targetID: "End",
type: 'Bezier',
}];
function App() {
return (
<DiagramComponent
id="container"
width={'100%'}
height={'600px'}
nodes={nodes}
connectors={connectors}
getNodeDefaults={(node: NodeModel) => {
node.height = 100;
node.width = 100;
node.shape = { type: 'Basic', shape: 'Rectangle' };
node.style.fill = '#6BA5D7';
node.style.strokeColor = 'white';
return node;
}}
getConnectorDefaults={(connector: ConnectorModel) => {
connector.constraints =
ConnectorConstraints.Default | ConnectorConstraints.DragSegmentThumb;
}}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
How to customize Bezier Segment Thumb Size
Bezier segment thumbs default to size 10. This can be adjusted globally or for individual connectors using the segmentThumbSize
property.
To change the thumb size for all Bezier connectors, set the segmentThumbSize
property in the diagram’s model.
To customize the thumb size for a specific connector, disable the InheritSegmentThumbSize
constraint, then set the desired segmentThumbSize
.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Diagram, DiagramComponent, ConnectorConstraints, ConnectorEditing } from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(ConnectorEditing);
let nodes = [
{
id: 'node1', width: 100, height: 100, offsetX: 150, offsetY: 150,
},
{
id: 'node2', width: 100, height: 100, offsetX: 350, offsetY: 400,
},
{
id: 'node3', width: 100, height: 100, offsetX: 550, offsetY: 150,
},
{
id: 'node4', width: 100, height: 100, offsetX: 800, offsetY: 400,
},
];
let connectors = [{
id: 'connector1',
type: 'Bezier',
sourceID: 'node1',
targetID: 'node2',
segments: [
{
type: 'Bezier',
point: { x: 200, y: 300 },
},
{
type: 'Bezier',
point: { x: 320, y: 400 }
}
],
constraints: ConnectorConstraints.Default | ConnectorConstraints.DragSegmentThumb,
},
{
id: 'connector2',
type: 'Bezier',
sourceID: 'node3',
targetID: 'node4',
segments: [
{
type: 'Bezier',
point: { x: 600, y: 300 },
},
{
type: 'Bezier',
point: { x: 320, y: 400 }
}
],
constraints: ConnectorConstraints.Default & ~(ConnectorConstraints.InheritSegmentThumbSize) | ConnectorConstraints.DragSegmentThumb,
segmentThumbSize: 20
},];
function App() {
return (<DiagramComponent id="container" width={'900px'} height={'500px'} nodes = {nodes} connectors={connectors}
segmentThumbSize={15} />);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Diagram, ConnectorModel, NodeModel, ConnectorEditing, DiagramComponent, ConnectorConstraints } from "@syncfusion/ej2-react-diagrams";
Diagram.Inject(ConnectorEditing);
let nodes: NodeModel[] = [
{
id: 'node1', width: 100, height: 100, offsetX: 150, offsetY: 150,
},
{
id: 'node2', width: 100, height: 100, offsetX: 350, offsetY: 400,
},
{
id: 'node3', width: 100, height: 100, offsetX: 550, offsetY: 150,
},
{
id: 'node4', width: 100, height: 100, offsetX: 800, offsetY: 400,
},
];
let connectors: ConnectorModel[] = [
{
id: 'connector1',
type: 'Bezier',
sourceID: 'node1',
targetID: 'node2',
segments: [
{
type: 'Bezier',
point: { x: 200, y: 300 },
},
{
type: 'Bezier',
point: { x: 320, y: 400 }
}
],
constraints: ConnectorConstraints.Default | ConnectorConstraints.DragSegmentThumb,
},
{
id: 'connector2',
type: 'Bezier',
sourceID: 'node3',
targetID: 'node4',
segments: [
{
type: 'Bezier',
point: { x: 600, y: 300 },
},
{
type: 'Bezier',
point: { x: 320, y: 400 }
}
],
constraints: ConnectorConstraints.Default & ~(ConnectorConstraints.InheritSegmentThumbSize) | ConnectorConstraints.DragSegmentThumb,
segmentThumbSize: 20
},
];
function App() {
return (
<DiagramComponent
id="container"
width={'900px'}
height={'500px'}
nodes={nodes}
connectors={connectors}
segmentThumbSize={15}
/>
);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);