Ports interaction in Vue Diagram component | Syncfusion®

21 Jun 202524 minutes to read

Draw connector from port

The port can be used to create connector by enabling Draw constraints to the constraints property. By default, the connector segment type is set to Orthogonal.

The following code explains how to draw the connector by using the port constraints.

<template>
  <div id="app">
    <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,PortConstraints} from "@syncfusion/ej2-vue-diagrams";

const diagram = ref(null);

const nodes = [
  {
    id: 'node1',
    offsetX: 250,
    offsetY: 250,
    width: 100,
    height: 100,
    ports: [
      {
        offset: { x: 1, y: 0.5 },
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default |
          PortConstraints.Draw,
      },
    ],
  },
];

const connectors = [
  {
    id: 'connector1',
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 120 },
    type: 'Orthogonal',
    ports: [
      {
        offset: 0.5,
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default | PortConstraints.Draw,
      },
    ],
  },
];

const width = "100%";
const height = "600px";

</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"
      :connectors="connectors"
    ></ejs-diagram>
  </div>
</template>
<script>
import { DiagramComponent, PortVisibility, PortConstraints } from "@syncfusion/ej2-vue-diagrams";


let nodes = [
  {
    id: 'node1',
    offsetX: 250,
    offsetY: 250,
    width: 100,
    height: 100,
    ports: [
      {
        offset: { x: 1, y: 0.5 },
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default |
          PortConstraints.Draw,
      },
    ],
  },
];

let connectors = [
  {
    id: 'connector1',
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 120 },
    type: 'Orthogonal',
    ports: [
      {
        offset: 0.5,
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default | PortConstraints.Draw,
      },
    ],
  },
];


export default {
  name: "App",
  components: {
    "ejs-diagram": DiagramComponent,
  },
  data() {
    return {
      width: "100%",
      height: "600px",
      nodes:nodes,
      connectors: connectors,
    };
  },

};
</script>

<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

Draw different connector types from port

You can change the default connector type while drawing the connector from the port by setting the specific connector type in connector defaults. This enables the drawing of various connector types from the port, including:

  • Straight
  • Bezier
  • Orthogonal

The following code explains how to draw different connectors by using the port constraints.

<template>
  <div id="app">
    <ejs-diagram
      id="diagram"
      ref="diagram"
      :width="width"
      :height="height"
      :nodes="nodes"
      :connectors="connectors"
      :getConnectorDefaults="getConnectorDefaults"
    ></ejs-diagram>
  </div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import {DiagramComponent as EjsDiagram,PortVisibility,PortConstraints} from "@syncfusion/ej2-vue-diagrams";

const diagram = ref(null);

const nodes = [
  {
    id: 'node1',
    offsetX: 250,
    offsetY: 250,
    width: 100,
    height: 100,
    ports: [
      {
        offset: { x: 1, y: 0.5 },
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default |
          PortConstraints.Draw,
      },
    ],
  },
];

const connectors = [
  {
    id: 'connector1',
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 120 },
    ports: [
      {
        offset: 0.5,
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default | PortConstraints.Draw,
      },
    ],
  },
];

const getConnectorDefaults = (connector) => {
  connector.type = 'Bezier';
  return connector;
};

const width = "100%";
const height = "600px";

</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"
      :connectors='connectors'
      :getConnectorDefaults="getConnectorDefaults"
    ></ejs-diagram>
  </div>
</template>
<script>
import { DiagramComponent, PortVisibility, PortConstraints } from "@syncfusion/ej2-vue-diagrams";


let nodes = [
  {
    id: 'node1',
    offsetX: 250,
    offsetY: 250,
    width: 100,
    height: 100,
    ports: [
      {
        offset: { x: 1, y: 0.5 },
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default |
          PortConstraints.Draw,
      },
    ],
  },
];

let connectors = [
  {
    id: 'connector1',
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 120 },
    ports: [
      {
        offset: 0.5,
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default | PortConstraints.Draw,
      },
    ],
  },
];


export default {
  name: "App",
  components: {
    "ejs-diagram": DiagramComponent,
  },
  data() {
    return {
      width: "100%",
      height: "600px",
      nodes:nodes,
      connectors: connectors,
      getConnectorDefaults: function (connector) {
      connector.type = 'Bezier';
      return connector;
    },
    };
  },
};
</script>

<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

