Radial tree layout in React Diagram control

6 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.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, DataBinding, RadialTree } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";

//Initializes data source
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 function App() {
    return (
        <DiagramComponent
            id="container"
            width={"100%"}
            height={"550px"}
            snapSettings={{ constraints: 0 }}

            //Uses layout to auto-arrange nodes on the diagram page
            layout={{
                //set layout type
                type: 'RadialTree',
                root: 'parent'
            }}

            //Configures data source for diagram
            dataSourceSettings={{
                id: 'Id',
                parentId: 'ReportingPerson',
                dataSource: items
            }}

            //Sets the default properties for nodes
            getNodeDefaults={(node) => {
                node.height = 20;
                node.width = 20;
                return node;
            }}

            //Sets the default properties for connectors
            getConnectorDefaults={(connector) => {
                connector.targetDecorator.shape = 'None';
                connector.type = 'Straight';
                return connector;
            }}
        >

            {/* Inject necessary services for the diagram */}
            <Inject services={[DataBinding, RadialTree]} />
        </DiagramComponent>
    );
}

// Render the App component into the 'diagram' element in the DOM
const root = ReactDOM.createRoot(document.getElementById("diagram"));
root.render(<App />);
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, ConnectorModel, DataBinding, NodeModel, RadialTree, DecoratorModel } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";

//Initializes data source
let data: object[] = [
  {
    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: DataManager = new DataManager(data as JSON[], new Query().take(7));

export default function App() {
  return (
    <DiagramComponent
      id="container"
      width={"100%"}
      height={"550px"}
      snapSettings={{ constraints: 0 }}

      //Uses layout to auto-arrange nodes on the diagram page
      layout={{
        //set layout type
        type: 'RadialTree',
        root: 'parent'
      }}

      //Configures data source for diagram
      dataSourceSettings={{
        id: 'Id',
        parentId: 'ReportingPerson',
        dataSource: items
      }}

      //Sets the default properties for nodes
      getNodeDefaults={(node: NodeModel) => {
        node.height = 20;
        node.width = 20;
        return node;
      }}

      //Sets the default properties for connectors
      getConnectorDefaults={(connector: ConnectorModel) => {
        (connector.targetDecorator as DecoratorModel).shape = 'None';
        connector.type = 'Straight';
        return connector;
      }}
    >

      {/* Inject necessary services for the diagram */}
      <Inject services={[DataBinding, RadialTree]} />
    </DiagramComponent>
  );
}

// Render the App component into the 'diagram' element in the DOM
const root = ReactDOM.createRoot(document.getElementById("diagram") as HTMLElement);
root.render(<App />);

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.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, DataBinding, RadialTree } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";

//Initializes data source
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 function App() {
    return (
        <DiagramComponent
            id="container"
            width={"100%"}
            height={"550px"}
            snapSettings={{ constraints: 0 }}

            //Uses layout to auto-arrange nodes on the diagram page
            layout={{
                //set layout type
                type: 'RadialTree',
                root: 'parent'
            }}

            //Configures data source for diagram
            dataSourceSettings={{
                id: 'Id',
                parentId: 'ReportingPerson',
                dataSource: items
            }}

            //Sets the default properties for nodes
            getNodeDefaults={(node) => {
                node.height = 20;
                node.width = 20;
                return node;
            }}

            //Sets the default properties for connectors
            getConnectorDefaults={(connector) => {
                connector.targetDecorator.shape = 'None';
                connector.type = 'Straight';
                return connector;
            }}
        >

            {/* Inject necessary services for the diagram */}
            <Inject services={[DataBinding, RadialTree]} />
        </DiagramComponent>
    );
}

// Render the App component into the 'diagram' element in the DOM
const root = ReactDOM.createRoot(document.getElementById("diagram"));
root.render(<App />);
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, ConnectorModel, DataBinding, NodeModel, RadialTree, DecoratorModel } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";

//Initializes data source
let data: object[] = [
  {
    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: DataManager = new DataManager(data as JSON[], new Query().take(7));

export default function App() {
  return (
    <DiagramComponent
      id="container"
      width={"100%"}
      height={"550px"}
      snapSettings={{ constraints: 0 }}

      //Uses layout to auto-arrange nodes on the diagram page
      layout={{
        //set layout type
        type: 'RadialTree',
        root: 'parent'
      }}

      //Configures data source for diagram
      dataSourceSettings={{
        id: 'Id',
        parentId: 'ReportingPerson',
        dataSource: items
      }}

      //Sets the default properties for nodes
      getNodeDefaults={(node: NodeModel) => {
        node.height = 20;
        node.width = 20;
        return node;
      }}

      //Sets the default properties for connectors
      getConnectorDefaults={(connector: ConnectorModel) => {
        (connector.targetDecorator as DecoratorModel).shape = 'None';
        connector.type = 'Straight';
        return connector;
      }}
    >

      {/* Inject necessary services for the diagram */}
      <Inject services={[DataBinding, RadialTree]} />
    </DiagramComponent>
  );
}

// Render the App component into the 'diagram' element in the DOM
const root = ReactDOM.createRoot(document.getElementById("diagram") as HTMLElement);
root.render(<App />);

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

Radial tree