Calendar Settings in TypeScript Gantt Chart Control
The Gantt Chart control supports advanced calendar configuration through the calendarSettings property, enabling management of working hours, holidays, and task-specific scheduling. Calendar settings control how the Gantt Chart calculates task duration, determines working days, and schedules dependencies.
The calendarSettings property contains two key configurations:
- Project Calendar: Defines working hours and holidays for the entire project, applied to all tasks by default
- Task Calendars: Defines custom working days and holidays for specific tasks, enabling team-specific or shift-based scheduling
Project calendar
The calendarSettings.projectCalendar defines the default working hours and non-working days for the entire project. All tasks follow the project calendar unless assigned a task-specific calendar.
Configure project working hours and exceptions
Working hours are defined per day using start and end times. The following example configures the project to have working hours from 9:00 AM to 5:00 PM with a lunch break from 12:00 PM to 1:00 PM. Calendar exceptions allow overriding working hours for specific dates, enabling custom scheduling for special working days or non-working days that don’t fit the standard holiday definition:
import { Gantt, Edit, Selection } from '@syncfusion/ej2-gantt';
import {GanttData} from './datasource';
Gantt.Inject(Edit, Selection);
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '450px',
projectStartDate: new Date('04/01/2019'),
projectEndDate: new Date('04/30/2019'),
taskFields: {
id: 'TaskId',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
parentID: 'ParentId'
},
labelSettings: {
leftLabel: 'TaskName'
},
calendarSettings: {
projectCalendar: {
workingTime: [
{ from: 9, to: 12 },
{ from: 13, to: 17 }
],
exceptions: [
{ from: new Date('04/06/2026'), to: new Date('04/06/2026'), name: 'Extended Working Day', isWorking: true, workingTime: [{ from: 8, to: 18 }] }
]
}
}
});
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/34.2.2/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>Define project holidays
Holidays are non-working dates that exclude time from task calculations. The following example defines holidays for April 10 and April 17, excluding these dates from task scheduling calculations:
import { Gantt, Edit, Selection } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource';
Gantt.Inject(Edit, Selection);
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '450px',
projectStartDate: new Date('04/01/2019'),
projectEndDate: new Date('04/30/2019'),
taskFields: {
id: 'TaskId',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
parentID: 'ParentId'
},
labelSettings: {
leftLabel: 'TaskName'
},
calendarSettings: {
projectCalendar: {
holidays: [
{ from: new Date('04/10/2019'), to: new Date('04/10/2019'), label: 'Holiday 1' },
{ from: new Date('04/17/2019'), to: new Date('04/17/2019'), label: 'Holiday 2' }
]
}
}
});
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/34.2.2/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>Task calendars
Task calendars enable specific tasks to use custom working days and holidays instead of the project calendar. This is useful for managing work across different shifts, regions, or external teams with different availability.
Assign task-specific calendars with exceptions
To assign a custom calendar to a task, first define the calendar in calendarSettings.taskCalendar, then reference it using the calendarId property in the task data. Calendar exceptions allow defining specific dates with custom working days, enabling team-specific scheduling adjustments such as split shifts or holidays that differ from the main schedule.
When a task is assigned a calendar through calendarId, that task follows only the assigned task calendar. The assigned task calendar overrides the project calendar for that task. Working days, holidays, and calendar exceptions defined in the assigned calendar are used when calculating the task schedule and working duration. Other task calendars are not considered when scheduling that task.
The following example defines two task calendars with different working days, task-specific exceptions, and assigns them to specific tasks:
import { Gantt, Edit, Selection } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource';
Gantt.Inject(Edit, Selection);
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '450px',
projectStartDate: new Date('04/01/2019'),
projectEndDate: new Date('04/30/2019'),
taskFields: {
id: 'TaskId',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
calendarId: 'CalendarId'
},
labelSettings: {
leftLabel: 'TaskName'
},
calendarSettings: {
projectCalendar: {
workingTime: [
{ from: 9, to: 17 }
]
},
taskCalendars: [
{
calendarId: 'day-shift',
workingTime: [
{ from: 9, to: 17 }
],
holidays: [],
exceptions: [
{ from: new Date('04/09/2026'), to: new Date('04/09/2026'), label: 'Team Meeting Day' }
]
},
{
calendarId: 'night-shift',
workingTime: [
{ from: 17, to: 9 }
],
holidays: [],
exceptions: [
{ from: new Date('04/10/2026'), to: new Date('04/10/2026'), name: 'Maintenance Window', isWorking: true, workingTime: [{ from: 18, to: 8 }] }
]
}
]
}
});
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/34.2.2/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>Define task calendar holidays
Task calendars can include holidays that override project calendar holidays for the assigned task. These holidays are considered when calculating the task schedule and working duration. The following example configures a task calendar with specific holidays:
import { Gantt, Edit, Selection } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource';
Gantt.Inject(Edit, Selection);
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '450px',
projectStartDate: new Date('04/01/2019'),
projectEndDate: new Date('04/30/2019'),
taskFields: {
id: 'TaskId',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
calendarId: 'CalendarId'
},
labelSettings: {
leftLabel: 'TaskName'
},
calendarSettings: {
projectCalendar: {
workingTime: [
{ from: 9, to: 17 }
],
holidays: [
{ from: new Date('04/10/2019'), to: new Date('04/10/2019'), label: 'Regional Holiday' }
]
},
taskCalendars: [
{
calendarId: 'local-team',
holidays: [
{ from: new Date('04/05/2019'), to: new Date('04/05/2019'), label: 'Local Holiday' }
]
},
{
calendarId: 'offshore-team',
holidays: [
{ from: new Date('04/08/2019'), to: new Date('04/08/2019'), label: 'Offshore Holiday' }
]
}
]
}
});
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/34.2.2/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>Configure hours per day for task durations
The hoursPerDay property defines the number of hours used to represent one day when calculating task durations. Changing hoursPerDay recalculates day-based duration values using the existing working duration of the task. This affects how duration is displayed and calculated in days, but does not modify the task’s start date, end date, or underlying working duration.
For example, a task with 32 hours of working duration is displayed as 4 days when hoursPerDay is set to 8. If hoursPerDay is changed to 16, the same task is displayed as 2 days. The task schedule remains unchanged because the underlying working duration is not modified.
The following example demonstrates how changing hoursPerDay affects duration calculations.
import { Gantt } from '@syncfusion/ej2-gantt';
import { Button } from '@syncfusion/ej2-buttons';
import { GanttData } from './datasource.ts';
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '450px',
hoursPerDay: 8,
projectStartDate: new Date('04/01/2026'),
projectEndDate: new Date('04/30/2026'),
taskFields: {
id: 'TaskId',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
parentID: 'ParentId'
},
labelSettings: {
leftLabel: 'TaskName'
},
calendarSettings: {
projectCalendar: {
workingTime: [
{ from: 9, to: 12 },
{ from: 13, to: 17 }
],
exceptions: [
{ from: new Date('04/06/2026'), to: new Date('04/06/2026'), label: 'Extended Working Day'}
]
}
}
});
gantt.appendTo('#Gantt');
let addBtn: Button = new Button();
addBtn.appendTo('#updateHoursPerDay');
document.getElementById('updateHoursPerDay').addEventListener('click', () => {
gantt.hoursPerDay = 16;
});<!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/34.2.2/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'>
<button id="updateHoursPerDay">Update HoursPerDay</button>
<div id='Gantt'></div>
</div>
</body>
</html>Note: The default
hoursPerDayvalue is 8 hours. When a task has 4 days duration with thehoursPerDayvalue of 6, the total working hours = 4 days × 6 hours = 24 hours. If the calendar’s working time is configured as 24 hours (0:00 to 24:00), these 24 hours fit within a single calendar day, so the task displays as 1 calendar day on the chart, even though the duration specification is 4 days.
Impact on task scheduling
Calendar settings directly affect how task duration is calculated and when tasks are scheduled:
- Working hours: Task durations are calculated using the configured working hours. Non-working hours are excluded from duration calculations.
- Holidays: Tasks skip over holiday dates, extending the end date accordingly to maintain the required working duration.
- Weekends: By default, weekends are treated as non-working days when includeWeekend is set to false.
- Task dependencies: Dependency calculations use the predecessor task’s calendar to determine when the successor task can start.
- Task calendars: Tasks without an assigned task calendar follow the project calendar. Tasks with an assigned task calendar use the working hours, holidays, and exceptions defined in that calendar for scheduling and duration calculations.
-
Duration calculations: Changing
hoursPerDayrecalculates day-based duration values without changing the scheduled start and end dates.