Radial tree layout in Vue Diagram control

14 Dec 202424 minutes to read

A Radial tree layout is a diagram that presents information in a hierarchical structure, with a central node at the core of the diagram. The central node represents the main concept or topic, and branches extend outward in a radial fashion, creating a tree-like structure. The layout root property can be used to define the root node of the layout. When no root node is set, the algorithm automatically considers the node without any incoming edges (InEdges connector count of 0) as the root node. To create radial tree, the type of the layout as RadialTree.

The RadialTree layout provides support for adding space between the nodes. The HorizontalSpacingand VerticalSpacing properties of the layout allow you to set the space between the nodes. The arrangement results in an ever-expanding concentric arrangement with radial proximity to the root node indicating the node level in the hierarchy.

Radial tree with DataSource

You can create a radial tree layout with DataSource. The following code example illustrates how to create a radial tree layout using a data source.

<template>
    <div id="app">
  
      <ejs-diagram id="diagram" :width='width' :height='height' :dataSourceSettings='dataSourceSettings'
        :snapSettings="snapSettings" :getNodeDefaults='getNodeDefaults' :getConnectorDefaults='getConnectorDefaults'
        :layout='layout'></ejs-diagram>
  
    </div>
  </template>
  
  <script setup>
  import { provide } from "vue";
  import { DiagramComponent as EjsDiagram, RadialTree, DataBinding, SnapConstraints } from '@syncfusion/ej2-vue-diagrams';
  import { DataManager, Query } from "@syncfusion/ej2-data";
  
  //Initialize data
  let data = [
      {
          Id: 'parent',
          Name: 'Maria Anders',
          Designation: 'Managing Director'
      },
      {
          Id: '1',
          Name: 'Ana Trujillo',
          Designation: 'Project Manager',
          ReportingPerson: 'parent',
      },
      {
          Id: '2',
          Name: 'Lino Rodri',
          Designation: 'Project Manager',
          ReportingPerson: 'parent',
      },
      {
          Id: '3',
          Name: 'Philip Cramer',
          Designation: 'Project Manager',
          ReportingPerson: 'parent',
      },
      {
          Id: '4',
          Name: 'Pedro Afonso',
          Designation: 'Project Manager',
          ReportingPerson: 'parent',
      },
      {
          Id: '15',
          Name: 'Paul Henriot',
          Designation: 'Project Manager',
          ReportingPerson: 'parent',
      },
      {
          Id: '18',
          Name: 'Laura Callahan',
          Designation: 'Project Manager',
          ReportingPerson: 'parent',
      },
      {
          Id: '5',
          Name: 'Anto Moreno',
          Designation: 'Project Lead',
          ReportingPerson: '1',
      },
      {
          Id: '6',
          Name: 'Elizabeth Roel',
          Designation: 'Project Lead',
          ReportingPerson: '1',
      },
      {
          Id: '7',
          Name: 'Aria Cruz',
          Designation: 'Project Lead',
          ReportingPerson: '18',
      },
      {
          Id: '8',
          Name: 'Eduardo Roel',
          Designation: 'Project Lead',
          ReportingPerson: '18',
      },
      {
          Id: '9',
          Name: 'Howard Snyd',
          Designation: 'Project Lead',
          ReportingPerson: '2',
      },
      {
          Id: '10',
          Name: 'Daniel Tonini',
          Designation: 'Project Lead',
          ReportingPerson: '2',
      },
      {
          Id: '11',
          Name: 'Nardo Batista',
          Designation: 'Project Lead',
          ReportingPerson: '3',
      },
      {
          Id: '12',
          Name: 'Michael Holz',
          Designation: 'Project Lead',
          ReportingPerson: '3',
      },
      {
          Id: '13',
          Name: 'Kloss Perrier',
          Designation: 'Project Lead',
          ReportingPerson: '4',
      },
      {
          Id: '14',
          Name: 'Liz Nixon',
          Designation: 'Project Lead',
          ReportingPerson: '4',
      },
      {
          Id: '16',
          Name: 'Paula Parente',
          Designation: 'Project Lead',
          ReportingPerson: '15',
      },
      {
          Id: '17',
          Name: 'Matti Kenna',
          Designation: 'Project Lead',
          ReportingPerson: '15',
      }
  ];
  
  let items = new DataManager(data, new Query().take(7));
  
  const width = "1000px";
  const height = "590px";
  const snapSettings = { constraints: SnapConstraints.None };
  
  //Configures data source for Diagram
  const dataSourceSettings = {
    id: 'Id',
    parentId: 'ReportingPerson',
    dataSource: items,
  }
  
  //Uses layout to auto-arrange nodes on the Diagram page
  const layout = {
    //Sets layout type
    type: 'RadialTree',
    root: 'parent'
  }
  
  //Sets the default properties for nodes and connectors
  const getNodeDefaults = (node) => {
    node.width = 20; node.height = 20;
    return node;
  }
  const getConnectorDefaults = (connector) => {
    connector.type = 'Straight';
    connector.targetDecorator.shape = 'None';
    return connector;
  }
  
  provide('diagram', [RadialTree, DataBinding]);
  
  </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'
            :getConnectorDefaults='getConnectorDefaults' :layout='layout' :snapSettings='snapSettings'
            :dataSourceSettings='dataSourceSettings'></ejs-diagram>
    </div>
