Hierarchical tree layout in React Diagram control

6 Dec 202419 minutes to read

The hierarchical tree layout arranges nodes in a tree-like structure, where the nodes in the hierarchical layout may have multiple parents. There is no need to specify the layout root.

Hierarchical tree layout with nodes and connectors

To arrange the nodes in a hierarchical structure, specify the layout type as HierarchicalTree. The following example shows how to arrange the nodes in a hierarchical structure.

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

//Initialize nodes for diagram
let nodes = [
    {
        id: 'Steve-Ceo',
    },
    {
        id: 'Kevin-Manager',
    },
    {
        id: 'Peter-Manager',
    },
    {
        id: 'John-Manager',
    },
    {
        id: 'Mary-CSE',
    },
    {
        id: 'Jim-CSE',
    },
    {
        id: 'Martin-CSE',
    },
];

//Initialize connectors for diagram
let connectors = [
    {
        id: 'Steve-Ceo_Kevin-Manager',
        sourceID: 'Steve-Ceo',
        targetID: 'Kevin-Manager',
    },
    {
        id: 'Steve-Ceo_Peter-Manager',
        sourceID: 'Steve-Ceo',
        targetID: 'Peter-Manager',
    },
    {
        id: 'Peter-Manager_John-Manager',
        sourceID: 'Peter-Manager',
        targetID: 'John-Manager',
    },
    {
        id: 'Peter-Manager_Mary-CSE',
        sourceID: 'Peter-Manager',
        targetID: 'Mary-CSE',
    },
    {
        id: 'Kevin-Manager_Jim-CSE',
        sourceID: 'Kevin-Manager',
        targetID: 'Jim-CSE',
    },
    {
        id: 'Kevin-Manager_Martin-CSE',
        sourceID: 'Kevin-Manager',
        targetID: 'Martin-CSE',
    },
];

