Task Scheduling with Duration Units in TypeScript Gantt Chart
Task scheduling in the TypeScript Gantt Chart control defines and visualizes task start dates, durations, and end dates as taskbars in a project timeline, enabling precise planning and tracking. Configure scheduling with properties like taskFields for mapping task data, taskMode for auto or manual validation, taskType for fixed unit, work, or duration, and durationUnit for day, hour, or minute units. Working time, set via dayWorkingTime, and non-working periods, like weekends or holidays, ensure realistic calculations. Events like dataBound customize scheduling logic on run-time. Taskbars include ARIA labels for accessibility, describing start, end, and duration, and adapt to responsive designs, though narrow screens may require scrolling for long timelines.
Configure scheduling modes
Scheduling modes control task date validation:
- Auto (default): Validates dates based on dependencies, working time, holidays, and weekends. Parent tasks adjust to child tasks’ minimum start and maximum end dates.
- Manual: Allows custom dates without automatic validation, editable for parent tasks.
- Custom: Renders both auto and manual tasks from the data source.
Configure using:
- taskMode: Sets global mode.
- taskFields.manual: Sets per-task mode.
Automatically scheduled Tasks
The following example configures auto scheduling:
import { Gantt, Toolbar, Edit } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
Gantt.Inject(Toolbar, Edit);
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '420px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
parentID: 'ParentID'
},
taskMode:"Auto",
treeColumnIndex: 1,
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel', 'CollapseAll', 'ExpandAll', 'Search'],
editSettings: {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: 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/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>Manually scheduled Tasks
The following example configures manual scheduling:
import { Gantt, Toolbar, Edit } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
Gantt.Inject(Toolbar, Edit);
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '420px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
parentID: 'ParentID'
},
taskMode:"Manual",
treeColumnIndex: 1,
validateManualTasksOnLinking: true,
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel', 'CollapseAll', 'ExpandAll', 'Search'],
editSettings: {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: 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/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>Custom scheduled
The following example mixes auto and manual tasks:
import { Gantt, Toolbar, Edit } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
Gantt.Inject(Toolbar, Edit);
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '420px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
parentID: 'ParentID',
manual: 'isManual'
},
taskMode:"Custom",
treeColumnIndex: 1,
validateManualTasksOnLinking: true,
toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel', 'CollapseAll', 'ExpandAll', 'Search'],
editSettings: {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
},
columns: [
{ field: 'TaskID', visible: false },
{ field: 'TaskName' },
{ field: 'isManual' }
],
});
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 task types
Task types define how changes to duration, work, or resource units affect other properties:
- FixedUnit (default): Adjusts duration when work changes, maintaining unit allocation.
- FixedWork: Adjusts duration when units change, maintaining work amount.
- FixedDuration: Adjusts units when work changes, maintaining duration.
Configure using:
- taskType: Sets global type.
- taskFields.type: Sets per-task type.
The following example configures task types:
import { Gantt, Edit, Toolbar, DayMarkers } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
Gantt.Inject(Edit, Toolbar, DayMarkers);
const resources: Object[] = [
{ resourceId: 1, resourceName: 'Martin Tamer' },
{ resourceId: 2, resourceName: 'Rose Fuller' },
{ resourceId: 3, resourceName: 'Margaret Buchanan' },
{ resourceId: 4, resourceName: 'Fuller King' },
{ resourceId: 5, resourceName: 'Davolio Fuller' },
{ resourceId: 6, resourceName: 'Van Jack' },
{ resourceId: 7, resourceName: 'Fuller Buchanan' },
{ resourceId: 8, resourceName: 'Jack Davolio' },
{ resourceId: 9, resourceName: 'Tamer Vinet' },
{ resourceId: 10, resourceName: 'Vinet Fuller' },
{ resourceId: 11, resourceName: 'Bergs Anton' },
{ resourceId: 12, resourceName: 'Construction Supervisor' }
];
const gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '450px',
highlightWeekends: true,
projectStartDate: new Date('03/25/2019'),
projectEndDate: new Date('04/30/2019'),
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
resourceInfo: 'resources',
parentID: 'ParentID',
work: 'Work',
taskType: 'taskType'
},
resources: resources,
resourceFields: {
id: 'resourceId',
name: 'resourceName',
unit: 'Unit'
},
resourceNameMapping: 'resourceName',
resourceIDMapping: 'resourceId',
resourceUnitMapping: 'Unit',
workUnit: 'hour',
taskType: 'FixedWork',
treeColumnIndex: 1,
toolbar: [
'Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll'
],
editSettings: {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
},
columns: [
{ field: 'TaskID', visible: false },
{ field: 'TaskName', headerText: 'Task Name', width: '180' },
{ field: 'resources', headerText: 'Resources', width: '160' },
{ field: 'Work', width: '110' },
{ field: 'Duration', width: '100' },
{ field: 'taskType', headerText: 'Task Type', width: '110' }
]
});
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 duration units
Duration units define how task duration values are interpreted and calculated in the Gantt Chart. Duration units can be configured globally for the entire project or individually for each task.
The Gantt Chart control supports the following duration units:
- Day: Standard for general planning.
- Hour: For detailed task management.
- Minute: For short-duration tasks.
- Week: Represents a duration calculated using the configured daysPerWeek value.
- Month: Represents a duration calculated using the configured daysPerMonth value.
Configure using:
-
durationUnit: Sets global unit (default:
day). - taskFields.durationUnit: Maps per-task units.
- daysPerWeek: Specifies the number of working days that constitute one week duration.
- daysPerMonth: Specifies the number of working days that constitute one month duration.
- Duration field values: You can specify the duration unit directly in the duration value (for example, “5 minutes”, “2 weeks”, or “1 month”).
The following example maps duration units:
import { Gantt, } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
const gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '450px',
splitterSettings: {columnIndex:4},
daysPerWeek: 5,
daysPerMonth: 20,
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
durationUnit:'DurationUnit',
parentID: 'ParentID',
},
});
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>Defining duration unit with duration value:
The following example defines units in duration values:
import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '380px',
daysPerWeek: 5,
daysPerMonth: 20,
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
durationUnit: 'DurationUnit',
parentID: 'ParentID'
},
splitterSettings: {
columnIndex: 4
}
});
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 days per week and month
The daysPerWeek property specifies how many working days constitute one week, directly impacting how week-based durations are calculated. For example, if daysPerWeek is 5, then 1 week equals 5 working days.
Similarly, the daysPerMonth property specifies how many working days constitute one month, affecting how month-based durations are converted to actual working days for scheduling calculations. For example, if daysPerMonth is 20, then 1 month equals 20 working days.
The following example configures daysPerWeek and daysPerMonth properties:
import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '380px',
daysPerWeek: 5,
daysPerMonth: 20,
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
durationUnit: 'DurationUnit',
parentID: 'ParentID'
},
splitterSettings: {
columnIndex: 4
}
});
gantt.appendTo('#Gantt');
// Update button functionality
document.getElementById('updateButton').addEventListener('click', function() {
let daysPerWeek = parseInt((document.getElementById('daysPerWeek') as HTMLInputElement).value);
let daysPerMonth = parseInt((document.getElementById('daysPerMonth') as HTMLInputElement).value);
// Validate input ranges
if (daysPerWeek < 1 || daysPerWeek > 7) {
alert('Days per Week must be between 1 and 7');
return;
}
if (daysPerMonth < 1 || daysPerMonth > 31) {
alert('Days per Month must be between 1 and 31');
return;
}
// Update Gantt chart properties
gantt.daysPerWeek = daysPerWeek;
gantt.daysPerMonth = daysPerMonth;
});<!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="configPanel" class="config-panel">
<div class="config-group">
<div class="config-item">
<label for="daysPerWeek">Days per Week:</label>
<input type="number" id="daysPerWeek" min="1" max="7" value="5">
</div>
<div class="config-item">
<label for="daysPerMonth">Days per Month:</label>
<input type="number" id="daysPerMonth" min="1" max="31" value="20">
</div>
<button id="updateButton" class="update-button">Update</button>
</div>
</div>
<div id="Gantt"></div>
</div>
<script>
var ele = document.getElementById('container');
if(ele) {
ele.style.visibility = "visible";
}
</script>
</body>
</html>Enable unscheduled tasks
Unscheduled tasks lack start date, end date, or duration, visualized as milestones or single-day tasks. Enable with allowUnscheduledTasks set to true (default: false), defaulting to a 1-day duration from the project start.
Available unscheduled task types:
-
Start date only
Tasks with only a start date defined, allowing for open-ended planning.

