Task scheduling in React Gantt component
2 Feb 202324 minutes to read
The Gantt provides support for automatic and manual task scheduling modes. It is used to indicate whether the start date and end date of all the tasks will be automatically validated or not. taskMode
is the property used to change the schedule mode of a task.
The Gantt control supports three types of mode. They are:
-
Auto
: All the tasks are automatically validate. -
Manual
: All the tasks are manually validate by the user. -
Custom
: Both Auto and Manual tasks are render by mapped from data source.
Note: The default value of
taskMode
isAuto
.
Automatically Scheduled Tasks
When the taskMode
property is set as Auto
, the start date and end date of all the tasks in the project will be automatically validated. That is, dates are validated based on various factors such as working time, holidays, weekends and predecessors.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, Selection, Toolbar, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'Children',
manual: 'isManual'
};
const toolbarOptions = ['Add', 'Edit', 'Delete', 'Cancel', 'Update', 'PrevTimeSpan', 'NextTimeSpan', 'ExpandAll', 'CollapseAll', 'Search'];
const editSettings = {
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true
};
return <GanttComponent dataSource={data} taskFields={taskFields} highlightWeekends={true} toolbar={toolbarOptions} editSettings={editSettings} taskMode='Custom' height='450px'>
<ColumnsDirective>
<ColumnDirective field='TaskID' visible={false}></ColumnDirective>
<ColumnDirective field='TaskName'></ColumnDirective>
<ColumnDirective field='isManual'></ColumnDirective>
</ColumnsDirective>
<Inject services={[Edit, Selection, Toolbar]}/>
</GanttComponent>
};
ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, Selection, Toolbar, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'Children',
manual: 'isManual'
};
const toolbarOptions = ['Add', 'Edit', 'Delete', 'Cancel', 'Update', 'PrevTimeSpan', 'NextTimeSpan', 'ExpandAll', 'CollapseAll', 'Search'];
const editSettings = {
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true
};
return <GanttComponent dataSource={data} taskFields={taskFields} highlightWeekends={true} toolbar={toolbarOptions} editSettings={editSettings} taskMode='Custom' height='450px'>
<ColumnsDirective>
<ColumnDirective field='TaskID' visible={false}></ColumnDirective>
<ColumnDirective field='TaskName'></ColumnDirective>
<ColumnDirective field='isManual'></ColumnDirective>
</ColumnsDirective>
<Inject services={[Edit, Selection, Toolbar]}/>
</GanttComponent>
};
ReactDOM.render(<App />, document.getElementById('root'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Gantt</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet" type="text/css"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='root'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
Manually Scheduled Tasks
When the taskMode
property is set as Manual
, the start date and end date of all the tasks in the project will be same as given in the data source. That is, dates are not validated based on various factors such as dependencies between tasks, holidays, weekends, working time.We can restrict this mode in predecessor validation alone. That is, we can automatically validate the dates based on predecessor values by enabling the validateManualTasksOnLinking
property.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, Selection, Toolbar, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'Children',
manual: 'isManual'
};
const toolbarOptions = ['Add', 'Edit', 'Delete', 'Cancel', 'Update', 'PrevTimeSpan', 'NextTimeSpan', 'ExpandAll', 'CollapseAll', 'Search'];
const editSettings = {
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true
};
return <GanttComponent dataSource={data} taskFields={taskFields} highlightWeekends={true} toolbar={toolbarOptions} editSettings={editSettings} taskMode='Custom' height='450px'>
<ColumnsDirective>
<ColumnDirective field='TaskID' visible={false}></ColumnDirective>
<ColumnDirective field='TaskName'></ColumnDirective>
<ColumnDirective field='isManual'></ColumnDirective>
</ColumnsDirective>
<Inject services={[Edit, Selection, Toolbar]}/>
</GanttComponent>
};
ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, Selection, Toolbar, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'Children',
manual: 'isManual'
};
const toolbarOptions = ['Add', 'Edit', 'Delete', 'Cancel', 'Update', 'PrevTimeSpan', 'NextTimeSpan', 'ExpandAll', 'CollapseAll', 'Search'];
const editSettings = {
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true
};
return <GanttComponent dataSource={data} taskFields={taskFields} highlightWeekends={true} toolbar={toolbarOptions} editSettings={editSettings} taskMode='Custom' height='450px'>
<ColumnsDirective>
<ColumnDirective field='TaskID' visible={false}></ColumnDirective>
<ColumnDirective field='TaskName'></ColumnDirective>
<ColumnDirective field='isManual'></ColumnDirective>
</ColumnsDirective>
<Inject services={[Edit, Selection, Toolbar]}/>
</GanttComponent>
};
ReactDOM.render(<App />, document.getElementById('root'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Gantt</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet" type="text/css"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='root'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
Custom
When the taskMode
property is set as Custom
, the scheduling mode for each tasks will be mapped from the data source field. The Boolean
property taskFields.manual
is used to map the manual scheduling mode field from the data source.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, Selection, Toolbar, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'Children',
manual: 'isManual'
};
const toolbarOptions = ['Add', 'Edit', 'Delete', 'Cancel', 'Update', 'PrevTimeSpan', 'NextTimeSpan', 'ExpandAll', 'CollapseAll', 'Search'];
const editSettings = {
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true
};
return <GanttComponent dataSource={data} taskFields={taskFields} highlightWeekends={true} toolbar={toolbarOptions} editSettings={editSettings} taskMode='Custom' height='450px'>
<ColumnsDirective>
<ColumnDirective field='TaskID' visible={false}></ColumnDirective>
<ColumnDirective field='TaskName'></ColumnDirective>
<ColumnDirective field='isManual'></ColumnDirective>
</ColumnsDirective>
<Inject services={[Edit, Selection, Toolbar]}/>
</GanttComponent>
};
ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit, Selection, Toolbar, ColumnsDirective, ColumnDirective } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'Children',
manual: 'isManual'
};
const toolbarOptions = ['Add', 'Edit', 'Delete', 'Cancel', 'Update', 'PrevTimeSpan', 'NextTimeSpan', 'ExpandAll', 'CollapseAll', 'Search'];
const editSettings = {
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true
};
return <GanttComponent dataSource={data} taskFields={taskFields} highlightWeekends={true} toolbar={toolbarOptions} editSettings={editSettings} taskMode='Custom' height='450px'>
<ColumnsDirective>
<ColumnDirective field='TaskID' visible={false}></ColumnDirective>
<ColumnDirective field='TaskName'></ColumnDirective>
<ColumnDirective field='isManual'></ColumnDirective>
</ColumnsDirective>
<Inject services={[Edit, Selection, Toolbar]}/>
</GanttComponent>
};
ReactDOM.render(<App />, document.getElementById('root'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Gantt</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet" type="text/css"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='root'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
–>
Unscheduled Tasks
Unscheduled tasks are planned for a project without any definite schedule dates. The Gantt control supports rendering the unscheduled tasks. You can create or update the tasks with anyone of start date, end date, and duration values or none. You can enable or disable the unscheduled tasks by using the allowUnscheduledTasks
property. The following images represent the various types of unscheduled tasks in Gantt.
Taskbar state | Auto | Manual |
---|---|---|
Start Date Only |
![]() |
![]() |
End Date Only |
![]() |
![]() |
Duration Only |
![]() |
![]() |
Milestone |
![]() |
![]() |
Note: A milestone is a task that has no start and end dates, but it has a duration value of zero
Define unscheduled tasks in data source
You can define the various types of unscheduled tasks in the data source as follows
let GanttData = [
{
TaskID: 1,
TaskName: 'Project Initiation',
StartDate: new Date('04/02/2019'),
EndDate: new Date('04/21/2019'),
subtasks: [
{ TaskID: 2, TaskName: 'Identify Site location', Duration: 3, Progress: 50 },
{ TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Progress: 50 },
{ TaskID: 4, TaskName: 'Soil test approval', EndDate: new Date('04/08/2019'), Progress: 50 },
]
},
{
TaskID: 5,
TaskName: 'Project Estimation',
StartDate: new Date('04/02/2019'),
EndDate: new Date('04/21/2019'),
subtasks: [
{ TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), EndDate: new Date('04/08/2019'), Progress: 50 },
{ TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Progress: 50 },
{ TaskID: 8, TaskName: 'Estimation approval', Duration: 0, Progress: 50 }
]
},
];
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit } from '@syncfusion/ej2-react-gantt';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
child: 'subtasks'
};
const editSettings = {
allowEditing: true,
allowTaskbarEditing: true,
};
return < GanttComponent dataSource={GanttData} taskFields={taskFields} editSettings={editSettings} allowUnscheduledTasks={true} height='400px'>
<Inject services={[Edit]}/>
</GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
let GanttData = [
{
TaskID: 1,
TaskName: 'Project Initiation',
StartDate: new Date('04/02/2019'),
EndDate: new Date('04/21/2019'),
subtasks: [
{ TaskID: 2, TaskName: 'Identify Site location', Duration: 3, Progress: 50 },
{ TaskID: 3, TaskName: 'Perform Soil test', StartDate: new Date('04/02/2019'), Progress: 50 },
{ TaskID: 4, TaskName: 'Soil test approval', EndDate: new Date('04/08/2019'), Progress: 50 },
]
},
{
TaskID: 5,
TaskName: 'Project Estimation',
StartDate: new Date('04/02/2019'),
EndDate: new Date('04/21/2019'),
subtasks: [
{ TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('04/04/2019'), EndDate: new Date('04/08/2019'), Progress: 50 },
{ TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Progress: 50 },
{ TaskID: 8, TaskName: 'Estimation approval', Duration: 0, Progress: 50 }
]
},
];
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, Edit } from '@syncfusion/ej2-react-gantt';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
child: 'subtasks'
};
const editSettings = {
allowEditing: true,
allowTaskbarEditing: true,
};
return < GanttComponent dataSource={GanttData} taskFields={taskFields} editSettings={editSettings} allowUnscheduledTasks={true} height='400px'>
<Inject services={[Edit]}/>
</GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Gantt</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet" type="text/css"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='root'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
NOTE
If theallowUnscheduledTasks
property is set to false, then the Gantt control automatically calculates the scheduled date values with a default value of duration 1 and the project start date is considered as the start date for the task.
Working Time Range
In the Gantt control, working hours in a day for a project can be defined by using the dayWorkingTime
property. Based on the working hours, automatic date scheduling and duration validations for a task are performed.
The following code snippet explains how to define the working time range for the project in Gantt.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'Children'
};
const timelineSettings = {
timelineViewMode: 'Day'
};
const dayWorkingTime = [{ from: 9, to: 18 }];
return <GanttComponent dataSource={data} taskFields={taskFields} dayWorkingTime={dayWorkingTime} timelineSettings={timelineSettings} height='450px'>
</GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'Children'
};
const timelineSettings = {
timelineViewMode: 'Day'
};
const dayWorkingTime = [{ from: 9, to: 18 }];
return <GanttComponent dataSource={data} taskFields={taskFields} dayWorkingTime={dayWorkingTime} timelineSettings={timelineSettings} height='450px'>
</GanttComponent>;
};
ReactDOM.render(<App />, document.getElementById('root'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Gantt</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet" type="text/css"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='root'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
NOTE
- Individual tasks can lie between any time within the defined working time range of the project.
- The
dayWorkingTime
property is used to define the working time for the whole project.
Weekend/Non-working days
Non-working days/weekend are used to represent the non-productive days in a project. You can define the non-working days in a week using the workWeek
property in Gantt.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, DayMarkers } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'Children'
};
const workWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday'];
return <GanttComponent dataSource={data} taskFields={taskFields} highlightWeekends={true} workWeek={workWeek} height='450px'>
<Inject services={[DayMarkers]}/>
</GanttComponent>
};
ReactDOM.render(<App />, document.getElementById('root'));
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, Inject, DayMarkers } from '@syncfusion/ej2-react-gantt';
import { data } from './datasource';
function App() {
const taskFields = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
child: 'Children'
};
const workWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday'];
return <GanttComponent dataSource={data} taskFields={taskFields} highlightWeekends={true} workWeek={workWeek} height='450px'>
<Inject services={[DayMarkers]}/>
</GanttComponent>
};
ReactDOM.render(<App />, document.getElementById('root'));
<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Gantt</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet" type="text/css"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='root'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
By default, Saturdays and Sundays are considered as non-working days/weekend in a project.
In the Gantt control, you can make weekend as working day by setting theincludeWeekend
property totrue
.