Nodes in Vue Diagram component

12 Nov 202424 minutes to read

Nodes are graphical objects used to visually represent the geometrical information, process flow, internal business procedure, entity, or any other kind of data, and it represents the functions of a complete system regarding to how it interacts with external entities.

Node

Create node

A node can be created and added to the diagram either programmatically or interactively. The id property of a node is used to define its unique identifier and can later be used to find the node at runtime for customization. Nodes are stacked on the diagram area from bottom to top in the order they are added.

NOTE

Note: There should not be any white-spaces in the ID string while setting the ID.

Add node through nodes collection

To create a node, define the node object and add that to nodes collection of the diagram model. The following code example illustrates how to add a node to the diagram.

<template>
    <div id="app">
        <ejs-diagram id="diagram" :width='width' :height='height' :nodes='nodes'></ejs-diagram>
    </div>
</template>
<script setup>
import { DiagramComponent as EjsDiagram } from '@syncfusion/ej2-vue-diagrams';

const nodes = [{
    // Position of the node
    offsetX: 250,
    offsetY: 250,
    // Size of the node
    width: 100,
    height: 100,
    style: {
        fill: '#6BA5D7',
        strokeColor: 'white'
    },
    // Text(label) added to the node
}];

const width = "100%";
const height = "700px";
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
    <div id="app">
        <ejs-diagram id="diagram" :width='width' :height='height' :nodes='nodes'></ejs-diagram>
    </div>
</template>
<script>
import { DiagramComponent } from '@syncfusion/ej2-vue-diagrams';

let nodes = [{
    // Position of the node
    offsetX: 250,
    offsetY: 250,
    // Size of the node
    width: 100,
    height: 100,
    style: {
        fill: '#6BA5D7',
        strokeColor: 'white'
    },
    // Text(label) added to the node
}];

