Hierarchical Tree Layout in React Diagram Component
21 Oct 202519 minutes to read
The hierarchical tree layout arranges nodes in a tree-like structure where nodes can have multiple parent nodes, creating complex organizational relationships. Unlike traditional tree structures with single parent-child relationships, this layout supports scenarios such as matrix organizations, project dependencies, or any structure where entities report to multiple authorities. The layout automatically determines positioning without requiring a specified root node.
Hierarchical Tree Layout with Nodes and Connectors
To arrange nodes in a hierarchical structure, specify the layout type as HierarchicalTree. This approach provides full control over node and connector definitions while leveraging automatic positioning.
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: The HierarchicalTree module must be injected into the diagram to use hierarchical tree layout functionality.
Hierarchical Layout with DataSource
For data-driven scenarios, hierarchical layout can be created using a DataSource, which automatically generates nodes and connectors based on the data relationships. This approach is more efficient for large datasets and dynamic content.
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: When using DataSource for layout generation, both DataBinding and HierarchicalTree modules must be injected into the diagram.
