Ports in Vue Diagram component
7 Dec 202424 minutes to read
Port is a special connection point in a Node where you can glue the connectors. When you glue a connector to a node or port, they remain connected even if one of the nodes is moved.
Types of connections
There are two main types of connections, node to node and port to port. The difference between these two connections is whether or not a connector remains glued to a specific connection point when you move the attached node or connector.
Node to node connection
A node to node connection is one where the connector will move around the node as you move the node. Diagram will always ensure the connector in the shortest, most direct line possible. You can create a node to node connection by selecting the entire node (rather than the port) and connect it to another shape (rather than to a port).
When a connector is connected between two nodes, its end points are automatically docked to the node’s nearest boundary as shown in the following Gif.
Port to port connection
Ports act as the connection points of the node and allows creating connections with only those specific points as shown in the following image.
Create Port
To add a connection port, define the port object and add it to node’s ports
collection. The offset
property of the port accepts an object of fractions and is used to determine the position of ports. The following code explains how to add ports when initializing the node.
<template>
<div id="app">
<ejs-diagram id="diagram" ref="diagram" :width='width' :height='height' :nodes='nodes'></ejs-diagram>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import { DiagramComponent as EjsDiagram, PortVisibility } from '@syncfusion/ej2-vue-diagrams';
const diagram = ref(null);
const nodes = [{
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
// Initialize port collection
ports: [{
id: 'port1',
offset: {
x: 0.5,
y: 0.5
},
visibility: PortVisibility.Visible
}]
}]
const width = "100%";
const height = "350px";
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
<div id="app">
<ejs-diagram id="diagram" ref="diagram" :width='width' :height='height' :nodes='nodes'></ejs-diagram>
</div>
</template>
<script>
import { DiagramComponent, PortVisibility } from '@syncfusion/ej2-vue-diagrams';
let nodes = [{
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
// Initialize port collection
ports: [{
id: 'port1',
offset: {
x: 0.5,
y: 0.5
},
visibility: PortVisibility.Visible
}]
}];
export default {
name: "App",
components: {
"ejs-diagram": DiagramComponent
},
data() {
return {
width: "100%",
height: "350px",
nodes: nodes,
}
},
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
Add ports at runtime
You can add ports to the nodes at runtime by using the diagram method addPorts
. The following code illustrates how to add ports to node at runtime.
The port’s ID property is used to define the unique ID for the port and its further used to find the port at runtime.
If ID is not set, then default ID is automatically set.
<template>
<div id="app">
<ejs-button v-on:click='addPorts'>Add Ports</ejs-button>
<ejs-diagram id="diagram" ref="diagram" :width='width' :height='height' :nodes='nodes'></ejs-diagram>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import { DiagramComponent as EjsDiagram, PortVisibility } from '@syncfusion/ej2-vue-diagrams';
import { ButtonComponent as EjsButton } from '@syncfusion/ej2-vue-buttons';
let diagramInstance;
const diagram = ref(null);
const nodes = [{
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
}];
const port = [{
id: 'port1',
offset: {
x: 0,
y: 0.5
},
visibility: PortVisibility.Visible
},
{
id: 'port2',
offset: {
x: 1,
y: 0.5
},
visibility: PortVisibility.Visible
},
{
id: 'port3',
offset: {
x: 0.5,
y: 0
},
visibility: PortVisibility.Visible
},
{
id: 'port4',
offset: {
x: 0.5,
y: 1
},
visibility: PortVisibility.Visible
}
];
const width = "100%";
const height = "600px";
onMounted(function () {
diagramInstance = diagram.value.ej2Instances;
});
const addPorts = function() {
// Method to add ports to a node at runtime
// Parameters:
// - node: The node to which the port will be added.
// - port: The port collection to be added to the node.
diagramInstance.addPorts(diagramInstance.nodes[0], port);
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
<div id="app">
<ejs-button v-on:click="addPorts">Add Ports</ejs-button>
<ejs-diagram
id="diagram"
ref="diagram"
:width="width"
:height="height"
:nodes="nodes"
></ejs-diagram>
</div>
</template>
<script>
import { DiagramComponent, PortVisibility } from "@syncfusion/ej2-vue-diagrams";
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
let diagramInstance;
let nodes = [
{
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
},
];
let port = [
{
id: "port1",
offset: {
x: 0,
y: 0.5,
},
visibility: PortVisibility.Visible,
},
{
id: "port2",
offset: {
x: 1,
y: 0.5,
},
visibility: PortVisibility.Visible,
},
{
id: "port3",
offset: {
x: 0.5,
y: 0,
},
visibility: PortVisibility.Visible,
},
{
id: "port4",
offset: {
x: 0.5,
y: 1,
},
visibility: PortVisibility.Visible,
},
];
export default {
name: "App",
components: {
"ejs-diagram": DiagramComponent,
"ejs-button": ButtonComponent,
},
data() {
return {
width: "100%",
height: "600px",
nodes: nodes,
};
},
mounted: function () {
diagramInstance = this.$refs.diagram.ej2Instances;
},
methods: {
addPorts() {
// Method to add ports to a node at runtime
// Parameters:
// - node: The node to which the port will be added.
// - port: The port collection to be added to the node.
diagramInstance.addPorts(diagramInstance.nodes[0], port);
},
},
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
Remove ports at runtime
You can remove ports at runtime by using diagram method removePorts
. Refer to the following example which shows how to remove ports at runtime.
<template>
<div id="app">
<ejs-button v-on:click="removePorts">Remove Ports</ejs-button>
<ejs-diagram
id="diagram"
ref="diagram"
:width="width"
:height="height"
:nodes="nodes"
></ejs-diagram>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import {
DiagramComponent as EjsDiagram,
PortVisibility,
} from "@syncfusion/ej2-vue-diagrams";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
let diagramInstance;
const diagram = ref(null);
const nodes = [
{
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
ports: [
{
id: "port1",
offset: {
x: 0,
y: 0.5,
},
visibility: PortVisibility.Visible,
},
{
id: "port2",
offset: {
x: 1,
y: 0.5,
},
visibility: PortVisibility.Visible,
},
{
id: "port3",
offset: {
x: 0.5,
y: 0,
},
visibility: PortVisibility.Visible,
},
{
id: "port4",
offset: {
x: 0.5,
y: 1,
},
visibility: PortVisibility.Visible,
},
],
},
];
const width = "100%";
const height = "600px";
onMounted(function () {
diagramInstance = diagram.value.ej2Instances;
});
const removePorts = function () {
// Method to remove ports from a node at runtime
// Parameters:
// - node: The node to which the port will be removed from.
// - port: The port collection to be removed from the node.
diagramInstance.removePorts(diagramInstance.nodes[0], diagramInstance.nodes[0].ports);
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
<div id="app">
<ejs-button v-on:click="removePorts">Remove Ports</ejs-button>
<ejs-diagram
id="diagram"
ref="diagram"
:width="width"
:height="height"
:nodes="nodes"
></ejs-diagram>
</div>
</template>
<script>
import { DiagramComponent, PortVisibility } from "@syncfusion/ej2-vue-diagrams";
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
let diagramInstance;
let nodes = [
{
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
ports: [
{
id: "port1",
offset: {
x: 0,
y: 0.5,
},
visibility: PortVisibility.Visible,
},
{
id: "port2",
offset: {
x: 1,
y: 0.5,
},
visibility: PortVisibility.Visible,
},
{
id: "port3",
offset: {
x: 0.5,
y: 0,
},
visibility: PortVisibility.Visible,
},
{
id: "port4",
offset: {
x: 0.5,
y: 1,
},
visibility: PortVisibility.Visible,
},
],
},
];
export default {
name: "App",
components: {
"ejs-diagram": DiagramComponent,
"ejs-button": ButtonComponent,
},
data() {
return {
width: "100%",
height: "600px",
nodes: nodes,
};
},
mounted: function () {
diagramInstance = this.$refs.diagram.ej2Instances;
},
methods: {
removePorts() {
// Method to remove ports from a node at runtime
// Parameters:
// - node: The node to which the port will be removed from.
// - port: The port collection to be removed from the node.
diagramInstance.removePorts(diagramInstance.nodes[0], diagramInstance.nodes[0].ports);
},
},
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
Update Port at runtime
You can change any port properties at runtime and update it through the diagram method [dataBind
].
The following code example illustrates how to change the port offset at runtime.
<template>
<div id="app">
<ejs-button v-on:click="updatePortOffset">update PortOffset</ejs-button>
<ejs-diagram
id="diagram"
ref="diagram"
:width="width"
:height="height"
:nodes="nodes"
></ejs-diagram>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import {DiagramComponent as EjsDiagram,PortVisibility} from "@syncfusion/ej2-vue-diagrams";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
let diagramInstance;
const diagram = ref(null);
const nodes = [
{
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
ports: [
{
id: "port1",
offset: {
x: 0,
y: 0.5,
},
visibility: PortVisibility.Visible,
},
{
id: "port2",
offset: {
x: 1,
y: 0.5,
},
visibility: PortVisibility.Visible,
},
{
id: "port3",
offset: {
x: 0.5,
y: 0,
},
visibility: PortVisibility.Visible,
},
{
id: "port4",
offset: {
x: 0.5,
y: 1,
},
visibility: PortVisibility.Visible,
},
],
},
];
const width = "100%";
const height = "600px";
onMounted(function () {
diagramInstance = diagram.value.ej2Instances;
});
const updatePortOffset = function () {
let port1 = diagramInstance.nodes[0].ports[0];
port1.offset = { x: 1, y: 1 };
diagramInstance.dataBind();
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
<div id="app">
<ejs-button v-on:click="updatePortOffset">update PortOffset</ejs-button>
<ejs-diagram
id="diagram"
ref="diagram"
:width="width"
:height="height"
:nodes="nodes"
></ejs-diagram>
</div>
</template>
<script>
import { DiagramComponent, PortVisibility } from "@syncfusion/ej2-vue-diagrams";
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
let diagramInstance;
let nodes = [
{
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
ports: [
{
id: "port1",
offset: {
x: 0,
y: 0.5,
},
visibility: PortVisibility.Visible,
},
{
id: "port2",
offset: {
x: 1,
y: 0.5,
},
visibility: PortVisibility.Visible,
},
{
id: "port3",
offset: {
x: 0.5,
y: 0,
},
visibility: PortVisibility.Visible,
},
{
id: "port4",
offset: {
x: 0.5,
y: 1,
},
visibility: PortVisibility.Visible,
},
],
},
];
export default {
name: "App",
components: {
"ejs-diagram": DiagramComponent,
"ejs-button": ButtonComponent,
},
data() {
return {
width: "100%",
height: "600px",
nodes: nodes,
};
},
mounted: function () {
diagramInstance = this.$refs.diagram.ej2Instances;
},
methods: {
updatePortOffset() {
let port1 = diagramInstance.nodes[0].ports[0];
port1.offset = { x: 1, y: 1 };
diagramInstance.dataBind();
},
},
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
Specify connection direction to port
The connectionDirection
property of a port allows users to specify the direction in which a connector should establish a connection. This can be either to the port (incoming) or from the port (outgoing).
<template>
<div id="app">
<ejs-button v-on:click="updateConnectionDirection">updateConnectionDirection</ejs-button>
<ejs-diagram
id="diagram"
ref="diagram"
:width="width"
:height="height"
:nodes="nodes"
:connectors="connectors"
></ejs-diagram>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import {
DiagramComponent as EjsDiagram,
PortVisibility,
} from "@syncfusion/ej2-vue-diagrams";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
let diagramInstance;
const diagram = ref(null);
const nodes = [
{
id: "node1",
offsetX: 450,
offsetY: 200,
width: 100,
height: 100,
ports: [
{
id: "port1",
offset: {
x: 0,
y: 0,
},
visibility: PortVisibility.Visible,
},
],
},
{
id: "node2",
offsetX: 270,
offsetY: 300,
width: 100,
height: 100,
ports: [
{
id: "port3",
offset: { x: 0.5, y: 0.5 },
visibility: PortVisibility.Visible,
//Sets the connection direction as Left
connectionDirection: "Left",
},
],
},
];
const connectors = [
{
id: "connector1",
sourceID: "node2",
targetID: "node1",
type: "Orthogonal",
sourcePortID: "port3",
targetPortID: "port1",
},
];
const width = "100%";
const height = "600px";
onMounted(function () {
diagramInstance = diagram.value.ej2Instances;
});
const updateConnectionDirection = function () {
let port1 = diagramInstance.nodes[0].ports[0];
port1.connectionDirection = "Top";
diagramInstance.dataBind();
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
<div id="app">
<ejs-button v-on:click="updateConnectionDirection">update ConnectionDirection</ejs-button>
<ejs-diagram
id="diagram"
ref="diagram"
:width="width"
:height="height"
:nodes="nodes"
:connectors="connectors"
></ejs-diagram>
</div>
</template>
<script>
import { DiagramComponent, PortVisibility } from "@syncfusion/ej2-vue-diagrams";
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
let diagramInstance;
let nodes = [
{
id: "node1",
offsetX: 450,
offsetY: 200,
width: 100,
height: 100,
ports: [
{
id: "port1",
offset: {
x: 0,
y: 0,
},
visibility: PortVisibility.Visible,
},
],
},
{
id: "node2",
offsetX: 270,
offsetY: 300,
width: 100,
height: 100,
ports: [
{
id: "port3",
offset: { x: 0.5, y: 0.5 },
visibility: PortVisibility.Visible,
//Sets the connection direction as Left
connectionDirection: "Left",
},
],
},
];
let connectors = [
{
id: "connector1",
sourceID: "node2",
targetID: "node1",
type: "Orthogonal",
sourcePortID: "port3",
targetPortID: "port1",
},
];
export default {
name: "App",
components: {
"ejs-diagram": DiagramComponent,
"ejs-button": ButtonComponent,
},
data() {
return {
width: "100%",
height: "600px",
nodes: nodes,
connectors: connectors,
};
},
mounted: function () {
diagramInstance = this.$refs.diagram.ej2Instances;
},
methods: {
updateConnectionDirection() {
let port1 = diagramInstance.nodes[0].ports[0];
port1.connectionDirection = "Top";
diagramInstance.dataBind();
},
},
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
InEdges and outEdges of ports
The inEdges
is used to get the incoming connectors of the port that are connected to the port. outEdges
is used to get the outgoing connectors of the port that are connected to the port.
The inEdges
and outEdges
of the port are read-only and cannot be customized.
The following code example shows how to get inEdges and outEdges of port.
<template>
<div id="app">
<ejs-button v-on:click="getInEdges">Get InEdges</ejs-button>
<ejs-button v-on:click="getOutEdges">Get OutEdges</ejs-button>
<ejs-diagram
id="diagram"
ref="diagram"
:width="width"
:height="height"
:nodes="nodes"
:connectors="connectors"
></ejs-diagram>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import {
DiagramComponent as EjsDiagram,
PortVisibility,
} from "@syncfusion/ej2-vue-diagrams";
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
let diagramInstance;
const diagram = ref(null);
const nodes = [
{
id: "node1",
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
ports: [
{
id: "port1",
offset: { x: 0, y: 0.5 },
visibility: PortVisibility.Visible,
},
{
id: "port2",
offset: { x: 0.5, y: 0 },
visibility: PortVisibility.Visible,
}
],
},
{
id: "node2",
offsetX: 250,
offsetY: 400,
width: 100,
height: 100,
ports: [
{
id: "port3",
offset: { x: 0, y: 0.5},
visibility: PortVisibility.Visible,
},
{
id: "port4",
offset: { x: 0.5, y: 1},
visibility: PortVisibility.Visible,
}
],
},
];
const connectors = [
{
id: 'connector1',
sourceID: 'node1',
targetID: 'node2',
type: 'Orthogonal',
sourcePortID: 'port1',
targetPortID: 'port3',
annotations: [{ content: 'connector1' }],
},
{
id: 'connector2',
sourceID: 'node2',
targetID: 'node1',
type: 'Orthogonal',
sourcePortID: 'port4',
targetPortID: 'port2',
annotations: [{ content: 'connector2' }],
},
];
const width = "100%";
const height = "600px";
onMounted(function () {
diagramInstance = diagram.value.ej2Instances;
});
const getInEdges = function () {
let port1 = diagramInstance.nodes[0].ports[1];
console.log(port1.inEdges[0]);
};
const getOutEdges = function () {
let port1 = diagramInstance.nodes[0].ports[0];
console.log(port1.outEdges[0]);
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
<div id="app">
<ejs-button v-on:click="getInEdges">Get InEdges</ejs-button>
<ejs-button v-on:click="getOutEdges">Get OutEdges</ejs-button>
<ejs-diagram
id="diagram"
ref="diagram"
:width="width"
:height="height"
:nodes="nodes"
:connectors="connectors"
></ejs-diagram>
</div>
</template>
<script>
import { DiagramComponent, PortVisibility } from "@syncfusion/ej2-vue-diagrams";
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
let diagramInstance;
let nodes = [
{
id: "node1",
offsetX: 250,
offsetY: 250,
width: 100,
height: 100,
ports: [
{
id: "port1",
offset: { x: 0, y: 0.5 },
visibility: PortVisibility.Visible,
},
{
id: "port2",
offset: { x: 0.5, y: 0 },
visibility: PortVisibility.Visible,
}
],
},
{
id: "node2",
offsetX: 250,
offsetY: 400,
width: 100,
height: 100,
ports: [
{
id: "port3",
offset: { x: 0, y: 0.5},
visibility: PortVisibility.Visible,
},
{
id: "port4",
offset: { x: 0.5, y: 1},
visibility: PortVisibility.Visible,
}
],
},
];
let connectors = [
{
id: 'connector1',
sourceID: 'node1',
targetID: 'node2',
type: 'Orthogonal',
sourcePortID: 'port1',
targetPortID: 'port3',
annotations: [{ content: 'connector1' }],
},
{
id: 'connector2',
sourceID: 'node2',
targetID: 'node1',
type: 'Orthogonal',
sourcePortID: 'port4',
targetPortID: 'port2',
annotations: [{ content: 'connector2' }],
},
];
export default {
name: "App",
components: {
"ejs-diagram": DiagramComponent,
"ejs-button": ButtonComponent,
},
data() {
return {
width: "100%",
height: "600px",
nodes: nodes,
connectors: connectors,
};
},
mounted: function () {
diagramInstance = this.$refs.diagram.ej2Instances;
},
methods: {
getInEdges() {
let port1 = diagramInstance.nodes[0].ports[1];
console.log(port1.inEdges[0]);
},
getOutEdges() {
let port1 = diagramInstance.nodes[0].ports[0];
console.log(port1.outEdges[0]);
},
}
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
Additional information to port
The addInfo
property of the port allows you to maintain additional information to the port.
The following code example shows how to set addInfo to the port.
let port = {id:'port1',offset:{x:0.5,y:0},addInfo:{position:'TopCenter',id:'port1'}};