Complex Hierarchical Tree Layout in React Diagram Component
21 Oct 202524 minutes to read
Complex hierarchical tree layout arranges nodes in a tree-like structure where child nodes can have multiple parent nodes, creating interconnected relationships beyond traditional single-parent hierarchies. This layout type is ideal for organizational charts with dotted-line relationships, project dependencies, or any structure where entities report to multiple authorities. This layout extends the standard hierarchical tree layout to support these complex relationships.
To create a complex hierarchical tree, set the type property of layout to ComplexHierarchicalTree.
Complex Hierarchical Tree Layout with Nodes and Connectors
This example demonstrates how to create a complex hierarchical tree layout by manually defining nodes and connectors. The layout automatically positions nodes based on their hierarchical relationships while handling multiple parent-child connections.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, DataBinding, ComplexHierarchicalTree } from "@syncfusion/ej2-react-diagrams";
//Initialize nodes for diagram
let nodes = [
{ id: 'node1' },
{ id: 'node2' },
{ id: 'node3' },
{ id: 'node4' },
{ id: 'node5' },
{ id: 'node6' },
{ id: 'node7' },
];
//Initialize connectors for diagram
let connectors = [
{ id: 'node1-node4', sourceID: 'node1', targetID: 'node4' },
{ id: 'node2-node4', sourceID: 'node2', targetID: 'node4' },
{ id: 'node3-node4', sourceID: 'node3', targetID: 'node4' },
{ id: 'node4-node5', sourceID: 'node4', targetID: 'node5' },
{ id: 'node4-node6', sourceID: 'node4', targetID: 'node6' },
{ id: 'node5-node6', sourceID: 'node6', targetID: 'node7' },
];
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: 'ComplexHierarchicalTree',
}}
//Sets the default properties for nodes
getNodeDefaults={(node) => {
node.width = 70; node.height = 70;
node.annotations = [{ content: node.id }];
return node;
}}
//Sets the default properties for connectors
getConnectorDefaults={(connector) => {
connector.type = 'Orthogonal';
return connector;
}}
>
{/* Inject necessary services for the diagram */}
<Inject services={[DataBinding, ComplexHierarchicalTree]} />
</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, NodeModel, ConnectorModel, DataBinding,
ComplexHierarchicalTree } from "@syncfusion/ej2-react-diagrams";
//Initialize nodes for diagram
let nodes: NodeModel[] = [
{ id: 'node1' },
{ id: 'node2' },
{ id: 'node3' },
{ id: 'node4' },
{ id: 'node5' },
{ id: 'node6' },
{ id: 'node7' },
];
//Initialize connectors for diagram
let connectors: ConnectorModel[] = [
{ id: 'node1-node4', sourceID: 'node1', targetID: 'node4' },
{ id: 'node2-node4', sourceID: 'node2', targetID: 'node4' },
{ id: 'node3-node4', sourceID: 'node3', targetID: 'node4' },
{ id: 'node4-node5', sourceID: 'node4', targetID: 'node5' },
{ id: 'node4-node6', sourceID: 'node4', targetID: 'node6' },
{ id: 'node5-node6', sourceID: 'node6', targetID: 'node7' },
];
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: 'ComplexHierarchicalTree',
}}
//Sets the default properties for nodes
getNodeDefaults={(node: NodeModel) => {
node.width = 70; node.height = 70;
node.annotations = [{ content: node.id }];
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, ComplexHierarchicalTree]} />
</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 />);Complex Hierarchical Tree Layout with DataSource
When working with large datasets, binding the layout to a data source provides better maintainability and dynamic content management. The following example shows how to create a complex hierarchical tree using a data source configuration.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, DataBinding, ComplexHierarchicalTree } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";
//Initializes data source
let data = [
{ "Name": "node11" },
{ "Name": "node12", "ReportingPerson": ["node114"] },
{ "Name": "node13", "ReportingPerson": ["node12"] },
{ "Name": "node14", "ReportingPerson": ["node12"] },
{ "Name": "node15", "ReportingPerson": ["node12"] },
{ "Name": "node16", "ReportingPerson": [] },
{ "Name": "node17", "ReportingPerson": ["node13", "node14", "node15"] },
{ "Name": "node18", "ReportingPerson": [] },
{ "Name": "node19", "ReportingPerson": ["node16", "node17", "node18"] },
{ "Name": "node110", "ReportingPerson": ["node16", "node17", "node18"] },
{ "Name": "node111", "ReportingPerson": ["node16", "node17", "node18", "node116"] },
{ "Name": "node21" },
{ "Name": "node22", "ReportingPerson": ["node114"] },
{ "Name": "node23", "ReportingPerson": ["node22"] },
{ "Name": "node24", "ReportingPerson": ["node22"] },
{ "Name": "node25", "ReportingPerson": ["node22"] },
{ "Name": "node26", "ReportingPerson": [] },
{ "Name": "node27", "ReportingPerson": ["node23", "node24", "node25"] },
{ "Name": "node28", "ReportingPerson": [] },
{ "Name": "node29", "ReportingPerson": ["node26", "node27", "node28", "node116"] },
{ "Name": "node210", "ReportingPerson": ["node26", "node27", "node28"] },
{ "Name": "node211", "ReportingPerson": ["node26", "node27", "node28"] },
{ "Name": "node31" },
{ "Name": "node114", "ReportingPerson": ["node11", "node21", "node31"] },
{ "Name": "node116", "ReportingPerson": ["node12", "node22"], }
];
let items = new DataManager(data, new Query().take(7));
export default function App() {
return (
<div>
<DiagramComponent
id="container"
width={"100%"}
height={"700px"}
//Uses layout to auto-arrange nodes on the diagram page
layout={{
//Sets layout type
type: 'ComplexHierarchicalTree'
}}
//Configures data source for diagram
dataSourceSettings={{
id: 'Name',
parentId: 'ReportingPerson',
dataSource: items
}}
//Sets the default properties for nodes
getNodeDefaults={(node) => {
node.width = 70; node.height = 70;
return node;
}}
//Sets the default properties for connectors
getConnectorDefaults={(connector) => {
connector.type = 'Orthogonal';
return connector;
}}
>
{/* Inject necessary services for the diagram */}
<Inject services={[DataBinding, ComplexHierarchicalTree]} />
</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, NodeModel, ConnectorModel, DataBinding,
ComplexHierarchicalTree } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";
//Initializes data source
let data: object[] = [
{ "Name": "node11" },
{ "Name": "node12", "ReportingPerson": ["node114"] },
{ "Name": "node13", "ReportingPerson": ["node12"] },
{ "Name": "node14", "ReportingPerson": ["node12"] },
{ "Name": "node15", "ReportingPerson": ["node12"] },
{ "Name": "node16", "ReportingPerson": [] },
{ "Name": "node17", "ReportingPerson": ["node13", "node14", "node15"] },
{ "Name": "node18", "ReportingPerson": [] },
{ "Name": "node19", "ReportingPerson": ["node16", "node17", "node18"] },
{ "Name": "node110", "ReportingPerson": ["node16", "node17", "node18"] },
{ "Name": "node111", "ReportingPerson": ["node16", "node17", "node18", "node116"] },
{ "Name": "node21" },
{ "Name": "node22", "ReportingPerson": ["node114"] },
{ "Name": "node23", "ReportingPerson": ["node22"] },
{ "Name": "node24", "ReportingPerson": ["node22"] },
{ "Name": "node25", "ReportingPerson": ["node22"] },
{ "Name": "node26", "ReportingPerson": [] },
{ "Name": "node27", "ReportingPerson": ["node23", "node24", "node25"] },
{ "Name": "node28", "ReportingPerson": [] },
{ "Name": "node29", "ReportingPerson": ["node26", "node27", "node28", "node116"] },
{ "Name": "node210", "ReportingPerson": ["node26", "node27", "node28"] },
{ "Name": "node211", "ReportingPerson": ["node26", "node27", "node28"] },
{ "Name": "node31" },
{ "Name": "node114", "ReportingPerson": ["node11", "node21", "node31"] },
{ "Name": "node116", "ReportingPerson": ["node12", "node22"], }
];
let items: DataManager = new DataManager(data as JSON[], new Query().take(7));
export default function App() {
return (
<div>
<DiagramComponent
id="container"
width={"100%"}
height={"700px"}
//Uses layout to auto-arrange nodes on the diagram page
layout={{
//Sets layout type
type: 'ComplexHierarchicalTree'
}}
//Configures data source for diagram
dataSourceSettings={{
id: 'Name',
parentId: 'ReportingPerson',
dataSource: items
}}
//Sets the default properties for nodes
getNodeDefaults={(node: NodeModel) => {
node.width = 70; node.height = 70;
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, ComplexHierarchicalTree]} />
</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: In Diagram layouts, all root nodes will always render at the same level. This default behavior cannot be changed to render different trees at distinct levels.
Line Distribution
Line distribution prevents connector overlap by controlling how multiple connectors from a single parent node are positioned. Without line distribution, connectors may overlap and create visual confusion in complex layouts. The connectionPointOrigin property of layout is used to enable or disable the line distribution in layout. By default ConnectionPointOrigin will be SamePoint.
The following code example illustrates how to create a complex hierarchical tree with line distribution.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, DataBinding, ComplexHierarchicalTree,
ConnectionPointOrigin, LineDistribution } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";
//Initializes data source
let data = [
{ "Name": "node11" },
{ "Name": "node12", "ReportingPerson": ["node114"] },
{ "Name": "node13", "ReportingPerson": ["node12"] },
{ "Name": "node14", "ReportingPerson": ["node12"] },
{ "Name": "node15", "ReportingPerson": ["node12"] },
{ "Name": "node116", "ReportingPerson": ["node22", "node12"] },
{ "Name": "node16", "ReportingPerson": [] },
{ "Name": "node18", "ReportingPerson": [] },
{ "Name": "node21" },
{ "Name": "node22", "ReportingPerson": ["node114"] },
{ "Name": "node23", "ReportingPerson": ["node22"] },
{ "Name": "node24", "ReportingPerson": ["node22"] },
{ "Name": "node25", "ReportingPerson": ["node22"] },
{ "Name": "node26", "ReportingPerson": [] },
{ "Name": "node28", "ReportingPerson": [] },
{ "Name": "node31" },
{ "Name": "node114", "ReportingPerson": ["node11", "node21", "node31"] }
];
let items = new DataManager(data, new Query().take(7));
export default function App() {
return (
<div>
<DiagramComponent
id="container"
width={"100%"}
height={"700px"}
//Uses layout to auto-arrange nodes on the diagram page
layout={{
//Sets layout type
type: 'ComplexHierarchicalTree',
connectionPointOrigin: ConnectionPointOrigin.DifferentPoint,
}}
//Configures data source for diagram
dataSourceSettings={{
id: 'Name',
parentId: 'ReportingPerson',
dataSource: items
}}
//Sets the default properties for nodes
getNodeDefaults={(node) => {
node.width = 40; node.height = 40;
return node;
}}
//Sets the default properties for connectors
getConnectorDefaults={(connector) => {
connector.type = 'Orthogonal';
connector.cornerRadius = 7;
return connector;
}}
>
{/* Inject necessary services for the diagram */}
<Inject services={[DataBinding, ComplexHierarchicalTree, LineDistribution]} />
</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, NodeModel, ConnectorModel, DataBinding,
ComplexHierarchicalTree, ConnectionPointOrigin, LineDistribution } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";
//Initializes data source
let data: object[] = [
{ "Name": "node11" },
{ "Name": "node12", "ReportingPerson": ["node114"] },
{ "Name": "node13", "ReportingPerson": ["node12"] },
{ "Name": "node14", "ReportingPerson": ["node12"] },
{ "Name": "node15", "ReportingPerson": ["node12"] },
{ "Name": "node116", "ReportingPerson": ["node22", "node12"] },
{ "Name": "node16", "ReportingPerson": [] },
{ "Name": "node18", "ReportingPerson": [] },
{ "Name": "node21" },
{ "Name": "node22", "ReportingPerson": ["node114"] },
{ "Name": "node23", "ReportingPerson": ["node22"] },
{ "Name": "node24", "ReportingPerson": ["node22"] },
{ "Name": "node25", "ReportingPerson": ["node22"] },
{ "Name": "node26", "ReportingPerson": [] },
{ "Name": "node28", "ReportingPerson": [] },
{ "Name": "node31" },
{ "Name": "node114", "ReportingPerson": ["node11", "node21", "node31"] }
];
let items: DataManager = new DataManager(data as JSON[], new Query().take(7));
export default function App() {
return (
<div>
<DiagramComponent
id="container"
width={"100%"}
height={"700px"}
//Uses layout to auto-arrange nodes on the diagram page
layout={{
//Sets layout type
type: 'ComplexHierarchicalTree',
connectionPointOrigin: ConnectionPointOrigin.DifferentPoint,
}}
//Configures data source for diagram
dataSourceSettings={{
id: 'Name',
parentId: 'ReportingPerson',
dataSource: items
}}
//Sets the default properties for nodes
getNodeDefaults={(node: NodeModel) => {
node.width = 40; node.height = 40;
return node;
}}
//Sets the default properties for connectors
getConnectorDefaults={(connector: ConnectorModel) => {
connector.type = 'Orthogonal';
connector.cornerRadius = 7;
return connector;
}}
>
{/* Inject necessary services for the diagram */}
<Inject services={[DataBinding, ComplexHierarchicalTree, LineDistribution ]} />
</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 line distribution in diagram layout, you need to inject LineDistribution module in the diagram.

Linear Arrangement
Linear arrangement is used to linearly arrange the child nodes in layout, which means the parent node is placed in the center corresponding to its children. When line distribution is enabled, linear arrangement is also activated by default. The arrangement property provides control over this feature:
- Nonlinear (default): Child nodes are arranged based on available space
- Linear: Child nodes are arranged in a straight line with the parent centered. By default arrangement will be Nonlinear.
Note: If you want to use linear arrangement in diagram layout, you need to inject LineDistribution module in the diagram. Linear arrangement is applicable only for complex hierarchical tree layout.
The following code illustrates how to allow a linear arrangement in diagram layout.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, DataBinding, ComplexHierarchicalTree, LineDistribution,
ChildArrangement } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";
//Initializes data source
let data = [
{ "Name": "node11" },
{ "Name": "node12", "ReportingPerson": ["node114"] },
{ "Name": "node13", "ReportingPerson": ["node12"] },
{ "Name": "node14", "ReportingPerson": ["node12"] },
{ "Name": "node15", "ReportingPerson": ["node12"] },
{ "Name": "node116", "ReportingPerson": ["node22", "node12"] },
{ "Name": "node16", "ReportingPerson": [] },
{ "Name": "node18", "ReportingPerson": [] },
{ "Name": "node21" },
{ "Name": "node22", "ReportingPerson": ["node114"] },
{ "Name": "node23", "ReportingPerson": ["node22"] },
{ "Name": "node24", "ReportingPerson": ["node22"] },
{ "Name": "node25", "ReportingPerson": ["node22"] },
{ "Name": "node26", "ReportingPerson": [] },
{ "Name": "node28", "ReportingPerson": [] },
{ "Name": "node31" },
{ "Name": "node114", "ReportingPerson": ["node11", "node21", "node31"] }
];
let items = new DataManager(data, new Query().take(7));
export default function App() {
return (
<div>
<DiagramComponent
id="container"
width={"100%"}
height={"700px"}
//Uses layout to auto-arrange nodes on the diagram page
layout={{
//Sets layout type
type: 'ComplexHierarchicalTree',
arrangement: ChildArrangement.Linear,
}}
//Configures data source for diagram
dataSourceSettings={{
id: 'Name',
parentId: 'ReportingPerson',
dataSource: items
}}
//Sets the default properties for nodes
getNodeDefaults={(node) => {
node.width = 40; node.height = 40;
return node;
}}
//Sets the default properties for connectors
getConnectorDefaults={(connector) => {
connector.type = 'Orthogonal';
connector.cornerRadius = 7;
return connector;
}}
>
{/* Inject necessary services for the diagram */}
<Inject services={[DataBinding, ComplexHierarchicalTree, LineDistribution]} />
</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, NodeModel, ConnectorModel, DataBinding, ComplexHierarchicalTree,
LineDistribution, ChildArrangement } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";
//Initializes data source
let data: object[] = [
{ "Name": "node11" },
{ "Name": "node12", "ReportingPerson": ["node114"] },
{ "Name": "node13", "ReportingPerson": ["node12"] },
{ "Name": "node14", "ReportingPerson": ["node12"] },
{ "Name": "node15", "ReportingPerson": ["node12"] },
{ "Name": "node116", "ReportingPerson": ["node22", "node12"] },
{ "Name": "node16", "ReportingPerson": [] },
{ "Name": "node18", "ReportingPerson": [] },
{ "Name": "node21" },
{ "Name": "node22", "ReportingPerson": ["node114"] },
{ "Name": "node23", "ReportingPerson": ["node22"] },
{ "Name": "node24", "ReportingPerson": ["node22"] },
{ "Name": "node25", "ReportingPerson": ["node22"] },
{ "Name": "node26", "ReportingPerson": [] },
{ "Name": "node28", "ReportingPerson": [] },
{ "Name": "node31" },
{ "Name": "node114", "ReportingPerson": ["node11", "node21", "node31"] }
];
let items: DataManager = new DataManager(data as JSON[], new Query().take(7));
export default function App() {
return (
<div>
<DiagramComponent
id="container"
width={"100%"}
height={"700px"}
//Uses layout to auto-arrange nodes on the diagram page
layout={{
//Sets layout type
type: 'ComplexHierarchicalTree',
arrangement: ChildArrangement.Linear,
}}
//Configures data source for diagram
dataSourceSettings={{
id: 'Name',
parentId: 'ReportingPerson',
dataSource: items
}}
//Sets the default properties for nodes
getNodeDefaults={(node: NodeModel) => {
node.width = 40; node.height = 40;
return node;
}}
//Sets the default properties for connectors
getConnectorDefaults={(connector: ConnectorModel) => {
connector.type = 'Orthogonal';
connector.cornerRadius = 7;
return connector;
}}
>
{/* Inject necessary services for the diagram */}
<Inject services={[DataBinding, ComplexHierarchicalTree, LineDistribution]} />
</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 />);Enable Routing for Layout
In complex diagrams with intricate parent-child relationships, connectors may pass through or overlap with nodes, making the diagram difficult to read. Routing functionality automatically calculates connector paths that avoid intersecting with nodes and other obstacles.
Set the enableRouting property to true to activate intelligent connector routing.
The following example shows how to activate enableRouting in the layout:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, DataBinding, ComplexHierarchicalTree, LineDistribution } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";
//Initializes data source
let data = [
{ Name: 'node11' },
{ Name: 'node12', ReportingPerson: ['node114'] },
{ Name: 'node13', ReportingPerson: ['node12'] },
{ Name: 'node14', ReportingPerson: ['node12'] },
{ Name: 'node15', ReportingPerson: ['node12'] },
{ Name: 'node16', ReportingPerson: ['node12'] },
{ Name: 'node116', ReportingPerson: ['node22', 'node12', 'node114'] },
{ Name: 'node21' },
{ Name: 'node22', ReportingPerson: ['node114'] },
{ Name: 'node222', ReportingPerson: ['node114'] },
{ Name: 'node2222', ReportingPerson: ['node114'] },
{ Name: 'node23', ReportingPerson: ['node22'] },
{ Name: 'node31' },
{ Name: 'node114', ReportingPerson: ['node11', 'node21', 'node31'] },
];
let items = new DataManager(data, new Query().take(7));
export default function App() {
return (
<div>
<DiagramComponent
id="container"
width={"100%"}
height={"700px"}
//Uses layout to auto-arrange nodes on the diagram page
layout={{
//Sets layout type
type: 'ComplexHierarchicalTree',
enableRouting: true
}}
//Configures data source for diagram
dataSourceSettings={{
id: 'Name',
parentId: 'ReportingPerson',
dataSource: items
}}
//Sets the default properties for nodes
getNodeDefaults={(node) => {
node.width = 40; node.height = 40;
return node;
}}
//Sets the default properties for connectors
getConnectorDefaults={(connector) => {
connector.type = 'Orthogonal';
connector.cornerRadius = 7;
return connector;
}}
>
{/* Inject necessary services for the diagram */}
<Inject services={[DataBinding, ComplexHierarchicalTree, LineDistribution]} />
</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, NodeModel, ConnectorModel, DataBinding, ComplexHierarchicalTree, LineDistribution } from "@syncfusion/ej2-react-diagrams";
import { DataManager, Query } from "@syncfusion/ej2-data";
//Initializes data source
let data: object[] = [
{ Name: 'node11' },
{ Name: 'node12', ReportingPerson: ['node114'] },
{ Name: 'node13', ReportingPerson: ['node12'] },
{ Name: 'node14', ReportingPerson: ['node12'] },
{ Name: 'node15', ReportingPerson: ['node12'] },
{ Name: 'node16', ReportingPerson: ['node12'] },
{ Name: 'node116', ReportingPerson: ['node22', 'node12', 'node114'] },
{ Name: 'node21' },
{ Name: 'node22', ReportingPerson: ['node114'] },
{ Name: 'node222', ReportingPerson: ['node114'] },
{ Name: 'node2222', ReportingPerson: ['node114'] },
{ Name: 'node23', ReportingPerson: ['node22'] },
{ Name: 'node31' },
{ Name: 'node114', ReportingPerson: ['node11', 'node21', 'node31'] },
];
let items: DataManager = new DataManager(data as JSON[], new Query().take(7));
export default function App() {
return (
<div>
<DiagramComponent
id="container"
width={"100%"}
height={"700px"}
//Uses layout to auto-arrange nodes on the diagram page
layout={{
//Sets layout type
type: 'ComplexHierarchicalTree',
enableRouting: true
}}
//Configures data source for diagram
dataSourceSettings={{
id: 'Name',
parentId: 'ReportingPerson',
dataSource: items
}}
//Sets the default properties for nodes
getNodeDefaults={(node: NodeModel) => {
node.width = 40; node.height = 40;
return node;
}}
//Sets the default properties for connectors
getConnectorDefaults={(connector: ConnectorModel) => {
connector.type = 'Orthogonal';
connector.cornerRadius = 7;
return connector;
}}
>
{/* Inject necessary services for the diagram */}
<Inject services={[DataBinding, ComplexHierarchicalTree, LineDistribution ]} />
</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 />);Best Practices
- Use data source binding for dynamic content and better maintainability.
- Enable line distribution when dealing with nodes that have multiple connections.
- Consider enabling routing for complex layouts to improve visual clarity.
- Test layout performance with large datasets and optimize as needed.
- Ensure proper module injection for advanced features like line distribution.