export default function App() {

    return (
        <div>
            <DiagramComponent
                id="container"
                width={"100%"}
                height={"550px"}
                nodes={nodes}
                connectors={connectors}
                //Uses layout to auto-arrange nodes on the diagram page
                layout={{
                    //Sets layout type
                    type: 'HierarchicalTree'
                }}

                //Sets the default properties for nodes
                getNodeDefaults={(node) => {
                    node.annotations = [{ content: node.id }];
                    node.width = 100; node.height = 40;
                    return node;
                }}

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

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

// 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, HierarchicalTree } from "@syncfusion/ej2-react-diagrams";

//Initialize nodes for diagram
let nodes: NodeModel[] = [
  {
    id: 'Steve-Ceo',
  },
  {
    id: 'Kevin-Manager',
  },
  {
    id: 'Peter-Manager',
  },
  {
    id: 'John-Manager',
  },
  {
    id: 'Mary-CSE',
  },
  {
    id: 'Jim-CSE',
  },
  {
    id: 'Martin-CSE',
  },
];

//Initialize connectors for diagram
let connectors: ConnectorModel[] = [
  {
    id: 'Steve-Ceo_Kevin-Manager',
    sourceID: 'Steve-Ceo',
    targetID: 'Kevin-Manager',
  },
  {
    id: 'Steve-Ceo_Peter-Manager',
    sourceID: 'Steve-Ceo',
    targetID: 'Peter-Manager',
  },
  {
    id: 'Peter-Manager_John-Manager',
    sourceID: 'Peter-Manager',
    targetID: 'John-Manager',
  },
  {
    id: 'Peter-Manager_Mary-CSE',
    sourceID: 'Peter-Manager',
    targetID: 'Mary-CSE',
  },
  {
    id: 'Kevin-Manager_Jim-CSE',
    sourceID: 'Kevin-Manager',
    targetID: 'Jim-CSE',
  },
  {
    id: 'Kevin-Manager_Martin-CSE',
    sourceID: 'Kevin-Manager',
    targetID: 'Martin-CSE',
  },
];

export default function App() {

  return (
    <div>
      <DiagramComponent
        id="container"
        width={"100%"}
        height={"550px"}
        nodes={nodes}
        connectors={connectors}
        //Uses layout to auto-arrange nodes on the diagram page
        layout={{
          //Sets layout type
          type: 'HierarchicalTree'
        }}

        //Sets the default properties for nodes
        getNodeDefaults={(node: NodeModel) => {
          node.annotations = [{ content: node.id }];
          node.width = 100; node.height = 40;
          return node;
        }}

        //Sets the default properties for connectors
        getConnectorDefaults={(connector: ConnectorModel) => {
          connector.type = 'Orthogonal';
          return connector;
        }}
      >

        {/* Inject necessary services for the diagram */}
        <Inject services={[DataBinding, HierarchicalTree]} />
      </DiagramComponent>
    </div>

  );
}

// 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 hierarchical tree layout in diagram, you need to inject HierarchicalTree in the diagram.

Hierarchical layout with DataSource

You can create a hierarchical layout with data Source. The following code demonstrates how to render a Hierarchical layout using DataSource.

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

//Initializes data source
let data = [
    { Name: "Steve-Ceo" },
    { Name: "Kevin-Manager", ReportingPerson: "Steve-Ceo" },
    { Name: "Peter-Manager", ReportingPerson: "Steve-Ceo" },
    { Name: "John- Manager", ReportingPerson: "Peter-Manager" },
    { Name: "Mary-CSE ", ReportingPerson: "Peter-Manager" },
    { Name: "Jim-CSE ", ReportingPerson: "Kevin-Manager" },
    { Name: "Martin-CSE", ReportingPerson: "Kevin-Manager" }
];

let items = new DataManager(data, new Query().take(7));

export default function App() {

    return (
        <div>
            <DiagramComponent
                id="container"
                width={"100%"}
                height={"550px"}

                //Uses layout to auto-arrange nodes on the diagram page
                layout={{
                    //Sets layout type
                    type: 'HierarchicalTree'
                }}

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

                //Sets the default properties for nodes
                getNodeDefaults={(node) => {
                    node.annotations = [{ content: node.data.Name }];
                    node.width = 100; node.height = 40;
                    return node;
                }}

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

                {/* Inject necessary services for the diagram */}
                <Inject services={[DataBinding, HierarchicalTree]} />
            </DiagramComponent>
        </div>

    );
}

// 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, HierarchicalTree } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";

//Initializes data source
let data: object[] = [
  { Name: "Steve-Ceo" },
  { Name: "Kevin-Manager", ReportingPerson: "Steve-Ceo" },
  { Name: "Peter-Manager", ReportingPerson: "Steve-Ceo" },
  { Name: "John- Manager", ReportingPerson: "Peter-Manager" },
  { Name: "Mary-CSE ", ReportingPerson: "Peter-Manager" },
  { Name: "Jim-CSE ", ReportingPerson: "Kevin-Manager" },
  { Name: "Martin-CSE", ReportingPerson: "Kevin-Manager" }
];

let items: DataManager = new DataManager(data as JSON[], new Query().take(7));

export default function App() {

  return (
    <div>
      <DiagramComponent
        id="container"
        width={"100%"}
        height={"550px"}

        //Uses layout to auto-arrange nodes on the diagram page
        layout={{
          //Sets layout type
          type: 'HierarchicalTree'
        }}

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

        //Sets the default properties for nodes
        getNodeDefaults={(node: NodeModel) => {
          node.annotations = [{ content: (node.data as { Name: 'string' }).Name }];
          node.width = 100; node.height = 40;
          return node;
        }}

        //Sets the default properties for connectors
        getConnectorDefaults={(connector: ConnectorModel) => {
          connector.type = 'Orthogonal';
          return connector;
        }}
      >

        {/* Inject necessary services for the diagram */}
        <Inject services={[DataBinding, HierarchicalTree]} />
      </DiagramComponent>
    </div>

  );
}

// 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 HierarchicalTree module in the diagram.

Hierarchical tree