Port drag

The port drag feature allows users to click and drag a port using the mouse. This functionality can be enabled by setting the port constraints to “Drag”.

The following code explains how to enable port drag.

<template>
  <div id="app">
    <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,PortConstraints} from "@syncfusion/ej2-vue-diagrams";

const diagram = ref(null);

const nodes = [
  {
    id: 'node1',
    offsetX: 250,
    offsetY: 250,
    width: 100,
    height: 100,
    annotations: [{ content: 'Click and drag the port' }],
    ports: [
      {
        offset: { x: 1, y: 0.5 },
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default |
          PortConstraints.Drag,
      },
    ],
  },
];

let connectors = [
  {
    id: 'connector1',
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 120 },
    type: 'Orthogonal',
    ports: [
      {
        offset: 0.5,
        visibility: PortVisibility.Visible,
        constraints: PortConstraints.Default | PortConstraints.Drag,
      },
    ],
  },
];

const width = "100%";
const height = "600px";


</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"
      :connectors='connectors'
    ></ejs-diagram>
  </div>
</template>
<script>
import { DiagramComponent, PortVisibility, PortConstraints } from "@syncfusion/ej2-vue-diagrams";


let nodes = [
  {
    id: 'node1',
    offsetX: 250,
    offsetY: 250,
    width: 100,
    height: 100,
    annotations: [{ content: 'Click and drag the port' }],
    ports: [
      {
        offset: { x: 1, y: 0.5 },
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default |
          PortConstraints.Drag,
      },
    ],
  },
];

let connectors = [
  {
    id: 'connector1',
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 120 },
    type: 'Orthogonal',
    ports: [
      {
        offset: 0.5,
        visibility: PortVisibility.Visible,
        constraints: PortConstraints.Default | PortConstraints.Drag,
      },
    ],
  },
];


export default {
  name: "App",
  components: {
    "ejs-diagram": DiagramComponent,
  },
  data() {
    return {
      width: "100%",
      height: "600px",
      nodes:nodes,
      connectors: connectors,
    };
  },
};
</script>

<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

Automatic Port Creation

The Diagram component allows you to dynamically create ports on nodes or connectors by clicking and dragging the mouse while holding the Control (Ctrl) key. This feature is disabled by default and can be enabled by using the DiagramConstraints.AutomaticPortCreation constraint.

You can also remove a port using the same Ctrl + Click interaction, but only if the port is not currently connected to any connector.

The following example shows how to enable automatic port creation:

<template>
    <div id="app">
        <ejs-diagram id="diagram" width="100%" height="500px" :nodes="nodes"
        :constraints="constraints" :snapSettings="snapSettings" />
    </div>
</template>

<script setup>
import { DiagramComponent as EjsDiagram } from '@syncfusion/ej2-vue-diagrams';
import { NodeConstraints, SnapConstraints, DiagramConstraints } from '@syncfusion/ej2-diagrams';

const nodes = [
    {
        id: 'node1', width: 100, height: 100, offsetX: 150, offsetY: 200, style: { fill: 'cornflowerblue' },
        constraints: NodeConstraints.Default &
            ~(NodeConstraints.InConnect | NodeConstraints.OutConnect)

    },
    {
        id: 'node2', width: 100, height: 100, offsetX: 400, offsetY: 200, style: { fill: 'cornflowerblue' },
        constraints: NodeConstraints.Default &
            ~(NodeConstraints.InConnect | NodeConstraints.OutConnect)
    },
];
// Enable AutomaticPortCreation
const constraints = DiagramConstraints.Default | DiagramConstraints.AutomaticPortCreation;
const snapSettings = { constraints: SnapConstraints.None };
</script>

<style scoped>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
</style>
<template>
  <div id="app">
    <ejs-diagram id="diagram" width="100%" height="500px" :nodes="nodes" :constraints="constraints"
      :snapSettings="snapSettings" />
  </div>
</template>

