Syncfusion AI Assistant

How can I help you?

Timeline in EJ2 TypeScript Gantt Control

18 Mar 202624 minutes to read

In the Gantt control, timeline is used to represent the project duration as individual cells with defined unit and formats.

Timeline view modes

Gantt contains the following in-built timeline view modes:

  • Hour
  • Day
  • Week
  • Month
  • Year

Timescale mode in Gantt can be defined by using timelineViewMode property and also we can define timescale mode of top tier and bottom tier by using topTier.unit and bottomTier.unit properties.

Week timeline mode

In the Week timeline mode, the upper part of the schedule header displays the weeks, whereas the bottom half of the header displays the days. Refer to the following code example.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    timelineSettings: {
        timelineViewMode: 'Week'
    }
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <script src="es5-datasource.js" type="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Month timeline mode

In the Month timeline mode, the upper part of the schedule header displays the months, whereas the bottom header of the schedule displays its corresponding weeks. Refer to the following code example.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    timelineSettings: {
        timelineViewMode: 'Month',
        timelineUnitSize: 150
    }
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
       
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Year timeline mode

In the Year timeline mode, the upper schedule header displays the years whereas, the bottom header displays its corresponding months. Refer to the following code example.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    timelineSettings: {
        timelineViewMode: 'Year',
        timelineUnitSize: 70
    }
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
       
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Day timeline mode

In the Day timeline mode, the upper part of the header displays the days whereas, the bottom schedule header displays its corresponding hours. Refer to the following code example.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    timelineSettings: {
        timelineViewMode: 'Day'
    }
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
       
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Hour timeline mode

An Hour timeline mode tracks the tasks in minutes scale. In this mode, the upper schedule header displays hour scale and the lower schedule header displays its corresponding minutes.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    timelineSettings: {
        timelineViewMode: 'Hour'
    }
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
       
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Timeline view dates

The Gantt Chart control supports rendering a fixed timeline range using the viewStartDate and viewEndDate properties. These properties allow the visible portion of the timeline to be explicitly defined and locked within the Gantt chart UI, independent of the project’s overall scheduling boundaries defined by projectStartDate and projectEndDate. The projectStartDate and projectEndDate values represent the full scheduling window for the project and are used for baseline processing, critical-path calculations, and project-level reporting. By default, both viewStartDate and viewEndDate are set to auto. The following example demonstrates how to configure a custom timeline view range.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'parentID'
    },
    timelineSettings: {
        viewStartDate: new Date('04/03/2019'),
        viewEndDate: new Date('04/07/2019'),
    },
    projectStartDate: new Date('03/31/2019'),
    projectEndDate: new Date('04/13/2019')
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
       
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Key behaviors

When viewStartDate and viewEndDate are set to concrete Date values, the timeline rendering is restricted to the inclusive range [viewStartDate, viewEndDate].

  • When viewStartDate is set to auto:
    • If projectStartDate is defined, the timeline begins at projectStartDate.
    • If projectStartDate is not defined, the earliest task start date is used as the beginning of the visible range.
  • When viewEndDate is set to auto:
    • If projectEndDate is defined, the timeline ends at projectEndDate.
    • If projectEndDate is not defined, the maximum task end date is used. If this end date leaves visible white-space in the timeline area, the end date is automatically extended to fill the chart width.

Note: The ZoomToFit feature uses projectStartDate and projectEndDate to fit the entire project within the available timeline viewport.

Week start day customization

In the Gantt control, you can customize the week start day using the weekStartDay property. By default, the weekStartDay is set to 0, which specifies the Sunday as a start day of the week. But, you can customize the week start day by using the following code example.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    timelineSettings: {
        timelineViewMode: 'Week',
        weekStartDay: 3
    }
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">
<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body> 
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Customize automatic timescale update action

In the Gantt control, the schedule timeline will be automatically updated when the tasks date values are updated beyond the project start date and end date ranges. This can be enabled or disabled using the updateTimescaleView property.

import { Gantt, Edit } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

Gantt.Inject(Edit);

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    timelineSettings: {
        updateTimescaleView: false
    },
    editSettings: {
        allowEditing: true,
        allowTaskbarEditing: true
    }
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
       
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Timeline cells tooltip

In the Gantt control, you can enable or disable the mouse hover tooltip of timeline cells using the timelineSettings.showTooltip property. The default value of this property is true. The following code example shows how to enable the timeline cells tooltip in Gantt.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'parentID'
    },
    timelineSettings: {
        showTooltip: true
    }
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
   
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Show/hide weekends

The timelineSettings.showWeekend property is used to customize the timeline in the Gantt component by controlling the visibility of weekends. To exclude weekends from the timeline, set the showWeekend property to false in the timelineSettings configuration. This feature is particularly useful for focusing the timeline on working days, enhancing project management efficiency by hiding weekends from the view.

Note: To customize non-working or weekend days in the Gantt chart, refer to the workWeek documentation for detailed information.

import { Gantt, Edit } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

