Hierarchical tree layout in EJ2 TypeScript Diagram control

16 Dec 202415 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 {
    Diagram,
    ConnectorModel,
    NodeModel,
    DiagramConstraints,
    HierarchicalTree,
    TextModel,
    DataBinding,
  } from '@syncfusion/ej2-diagrams';
  import { DataManager, Query } from '@syncfusion/ej2-data';
  Diagram.Inject(HierarchicalTree);
  //Initializes 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',
    },
  ];
  //Initializes 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',
    },
  ];
  let diagram: Diagram = new Diagram({
    width: '100%',
    height: '550px',
    //Uses layout to auto-arrange nodes on the diagram page
    layout: {
      //Sets layout type
      type: 'HierarchicalTree',
    },
    nodes: nodes,
    connectors: connectors,
    //Sets the default properties for nodes
    getNodeDefaults: (obj: NodeModel) => {
      obj.shape = {
        type: 'Text',
        content: obj.id,
      };
      obj.style = {
        fill: 'None',
        strokeColor: 'none',
        strokeWidth: 2,
        bold: true,
        color: 'white',
      };
      obj.borderColor = 'white';
      obj.width = 100;
      obj.height = 40;
      obj.backgroundColor = '#6BA5D7';
      obj.borderWidth = 1;
      (obj.shape as TextModel).margin = {
        left: 5,
        right: 5,
        top: 5,
        bottom: 5,
      };
      return obj;
    }, //Sets the default properties for and connectors
    getConnectorDefaults: (connector: ConnectorModel, diagram: Diagram) => {
      connector.style = {
        strokeColor: '#6BA5D7',
        strokeWidth: 2,
      };
      connector.targetDecorator.style.fill = '#6BA5D7';
      connector.targetDecorator.style.strokeColor = '#6BA5D7';
      connector.type = 'Orthogonal';
      return connector;
    },
  });
  diagram.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Diagram</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-diagrams/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/fabric.css" rel="stylesheet" />
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

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 {
    Diagram, ConnectorModel, NodeModel, DiagramConstraints, HierarchicalTree, TextModel, DataBinding
} from '@syncfusion/ej2-diagrams';
import {
    DataManager,
    Query
} from '@syncfusion/ej2-data';
Diagram.Inject(DataBinding, HierarchicalTree);
//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));
let diagram: Diagram = new Diagram({
    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',
        dataManager: items
    },//Sets the default properties for nodes
    getNodeDefaults: (obj: Node) => {
        obj.shape = {
            type: 'Text',
            content: (obj.data as {
                Name: 'string'
            }).Name
        };
        obj.style = {
            fill: 'None',
            strokeColor: 'none',
            strokeWidth: 2,
            bold: true,
            color: 'white'
        };
        obj.borderColor = 'white';
        obj.width = 100;
        obj.height = 40;
        obj.backgroundColor = '#6BA5D7';
        obj.borderWidth = 1;
        (obj.shape as TextModel).margin = {
            left: 5,
            right: 5,
            top: 5,
            bottom: 5
        };
        return obj;
    },//Sets the default properties for and connectors
    getConnectorDefaults: (connector: ConnectorModel, diagram: Diagram) => {
        connector.style = {
            strokeColor: '#6BA5D7',
            strokeWidth: 2
        };
        connector.targetDecorator.style.fill  =  '#6BA5D7';
        connector.targetDecorator.style.strokeColor  =  '#6BA5D7';
        connector.type = 'Orthogonal';
        return connector;
    }
});
diagram.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Diagram</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-diagrams/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.1.33/ej2-navigations/styles/fabric.css" rel="stylesheet" />
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

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