Automatic layout in Angular Diagram component
7 Sep 202324 minutes to read
Diagram provides support to auto-arrange the nodes in the diagram area that is referred as Layout
. It includes the following layout modes:
Layout modes
- Hierarchical layout
- Organization chart
- Radial tree
- Symmetric layout
- Mind Map layout
- Complex hierarchical tree layout
Hierarchical layout
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. To arrange the nodes in a hierarchical structure, specify the layout type
as hierarchical tree.
Note: If you want to use hierarchical tree layout in diagram, you need to inject HierarchicalTree in the diagram.
The following example shows how to arrange the nodes in a hierarchical structure.
import { Component, OnInit, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, NodeModel, ConnectorModel, SnapSettingsModel, LayoutModel, DataSourceModel, TextModel, DecoratorModel, ShapeStyleModel } from '@syncfusion/ej2-angular-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';
@Component({
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" [getConnectorDefaults]="getConnectorDefaults" [snapSettings]="snapSettings" [layout]="layout" [dataSourceSettings]="dataSourceSettings">
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public snapSettings?: SnapSettingsModel;
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(obj: NodeModel, diagram: Diagram): NodeModel {
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 all the connectors
public getConnectorDefaults(connector: ConnectorModel, diagram: Diagram): ConnectorModel {
connector.style = {
strokeColor: '#6BA5D7',
strokeWidth: 2
};
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).fill = '#6BA5D7';
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).strokeColor = '#6BA5D7';
connector.type = 'Orthogonal';
return connector;
}
ngOnInit(): void {
this.snapSettings = {
constraints: 0
}
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 { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { DiagramModule, HierarchicalTreeService, DataBindingService } from '@syncfusion/ej2-angular-diagrams';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule, DiagramModule
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [HierarchicalTreeService, DataBindingService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
Radial tree layout
The radial tree layout arranges nodes on a virtual concentric circle around a root node. Sub-trees formed by the branching of child nodes are located radially around the child nodes. This arrangement result in an ever-expanding concentric arrangement with radial proximity to the root node indicating the node level in the hierarchy. The layout root
property can be used to define the root node of the layout. When no root node is set, the algorithm automatically considers one of the diagram nodes as the root node.
To arrange nodes in a radial tree structure, set the type
of the layout as RadialTree
.
Note: If you want to use radial tree layout in diagram, you need to inject DataBinding and RadialTree in the diagram.
The following code illustrates how to arrange the nodes in a radial tree structure.
import { Component, OnInit, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, NodeModel, ConnectorModel, SnapSettingsModel, LayoutModel, DataSourceModel, DecoratorModel, ShapeStyleModel } from '@syncfusion/ej2-angular-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';
@Component({
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" [getConnectorDefaults]="getConnectorDefaults" [snapSettings]="snapSettings" [layout]="layout" [dataSourceSettings]="dataSourceSettings">
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public snapSettings?: SnapSettingsModel;
public items?: DataManager;
public layout?: LayoutModel;
public dataSourceSettings?: DataSourceModel;
//Initializes data source
public data: object[] = [{
"Id": 1,
"Name": "Ana Trujillo",
"Designation": "Project Manager",
"RatingColor": "#68C2DE"
},
{
"Id": 2,
"Name": "Lino Rodri",
"Designation": "Project Manager",
"RatingColor": "#68C2DE",
"ReportingPerson": 1
},
{
"Id": 3,
"Name": "Philip Cramer",
"Designation": "Project Manager",
"RatingColor": "#68C2DE",
"ReportingPerson": 1
},
{
"Id": 4,
"Name": "Pedro Afonso",
"Designation": "Project Manager",
"RatingColor": "#68C2DE",
"ReportingPerson": 1
},
{
"Id": 5,
"Name": "Anto Moreno",
"Designation": "Project Lead",
"RatingColor": "#93B85A",
"ReportingPerson": 1
},
{
"Id": 6,
"Name": "Elizabeth Roel",
"Designation": "Project Lead",
"RatingColor": "#93B85A",
"ReportingPerson": 1
},
{
"Id": 7,
"Name": "Aria Cruz",
"Designation": "Project Lead",
"RatingColor": "#93B85A",
"ReportingPerson": 1
},
{
"Id": 8,
"Name": "Eduardo Roel",
"Designation": "Project Lead",
"RatingColor": "#93B85A",
"ReportingPerson": 1
},
{
"Id": 9,
"Name": "Howard Snyd",
"Designation": "Project Lead",
"RatingColor": "#68C2DE",
"ReportingPerson": 1
},
{
"Id": 10,
"Name": "Daniel Tonini",
"Designation": "Project Lead",
"RatingColor": "#93B85A",
"ReportingPerson": 1
},
{
"Id": 11,
"Name": "Nardo Batista",
"Designation": "Project Lead",
"RatingColor": "#68C2DE",
"ReportingPerson": 1
}
];
public getNodeDefaults(obj: NodeModel): NodeModel {
obj.height = 15;
obj.width = 15;
obj.borderWidth = 1;
obj.style = {
fill: '#6BA5D7',
strokeWidth: 2,
strokeColor: '#6BA5D7'
};
return obj;
}
//Sets the default properties for and connectors
public getConnectorDefaults(connector: ConnectorModel, diagram: Diagram): ConnectorModel {
connector.style = {
strokeColor: '#6BA5D7',
strokeWidth: 2
};
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).fill = '#6BA5D7';
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).strokeColor = '#6BA5D7';
((connector as ConnectorModel).targetDecorator as DecoratorModel).shape = 'None';
connector.type = 'Straight';
return connector;
}
ngOnInit(): void {
this.snapSettings = {
constraints: 0
}
this.items = new DataManager(this.data as JSON[], new Query().take(7));
//Uses layout to auto-arrange nodes on the Diagram page
this.layout = {
//set the type as Radial Tree
type: 'RadialTree',
root: 'parent'
}
//Configures data source for Diagram
this.dataSourceSettings = {
id: 'Id',
parentId: 'ReportingPerson',
dataSource: this.items
}
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { DiagramModule, RadialTreeService, DataBindingService } from '@syncfusion/ej2-angular-diagrams';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule, DiagramModule
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [RadialTreeService, DataBindingService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
Organizational Chart
An organizational chart is a diagram that displays the structure of an organization and relationships. To create an organizational chart, the type
of layout should be set as an OrganizationalChart
.
The following code example illustrates how to create an organizational chart.
import { Component, OnInit, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, NodeModel, ConnectorModel, SnapSettingsModel, LayoutModel, DataSourceModel, TextModel, DecoratorModel, ShapeStyleModel } from '@syncfusion/ej2-angular-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';
@Component({
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" [getConnectorDefaults]="getConnectorDefaults" [snapSettings]="snapSettings" [layout]="layout" [dataSourceSettings]="dataSourceSettings">
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public snapSettings?: SnapSettingsModel;
public items?: DataManager;
public layout?: LayoutModel;
public dataSourceSettings?: DataSourceModel;
//Initializes data source
public data: object[] = [{
Id: "parent",
Role: "Project Management"
},
{
Id: 1,
Role: "R&D Team",
Team: "parent"
},
{
Id: 3,
Role: "Philosophy",
Team: "1"
},
{
Id: 4,
Role: "Organization",
Team: "1"
},
{
Id: 5,
Role: "Technology",
Team: "1"
},
{
Id: 7,
Role: "Funding",
Team: "1"
},
{
Id: 8,
Role: "Resource Allocation",
Team: "1"
},
{
Id: 9,
Role: "Targeting",
Team: "1"
},
{
Id: 11,
Role: "Evaluation",
Team: "1"
},
{
Id: 156,
Role: "HR Team",
Team: "parent"
},
{
Id: 13,
Role: "Recruitment",
Team: "156"
},
{
Id: 113,
Role: "Training",
Team: "12"
},
{
Id: 112,
Role: "Employee Relation",
Team: "156"
},
{
Id: 14,
Role: "Record Keeping",
Team: "12"
},
{
Id: 15,
Role: "Compensations & Benefits",
Team: "12"
},
{
Id: 16,
Role: "Compliances",
Team: "12"
},
{
Id: 17,
Role: "Production & Sales Team",
Team: "parent"
},
{
Id: 119,
Role: "Design",
Team: "17"
},
{
Id: 19,
Role: "Operation",
Team: "17"
},
{
Id: 20,
Role: "Support",
Team: "17"
},
{
Id: 21,
Role: "Quality Assurance",
Team: "17"
},
{
Id: 23,
Role: "Customer Interaction",
Team: "17"
},
{
Id: 24,
Role: "Support and Maintenance",
Team: "17"
},
{
Id: 25,
Role: "Task Coordination",
Team: "17"
}
];
//Sets the default properties for all the Nodes
public getNodeDefaults(obj: NodeModel, diagram: Diagram): NodeModel {
obj.shape = {
type: 'Text',
content: (obj.data as {
Role: 'string'
}).Role
};
obj.style = {
fill: 'None',
strokeColor: 'none',
strokeWidth: 2,
bold: true,
color: 'white'
};
obj.borderColor = 'white';
obj.backgroundColor = '#6BA5D7';
obj.borderWidth = 1;
obj.width = 75;
obj.height = 40;
(obj.shape as TextModel).margin = {
left: 5,
right: 5,
top: 5,
bottom: 5
};
return obj;
}
//Sets the default properties for all the connectors
public getConnectorDefaults(connector: ConnectorModel, diagram: Diagram): ConnectorModel {
connector.style = {
strokeColor: '#6BA5D7',
strokeWidth: 2
};
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).fill = '#6BA5D7';
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).strokeColor = '#6BA5D7';
connector.type = 'Orthogonal';
return connector;
}
ngOnInit(): void {
this.snapSettings = {
constraints: 0
}
this.items = new DataManager(this.data as JSON[], new Query().take(5));
//Uses layout to auto-arrange nodes on the Diagram page
this.layout = {
//set the type as Organizational Chart
type: 'OrganizationalChart'
}
//Configures data source for Diagram
this.dataSourceSettings = {
id: 'Id',
parentId: 'Team',
dataSource: this.items
}
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { DiagramModule, HierarchicalTreeService, DataBindingService } from '@syncfusion/ej2-angular-diagrams';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule, DiagramModule
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [HierarchicalTreeService, DataBindingService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
Organizational chart layout starts parsing from root and iterate through all its child elements. The getLayoutInfo
method provides necessary information of a node’s children and the way to arrange (direction, orientation, offsets, etc.) them. The arrangements can be customized by overriding this function as explained.
GetLayoutInfo - Set chart orientations, chart types, and offset to be left between parent and child nodes by overriding the method, diagram.layout.getLayoutInfo
. The getLayoutInfo
method is called to configure every subtree of the organizational chart. It takes the following arguments.
- node - Parent node to that options are to be customized.
- options - Object to set the customizable properties.
import { Component, OnInit, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, NodeModel, ConnectorModel, SnapSettingsModel, LayoutModel, DataSourceModel, DecoratorModel, ShapeStyleModel, TreeInfo } from '@syncfusion/ej2-angular-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';
@Component({
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" [getConnectorDefaults]="getConnectorDefaults" [snapSettings]="snapSettings" [layout]="layout" [dataSourceSettings]="dataSourceSettings">
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public snapSettings?: SnapSettingsModel;
public items?: DataManager;
public layout?: LayoutModel;
public dataSourceSettings?: DataSourceModel;
//Initializes data source
public data: object[] = [{
Id: 1,
Role: "General Manager"
},
{
Id: 2,
Role: "Assistant Manager",
Team: 1
},
{
Id: 3,
Role: "Human Resource Manager",
Team: 1
},
{
Id: 4,
Role: "Design Manager",
Team: 1
},
{
Id: 5,
Role: "Operation Manager",
Team: 1
},
{
Id: 6,
Role: "Marketing Manager",
Team: 1
}
];
//Sets the default properties for all the Nodes
public getNodeDefaults(obj: NodeModel | any, diagram: Diagram): NodeModel {
obj.width = 150;
obj.height = 50;
obj.style.fill = '#6BA5D7';
obj.annotations = [{
content: obj.data['Role'],
style: {
color: 'white'
}
}];
return obj;
}
//Sets the default properties for all the connectors
public getConnectorDefaults(connector: ConnectorModel, diagram: Diagram): ConnectorModel {
connector.style = {
strokeColor: '#6BA5D7',
strokeWidth: 2
};
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).fill = '#6BA5D7';
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).strokeColor = '#6BA5D7';
((connector as ConnectorModel).targetDecorator as DecoratorModel).shape = 'None';
((connector as ConnectorModel).targetDecorator as DecoratorModel).shape = 'None';
connector.type = 'Orthogonal';
return connector;
}
ngOnInit(): void {
this.snapSettings = {
constraints: 0
}
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: 'OrganizationalChart',
getLayoutInfo: (node: Node, options: TreeInfo) => {
if (!options.hasSubTree) {
options.type = 'Center';
options.orientation = 'Horizontal';
}
}
}
//Configures data source for Diagram
this.dataSourceSettings = {
id: 'Id',
parentId: 'Team',
dataSource: this.items
}
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { DiagramModule, HierarchicalTreeService, DataBindingService } from '@syncfusion/ej2-angular-diagrams';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule, DiagramModule
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [HierarchicalTreeService, DataBindingService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
The following table illustrates the properties that “options” argument takes.
Property | Description | Default Value |
---|---|---|
options.assistants | By default, the collection is empty. When any of the child nodes have to be set as Assistant, you can remove from children collection and have to insert into assistants collection. | Empty array |
options.orientation | Gets or sets the organizational chart orientation. | SubTreeOrientation.Vertical |
options.type | Gets or sets the chart organizational chart type. | For horizontal chart orientation:SubTreeAlignments.Center and for vertical chart orientation:SubTreeAlignments.Alternate |
options.offset | Offset is the horizontal space to be left between parent and child nodes. | 20 pixels applicable only for vertical chart orientations. |
options.hasSubTree | Gets whether the node contains subtrees. | Boolean |
options.level | Gets the depth of the node from layout root. | Number |
options.enableRouting | By default, connections are routed based on the chart type and orientations. This property gets or sets whether default routing is to be enabled or disabled. | true |
options.rows | Sets the number of rows on which the child nodes will be arranged. Applicable only for balanced type horizontal tree. | Number |
The following table illustrates the different chart orientations and chart types.
Orientation | Type | Description | Example |
---|---|---|---|
Horizontal | Left | Arranges the child nodes horizontally at the left side of the parent. | ![]() |
Right | Arranges the child nodes horizontally at the right side of the parent. | ![]() |
|
Center | Arranges the children like standard tree layout orientation. | ![]() |
|
Balanced | Arranges the leaf level child nodes in multiple rows. | ![]() |
|
Vertical | Left | Arranges the children vertically at the left side of the parent. | ![]() |
Right | Arranges the children vertically at the right side of the parent. | ![]() |
|
Alternate | Arranges the children vertically at both left and right sides of the parent. | ![]() |
The following code example illustrates how to set the vertical right arrangement to the leaf level trees.
import { Component, OnInit, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, NodeModel, ConnectorModel, SnapSettingsModel, LayoutModel, DataSourceModel, DecoratorModel, ShapeStyleModel, TreeInfo } from '@syncfusion/ej2-angular-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';
@Component({
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" [getConnectorDefaults]="getConnectorDefaults" [snapSettings]="snapSettings" [layout]="layout" [dataSourceSettings]="dataSourceSettings">
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public snapSettings?: SnapSettingsModel;
public items?: DataManager;
public layout?: LayoutModel;
public dataSourceSettings?: DataSourceModel;
//Initializes data source
public data: object[] = [{
Id: "parent",
Role: "Board"
},
{
Id: "1",
Role: "General Manager",
Manager: "parent"
},
{
Id: "2",
Role: "Human Resource Manager",
Manager: "1"
},
{
Id: "3",
Role: "Trainers",
Manager: "2"
},
{
Id: "4",
Role: "Recruiting Team",
Manager: "2"
},
{
Id: "6",
Role: "Design Manager",
Manager: "1"
},
{
Id: "7",
Role: "Design Supervisor",
Manager: "6"
},
{
Id: "8",
Role: "Development Supervisor",
Manager: "6"
},
{
Id: "9",
Role: "Drafting Supervisor",
Manager: "6"
},
{
Id: "10",
Role: "Marketing Manager",
Manager: "1"
},
{
Id: "11",
Role: "Oversea sales Manager",
Manager: "10"
},
{
Id: "12",
Role: "Petroleum Manager",
Manager: "10"
},
{
Id: "13",
Role: "Service Dept. Manager",
Manager: "10"
},
];
//Sets the default properties for all the Nodes
public getNodeDefaults(obj: NodeModel | any, diagram: Diagram): NodeModel {
obj.width = 150;
obj.height = 50;
obj.borderColor = 'white';
obj.style.fill = '#6BA5D7';
obj.borderWidth = 1;
obj.annotations = [{
content: obj.data['Role'],
style: {
color: 'white'
}
}];
return obj;
}
//Sets the default properties for all the connectors
public getConnectorDefaults(connector: ConnectorModel, diagram: Diagram): ConnectorModel {
connector.style = {
strokeColor: '#6BA5D7',
strokeWidth: 2
};
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).fill = '#6BA5D7';
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).strokeColor = '#6BA5D7';
((connector as ConnectorModel).targetDecorator as DecoratorModel).shape = 'None';
connector.type = 'Orthogonal';
return connector;
}
ngOnInit(): void {
this.snapSettings = {
constraints: 0
}
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: 'OrganizationalChart',
//Defines getLayoutInfo
getLayoutInfo: (node: Node | any, options: TreeInfo) => {
if (node.data['Role'] === 'General Manager') {
((options as TreeInfo).assistants as string[]).push(((options as TreeInfo).children as string[])[0]);
((options as TreeInfo).children as string[]).splice(0, 1);
}
if (!options.hasSubTree) {
options.type = 'Right';
options.orientation = 'Vertical';
}
}
}
//Configures data source for Diagram
this.dataSourceSettings = {
id: 'Id',
parentId: 'Manager',
dataSource: this.items
}
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { DiagramModule, HierarchicalTreeService, DataBindingService } from '@syncfusion/ej2-angular-diagrams';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule, DiagramModule
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [HierarchicalTreeService, DataBindingService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
Assistant
Assistants are child item that have a different relationship with the parent node. They are laid out in a dedicated part of the tree. A node can be specified as an assistant of its parent by adding it to the assistants
property of the argument “options”.
The following code example illustrates how to add assistants to layout.
import { Component, OnInit, ViewEncapsulation, ViewChild } from '@angular/core';
import { DiagramComponent, Diagram, NodeModel, ConnectorModel, SnapSettingsModel, LayoutModel, DataSourceModel, DecoratorModel, ShapeStyleModel, TreeInfo } from '@syncfusion/ej2-angular-diagrams';
import { DataManager, Query } from '@syncfusion/ej2-data';
@Component({
selector: "app-container",
template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults]="getNodeDefaults" [getConnectorDefaults]="getConnectorDefaults" [snapSettings]="snapSettings" [layout]="layout" [dataSourceSettings]="dataSourceSettings">
</ejs-diagram>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
@ViewChild("diagram")
public diagram?: DiagramComponent;
public snapSettings?: SnapSettingsModel;
public items?: DataManager;
public layout?: LayoutModel;
public dataSourceSettings?: DataSourceModel;
//Initializes data source
public data: object[] = [{
Id: 1,
Role: "General Manager"
},
{
Id: 2,
Role: "Assistant Manager",
Team: 1
},
{
Id: 3,
Role: "Human Resource Manager",
Team: 1
},
{
Id: 4,
Role: "Design Manager",
Team: 1
},
{
Id: 5,
Role: "Operation Manager",
Team: 1
},
{
Id: 6,
Role: "Marketing Manager",
Team: 1
}
];
//Sets the default properties for all the Nodes
public getNodeDefaults(obj: NodeModel | any, diagram: Diagram): NodeModel {
obj.width = 150;
obj.height = 50;
obj.borderColor = 'white';
obj.style.fill = '#6BA5D7';
obj.borderWidth = 1;
obj.annotations = [{
content: obj.data['Role'],
style: {
color: 'white'
}
}];
return obj;
}
//Sets the default properties for all the connectors
public getConnectorDefaults(connector: ConnectorModel, diagram: Diagram): ConnectorModel {
connector.style = {
strokeColor: '#6BA5D7',
strokeWidth: 2
};
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).fill = '#6BA5D7';
(((connector as ConnectorModel).targetDecorator as DecoratorModel).style as ShapeStyleModel).strokeColor = '#6BA5D7';
((connector as ConnectorModel).targetDecorator as DecoratorModel).shape = 'None';
connector.type = 'Orthogonal';
return connector;
}
ngOnInit(): void {
this.snapSettings = {
constraints: 0
}
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: 'OrganizationalChart',
// define the getLayoutInfo
getLayoutInfo: (node: Node | any, options: TreeInfo) => {
if (node.data['Role'] === 'General Manager') {
((options as TreeInfo).assistants as string[]).push(((options as TreeInfo).children as string[])[0]);
((options as TreeInfo).children as string[]).splice(0, 1);
}
if (!options.hasSubTree) {
(options as TreeInfo).type = 'Center';
(options as TreeInfo).orientation = 'Horizontal';
}
}
}
//Configures data source for Diagram
this.dataSourceSettings = {
id: 'Id',
parentId: 'Team',
dataSource: this.items
}
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { DiagramModule, HierarchicalTreeService, DataBindingService } from '@syncfusion/ej2-angular-diagrams';
/**
* Module
*/
@NgModule({
imports: [
BrowserModule, DiagramModule
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [HierarchicalTreeService, DataBindingService]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
Symmetric layout
The symmetric layout has been formed using nodes position by closer together or pushing them further apart. This is repeated iteratively until the system comes to an equilibrium state.
The layout’s springLength
defined as how long edges should be, ideally. This will be the resting length for the springs. Edge attraction and vertex repulsion forces to be defined by using layout’s springFactor
, the more sibling nodes repel each other. The relative positions do not change any more from one iteration to the next. The number of iterations can be specified by using layout’s maxIteration
.
Note: If you want to use symmetric layout in diagram, you need to inject SymmetricLayout in the diagram.
Mind Map layout
A mind map is a diagram that displays the nodes as a spider diagram organizes information around a central concept. To create mind map, the type
of layout should be set as MindMap
.
To create a Mindmap Layout using Angular Diagram, refer to the below video link,
Tree Orientation in layout
An Orientation
of a MindMapTreeLayout
is used to arrange the tree layout according to a specific direction. By default, the orientation is set to Horizontal. The following table outlines the various orientation types available:
Orientation Type</td> | Description</td>
</tr>
Horizontal |
Aligns the tree layout from left to right |
Vertical |
Aligns the tree layout from top to bottom |
|