-
End date only
Tasks with only an end date defined, useful for deadline-driven activities.

-
Duration only
Tasks with only duration specified, providing flexibility in scheduling timing.

-
Milestone
Special tasks with zero duration representing key project events or deliverables.

The following example enables unscheduled tasks:
import { Gantt, Edit } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
Gantt.Inject(Edit);
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '380px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
parentID: 'ParentID'
},
editSettings: {
allowEditing: true,
},
allowUnscheduledTasks: 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/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>Convert to milestone using method
You can convert a task into a milestone using the convertToMilestone method.
import { Gantt, Edit } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
import { Button } from '@syncfusion/ej2-buttons';
Gantt.Inject(Edit);
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '380px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
parentID: 'ParentID'
},
editSettings: {
allowEditing: true,
},
allowUnscheduledTasks: true
});
gantt.appendTo('#Gantt');
let button: Button = new Button();
button.appendTo('#milestone');
document.getElementById('milestone').addEventListener('click', () => {
gantt.convertToMilestone('6')
});<!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="button">
<button id="milestone">Convert Task 6 to Milestone</button>
</div>
<div id='Gantt'></div>
</div>
</body>
</html>Configure working time range
Working time ranges define productive hours per day, ensuring accurate scheduling calculations. Configure with dayWorkingTime sets project-wide working hours.
The following example sets working hours from 9 AM to 6 PM:
import { Gantt, DayMarkers } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
Gantt.Inject(DayMarkers);
let gantt: Gantt = new Gantt({
dataSource: GanttData,
height: '450px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
parentID: 'ParentID'
},
highlightWeekends: true,
dayWorkingTime: [{ from: 9, to: 18 }],
timelineSettings: {
timelineViewMode: 'Day'
},
splitterSettings: {
columnIndex: 0
}
});
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 weekends and non-working days
Non-working days represent periods when project work cannot be performed, such as weekends, holidays, or planned maintenance periods. These settings ensure realistic project scheduling by excluding non-productive time from calculations.
Configure work week
Define which days of the week are considered working days using the workWeek property.
The following example excludes Monday and Tuesday:
import { Gantt, DayMarkers } from '@syncfusion/ej2-gantt';
import { ganttData } from './datasource.ts';
Gantt.Inject(DayMarkers)
let gantt: Gantt = new Gantt({
dataSource: ganttData,
height: '450px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
parentID: 'ParentID'
},
workWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday"],
highlightWeekends: 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/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>Weekend configuration
Configure weekends with:
- Default behavior: Saturday and Sunday are non-working.
- Timeline display: timelineSettings.showWeekend controls visibility.
- Working weekends: includeWeekend set to true includes weekends.
Customize scheduling with events
Customize scheduling with:
- dataBound: Adjusts task scheduling after data binding, e.g., switching auto-scheduled tasks to manual mode if their start date precedes the project start date.
The following example uses dataBound to switch auto-scheduled tasks to manual mode if their start date is before the project start date (04/01/2025):
import { Gantt } from '@syncfusion/ej2-gantt';
const ganttData: object[] = [
{ TaskID: 1, TaskName: 'Plan project', StartDate: new Date('04/03/2025'), Duration: 5, isManual: false },
{ TaskID: 2, TaskName: 'Develop feature', StartDate: new Date('04/03/2025'), Duration: 7, isManual: false },
{ TaskID: 3, TaskName: 'Test module', StartDate: new Date('03/31/2025'), Duration: 3, isManual: false }
];
const projectStartDate = new Date('04/01/2025');
let gantt: Gantt = new Gantt({
dataSource: ganttData,
height: '250px',
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
manual: 'isManual'
},
taskMode: 'Custom',
dataBound:dataBound,
});
gantt.appendTo('#Gantt');
function dataBound() {
const data = Array.isArray(gantt.dataSource) ? (gantt.dataSource as any[]) : [];
data.forEach((task) => {
if (!task.isManual && task.StartDate && new Date(task.StartDate) < projectStartDate) {
task.isManual = true; // Switch to manual mode.
const messageElement = document.getElementById('message');
if (messageElement) {
messageElement.textContent = `Task "${task.TaskName}" switched to manual mode as its start date is before project start date.`;
}
}
});
}<!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>
<p id="message"></p>
</div>
<div id='Gantt'></div>
</div>
</body>
</html>