- Change expand and collapse icon
- Change indent space of tree column cell text
- Render parent rows in collapsed state
- Retain expanded and collapsed state
- Persist expanded and collapsed state on page refresh using localStorage
- Programmatically expand and collapse a row
- Expand and collapse action events
Contact Support
Tree Column in Angular Gantt component
5 Apr 202524 minutes to read
The Syncfusion® Angular Gantt component provides a convenient way to represent parent-child relationships using expand and collapse icons in the tree column cell. This can be achieved by utilizing the treeColumnIndex property by setting its value to a column index. This guide outlines how to configure and use this property to display the expand or collapse icon in the desired column.
<ejs-gantt [dataSource]='data' [treeColumnIndex]='2'>
<!-- Other gantt configurations -->
</ejs-gantt>
Change expand and collapse icon
The Syncfusion® Angular Gantt component allows to customize the default expand and collapse icons by applying custom CSS styles.
To customize the expand and collapse icons, use the following CSS styles:
.e-gantt .e-grid .e-treegridexpand::before {
content: "\2795";
}
.e-gantt .e-grid .e-treegridcollapse::before {
content: "\2796";
}
In the following demo, the expand and collapse icons are customized using the CSS styles
import { BrowserModule } from '@angular/platform-browser';
import { GanttModule } from '@syncfusion/ej2-angular-gantt';
import { Component, ViewEncapsulation, ViewChild, OnInit, NgModule } from '@angular/core';
import { GanttComponent } from '@syncfusion/ej2-angular-gantt';
import { GanttData } from './data';
@Component({
imports: [
GanttModule
],
standalone: true,
selector: 'app-root',
template:
`<ejs-gantt id="ganttDefault" #gantt height="430px" [dataSource]="data"
[taskFields]="taskSettings" [treeColumnIndex]='1' [splitterSettings] = "splitterSettings" >
<e-columns>
<e-column field='TaskID' headerText='Task ID' width=90 ></e-column>
<e-column field='TaskName' headerText='Task Name' width=290></e-column>
<e-column field='StartDate' headerText='Start Date' width=120 ></e-column>
<e-column field='Duration' headerText='Duration' width=90 ></e-column>
<e-column field='Progress' headerText='Progress' width=120></e-column>
</e-columns>
</ejs-gantt>`,
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
// Data for Gantt
public data?: object[];
@ViewChild('gantt')
public gantt?: GanttComponent;
public taskSettings?: object;
public splitterSettings?: object;
public cssClass: string = "custom";
public ngOnInit(): void {
this.data = GanttData;
this.taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'subtasks'
};
this.splitterSettings = {
position: '75%'
};
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
.e-gantt .e-grid .e-treegridexpand::before {
content: "\2795";
}
.e-gantt .e-grid .e-treegridcollapse::before {
content: "\2796";
}
Change indent space of tree column cell text
The Gantt component allows to customize the indent space of tree column cell text by leveraging the queryCellInfo event.
In the following demonstration, indent space is applied by adding a CSS class to the tree column cell using the queryCellInfo
event.
import { BrowserModule } from '@angular/platform-browser';
import { GanttModule } from '@syncfusion/ej2-angular-gantt';
import { Component, ViewEncapsulation, ViewChild, OnInit, NgModule } from '@angular/core';
import { GanttComponent } from '@syncfusion/ej2-angular-gantt';
import { GanttData } from './data';
@Component({
imports: [
GanttModule
],
standalone: true,
selector: 'app-root',
template:
`<ejs-gantt id="ganttDefault" #gantt height="430px" [dataSource]="data" [treeColumnIndex]='1'
[taskFields]="taskSettings" [splitterSettings] = "splitterSettings" (queryCellInfo)=querycellinfo($event)>
<e-columns>
<e-column field='TaskID' headerText='Task ID' width=90 ></e-column>
<e-column field='TaskName' headerText='Task Name' width=290></e-column>
<e-column field='StartDate' headerText='Start Date' width=120 ></e-column>
<e-column field='Duration' headerText='Duration' width=90 ></e-column>
<e-column field='Progress' headerText='Progress' width=120></e-column>
</e-columns>
</ejs-gantt>`,
styles: [
`.indents {
text-indent: 20px !important;
}`
],
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
// Data for Gantt
public data?: object[];
@ViewChild('gantt')
public gantt?: GanttComponent;
public taskSettings?: object;
public splitterSettings?: object;
public ngOnInit(): void {
this.data = GanttData;
this.taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'subtasks'
};
this.splitterSettings = {
position: '75%'
};
}
querycellinfo(args: any): void {
if (!args.data.hasChildRecords && args.column.index == (this.gantt as GanttComponent).treeColumnIndex) {
args.cell.classList.add('indents');
}
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
Render parent rows in collapsed state
You can easily render all the parent rows in a collapsed state in the Gantt component using the collapseAllParentTasks property. Using this property, all parent rows are collapsed during the initial rendering.
In the following demo, all parent rows are rendered in collapsed state in initial rendering.
import { BrowserModule } from '@angular/platform-browser';
import { GanttModule } from '@syncfusion/ej2-angular-gantt';
import { Component, ViewEncapsulation, ViewChild, OnInit, NgModule } from '@angular/core';
import { GanttComponent } from '@syncfusion/ej2-angular-gantt';
import { GanttData } from './data';
@Component({
imports: [
GanttModule
],
standalone: true,
selector: 'app-root',
template:
`<ejs-gantt id="ganttDefault" #gantt height="410px" [dataSource]="data"
[taskFields]="taskSettings" [treeColumnIndex]='1' [splitterSettings] = "splitterSettings" [collapseAllParentTasks]="true">
<e-columns>
<e-column field='TaskID' headerText='Task ID' width=90 ></e-column>
<e-column field='TaskName' headerText='Task Name' width=290></e-column>
<e-column field='StartDate' headerText='Start Date' width=120 ></e-column>
<e-column field='Duration' headerText='Duration' width=90 ></e-column>
<e-column field='Progress' headerText='Progress' width=120></e-column>
</e-columns>
</ejs-gantt>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
// Data for Gantt
public data?: object[];
@ViewChild('gantt')
public gantt?: GanttComponent;
public taskSettings?: object;
public splitterSettings?: object;
public ngOnInit(): void {
this.data = GanttData;
this.taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'subtasks'
};
this.splitterSettings = {
position: '75%'
};
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
Retain expanded and collapsed state
To maintain the expanded and collapsed state of specific parent rows in the Syncfusion® Angular Gantt, utilize the expandState
property. This property corresponds to a value within the data object of the data source, signifying the expand status of the parent row.
In the following demonstration, the parent rows are rendered in an expanded or collapsed state based on the value of the expandState
property in the data source.
import { BrowserModule } from '@angular/platform-browser';
import { GanttModule } from '@syncfusion/ej2-angular-gantt';
import { Component, ViewEncapsulation, ViewChild, OnInit, NgModule } from '@angular/core';
import { GanttData } from './data';
@Component({
imports: [
GanttModule
],
standalone: true,
selector: 'app-root',
template:
` <ejs-gantt id="ganttDefault" height="430px" [dataSource]="data" [taskFields]="taskSettings" [treeColumnIndex]='1' [splitterSettings] = "splitterSettings">
<e-columns>
<e-column field='TaskID' headerText='Task ID' textAlign='Right' width=90 ></e-column>
<e-column field='TaskName' headerText='Task Name' textAlign='Left' width=290></e-column>
<e-column field='StartDate' headerText='Start Date' textAlign='Right' width=120 ></e-column>
<e-column field='Duration' headerText='Duration' textAlign='Right' width=90 ></e-column>
<e-column field='Progress' headerText='Progress' textAlign='Right' width=120></e-column>
</e-columns>
</ejs-gantt>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
// Data for Gantt
public data?: object[];
public taskSettings?: object;
public splitterSettings?: object;
public ngOnInit(): void {
this.data = GanttData;
this.taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
expandState: 'isExpand',
child: 'subtasks'
};
this.splitterSettings = {
position: '75%'
};
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let GanttData: Object[] = [
{
TaskID: 1,
TaskName: 'Project Initiation',
StartDate: new Date('04/02/2019'),
EndDate: new Date('04/21/2019'),
isExpand: true,
subtasks: [
{ TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 50, },
{ TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, Progress: 50, },
{
TaskID: 4,
TaskName: 'Soil test approval',
StartDate: new Date('04/02/2019'),
Duration: 4,
Progress: 50,
isExpand: true,
subtasks: [
{
TaskID: 5,
TaskName: 'Project Estimation',
StartDate: new Date('04/02/2019'),
EndDate: new Date('04/21/2019'),
isExpand: false,
subtasks: [
{ TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, },
{ TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, },
{ TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, Progress: 50, }
]
},
]
},
]
},
];
Persist expanded and collapsed state on page refresh using localStorage
To persist the expanded and collapsed state of rows using the dataBound event when the page refreshes in the browser, this guide illustrates how to utilize localStorage to save and retrieve the state of rows.
- Save the collapsed record’s primarykey value to localStorage in the collapsed event of the Gantt by using the setItem method of the local storage.
- On page refresh, the dataBound event will be triggered. In that event, retrieve the saved records by using the getItem method of the local storage.
- Then, collapsed the specific rows by using the CollapseByKey method of treegrid object in gantt instance by passing the primary key value as a parameter. and collapse the specific rows by using the
collapseRow
method of the Tree Grid by passing the row detail.
In the following demo, the above-mentioned steps have been followed to persist the expanded or collapsed state while refreshing the page in the browser.
import { BrowserModule } from '@angular/platform-browser';
import { GanttModule } from '@syncfusion/ej2-angular-gantt';
import { Component, ViewEncapsulation, ViewChild, OnInit, NgModule } from '@angular/core';
import { GanttData } from './data';
import { GanttComponent } from '@syncfusion/ej2-angular-gantt';
@Component({
imports: [
GanttModule
],
standalone: true,
selector: 'app-root',
template:
`<ejs-gantt id="ganttDefault" #gantt height="430px" [dataSource]="data" [taskFields]="taskSettings" [treeColumnIndex]='1'
(dataBound)='dataBound()' (collapsed)="collapsed($event)" (expanded)="expanded($event)" [splitterSettings] = "splitterSettings">
<e-columns>
<e-column field='TaskID' headerText='Task ID' isPrimaryKey="true" textAlign='Right' width=90 ></e-column>
<e-column field='TaskName' headerText='Name' textAlign='Left' width=290></e-column>
<e-column field='StartDate' headerText='Start Date' textAlign='Right' width=120 ></e-column>
<e-column field='Duration' headerText='Duration' textAlign='Right' width=90 ></e-column>
<e-column field='Progress' headerText='Progress' textAlign='Right' width=120></e-column>
</e-columns>
</ejs-gantt>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
// Data for Gantt
public data?: object[];
@ViewChild('gantt')
public gantt: GanttComponent | undefined;
public taskSettings?: object;
public splitterSettings?: object;
public collapsingData: any = [];
public ngOnInit(): void {
this.data = GanttData;
this.taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'subtasks'
};
this.splitterSettings = {
position: '75%'
};
}
dataBound(): void {
//checking whether it is initial rendering
if ((this.gantt as GanttComponent).treeGrid.initialRender &&
window.localStorage !== null
) {
//retriving collapsed record in local storage using getItem method
var Collapsed_storagedata = JSON.parse(
window.localStorage.getItem('collapsingData') as any
);
if (Collapsed_storagedata !== null) {
for (var i = 0; i < Collapsed_storagedata.length; i++) {
(this.gantt as GanttComponent).treeGrid.collapseByKey(
Collapsed_storagedata[i]
); //collapsing row using collapseByKey method
}
}
}
}
collapsed(args: any): void {
//Here collected the collapsed record's primarykey value
this.collapsingData.push((args.data as any).TaskID);
//Here set/ update the localstorage value
this.setstorage_data(this.collapsingData);
}
expanded(args: any): void {
//Check whether the collapsing data array has the same primary key value as the expanding data.
var index = this.collapsingData.findIndex((x: any) => {
if (x == (args.data as any).TaskID) {
return x;
}
});
//if yes here we remove that primary key value
this.collapsingData.splice(index, 1);
// update the localstorage value
this.setstorage_data(this.collapsingData);
}
setstorage_data(data: any): void {
window.localStorage.setItem('collapsingData', JSON.stringify(data));
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
Programmatically expand and collapse a row
In the Gantt, you can programmatically expand and collapse rows using various methods provided by the gantt. This guide demonstrates how to leverage these methods to control the expansion and collapse of rows based on different criteria.
To expand all rows in the gantt, use the expandAll
method.
this.gantt.expandAll();
To collapse all rows in gantt, use the collapseAll
method.
this.gantt.collapseAll();
To expand the records at a specific hierarchical level, use the expandAtLevel
method.
this.gantt.treegrid.expandAtLevel(0);
To collapse the records at a specific hierarchical level, use the collapseAtLevel
method.
this.gantt.treegrid.collapseAtLevel(0);
To expand records based on a given primary key value, use the expandByKey
method.
this.gantt.treegrid.expandByKey(1); //Here pass the primary key value
To collapse records based on a given primary key value, use the collapseByKey
method
this.gantt.treegrid.collapseByKey(1);//Here pass the primary key value
To expand child rows based on the row element, use the expandRow
method.
this.gantt.treegrid.expandRow(tr); //Here pass the row element as parameter
To collapse child rows based on the row element, use the collapseRow
method.
this.gantt.treegrid.collapseRow(tr);//Here pass the row element as parameter
Expand and collapse action events
In the Gantt, you can customize the behavior and perform specific actions when the expand or collapse icon is clicked. This can be achieved using a set of events provided by the gantt.
The following events are available for handling expand and collapse actions:
-
expanding: This event is triggered before a row is expanded. You can perform custom actions or cancel the row expansion based on certain conditions.
-
expanded: This event is triggered after a row is expanded. You can perform additional actions or updates after the row expansion is completed.
-
collapsing: This event is triggered before a row is collapsed. You can perform custom actions or cancel the row collapse based on certain conditions.
-
collapsed: This event is triggered after a row is collapsed. You can perform additional actions or updates after the row collapse is completed.
import { BrowserModule } from '@angular/platform-browser';
import { GanttModule } from '@syncfusion/ej2-angular-gantt';
import { Component, ViewEncapsulation, ViewChild, OnInit, NgModule } from '@angular/core';
import { GanttData } from './data';
@Component({
imports: [
GanttModule
],
standalone: true,
selector: 'app-root',
template:
`<div class="control-section">
<div style="margin-left:180px"><p style="color:red;" id="message"></p></div>
<ejs-gantt id="ganttDefault" height="430px" [dataSource]="data" [taskFields]="taskSettings" [treeColumnIndex]='1' (expanding)="expanding($event)" (collapsing)="collapsing($event)" (collapsed)="collapsed($event)"
(expanded)="expanded($event)" [splitterSettings] = "splitterSettings">
<e-columns>
<e-column field='TaskID' headerText='Task ID' textAlign='Right' width=90 ></e-column>
<e-column field='TaskName' headerText='Task Name' textAlign='Left' width=290></e-column>
<e-column field='StartDate' headerText='Start Date' textAlign='Right' width=120 ></e-column>
<e-column field='Duration' headerText='Duration' textAlign='Right' width=90 ></e-column>
<e-column field='Progress' headerText='Progress' textAlign='Right' width=120></e-column>
</e-columns>
</ejs-gantt>
</div>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
// Data for Gantt
public data?: object[];
public taskSettings?: object;
public splitterSettings?: object;
public message?: string;
public ngOnInit(): void {
this.data = GanttData;
this.taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
child: 'subtasks'
};
this.splitterSettings = {
position: '75%'
};
}
expanding(args: any): void {
this.message = 'Expanding event is triggered';
}
collapsing(args: any): void {
this.message = 'Collapsing event is triggered';
}
expanded(args: any): void {
this.message = 'Expanded event is triggered';
}
collapsed(args: any): void {
this.message = 'Collapsed event is triggered';
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));