Gantt.Inject(Edit);

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'parentID'
    },
    timelineSettings: {
        showWeekend: false
    },
    editSettings: {
        allowEditing: true,
        allowTaskbarEditing: true
    }
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Limitations

  • The showWeekend feature does not support baselines.
  • The showWeekend is not compatible with the manual task mode.
  • Non-working hours cannot be excluded when showWeekend is set to false.
  • Holidays are not excluded from the timeline if showWeekend is set to false.

Timeline template

In the Gantt component, you can customize timeline cells using the timelineTemplate property, allowing for the customization of HTML content within timeline cells. This feature enhances the visual appeal and enables personalized functionality.

When designing the timeline cells, you can utilize the following context properties within the template:

  • date: Defines the date of the timeline cells.
  • value: Defines the formatted date value that will be displayed in the timeline cells.
  • tier: Defines whether the cell is part of the top or bottom tier.

The following code example how to customize the top tier to display the week’s weather details and the bottom tier to highlight working and non-working days, with formatted text for holidays.

import { Gantt, Selection, Toolbar, DayMarkers, Edit, Filter } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
Gantt.Inject(Selection, Toolbar, DayMarkers, Edit, Filter);

(<{ bgColor?: Function }>window).bgColor = (value: string, date: string): string => {
    if (value === "S") {
        return "#7BD3EA"
    }
    const parsedDate = new Date(date);
    for (let i = 0; i < gantt.holidays.length; i++) {
        const holiday = gantt.holidays[i];
        const fromDate = new Date(holiday.from);
        const toDate = new Date(holiday.to)
        if (parsedDate >= fromDate && parsedDate <= toDate) {
            return "#97E7E1";
        }
    }
    return "#E0FBE2"
};
(<{ imagedate?: Function }>window).imagedate = () => {
    const getImage = Math.floor(Math.random() * 5) + 1;
    return  getImage + ".svg";

}
(<{ holidayValue?: Function }>window).holidayValue = (value: string, date: string): string => {

    const parsedDate = new Date(date);
    for (let i = 0; i < gantt.holidays.length; i++) {
        const holiday = gantt.holidays[i];
        const fromDate = new Date(holiday.from);
        const toDate = new Date(holiday.to)
        if (parsedDate >= fromDate && parsedDate <= toDate) {
            const options: any = { weekday: 'short' };
            return parsedDate.toLocaleDateString('en-US', options).toLocaleUpperCase();
        }
    }
    return value
}

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    allowSorting: true,
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        dependency: 'Predecessor',
        parentID: 'ParentID',
    },
    splitterSettings: {
        columnIndex: 1
    },
    treeColumnIndex: 1,
    allowSelection: true,
    gridLines: "Both",
    showColumnMenu: false,
    highlightWeekends: true,
    timelineSettings: {
        topTier: {
            unit: 'Week',
            format: 'dd/MM/yyyy'
        },
        bottomTier: {
            unit: 'Day',
            count: 1
        },
        timelineUnitSize: 100
    },
    holidays: [{
        from: "04/04/2019",
        to: "04/05/2019",
        label: " Public holidays",
        cssClass: "e-custom-holiday"

    },
    {
        from: "04/12/2019",
        to: "04/12/2019",
        label: " Public holiday",
        cssClass: "e-custom-holiday"

    }],
    columns: [
        { field: 'TaskID', headerText: 'Task ID', visible: false },
        { field: 'TaskName', headerText: 'Task Name', width: 300 },
        { field: 'StartDate', headerText: 'Start Date' },
        { field: 'Duration', headerText: 'Duration' },
        { field: 'Progress', headerText: 'Progress' },
    ],
    labelSettings: {
        leftLabel: 'TaskName',
        taskLabel: 'Progress'
    },
    timelineTemplate: "#TimelineTemplates",
    height: '550px',
    allowUnscheduledTasks: true,
    projectStartDate: new Date('03/25/2019'),
    projectEndDate: new Date('05/30/2019'),
});
gantt.appendTo('#Gantt');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Gantt</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Gantt Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
	<link href="https://cdn.syncfusion.com/ej2/33.1.44/tailwind3.css" rel="stylesheet" type="text/css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <script type="text/x-jsrender" id="TimelineTemplates"> 
        ${if(tier == 'topTier')} 
        <div class="e-header-cell-label e-gantt-top-cell-text" style="width:100%;background-color: #FBF9F1 ;  font-weight: bold;height: 100%;display: flex; justify-content: center ; align-items: center; "title=${date}> 
        <div> ${value}</div>
        <div style="width:20px; height: 20px; line-height: normal; padding-left: 10px; ">
        <img style="width:100%; height:100%;" src =${imagedate()}>
        </div>
        </div>
        ${/if}
        ${if(tier == 'bottomTier')} 
        <div class="e-header-cell-label e-gantt-top-cell-text" style="width:100%;background-color: ${bgColor(value,date)}; text-align: center;height: 100%;display: flex; align-items: center;  font-weight: bold;justify-content: center "title=${date}> 
         ${holidayValue(value,date)}
        </div>
        ${/if}
    </script>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>