</template>
<script>
import { DiagramComponent, RadialTree, DataBinding } from '@syncfusion/ej2-vue-diagrams';
import { DataManager, Query } from "@syncfusion/ej2-data";

let data = [
    {
        Id: 'parent',
        Name: 'Maria Anders',
        Designation: 'Managing Director'
    },
    {
        Id: '1',
        Name: 'Ana Trujillo',
        Designation: 'Project Manager',
        ReportingPerson: 'parent',
    },
    {
        Id: '2',
        Name: 'Lino Rodri',
        Designation: 'Project Manager',
        ReportingPerson: 'parent',
    },
    {
        Id: '3',
        Name: 'Philip Cramer',
        Designation: 'Project Manager',
        ReportingPerson: 'parent',
    },
    {
        Id: '4',
        Name: 'Pedro Afonso',
        Designation: 'Project Manager',
        ReportingPerson: 'parent',
    },
    {
        Id: '15',
        Name: 'Paul Henriot',
        Designation: 'Project Manager',
        ReportingPerson: 'parent',
    },
    {
        Id: '18',
        Name: 'Laura Callahan',
        Designation: 'Project Manager',
        ReportingPerson: 'parent',
    },
    {
        Id: '5',
        Name: 'Anto Moreno',
        Designation: 'Project Lead',
        ReportingPerson: '1',
    },
    {
        Id: '6',
        Name: 'Elizabeth Roel',
        Designation: 'Project Lead',
        ReportingPerson: '1',
    },
    {
        Id: '7',
        Name: 'Aria Cruz',
        Designation: 'Project Lead',
        ReportingPerson: '18',
    },
    {
        Id: '8',
        Name: 'Eduardo Roel',
        Designation: 'Project Lead',
        ReportingPerson: '18',
    },
    {
        Id: '9',
        Name: 'Howard Snyd',
        Designation: 'Project Lead',
        ReportingPerson: '2',
    },
    {
        Id: '10',
        Name: 'Daniel Tonini',
        Designation: 'Project Lead',
        ReportingPerson: '2',
    },
    {
        Id: '11',
        Name: 'Nardo Batista',
        Designation: 'Project Lead',
        ReportingPerson: '3',
    },
    {
        Id: '12',
        Name: 'Michael Holz',
        Designation: 'Project Lead',
        ReportingPerson: '3',
    },
    {
        Id: '13',
        Name: 'Kloss Perrier',
        Designation: 'Project Lead',
        ReportingPerson: '4',
    },
    {
        Id: '14',
        Name: 'Liz Nixon',
        Designation: 'Project Lead',
        ReportingPerson: '4',
    },
    {
        Id: '16',
        Name: 'Paula Parente',
        Designation: 'Project Lead',
        ReportingPerson: '15',
    },
    {
        Id: '17',
        Name: 'Matti Kenna',
        Designation: 'Project Lead',
        ReportingPerson: '15',
    }
];

let items = new DataManager(data, new Query().take(7));
export default {
    name: "App",
    components: {
        "ejs-diagram": DiagramComponent
    },
    data() {
        return {
            width: "1000px",
            height: "590px",
            snapSettings: { constraints: 0 },

            //Uses layout to auto-arrange nodes on the Diagram page
            layout: {
                //Sets layout type
                type: 'RadialTree',
                root: 'parent'
            },
            //Configures data source for Diagram
            dataSourceSettings: {
                id: 'Id',
                parentId: 'ReportingPerson',
                dataSource: items,
            },
            //Sets the default properties for nodes and connectors
            getNodeDefaults: (node) => {
                node.width = 20; node.height = 20;
                return node;
            },
            getConnectorDefaults: (connector) => {
                connector.type = 'Straight';
                connector.targetDecorator.shape = 'None';
                return connector;
            },
        }
    },
    provide: {
        diagram: [RadialTree, DataBinding]
    },
}
</script>

NOTE

If you want to convert the data source into layout, you need to inject DataBinding along with RadialTree module in the diagram.

Radial tree with nodes and connectors

You can render a radial tree layout without using DataSource. The following code demonstrates how to render a radial tree layout without using data source.

