Syncfusion AI Assistant

How can I help you?

Bezier Connectors in Diagram Component

21 Oct 202524 minutes to read

Bezier segments create curved paths whose shape can be configured using either control points or 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

The shape of a Bezier connector can be interactively modified by dragging its segment control points. These points, also known as thumbs, appear along the connector and allow you to adjust the curve’s vectors and points.

Bezier Segment edit Gif

Control Points

The curvature of a Bezier segment is determined by its control points. There are two primary ways to define the position of these control points:

  • Fixed Positioning (point1, point2): When you use the point1 and point2 properties, the control points are set at fixed coordinates. These points remain stationary even when the connector’s start or end points are moved. This is useful for creating static, predictable curves.

Point

The point1 and point2(https://helpej2.syncfusion.com/react/documentation/api/diagram/bezierSegment/#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 />);

Bezier Control point set by point1 and point2

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

Bezier Control point set by vector1 and vector1

Avoid Overlapping with Bezier

By default, if no segments are explicitly defined for a Bezier connector, the Diagram component automatically generates segments. This routing logic is designed to prevent the connector from overlapping with its connected source and target nodes, ensuring a clean and readable layout.

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.

The allowSegmentReset property gives you control over whether a Bezier segment’s control points should be reset to their default positions when the source or target node is moved. This provides greater flexibility in maintaining custom curve shapes during diagram editing.

allowSegmentReset is true (Default)

When allowSegmentReset is true, moving a connected node will reset the Bezier control points, recalculating the curve.

Allow Segment rest true

allowSegmentReset is false

When allowSegmentReset is false, the custom positions of the control points are preserved when a connected node is moved, maintaining the user-defined curve.

Allow Segment rest 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

The interactive thumbs used to edit Bezier segments have a default size of 10×10 pixels. This size can be customized either globally for all connectors or individually for each connector 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 />);