Bezier Connector in EJ2 Angular Diagram control
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 { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, DiagramModule, ConnectorModel, PointModel, OrthogonalSegmentModel } from '@syncfusion/ej2-angular-diagrams';
@Component({
imports: [
DiagramModule
],
providers: [ ],
standalone: true,
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" >
<e-connectors>
<e-connector id='connector' type='Bezier' [sourcePoint]='sourcePoint' [targetPoint]='targetPoint' [segments]='segments'>
</e-connector>
</e-connectors>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public sourcePoint?: PointModel;
public targetPoint?: PointModel;
public segments?: OrthogonalSegmentModel;
ngOnInit(): void {
this.sourcePoint = { x: 100, y: 100 };
this.targetPoint = { x: 200, y: 200 };
this.segments = [ { type: 'Bezier'} ];
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
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 { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, DiagramModule, ConnectorModel, PointModel, OrthogonalSegmentModel,ConnectorEditing } from '@syncfusion/ej2-angular-diagrams';
Diagram.Inject(ConnectorEditing);
@Component({
imports: [
DiagramModule
],
providers: [ ],
standalone: true,
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" >
<e-connectors>
<e-connector id='connector' type='Bezier' [sourcePoint]='sourcePoint' [targetPoint]='targetPoint' [segments]='segments'>
</e-connector>
</e-connectors>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public sourcePoint?: PointModel;
public targetPoint?: PointModel;
public segments?: OrthogonalSegmentModel;
ngOnInit(): void {
this.sourcePoint = { x: 100, y: 200 };
this.targetPoint = { x: 200, y: 100 };
this.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
}
}]
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
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 { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, DiagramModule,ConnectorModel, PointModel, OrthogonalSegmentModel,ConnectorEditing } from '@syncfusion/ej2-angular-diagrams';
Diagram.Inject(ConnectorEditing)
@Component({
imports: [
DiagramModule
],
providers: [ ],
standalone: true,
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" >
<e-connectors>
<e-connector id='connector' type='Bezier' [sourcePoint]='sourcePoint' [targetPoint]='targetPoint' [segments]='segments'>
</e-connector>
</e-connectors>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public sourcePoint?: PointModel;
public targetPoint?: PointModel;
public segments?: OrthogonalSegmentModel;
ngOnInit(): void {
this.sourcePoint = { x: 100, y: 100 };
this.targetPoint = { x: 200, y: 200 };
this.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
}
}]
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
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 { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { DiagramModule } from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, NodeModel, ConnectorModel,ConnectorEditing, ConnectorConstraints,BezierSegmentModel, PointPortModel, ControlPointsVisibility, PortVisibility, ShapeStyleModel } from '@syncfusion/ej2-angular-diagrams';
Diagram.Inject(ConnectorEditing);
@Component({
imports: [
DiagramModule
],
providers: [ ],
standalone: true,
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="600px" [getNodeDefaults]='getNodeDefaults' >
<e-nodes>
<e-node id='Start' [offsetX]=250 [offsetY]=150 [ports]='StartPort'>
<e-node-annotations>
<e-node-annotation content="Start">
</e-node-annotation>
</e-node-annotations>
</e-node>
<e-node id='End' [offsetX]=500 [offsetY]=200 [ports]='EndPort'>
<e-node-annotations>
<e-node-annotation content="End">
</e-node-annotation>
</e-node-annotations>
</e-node>
</e-nodes>
<e-connectors>
<e-connector id='connector1' type='Bezier' sourceID='Start' targetID='End' sourcePortID='StartPort' targetPortID='EndPort' bezierSettings='bezierSettings' [constraints]='constraints'>
</e-connector>
</e-connectors>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public StartPort?:PointPortModel[];
public EndPort?:PointPortModel[];
public bezierSettings?: any;
ngOnInit(): void {
this.StartPort = [{
id: 'StartPort',
visibility: PortVisibility.Visible,
shape: 'Circle',
offset: { x: 1, y: 0.5 },
style: { strokeColor: '#366F8C', fill: '#366F8C' }
}];
this.EndPort = [{
id: 'EndPort',
visibility: PortVisibility.Visible,
shape: 'Circle',
offset: { x: 0, y: 0.5 },
style: { strokeColor: '#366F8C', fill: '#366F8C' }
}];
this.bezierSettings = { controlPointsVisibility: ControlPointsVisibility.Source | ControlPointsVisibility.Target };
}
public getNodeDefaults(node: NodeModel | any): NodeModel {
node.height = 100;
node.width = 100;
node.shape = { type: 'Basic', shape: 'Rectangle' };
((node as NodeModel).style as ShapeStyleModel).fill = "#6BA5D7";
((node as NodeModel).style as ShapeStyleModel).strokeColor = "White";
return node;
}
constraints = ConnectorConstraints.Default | ConnectorConstraints.DragSegmentThumb;
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
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 { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, DiagramModule, Diagram, NodeModel, ConnectorModel, ConnectorEditing, ConnectorConstraints } from '@syncfusion/ej2-angular-diagrams';
Diagram.Inject(ConnectorEditing);
@Component({
imports: [
DiagramModule
],
providers: [],
standalone: true,
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="600px" [getNodeDefaults]='getNodeDefaults' [getConnectorDefaults] ='getConnectorDefaults'>
<e-nodes>
<e-node id= 'Start' [offsetX]=250 [offsetY]=150>
<e-node-annotations>
<e-node-annotation content="Start">
</e-node-annotation>
</e-node-annotations>
</e-node>
<e-node id='End' [offsetX]=450 [offsetY]=300>
<e-node-annotations>
<e-node-annotation content="End">
</e-node-annotation>
</e-node-annotations>
</e-node>
</e-nodes>
<e-connectors>
<e-connector id='connector1' type='Bezier' sourceID='Start' targetID='End' [segments]="segments">
</e-connector>
</e-connectors>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public getNodeDefaults(node: NodeModel): void {
node.height = 100;
node.width = 100;
node.shape = { type: 'Basic', shape: 'Rectangle' };
node.style = { fill: '#6BA5D7', strokeColor: 'white' };
};
public segments = [{
type: 'Bezier',
point1: { x: 450, y: 150 },
point2: { x: 250, y: 250 },
}];
public getConnectorDefaults(connector: ConnectorModel): void {
connector.targetDecorator = { shape: 'None' };
connector.bezierSettings = { allowSegmentsReset: false };
connector.constraints = ConnectorConstraints.Default | ConnectorConstraints.DragSegmentThumb;
};
};
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
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 { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, DiagramModule, ConnectorConstraints,NodeModel,ConnectorEditing, PointModel, OrthogonalSegmentModel } from '@syncfusion/ej2-angular-diagrams';
Diagram.Inject(ConnectorEditing);
@Component({
imports: [
DiagramModule
],
providers: [ ],
standalone: true,
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="900px" height="500px" [getNodeDefaults] ='getNodeDefaults' [segmentThumbSize]= 15>
<e-nodes>
<e-node id='node1' [offsetX]=150 [offsetY]=150 > </e-node>
<e-node id='node2' [offsetX]=350 [offsetY]=400 > </e-node>
<e-node id='node3' [offsetX]=550 [offsetY]=150 > </e-node>
<e-node id='node4' [offsetX]=800 [offsetY]=400 > </e-node>
</e-nodes>
<e-connectors>
<e-connector id='connector1' type='Bezier' sourceID='node1' targetID='node2' [segments]='segments1' [constraints]='Constraints1'>
</e-connector>
<e-connector id='connector2' type='Bezier' sourceID='node3' targetID='node4' [segments]='segments2' [constraints]='Constraints2' [segmentThumbSize] = 20 >
</e-connector>
</e-connectors>
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public sourcePoint?: PointModel;
public targetPoint?: PointModel;
public segments?: OrthogonalSegmentModel;
ngOnInit(): void {
}
public getNodeDefaults(node: NodeModel): NodeModel {
node.height = 100;
node.width = 100;
return node;
}
public segments1 = [
{
type: 'Bezier',
point: { x: 200, y: 300 },
},
{
type: 'Bezier',
point: { x: 320, y: 400 }
}
]
public segments2 = [
{
type: 'Bezier',
point: { x: 600, y: 300 },
},
{
type: 'Bezier',
point: { x: 320, y: 400 }
}
]
public Constraints1 = ConnectorConstraints.Default | ConnectorConstraints.DragSegmentThumb
public Constraints2 = ConnectorConstraints.Default & ~(ConnectorConstraints.InheritSegmentThumbSize) | ConnectorConstraints.DragSegmentThumb
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));