<template>
    <div id="app">
  
      <ejs-diagram id="diagram" :width='width' :height='height' :nodes='nodes' :connectors='connectors'
        :snapSettings="snapSettings" :getNodeDefaults='getNodeDefaults' :getConnectorDefaults='getConnectorDefaults'
        :layout='layout'></ejs-diagram>
  
    </div>
  </template>
  
  <script setup>
  import { provide } from "vue";
  import { DiagramComponent as EjsDiagram, RadialTree, DataBinding, SnapConstraints } from '@syncfusion/ej2-vue-diagrams';
  
  //Initialize nodes for diagram
  let nodes = [
    { id: 'Maria Anders' },
    { id: 'Ana Trujillo' },
    { id: 'Lino Rodri' },
    { id: 'Philip Cramer' },
    { id: 'Pedro Afonso' },
    { id: 'Paul Henriot' },
    { id: 'Laura Callahan' },
    { id: 'Anto Moreno' },
    { id: 'Elizabeth Roel' },
    { id: 'Aria Cruz' },
    { id: 'Eduardo Roel' },
    { id: 'Howard Snyd' },
    { id: 'Daniel Tonini' },
    { id: 'Nardo Batista' },
    { id: 'Michael Holz' },
    { id: 'Kloss Perrier' },
    { id: 'Liz Nixon' },
    { id: 'Paula Parente' },
    { id: 'Matti Kenna' },
  ];
  
  //Initialize connectors for diagram
  let connectors = [
    {
      id: 'Maria Anders-Ana Trujillo',
      sourceID: 'Maria Anders',
      targetID: 'Ana Trujillo',
    },
    {
      id: 'Maria Anders-Lino Rodri',
      sourceID: 'Maria Anders',
      targetID: 'Lino Rodri',
    },
    {
      id: 'Maria Anders-Philip Cramer',
      sourceID: 'Maria Anders',
      targetID: 'Philip Cramer',
    },
    {
      id: 'Maria Anders-Pedro Afonso',
      sourceID: 'Maria Anders',
      targetID: 'Pedro Afonso',
    },
    {
      id: 'Maria Anders-Paul Henriot',
      sourceID: 'Maria Anders',
      targetID: 'Paul Henriot',
    },
    {
      id: 'Maria Anders-Laura Callahan',
      sourceID: 'Maria Anders',
      targetID: 'Laura Callahan',
    },
    {
      id: 'Ana Trujillo-Anto Moreno',
      sourceID: 'Ana Trujillo',
      targetID: 'Anto Moreno',
    },
    {
      id: 'Ana Trujillo-Elizabeth Roel',
      sourceID: 'Ana Trujillo',
      targetID: 'Elizabeth Roel',
    },
    {
      id: 'Laura Callahan-Aria Cruz',
      sourceID: 'Laura Callahan',
      targetID: 'Aria Cruz',
    },
    {
      id: 'Laura Callahan-Eduardo Roel',
      sourceID: 'Laura Callahan',
      targetID: 'Eduardo Roel',
    },
    {
      id: 'Lino Rodri-Howard Snyd',
      sourceID: 'Lino Rodri',
      targetID: 'Howard Snyd',
    },
    {
      id: 'Lino Rodri-Daniel Tonini',
      sourceID: 'Lino Rodri',
      targetID: 'Daniel Tonini',
    },
    {
      id: 'Philip Cramer-Nardo Batista',
      sourceID: 'Philip Cramer',
      targetID: 'Nardo Batista',
    },
    {
      id: 'Philip Cramer-Michael Holz',
      sourceID: 'Philip Cramer',
      targetID: 'Michael Holz',
    },
    {
      id: 'Pedro Afonso-Kloss Perrier',
      sourceID: 'Pedro Afonso',
      targetID: 'Kloss Perrier',
    },
    {
      id: 'Pedro Afonso-Liz Nixon',
      sourceID: 'Pedro Afonso',
      targetID: 'Liz Nixon',
    },
    {
      id: 'Paul Henriot-Paula Parente',
      sourceID: 'Paul Henriot',
      targetID: 'Paula Parente',
    },
    {
      id: 'Paul Henriot-Matti Kenna',
      sourceID: 'Paul Henriot',
      targetID: 'Matti Kenna',
    }
  ];
  
  const width = "1000px";
  const height = "590px";
  const snapSettings = { constraints: SnapConstraints.None };
  
  //Uses layout to auto-arrange nodes on the Diagram page
  const layout = {
    //Sets layout type
    type: 'RadialTree',
    root: 'parent'
  }
  
  //Sets the default properties for nodes and connectors
  const getNodeDefaults = (node) => {
    node.width = 20; node.height = 20;
    return node;
  }
  const getConnectorDefaults = (connector) => {
    connector.type = 'Straight';
    connector.targetDecorator.shape = 'None';
    return connector;
  }
  
  provide('diagram', [RadialTree, DataBinding]);
  
  </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' :connectors='connectors'
            :getNodeDefaults='getNodeDefaults' :getConnectorDefaults='getConnectorDefaults' :snapSettings='snapSettings'
            :layout='layout'></ejs-diagram>
    </div>