<script>
import { DiagramComponent } from "@syncfusion/ej2-vue-diagrams";
import { NodeConstraints, SnapConstraints, DiagramConstraints } from '@syncfusion/ej2-diagrams';
const nodes = [
  {
    id: 'node1', width: 100, height: 100, offsetX: 150, offsetY: 200, style: { fill: 'cornflowerblue' },
    constraints: NodeConstraints.Default &
      ~(NodeConstraints.InConnect | NodeConstraints.OutConnect)

  },
  {
    id: 'node2', width: 100, height: 100, offsetX: 400, offsetY: 200, style: { fill: 'cornflowerblue' },
    constraints: NodeConstraints.Default &
      ~(NodeConstraints.InConnect | NodeConstraints.OutConnect)
  },
];
export default {
  name: "App",
  components: { "ejs-diagram": DiagramComponent },
  data() {
    return {
      nodes: nodes,
      // Enable AutomaticPortCreation
      constraints: DiagramConstraints.Default | DiagramConstraints.AutomaticPortCreation,
      snapSettings: { constraints: SnapConstraints.None },
    };
  },
};
</script>

<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
</style>

Port tooltip

The port tooltip feature allows a tooltip to be displayed when hovering over a port. This functionality can be enabled by setting the port constraints to “Tooltip”.

The following code explains how to enable port tooltip.

<template>
  <div id="app">
    <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,PortConstraints} from "@syncfusion/ej2-vue-diagrams";

const diagram = ref(null);

const nodes = [
  {
    id: 'node1',
    offsetX: 250,
    offsetY: 250,
    width: 100,
    height: 100,
    annotations: [{ content: 'Hover over port to see tooltip' }],
    ports: [
      {
        offset: { x: 1, y: 0.5 },
        visibility: PortVisibility.Visible,
        tooltip: { content: 'node port tooltip' },
        constraints:
          PortConstraints.Default |
          PortConstraints.ToolTip,
          
      },
    ],
  },
];


const connectors = [
  {
    id: 'connector1',
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 120 },
    type: 'Orthogonal',
    ports: [
      {
        offset: 0.5,
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default | PortConstraints.ToolTip,
          tooltip: { content: 'connector port tooltip' },
      },
    ],
  },
];

const width = "100%";
const height = "600px";

</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css';
</style>
<template>
  <div id="app">
    <ejs-diagram
      id="diagram"
      ref="diagram"
      :width="width"
      :height="height"
      :nodes="nodes"
      :connectors='connectors'
    ></ejs-diagram>
  </div>
</template>
<script>
import { DiagramComponent, PortVisibility, PortConstraints } from "@syncfusion/ej2-vue-diagrams";


let nodes = [
  {
    id: 'node1',
    offsetX: 250,
    offsetY: 250,
    width: 100,
    height: 100,
    annotations: [{ content: 'Hover over port to see tooltip' }],
    ports: [
      {
        offset: { x: 1, y: 0.5 },
        visibility: PortVisibility.Visible,
        tooltip: { content: 'node port tooltip' },
        constraints:
          PortConstraints.Default |
          PortConstraints.ToolTip,
          
      },
    ],
  },
];

let connectors = [
  {
    id: 'connector1',
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 120 },
    type: 'Orthogonal',
    ports: [
      {
        offset: 0.5,
        visibility: PortVisibility.Visible,
        constraints:
          PortConstraints.Default | PortConstraints.ToolTip,
          tooltip: { content: 'connector port tooltip' },
      },
    ],
  },
];


export default {
  name: "App",
  components: {
    "ejs-diagram": DiagramComponent,
  },
  data() {
    return {
      width: "100%",
      height: "600px",
      nodes:nodes,
      connectors: connectors,
    };
  },
};
</script>

<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

Events

There are several events that can be triggered while interacting with ports. These events are listed in the table below.

Event Description
Click Triggers when the port is clicked.
Element Draw Triggers when drawing a connector from the port.
Position Change Triggers when the port is dragged.
Connection Change Triggers when a connector is connected or disconnected from the port

The following example shows how to get these events in diagram.

<template>
  <div id="app">
    <ejs-diagram
      id="diagram"
      ref="diagram"
      :width="width"
      :height="height"
      :nodes="nodes"
      :connectors="connectors"
      :click="click"
      :elementDraw="elementDraw"
      :positionChange="positionChange"
      :connectionChange="connectionChange"
    ></ejs-diagram>
  </div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import {DiagramComponent as EjsDiagram,PortVisibility,PortConstraints, Connector} from "@syncfusion/ej2-vue-diagrams";

const diagram = ref(null);

