Sorting in Angular Gantt Component
18 Oct 202524 minutes to read
The Syncfusion® Angular Gantt component provides sorting functionality to arrange task data in ascending or descending order based on column values.
To enable sorting, set the allowSorting property to true. You can configure sorting behavior using the sortSettings property.
Sorting is applied by clicking a column header. For multi-column sorting, hold the CTRL key while selecting additional headers. To remove sorting from a specific column in a multi-sorted view, hold the SHIFT key and click the column header. For details on keyboard interactions, refer to the selection keyboard interaction documentation.
To enable sorting functionality, add the SortService in the providers of the component.
import { GanttModule, SortService } from '@syncfusion/ej2-angular-gantt'
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
@Component({
    imports: [GanttModule],
    providers: [SortService],
    standalone: true,
    selector: 'app-root',
    template:
        `<ejs-gantt height="430px" [dataSource]="data"  [taskFields]="taskSettings" [columns]="columns" [splitterSettings]="splitterSettings" [allowSorting]= 'true'></ejs-gantt>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent implements OnInit {
    public data?: object[];
    public taskSettings?: object;
    public splitterSettings?: object;
    public columns?: object[];
    public ngOnInit(): void {
        this.data = [
            {
                TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
            },
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            {
                TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
            },
            { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
        ];
        this.taskSettings = {
            id: 'TaskID',
            name: 'TaskName',
            startDate: 'StartDate',
            duration: 'Duration',
            progress: 'Progress',
            parentID: 'ParentID'
        };
        this.splitterSettings = {
            columnIndex: 3
        };
        this.columns = [
            { field: 'TaskID', headerText: 'Task ID', textAlign: 'Left', width: '100' },
            { field: 'TaskName', headerText: 'Task Name', width: '250' },
            { field: 'StartDate', headerText: 'Start Date', width: '150' },
            { field: 'Duration', headerText: 'Duration', width: '150' },
            { field: 'Progress', headerText: 'Progress', width: '150' },
        ];
    }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
- The Gantt columns are sorted in the ascending order. If you click the already sorted column, the sort direction toggles.
 - To disable sorting for a particular column, set the columns.allowSorting property to false.
 
Initial sorting
You can apply sorting during the initial render of the Syncfusion Angular Gantt component by configuring the sortSettings.columns property. Each column should be defined with a specific field and direction, ensuring that the Gantt loads with the desired sort order applied to the specified columns.
The following code example shows how to add sorted columns during Gantt initialization, with field set to TaskID and direction to Descending, and another with field as TaskName and direction as Ascending.
import { GanttModule, SortService } from '@syncfusion/ej2-angular-gantt'
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
@Component({
    imports: [ GanttModule ],
    providers: [SortService],
    standalone: true,
    selector: 'app-root',
    template:
       `<ejs-gantt id="ganttDefault" height="430px" [dataSource]="data"  [taskFields]="taskSettings" [columns]="columns" [splitterSettings]="splitterSettings" [allowSorting]= 'true' [sortSettings]="sortSettings"></ejs-gantt>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent implements OnInit{
    public data?: object[];
    public taskSettings?: object;
    public columns?: object[];
    public splitterSettings?: object;
    public sortSettings?: object;
    
    public ngOnInit(): void {
        this.data = [
            {
                TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
            },
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            {
                TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
            },
            { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
        ];
        this.taskSettings = {
            id: 'TaskID',
            name: 'TaskName',
            startDate: 'StartDate',
            duration: 'Duration',
            progress: 'Progress',
            parentID: 'ParentID'
        };
        this.splitterSettings = {
            columnIndex: 3
        };
        this.columns =  [
            { field: 'TaskID', headerText: 'Task ID', textAlign: 'Left', width: '120' },
            { field: 'TaskName', headerText: 'Task Name', width: '250' },
            { field: 'StartDate', headerText: 'Start Date', width: '150' },
            { field: 'Duration', headerText: 'Duration', width: '150' },
            { field: 'Progress', headerText: 'Progress', width: '150' },
        ];
        this.sortSettings = { columns: [{ field: 'TaskID', direction: 'Descending' }, { field: 'TaskName', direction: 'Ascending' }] };
    }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Sort columns externally
You can externally sort columns, remove a specific sort, or clear all sorting in the Syncfusion® Angular Gantt component using button clicks.
Add sort columns
You can externally sort a column in the Syncfusion® Angular Gantt component using the sortColumn method with parameters for column name, sort direction, and multi-sort configuration.
import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { GanttModule, GanttComponent, SortService } from '@syncfusion/ej2-angular-gantt';
import { DropDownListComponent, DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
@Component({
  imports: [GanttModule, ButtonModule, DropDownListModule],
  providers: [SortService],
  standalone: true,
  selector: 'app-root',
  template: `
    <div style="display: flex; align-items: center; gap: 20px; margin-bottom: 20px;">
      <label style="font-weight: bold;">Column name:</label>
      <ejs-dropdownlist #dropdownColumn index="0" width="120" [dataSource]="columnOptions" [fields]="field"></ejs-dropdownlist>
      <label style="font-weight: bold;">Sorting direction:</label>
      <ejs-dropdownlist #dropdownDirection index="0" width="120" [dataSource]="direction" [fields]="field"></ejs-dropdownlist>
      <button ejs-button id="button" cssClass="e-outline" (click)="addSortColumn()">
        Add sort column
      </button>
    </div>
    <ejs-gantt #gantt id="ganttDefault" height="430px" [dataSource]="data" [taskFields]="taskSettings" [columns]="columns" [splitterSettings]="splitterSettings" [allowSorting]="true">
    </ejs-gantt>`,
  encapsulation: ViewEncapsulation.None
})
export class AppComponent implements OnInit {
  @ViewChild('gantt', { static: true }) public ganttInstance!: GanttComponent;
  @ViewChild('dropdownColumn', { static: true }) public dropDownColumn!: DropDownListComponent;
  @ViewChild('dropdownDirection', { static: true }) public dropDownDirection!: DropDownListComponent;
  public data: object[] = [];
  public taskSettings: object = {};
  public splitterSettings: object = {};
  public columns: object[] = [];
  public columnOptions: object[] = [];
  public direction: object[] = [
    { text: 'Ascending', value: 'Ascending' },
    { text: 'Descending', value: 'Descending' }
  ];
  public field: object = { text: 'text', value: 'value' };
  public ngOnInit(): void {
    this.data = [
      { TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
    ];
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      duration: 'Duration',
      progress: 'Progress',
      parentID: 'ParentID'
    };
    this.splitterSettings = { columnIndex: 3 };
    this.columns = [
      { field: 'TaskID', headerText: 'Task ID', textAlign: 'Left', width: '100' },
      { field: 'TaskName', headerText: 'Task Name', width: '250' },
      { field: 'StartDate', headerText: 'Start Date', width: '150' },
      { field: 'Duration', headerText: 'Duration', width: '150' },
      { field: 'Progress', headerText: 'Progress', width: '150' }
    ];
    this.columnOptions = [
      { text: 'Task ID', value: 'TaskID' },
      { text: 'Task Name', value: 'TaskName' },
      { text: 'Start Date', value: 'StartDate' },
      { text: 'Duration', value: 'Duration' },
      { text: 'Progress', value: 'Progress' }
    ];
  }
  public addSortColumn(): void {
    const column = this.dropDownColumn.value as string;
    const direction = this.dropDownDirection.value as 'Ascending' | 'Descending';
    (this.ganttInstance as GanttComponent).sortColumn(column, direction, true);
  }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Remove sort columns
You can externally remove sorting from a specific column in the Syncfusion® Angular Gantt component using the removeSortColumn method by passing the column name.
import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { GanttModule, GanttComponent, SortService } from '@syncfusion/ej2-angular-gantt';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { DropDownListAllModule, DropDownListComponent } from '@syncfusion/ej2-angular-dropdowns';
@Component({
    selector: 'app-root',
    standalone: true,
    imports: [GanttModule, ButtonModule, DropDownListAllModule],
    providers: [SortService],
    encapsulation: ViewEncapsulation.None,
    template: `
        <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 20px;">
            <label style="margin-right: 10px;font-weight:bold">Column name:</label>
            <ejs-dropdownlist #dropdown index="0" width="120" [dataSource]="columnOptions" [fields]="field"></ejs-dropdownlist>
            <button ejs-button id="button" cssClass="e-outline" (click)="removeSortColumn()">
                Remove sort column
            </button>
        </div>
        <ejs-gantt #gantt id="ganttDefault" height="430px" [dataSource]="data" [taskFields]="taskSettings" [columns]="columns"
        [splitterSettings]="splitterSettings" [sortSettings]="sortSettings" [allowSorting]="true">
        </ejs-gantt>`
})
export class AppComponent implements OnInit {
    @ViewChild('gantt', { static: true }) public ganttInstance!: GanttComponent;
    @ViewChild('dropdown', { static: true }) public dropDown!: DropDownListComponent;
    public data: object[] = [];
    public taskSettings: object = {};
    public columns: object[] = [];
    public splitterSettings: object = {};
    public sortSettings: object = {};
    public columnOptions: object[] = [];
    public field: object = { text: 'text', value: 'value' };
    ngOnInit(): void {
        this.data = [
            { TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
            { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
        ];
        this.taskSettings = {
            id: 'TaskID',
            name: 'TaskName',
            startDate: 'StartDate',
            duration: 'Duration',
            progress: 'Progress',
            parentID: 'ParentID'
        };
        this.columns = [
            { field: 'TaskID', headerText: 'Task ID', textAlign: 'Left', width: '120' },
            { field: 'TaskName', headerText: 'Task Name', width: '250' },
            { field: 'StartDate', headerText: 'Start Date', width: '150' },
            { field: 'Duration', headerText: 'Duration', width: '150' },
            { field: 'Progress', headerText: 'Progress', width: '150' }
        ];
        this.splitterSettings = { columnIndex: 3 };
        this.sortSettings = {
            columns: [
                { field: 'TaskID', direction: 'Descending' },
                { field: 'TaskName', direction: 'Ascending' }
            ]
        };
        this.columnOptions = [
            { text: 'Task ID', value: 'TaskID' },
            { text: 'Task Name', value: 'TaskName' },
            { text: 'Start Date', value: 'StartDate' },
            { text: 'Duration', value: 'Duration' },
            { text: 'Progress', value: 'Progress' }
        ];
    }
    public removeSortColumn(): void {
        const columnField = this.dropDown.value as string;
        (this.ganttInstance as GanttComponent).removeSortColumn(columnField);
    }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Clear sorting
You can clear all sorted columns in the Syncfusion® Angular Gantt component using the clearSorting method to reset the Gantt chart to its unsorted state.
import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { GanttModule, GanttComponent, SortService } from '@syncfusion/ej2-angular-gantt';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [GanttModule, ButtonModule],
  providers: [SortService],
  encapsulation: ViewEncapsulation.None,
  template: `
    <button ejs-button id="Clearsort" (click)="clearSort()">Clear Sort</button>
    <br /><br /><br />
    <ejs-gantt #gantt id="ganttDefault" height="430px" [dataSource]="data" [taskFields]="taskSettings" [columns]="columns" [splitterSettings]="splitterSettings"
    [sortSettings]="sortSettings" [allowSorting]="true"></ejs-gantt>`
})
export class AppComponent implements OnInit {
  @ViewChild('gantt', { static: true }) public ganttInstance!: GanttComponent;
  public data: object[] = [];
  public taskSettings: object = {};
  public columns: object[] = [];
  public splitterSettings: object = {};
  public sortSettings: object = {};
  ngOnInit(): void {
    this.data = [
      { TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
    ];
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      duration: 'Duration',
      progress: 'Progress',
      parentID: 'ParentID'
    };
    this.columns = [
      { field: 'TaskID', headerText: 'Task ID', textAlign: 'Left', width: '120' },
      { field: 'TaskName', headerText: 'Task Name', width: '250' },
      { field: 'StartDate', headerText: 'Start Date', width: '150' },
      { field: 'Duration', headerText: 'Duration', width: '150' },
      { field: 'Progress', headerText: 'Progress', width: '150' }
    ];
    this.splitterSettings = { columnIndex: 3 };
    this.sortSettings = {
      columns: [
        { field: 'TaskID', direction: 'Descending' },
        { field: 'TaskName', direction: 'Ascending' }
      ]
    };
  }
  public clearSort(): void {
    (this.ganttInstance as GanttComponent).clearSorting();
  }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Customize sort icon
You can customize the sort icons in the Syncfusion® Angular Gantt component by overriding the .e-icon-ascending and .e-icon-descending CSS classes using the content property , as shown below:
 .e-gantt .e-icon-ascending::before {
      content: '\\e306';
    }
    .e-gantt .e-icon-descending::before {
      content: '\\e304';
    }import { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { GanttModule, SortService } from '@syncfusion/ej2-angular-gantt';
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [GanttModule],
  providers: [SortService],
  encapsulation: ViewEncapsulation.None,
  template: `
    <ejs-gantt height="430px" [dataSource]="data" [taskFields]="taskSettings" [columns]="columns" [splitterSettings]="splitterSettings" [sortSettings]="sortSettings" [allowSorting]="true">
    </ejs-gantt>`,
  styles: [`
    .e-gantt .e-icon-ascending::before {
      content: '\\e306';
    }
    .e-gantt .e-icon-descending::before {
      content: '\\e304';
    }
  `]
})
export class AppComponent implements OnInit {
  public data: object[] = [];
  public taskSettings: object = {};
  public columns: object[] = [];
  public splitterSettings: object = {};
  public sortSettings: object = {};
  ngOnInit(): void {
    this.data = [
      { TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
    ];
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      duration: 'Duration',
      progress: 'Progress',
      parentID: 'ParentID'
    };
    this.columns = [
      { field: 'TaskID', headerText: 'Task ID', textAlign: 'Left', width: '120' },
      { field: 'TaskName', headerText: 'Task Name', width: '250' },
      { field: 'StartDate', headerText: 'Start Date', width: '150' },
      { field: 'Duration', headerText: 'Duration', width: '150' },
      { field: 'Progress', headerText: 'Progress', width: '150' }
    ];
    this.splitterSettings = { columnIndex: 3 };
    this.sortSettings = {
      columns: [
        { field: 'TaskID', direction: 'Descending' },
        { field: 'StartDate', direction: 'Ascending' }
      ]
    };
  }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Custom sorting
You can customize the default sort behavior for a column in the Syncfusion® Angular Gantt component by assigning a column.sortComparer function to define custom sorting logic.
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { GanttModule, SortService } from '@syncfusion/ej2-angular-gantt';
@Component({
    selector: 'app-root',
    standalone: true,
    imports: [GanttModule],
    providers: [SortService],
    encapsulation: ViewEncapsulation.None,
    template: `
    <ejs-gantt height="430px" [dataSource]="data" [taskFields]="taskSettings" [columns]="columns" [splitterSettings]="splitterSettings" [sortSettings]="sortSettings" [allowSorting]="true">
    </ejs-gantt>`
})
export class AppComponent implements OnInit {
    public data: object[] = [];
    public taskSettings: object = {};
    public columns: object[] = [];
    public splitterSettings: object = {};
    public sortSettings: object = {};
    ngOnInit(): void {
        this.data = [
            { TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
            { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
        ];
        this.taskSettings = {
            id: 'TaskID',
            name: 'TaskName',
            startDate: 'StartDate',
            duration: 'Duration',
            progress: 'Progress',
            parentID: 'ParentID'
        };
        this.columns = [
            { field: 'TaskID', headerText: 'Task ID', textAlign: 'Left', width: '120' },
            {
                field: 'TaskName',
                headerText: 'Task Name',
                width: '250',
                sortComparer: this.customSortComparer
            },
            { field: 'StartDate', headerText: 'Start Date', width: '150' },
            { field: 'Duration', headerText: 'Duration', width: '150' },
            { field: 'Progress', headerText: 'Progress', width: '150' }
        ];
        this.splitterSettings = { columnIndex: 3 };
        this.sortSettings = {
            columns: [
                { field: 'TaskID', direction: 'Descending' },
                { field: 'StartDate', direction: 'Ascending' }
            ]
        };
    }
    
    public customSortComparer = (reference: string, comparer: string) => {
        if (reference < comparer) {
            return -1;
        }
        if (reference > comparer) {
            return 1;
        }
        return 0;
    }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Display null values always at bottom
You can customize the sorting behavior in the Syncfusion® Angular Gantt component to make null values consistently appear at the bottom, regardless of sort direction, by defining a column-level column.sortComparer function. By default, null values are placed at the bottom when sorting in ascending order and at the top when sorting in descending order. Applying a custom sortComparer helps override this default logic and is particularly useful when working with datasets where null entries should be visually separated from valid data.
The example below demonstrates how to display null values at the bottom of the Gantt while sorting the TaskName column in both ascending and descending order.
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { GanttModule, SortService } from '@syncfusion/ej2-angular-gantt';
import { SortDirection, SortEventArgs } from '@syncfusion/ej2-angular-grids';
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [GanttModule],
  providers: [SortService],
  encapsulation: ViewEncapsulation.None,
  template: `
    <ejs-gantt height="430px" [dataSource]="data" [taskFields]="taskSettings" [columns]="columns" [splitterSettings]="splitterSettings" [allowSorting]="true" (actionBegin)="actionBegin($event)">
    </ejs-gantt>`
})
export class AppComponent implements OnInit {
  public data: object[] = [];
  public taskSettings: object = {};
  public columns: object[] = [];
  public splitterSettings: object = {};
  public sortSettings: object = {};
  public action: 'Ascending' | 'Descending' = 'Ascending';
  ngOnInit(): void {
    this.data = [
      { TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 2, TaskName: null, StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 4, TaskName: null, StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
      { TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
      { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
    ];
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      duration: 'Duration',
      progress: 'Progress',
      parentID: 'ParentID'
    };
    this.columns = [
      { field: 'TaskID', headerText: 'Task ID', textAlign: 'Left', width: '120' },
      {
        field: 'TaskName',
        headerText: 'Task Name',
        width: '250',
        sortComparer: this.customSortComparer
      },
      { field: 'StartDate', headerText: 'Start Date', width: '150' },
      { field: 'Duration', headerText: 'Duration', width: '150' },
      { field: 'Progress', headerText: 'Progress', width: '150' }
    ];
    this.splitterSettings = { columnIndex: 3 };
  }
  public actionBegin(args: SortEventArgs) {
    if (args.requestType === 'sorting') {
      this.action = args.direction as SortDirection ;
    }
  }
  public customSortComparer = (reference: string, comparer: string): number => {
    const sortAsc = this.action === 'Ascending';
    
    // Always push nulls to the bottom.
    if (reference === null && comparer === null) return 0;
    if (reference === null) return 1;
    if (comparer === null) return -1;
    // Normal string comparison.
    if (reference < comparer) return sortAsc ? -1 : 1;
    if (reference > comparer) return sortAsc ? 1 : -1;
    return 0;
  };
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Sorting custom columns
You can sort custom columns of various types such as string or numeric in the Syncfusion® Angular Gantt component by adding them to the column collection. Initial sorting can be configured using the sortSettings property, or sorting can be triggered dynamically through external actions such as a button click.
The following code snippet demonstrates how to sort the CustomColumn using an external button.
import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { GanttComponent, GanttModule, SortService } from '@syncfusion/ej2-angular-gantt';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [GanttModule, ButtonModule],
  providers: [SortService],
  encapsulation: ViewEncapsulation.None,
  template: `
    <button ejs-button id="sortColumn" (click)="sort()">Sort Custom Column</button>
    <br /><br />
    <ejs-gantt #gantt id="ganttDefault" height="430px" [dataSource]="data" [taskFields]="taskSettings" [columns]="columns" [splitterSettings]="splitterSettings" [allowSorting]="true">
    </ejs-gantt>`
})
export class AppComponent implements OnInit {
  @ViewChild('gantt', { static: true }) public ganttInstance!: GanttComponent;
  public data: object[] = [];
  public taskSettings: object = {};
  public splitterSettings: object = {};
  public columns: object[] = [];
  ngOnInit(): void {
    this.data = [
      { TaskID: 1, TaskName: 'Initiation', StartDate: new Date('04/02/2019'), Duration: 5, Progress: 30, ParentID: null, CustomColumn: 'Alpha' },
      { TaskID: 2, TaskName: 'Planning', StartDate: new Date('04/03/2019'), Duration: 4, Progress: 50, ParentID: 1, CustomColumn: 'Beta' },
      { TaskID: 3, TaskName: 'Execution', StartDate: new Date('04/04/2019'), Duration: 6, Progress: 70, ParentID: 1, CustomColumn: 'Gamma' },
      { TaskID: 4, TaskName: 'Closure', StartDate: new Date('04/05/2019'), Duration: 3, Progress: 90, ParentID: 1, CustomColumn: 'Delta' },
      { TaskID: 5, TaskName: 'Review', StartDate: new Date('04/06/2019'), Duration: 2, Progress: 40, ParentID: null, CustomColumn: 'Epsilon' },
      { TaskID: 6, TaskName: 'Documentation', StartDate: new Date('04/07/2019'), Duration: 3, Progress: 60, ParentID: 5, CustomColumn: 'Zeta' },
      { TaskID: 7, TaskName: 'Training', StartDate: new Date('04/08/2019'), Duration: 4, Progress: 80, ParentID: 5, CustomColumn: 'Eta' },
      { TaskID: 8, TaskName: 'Deployment', StartDate: new Date('04/09/2019'), Duration: 5, Progress: 100, ParentID: 5, CustomColumn: 'Theta' }
    ];
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      duration: 'Duration',
      progress: 'Progress',
      parentID: 'ParentID'
    };
    this.splitterSettings = { columnIndex: 2 };
    this.columns = [
      { field: 'TaskID', headerText: 'Task ID', width: '100' },
      { field: 'TaskName', headerText: 'Task Name', width: '200' },
      { field: 'StartDate', headerText: 'Start Date', width: '150' },
      { field: 'Duration', headerText: 'Duration', width: '100' },
      { field: 'Progress', headerText: 'Progress', width: '100' },
      { field: 'Status', headerText: 'Status', width: '120' },
      { field: 'Priority', headerText: 'Priority', width: '120' },
      { field: 'CustomColumn', headerText: 'Custom Column', width: '150' }
    ];
  }
  public sort(): void {
    (this.ganttInstance as GanttComponent).sortModule.sortColumn('CustomColumn', 'Ascending', false);
  }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Prevent sorting on specific columns
You can prevent sorting on specific columns in the Syncfusion® Angular Gantt component by handling the actionBegin or actionComplete events. Alternatively, you can disable sorting for a column by setting its allowSorting property to false in the column configuration.
The following sample demonstrates how to prevent sorting for the TaskID and StartDate columns.
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { GanttModule, SortService } from '@syncfusion/ej2-angular-gantt';
import { SortEventArgs } from '@syncfusion/ej2-angular-grids';
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [GanttModule],
  providers: [SortService],
  encapsulation: ViewEncapsulation.None,
  template: `
    <div style="margin-left:100px;">
      <p style="color:red;" id="message"></p>
    </div>
    <ejs-gantt id="ganttDefault" height="430px" [dataSource]="data" [taskFields]="taskSettings" [columns]="columns" [splitterSettings]="splitterSettings" [allowSorting]="true" (actionBegin)="actionBegin($event)" (actionComplete)="actionComplete($event)"></ejs-gantt>`
})
export class AppComponent implements OnInit {
  public data: object[] = [];
  public taskSettings: object = {};
  public splitterSettings: object = {};
  public columns: object[] = [];
  public message: string = '';
  ngOnInit(): void {
    this.data = [
      { TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), Duration: 5, Progress: 30 },
      { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/03/2019'), Duration: 4, Progress: 50 },
      { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/04/2019'), Duration: 4, Progress: 50 },
      { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/05/2019'), Duration: 4, Progress: 50 },
      { TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/06/2019'), Duration: 6, Progress: 60 },
      { TaskID: 6, TaskName: 'Develop floor plan', StartDate: new Date('04/07/2019'), Duration: 3, Progress: 70 },
      { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/08/2019'), Duration: 3, Progress: 80 },
      { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/09/2019'), Duration: 3, Progress: 90 }
    ];
    this.taskSettings = {
      id: 'TaskID',
      name: 'TaskName',
      startDate: 'StartDate',
      duration: 'Duration',
      progress: 'Progress'
    };
    this.splitterSettings = { columnIndex: 3 };
    this.columns = [
      { field: 'TaskID', headerText: 'Task ID', textAlign: 'Left', width: '100' },
      { field: 'TaskName', headerText: 'Task Name', width: '250' },
      { field: 'StartDate', headerText: 'Start Date', width: '150' },
      { field: 'Duration', headerText: 'Duration', width: '150' },
      { field: 'Progress', headerText: 'Progress', width: '150' }
    ];
  }
  public actionBegin(args: SortEventArgs): void {
    if (args.requestType === 'sorting' && args.columnName === 'TaskID') {
      this.message = `${args.requestType} action cancelled for ${args.columnName} column`;
      args.cancel = true;
    }
  }
  public actionComplete(args: SortEventArgs): void {
    if (args.requestType === 'sorting' && args.columnName === 'StartDate') {
    this.message = `${args.requestType} action cancelled for ${args.columnName} column`;
    }
  }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Disable clear sort
By default, clicking a column header switches the sort order between ascending, descending, and unsorted. To restrict this to only ascending and descending, set [sortSettings.allowUnsort] to false. This ensures sorting remains active without reverting to an unsorted state.
import { GanttModule, SortService } from '@syncfusion/ej2-angular-gantt'
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
@Component({
    imports: [GanttModule],
    providers: [SortService],
    standalone: true,
    selector: 'app-root',
    template:
        `<ejs-gantt height="430px" [dataSource]="data"  [taskFields]="taskSettings" [columns]="columns" [sortSettings]="sortSettings" [splitterSettings]="splitterSettings" [allowSorting]= 'true'></ejs-gantt>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent implements OnInit {
    public data?: object[];
    public taskSettings?: object;
    public splitterSettings?: object;
    public columns?: object[];
    public sortSettings?: object;
    public ngOnInit(): void {
        this.data = [
            {
                TaskID: 1, TaskName: 'Project Initiation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
            },
            { TaskID: 2, TaskName: 'Identify Site location', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            { TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/02/2019'), Duration: 4, ParentID: 1, Progress: 50 },
            {
                TaskID: 5, TaskName: 'Project Estimation', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019'),
            },
            { TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 },
            { TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/04/2019'), Duration: 3, ParentID: 5, Progress: 50 }
        ];
        this.taskSettings = {
            id: 'TaskID',
            name: 'TaskName',
            startDate: 'StartDate',
            duration: 'Duration',
            progress: 'Progress',
            parentID: 'ParentID'
        };
        this.splitterSettings = {
            columnIndex: 3
        };
        this.sortSettings = { allowUnsort: false};
        this.columns = [
            { field: 'TaskID', headerText: 'Task ID', textAlign: 'Left', width: '100' },
            { field: 'TaskName', headerText: 'Task Name', width: '250' },
            { field: 'StartDate', headerText: 'Start Date', width: '150' },
            { field: 'Duration', headerText: 'Duration', width: '150' },
            { field: 'Progress', headerText: 'Progress', width: '150' },
        ];
    }
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Touch interaction
To perform a tap action on a column header in the Syncfusion® Angular Gantt component, the sorting operation is triggered for the selected column. A popup appears when multi-column sorting is enabled. To sort multiple columns, tap the popup and then tap the desired column headers. The following screenshot shows Gantt touch sorting.