</template>
<script>
import { DiagramComponent, RadialTree, DataBinding } from '@syncfusion/ej2-vue-diagrams';

//Initialize nodes for diagram
let nodes = [
    { id: 'Maria Anders' },
    { id: 'Ana Trujillo' },
    { id: 'Lino Rodri' },
    { id: 'Philip Cramer' },
    { id: 'Pedro Afonso' },
    { id: 'Paul Henriot' },
    { id: 'Laura Callahan' },
    { id: 'Anto Moreno' },
    { id: 'Elizabeth Roel' },
    { id: 'Aria Cruz' },
    { id: 'Eduardo Roel' },
    { id: 'Howard Snyd' },
    { id: 'Daniel Tonini' },
    { id: 'Nardo Batista' },
    { id: 'Michael Holz' },
    { id: 'Kloss Perrier' },
    { id: 'Liz Nixon' },
    { id: 'Paula Parente' },
    { id: 'Matti Kenna' },
];

//Initialize connectors for diagram
let connectors = [
    {
        id: 'Maria Anders-Ana Trujillo',
        sourceID: 'Maria Anders',
        targetID: 'Ana Trujillo',
    },
    {
        id: 'Maria Anders-Lino Rodri',
        sourceID: 'Maria Anders',
        targetID: 'Lino Rodri',
    },
    {
        id: 'Maria Anders-Philip Cramer',
        sourceID: 'Maria Anders',
        targetID: 'Philip Cramer',
    },
    {
        id: 'Maria Anders-Pedro Afonso',
        sourceID: 'Maria Anders',
        targetID: 'Pedro Afonso',
    },
    {
        id: 'Maria Anders-Paul Henriot',
        sourceID: 'Maria Anders',
        targetID: 'Paul Henriot',
    },
    {
        id: 'Maria Anders-Laura Callahan',
        sourceID: 'Maria Anders',
        targetID: 'Laura Callahan',
    },
    {
        id: 'Ana Trujillo-Anto Moreno',
        sourceID: 'Ana Trujillo',
        targetID: 'Anto Moreno',
    },
    {
        id: 'Ana Trujillo-Elizabeth Roel',
        sourceID: 'Ana Trujillo',
        targetID: 'Elizabeth Roel',
    },
    {
        id: 'Laura Callahan-Aria Cruz',
        sourceID: 'Laura Callahan',
        targetID: 'Aria Cruz',
    },
    {
        id: 'Laura Callahan-Eduardo Roel',
        sourceID: 'Laura Callahan',
        targetID: 'Eduardo Roel',
    },
    {
        id: 'Lino Rodri-Howard Snyd',
        sourceID: 'Lino Rodri',
        targetID: 'Howard Snyd',
    },
    {
        id: 'Lino Rodri-Daniel Tonini',
        sourceID: 'Lino Rodri',
        targetID: 'Daniel Tonini',
    },
    {
        id: 'Philip Cramer-Nardo Batista',
        sourceID: 'Philip Cramer',
        targetID: 'Nardo Batista',
    },
    {
        id: 'Philip Cramer-Michael Holz',
        sourceID: 'Philip Cramer',
        targetID: 'Michael Holz',
    },
    {
        id: 'Pedro Afonso-Kloss Perrier',
        sourceID: 'Pedro Afonso',
        targetID: 'Kloss Perrier',
    },
    {
        id: 'Pedro Afonso-Liz Nixon',
        sourceID: 'Pedro Afonso',
        targetID: 'Liz Nixon',
    },
    {
        id: 'Paul Henriot-Paula Parente',
        sourceID: 'Paul Henriot',
        targetID: 'Paula Parente',
    },
    {
        id: 'Paul Henriot-Matti Kenna',
        sourceID: 'Paul Henriot',
        targetID: 'Matti Kenna',
    }
];

export default {
    name: "App",
    components: {
        "ejs-diagram": DiagramComponent
    },
    data() {
        return {
            width: "1000px",
            height: "590px",
            nodes: nodes,
            connectors: connectors,
            snapSettings: { constraints: 0 },
            //Uses layout to auto-arrange nodes on the Diagram page
            layout: {
                //Sets layout type
                type: 'RadialTree',
                root: 'parent'

            },
            //Sets the default properties for nodes and connectors
            getNodeDefaults: (node) => {
                node.width = 20; node.height = 20;
                return node;
            },
            getConnectorDefaults: (connector) => {
                connector.type = 'Straight';
                connector.targetDecorator.shape = 'None';
                return connector;
            },
        }
    },
    provide: {
        diagram: [RadialTree, DataBinding]
    }
}
</script>

NOTE

If you want to use radial tree layout in diagram, you need to inject RadialTree in the diagram.

Radial tree