export default {
    name: "App",
    components: {
        "ejs-diagram": DiagramComponent
    },
    data() {
        return {
            width: "100%",
            height: "700px",
            nodes: nodes,
        }
    }
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

NOTE

Node id should not begin with numbers(should begin with a letter). Node Id should be unique for all the shapes and connectors.

Add/Remove node at runtime

Nodes can be added at runtime by using public method, add and can be removed at runtime by using public method, remove. On adding node at runtime, the nodes collection is changed and the collectionChange event will trigger.

The following code illustrates how to add a node.

<template>
    <div id="app">
        <button @click="add">add</button>
        <button @click="remove">remove</button>
        <ejs-diagram id="diagram" :width='width' :height='height' :nodes='nodes'></ejs-diagram>
    </div>
</template>
<script setup>
import { ref } from "vue";
import { DiagramComponent as EjsDiagram } from '@syncfusion/ej2-vue-diagrams';

const diagram = ref(null);
const nodes = [{
    // Position of the node
    offsetX: 250,
    offsetY: 250,
    // Size of the node
    width: 100,
    height: 100,
    style: {
        fill: '#6BA5D7',
        strokeColor: 'white'
    },
    // Text(label) added to the node
}];

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

const add = function () {
    diagram.value.ej2Instances.add(nodes);
}
const remove = function () {
    diagram.value.ej2Instances.remove(diagram.value.ej2Instances.nodes[0]);
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
  <div id="app">
    <button @click="add">add</button>
    <button @click="remove">remove</button>
    <ejs-diagram
      id="diagram"
      ref="diagram"
      :width="width"
      :height="height"
    ></ejs-diagram>
  </div>
</template>
<script>
import { DiagramComponent } from '@syncfusion/ej2-vue-diagrams';

let nodes = {
  // Position of the node
  offsetX: 250,
  offsetY: 250,
  // Size of the node
  width: 100,
  height: 100,
  style: {
    fill: '#6BA5D7',
    strokeColor: 'white',
  },
  // Text(label) added to the node
};

export default {
  name: 'App',
  components: {
    'ejs-diagram': DiagramComponent,
  },
  data() {
    return {
      width: '100%',
      height: '350px',
    };
  },
  methods: {
    add() {
      // Adds node to the diagram
      this.$refs.diagram.ej2Instances.add(nodes);
    },
    remove() {
      // remove node from the diagram
      this.$refs.diagram.ej2Instances.remove(
        this.$refs.diagram.ej2Instances.nodes[0]
      );
    },
  },
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

Add collection of nodes at runtime

The collection of nodes can be dynamically added using addElements method.Each time an element is added to the diagram canvas, the collectionChange event will be triggered.

The following code illustrates how to add a nodes collection at runtime.

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

const diagram = ref(null);
const nodes = [
    { id: 'node16', offsetX: 35, offsetY: 260 },
    { id: 'node17', offsetX: 140, offsetY: 260 },
    { id: 'node18', offsetX: 240, offsetY: 260 }
];

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

onMounted(function () {
    const diagramInstance = diagram.value.ej2Instances;
    //Add collection of nodes
    diagramInstance.addElements(nodes)
});

</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'></ejs-diagram>
    </div>
</template>
<script>
import { DiagramComponent } from '@syncfusion/ej2-vue-diagrams';
const nodes = [
    { id: 'node16', offsetX: 35, offsetY: 260 },
    { id: 'node17', offsetX: 140, offsetY: 260 },
    { id: 'node18', offsetX: 240, offsetY: 260 }
];

export default {
    name: "App",
    components: {
        "ejs-diagram": DiagramComponent
    },
    data() {
        return {
            width: "100%",
            height: "350px",
        }
    },
    mounted: function () {
        const diagramInstance = this.$refs.diagram.ej2instances;
          //Add collection of nodes
          diagramInstance.addElements(nodes)
    }
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

Add node from palette

Nodes can be predefined and added to the palette, and can be dropped into the diagram when needed. For more information about adding nodes from symbol palette, refer to Symbol Palette.

The following code illustrates how to add a nodes collection at runtime.

<template>
  <div id="app">
    <div style="width: 100%">
      <div id="palette-space" style="width: 25%; float: left">
        <ejs-symbolpalette
          id="symbolpalette"
          :expandMode="expandMode"
          :palettes="palettes"
          :symbolMargin="symbolMargin"
          :width="palettewidth"
          :height="paletteheight"
          :symbolHeight="symbolHeight"
          :symbolWidth="symbolWidth"
        >
        </ejs-symbolpalette>
      </div>
      <div id="diagram-space" style="width: 75%; float: right">
        <ejs-diagram
          id="diagram"
          ref="diagram"
          :width="width"
          :height="height"
        ></ejs-diagram>
      </div>
    </div>
  </div>
</template>
<script setup>
import { ref } from "vue";
import { DiagramComponent as EjsDiagram } from '@syncfusion/ej2-vue-diagrams';
import { SymbolPaletteComponent as EjsSymbolpalette } from '@syncfusion/ej2-vue-diagrams';

const diagram = ref(null);
const basicShapes = [
  {
    id: 'Rectangle',
    shape: {
      type: 'Basic',
      shape: 'Rectangle',
    },
  },
  {
    id: 'Ellipse',
    shape: {
      type: 'Basic',
      shape: 'Ellipse',
    },
  },
  {
    id: 'Hexagon',
    shape: {
      type: 'Basic',
      shape: 'Hexagon',
    },
  },
];

const width = "100%";
const height = "700px";
const palettes = [
        {
          id: 'basic',
          expanded: true,
          symbols: basicShapes,
          title: 'Basic Shapes',
          iconCss: 'e-ddb-icons e-basic',
        },
      ];
const symbolMargin = {
        left: 15,
        right: 15,
        top: 15,
        bottom: 15,
      };
const palettewidth= "100%";
const paletteheight= "700px";
const symbolHeight= 60;
const symbolWidth= 60;

</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
  <div id="app">
    <div style="width: 100%">
      <div id="palette-space" style="width: 25%; float: left">
        <ejs-symbolpalette
          id="symbolpalette"
          :expandMode="expandMode"
          :palettes="palettes"
          :symbolMargin="symbolMargin"
          :width="palettewidth"
          :height="paletteheight"
          :symbolHeight="symbolHeight"
          :symbolWidth="symbolWidth"
        >
        </ejs-symbolpalette>
      </div>
      <div id="diagram-space" style="width: 75%; float: right">
        <ejs-diagram
          id="diagram"
          ref="diagram"
          :width="width"
          :height="height"
        ></ejs-diagram>
      </div>
    </div>
  </div>
</template>
<script>
import { DiagramComponent } from '@syncfusion/ej2-vue-diagrams';
import { SymbolPaletteComponent } from '@syncfusion/ej2-vue-diagrams';

let basicShapes = [
  {
    id: 'Rectangle',
    shape: {
      type: 'Basic',
      shape: 'Rectangle',
    },
  },
  {
    id: 'Ellipse',
    shape: {
      type: 'Basic',
      shape: 'Ellipse',
    },
  },
  {
    id: 'Hexagon',
    shape: {
      type: 'Basic',
      shape: 'Hexagon',
    },
  },
];

export default {
  name: 'App',
  components: {
    'ejs-diagram': DiagramComponent,
    'ejs-symbolpalette': SymbolPaletteComponent,
  },
  data() {
    return {
      width: '100%',
      height: '700px',
      //Defines the palette collection
      palettes: [
        {
          id: 'basic',
          expanded: true,
          symbols: basicShapes,
          title: 'Basic Shapes',
          iconCss: 'e-ddb-icons e-basic',
        },
      ],
      symbolMargin: {
        left: 15,
        right: 15,
        top: 15,
        bottom: 15,
      },
      palettewidth: '100%',
      paletteheight: '700px',
      symbolHeight: 60,
      symbolWidth: 60,
    };
  },
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

Create node through data source

Nodes can be generated automatically with the information provided through data source. The default properties for
these nodes are fetched from default settings (getNodeDefaults). For more information about data source, refer to DataBinding.

The following code illustrates how to add a nodes collection at runtime.

<template>
    <div id="app">
        <ejs-diagram id="diagram" :width='width' :height='height' :getNodeDefaults='getNodeDefaults'
            :layout='layout'
            :dataSourceSettings='dataSourceSettings'></ejs-diagram>
    </div>
</template>
<script setup>
import { provide } from "vue";
import { DiagramComponent as EjsDiagram, HierarchicalTree, DataBinding } from '@syncfusion/ej2-vue-diagrams';
import { DataManager, Query } from "@syncfusion/ej2-data";

provide('diagram', [DataBinding, HierarchicalTree]);

let data = [{
    Name: "Steve-Ceo"
}];
let items = new DataManager(data, new Query().take(7));

const width = "100%";
const height = "700px";
//Uses layout to auto-arrange nodes on the Diagram page
const layout = {
    //Sets layout type
    type: 'HierarchicalTree'
};
const dataSourceSettings = {
    id: 'Name',
    parentId: 'ReportingPerson',
    dataManager: items
};
const getNodeDefaults = (obj) => {
    obj.shape = {
        type: 'Text',
    };
    obj.style = {
        fill: 'yellow',
        strokeColor: 'yellow',
        bold: true,
        color: 'white'
    };
    obj.borderColor = 'white';
    obj.width = 100;
    obj.height = 100;
    obj.offsetX = 300;
    obj.offsetY = 200;
    obj.borderWidth = 1;
    obj.shape.margin = {
        left: 5,
        right: 5,
        top: 5,
        bottom: 5
    };
    return obj;
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
  <div id="app">
    <ejs-diagram
      id="diagram"
      :width="width"
      :height="height"
      :getNodeDefaults="getNodeDefaults"
      :layout="layout"
      :dataSourceSettings="dataSourceSettings"
    ></ejs-diagram>
  </div>
</template>
<script>
import {
  DiagramComponent,
  HierarchicalTree,
  DataBinding,
} from '@syncfusion/ej2-vue-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';

let data = [
  {
    Name: 'Steve-Ceo',
  },
];
let items = new DataManager(data, new Query().take(7));
export default {
  name: 'App',
  components: {
    'ejs-diagram': DiagramComponent,
  },
  data() {
    return {
      width: '100%',
      height: '700px',
      //Uses layout to auto-arrange nodes on the Diagram page
      layout: {
        //Sets layout type
        type: 'HierarchicalTree',
      },
      dataSourceSettings: {
        id: 'Name',
        parentId: 'ReportingPerson',
        dataManager: items,
      },
      getNodeDefaults: (obj) => {
        obj.shape = {
          type: 'Text',
        };
        obj.style = {
          fill: 'yellow',
          strokeColor: 'yellow',
          bold: true,
          color: 'white',
        };
        obj.borderColor = 'white';
        obj.width = 100;
        obj.height = 100;
        obj.offsetX = 300;
        obj.offsetY = 200;
        obj.borderWidth = 1;
        obj.shape.margin = {
          left: 5,
          right: 5,
          top: 5,
          bottom: 5,
        };
        return obj;
      },
    };
  },
  provide: {
    diagram: [DataBinding, HierarchicalTree],
  },
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

Draw nodes

Nodes can be interactively drawn by clicking and dragging the diagram surface.

To draw a shape, you have to activate the drawing tool by setting DrawOnce or ContinuousDraw to the tool property and you need to set the node object by using the drawingObject property. The following code example illustrates how to draw a rectangle at runtime.

The following code illustrates how to add a nodes collection at runtime.

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

const diagram = ref(null);
const width = "100%";
const height = "350px";
const getNodeDefaults = (obj) => {
    obj.borderWidth = 1;
    obj.style = {
        fill: '#6BA5D7',
        strokeWidth: 2,
        strokeColor: '#6BA5D7'
    };
    return obj;
}
onMounted(function () {
    const diagramInstance = diagram.value.ej2Instances;
    let drawingshape = { type: 'Basic', shape: 'Rectangle' };
    let node = {
        shape: drawingshape
    };
    diagramInstance.drawingObject = node;
    //To draw an object once, activate draw once
    diagramInstance.tool = DiagramTools.ContinuousDraw;
    diagramInstance.dataBind();
})
</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"
      :getNodeDefaults="getNodeDefaults"
    ></ejs-diagram>
  </div>
</template>
<script>
import { DiagramComponent, DiagramTools } from '@syncfusion/ej2-vue-diagrams';

export default {
  name: 'App',
  components: {
    'ejs-diagram': DiagramComponent,
  },
  data() {
    return {
      width: '100%',
      height: '350px',
      getNodeDefaults: (obj) => {
        obj.borderWidth = 1;
        obj.style = {
          fill: '#6BA5D7',
          strokeWidth: 2,
          strokeColor: '#6BA5D7',
        };
        return obj;
      },
    };
  },
  mounted: function () {
    const diagramInstance = this.$refs.diagram.ej2Instances;
    let drawingshape = { type: 'Basic', shape: 'Rectangle' };
    let node = {
      shape: drawingshape,
    };
    diagramInstance.drawingObject = node;
    //To draw an object once, activate draw once
    diagramInstance.tool = DiagramTools.ContinuousDraw;
    diagramInstance.dataBind();
  },
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

Update node at runtime

You can modify any node properties at runtime, and the changes will be instantly reflected. For example, here you can change the size and color of the node.

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

const diagram = ref(null);
const width = "100%";
const height = "350px";
const getNodeDefaults = (obj) => {
    obj.borderWidth = 1;
    obj.style = {
        fill: '#6BA5D7',
        strokeWidth: 2,
        strokeColor: '#6BA5D7'
    };
    return obj;
}
const size = () => {
      if (this.$refs.diagram.ej2Instances.nodes[0].width === 100) {
        this.$refs.diagram.ej2Instances.nodes[0].width = 200;
      } else {
        this.$refs.diagram.ej2Instances.nodes[0].width = 100;
      }
    }
const color = () => {
      if (this.$refs.diagram.ej2Instances.nodes[0].style.fill === '#6BA5D7') {
        this.$refs.diagram.ej2Instances.nodes[0].style.fill = 'orange';
      } else {
        this.$refs.diagram.ej2Instances.nodes[0].style.fill = '#6BA5D7';
      }
    }
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
  <div id="app">
    <button @click="size">Change Size</button>
    <button @click="color">Change Color</button>
    <ejs-diagram
      id="diagram"
      ref="diagram"
      :width="width"
      :height="height"
      :nodes="nodes"
    ></ejs-diagram>
  </div>
</template>
<script>
import { DiagramComponent } from '@syncfusion/ej2-vue-diagrams';

let nodes = [
  {
    // Position of the node
    offsetX: 250,
    offsetY: 250,
    // Size of the node
    width: 100,
    height: 100,
    style: {
      fill: '#6BA5D7',
      strokeColor: 'white',
    },
    // Text(label) added to the node
  },
];

export default {
  name: 'App',
  components: {
    'ejs-diagram': DiagramComponent,
  },
  data() {
    return {
      width: '100%',
      height: '700px',
      nodes: nodes,
    };
  },
  methods: {
    size() {
      if (this.$refs.diagram.ej2Instances.nodes[0].width === 100) {
        this.$refs.diagram.ej2Instances.nodes[0].width = 200;
      } else {
        this.$refs.diagram.ej2Instances.nodes[0].width = 100;
      }
    },
    color() {
      if (this.$refs.diagram.ej2Instances.nodes[0].style.fill === '#6BA5D7') {
        this.$refs.diagram.ej2Instances.nodes[0].style.fill = 'orange';
      } else {
        this.$refs.diagram.ej2Instances.nodes[0].style.fill = '#6BA5D7';
      }
    },
  },
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

NOTE

Once the property is updated, you should call the dataBind to reflect the changes instantly.

Clone node at runtime

Cloning a node creates a new node instance with identical properties and attributes. You can clone a node using the copy and paste public methods of the diagram model.

The following code example illustrates how to clone node at runtime

<template>
    <div id="app">
        <ejs-diagram id="diagram" :width='width' :height='height' :nodes='nodes'></ejs-diagram>
    </div>
</template>
<script setup>
import { DiagramComponent as EjsDiagram } from '@syncfusion/ej2-vue-diagrams';

const nodes = [{
    // Position of the node
    offsetX: 250,
    offsetY: 250,
    // Size of the node
    width: 100,
    height: 100,
    style: {
        fill: '#6BA5D7',
        strokeColor: 'white'
    },
    // Text(label) added to the node
}];

const width = "100%";
const height = "700px";
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>
<template>
    <div id="app">
        <ejs-diagram id="diagram" :width='width' :height='height' :nodes='nodes'></ejs-diagram>
    </div>
</template>
<script>
import { DiagramComponent } from '@syncfusion/ej2-vue-diagrams';

let nodes = [{
    // Position of the node
    offsetX: 250,
    offsetY: 250,
    // Size of the node
    width: 100,
    height: 100,
    style: {
        fill: '#6BA5D7',
        strokeColor: 'white'
    },
    // Text(label) added to the node
}];

export default {
    name: "App",
    components: {
        "ejs-diagram": DiagramComponent
    },
    data() {
        return {
            width: "100%",
            height: "700px",
            nodes: nodes,
        }
    }
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-vue-diagrams/styles/material.css";
</style>

Add nodes from tree view

By customizing the dragEnter functionality, you can allow elements from other components, such as the tree view, to be converted into nodes based on the data of the dragged element.

See Also