Hierarchical tree layout in Angular Diagram control
23 Aug 20259 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 { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, NodeModel, ConnectorModel, LayoutModel, DiagramModule,
HierarchicalTreeService, HierarchicalTree } from '@syncfusion/ej2-angular-diagrams';
Diagram.Inject(HierarchicalTree);
@Component({
imports: [ DiagramModule ],
providers: [HierarchicalTreeService],
standalone: true,
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [nodes]="nodes" [connectors]="connectors"
[getNodeDefaults]="getNodeDefaults" [getConnectorDefaults]="getConnectorDefaults" [layout]="layout"> </ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public layout?: LayoutModel;
//Initialize nodes for diagram
public 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
public 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',
},
];
//Sets the default properties for all the Nodes
public getNodeDefaults(node: NodeModel): NodeModel {
node.annotations = [{ content: node.id }];
node.width = 100; node.height = 40;
return node;
}
//Sets the default properties for all the connectors
public getConnectorDefaults(connector: ConnectorModel): ConnectorModel {
connector.type = 'Orthogonal';
return connector;
}
ngOnInit(): void {
//Uses layout to auto-arrange nodes on the Diagram page
this.layout = {
//Sets layout type
type: 'HierarchicalTree'
}
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
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 { Component, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, NodeModel, ConnectorModel, LayoutModel, DataSourceModel, DiagramModule,
HierarchicalTreeService, DataBindingService, DataBinding, HierarchicalTree } from '@syncfusion/ej2-angular-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';
Diagram.Inject(DataBinding, HierarchicalTree);
@Component({
imports: [ DiagramModule ],
providers: [HierarchicalTreeService, DataBindingService],
standalone: true,
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults"
[getConnectorDefaults]="getConnectorDefaults" [layout]="layout" [dataSourceSettings]="dataSourceSettings">
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public items?: DataManager;
public layout?: LayoutModel;
public dataSourceSettings?: DataSourceModel;
//Initializes data source
public 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"
}
];
//Sets the default properties for all the Nodes
public getNodeDefaults(node: NodeModel): NodeModel {
node.annotations = [{ content: (node.data as { Name: 'string' }).Name }];
node.width = 100; node.height = 40;
return node;
}
//Sets the default properties for all the connectors
public getConnectorDefaults(connector: ConnectorModel): ConnectorModel {
connector.type = 'Orthogonal';
return connector;
}
ngOnInit(): void {
this.items = new DataManager(this.data as JSON[], new Query().take(7));
//Uses layout to auto-arrange nodes on the Diagram page
this.layout = {
//Sets layout type
type: 'HierarchicalTree'
}
//Configures data source for Diagram
this.dataSourceSettings = {
id: 'Name',
parentId: 'ReportingPerson',
dataSource: this.items
}
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
NOTE
When using DataSource for layout generation, both DataBinding and HierarchicalTree modules must be injected into the diagram.