const nodes = [
{
  id: "node1",
  offsetX: 250,
  offsetY: 250,
  annotations: [
    { content: "draw port", offset: { x: 0, y: 0.7 } },
    { content: "drag port", offset: { x: 1, y: 0.7 } },
  ],
  width: 100,
  height: 100,
  ports: [
    {
      id: "p1",
      offset: { x: 0, y: 0.5 },
      visibility: PortVisibility.Visible,
      constraints: PortConstraints.Default | PortConstraints.Draw,
    },
    {
      id: "p2",
      offset: { x: 1, y: 0.5 },
      visibility: PortVisibility.Visible,
      constraints: PortConstraints.Default | PortConstraints.Drag,
    },
  ],
},
];

const connectors = [
{
  id: "connector1",
  sourcePoint: { x: 100, y: 100 },
  targetPoint: { x: 300, y: 120 },
  type: "Orthogonal",
  annotations: [
    {
      content: "draw port",
      alignment: "After",
      displacement: { x: 0, y: 10 },
    },
    {
      content: "drag port",
      alignment: "After",
      offset: 0.7,
      displacement: { x: 0, y: 10 },
    },
  ],
  ports: [
    {
      id: "p1",
      offset: 0.5,
      visibility: PortVisibility.Visible,
      constraints: PortConstraints.Default | PortConstraints.Draw,
    },
    {
      id: "p2",
      offset: 0.8,
      visibility: PortVisibility.Visible,
      constraints: PortConstraints.Default | PortConstraints.Drag,
    },
  ],
},
];

const width = "100%";
const height = "600px";

const click = () => { console.log("Clicked on:"); }
const elementDraw= (args) => { 
  //Prevents connector drawn from connector port
      if (
        args.state === "Start" &&
        args.source instanceof Connector
      ) {
        args.cancel = true;
      }
 }
const positionChange = () => { console.log("Position changed:", args); }
const connectionChange = () => { console.log("Connection changed:", args); }


</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"
    :connectors="connectors"
    :click="click"
    :elementDraw="elementDraw"
    :positionChange="positionChange"
    :connectionChange="connectionChange"

  ></ejs-diagram>
</div>
</template>
<script>
import {DiagramComponent,PortVisibility,PortConstraints,Connector} from "@syncfusion/ej2-vue-diagrams";


let nodes = [
{
  id: "node1",
  offsetX: 250,
  offsetY: 250,
  annotations: [
    { content: "draw port", offset: { x: 0, y: 0.7 } },
    { content: "drag port", offset: { x: 1, y: 0.7 } },
  ],
  width: 100,
  height: 100,
  ports: [
    {
      id: "p1",
      offset: { x: 0, y: 0.5 },
      visibility: PortVisibility.Visible,
      constraints: PortConstraints.Default | PortConstraints.Draw,
    },
    {
      id: "p2",
      offset: { x: 1, y: 0.5 },
      visibility: PortVisibility.Visible,
      constraints: PortConstraints.Default | PortConstraints.Drag,
    },
  ],
},
];

let connectors = [
{
  id: "connector1",
  sourcePoint: { x: 100, y: 100 },
  targetPoint: { x: 300, y: 120 },
  type: "Orthogonal",
  annotations: [
    {
      content: "draw port",
      alignment: "After",
      displacement: { x: 0, y: 10 },
    },
    {
      content: "drag port",
      alignment: "After",
      offset: 0.7,
      displacement: { x: 0, y: 10 },
    },
  ],
  ports: [
    {
      id: "p1",
      offset: 0.5,
      visibility: PortVisibility.Visible,
      constraints: PortConstraints.Default | PortConstraints.Draw,
    },
    {
      id: "p2",
      offset: 0.8,
      visibility: PortVisibility.Visible,
      constraints: PortConstraints.Default | PortConstraints.Drag,
    },
  ],
},
];

export default {
name: "App",
components: {
  "ejs-diagram": DiagramComponent,
},
data() {
  return {
    width: "100%",
    height: "600px",
    nodes: nodes,
    connectors: connectors,
    click: function () {
      console.log("clicked");
    },
    elementDraw: function (args) {
      //Prevents connector drawn from connector port
      if (
        args.state === "Start" &&
        args.source instanceof Connector
      ) {
        args.cancel = true;
      }
    },
    positionChange: function () {
      console.log("Position change");
    },
    connectionChange: function () {
      console.log("Connection change");
    },
  };
},
};
</script>



<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

See also