Configure Work in React Gantt Chart Component

18 Nov 201824 minutes to read

The work feature in the React Gantt Chart component defines the total effort required to complete a task, mapped via the taskFields.work property to a numeric value (e.g., 40 for 40 hours). The effort is measured in hours, days, or minutes using the workUnit property, with Hour as the default. For example, a task with 40 hours of work and one resource at 100% allocation spans 5 8-hour workdays. Mapping taskFields.work sets the task type to FixedWork by default, ensuring work hours remain constant during edits. This feature, requiring Edit service for modifications, integrates with resources, dependencies, and critical path calculations, ensuring precise project scheduling for resource-driven projects.

Configure work

Use the taskFields.work property to map a numeric work value (e.g., hours) from the data source. Set the measurement unit with workUnit to Hour, Day, or Minute to define how work is calculated. For example, workUnit: "Day" assumes 8-hour workdays. Inject Edit service to enable editing work via dialogs or taskbar drags. Work values determine taskbar lengths and influence dependency scheduling, aligning project timelines with resource availability.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
    GanttComponent,
    Inject,
    Edit,
    Selection,
    Toolbar
} from '@syncfusion/ej2-react-gantt';

import { data, resources } from './datasource';
function App() {

    const taskFields = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        endDate: 'EndDate',
        duration: 'Duration',
        progress: 'Progress',
        resourceInfo: 'resources',
        work: 'Work',
        parentID: 'ParentID'
    };

    const editSettings = {
        allowAdding: true,
        allowEditing: true,
        allowDeleting: true,
        allowTaskbarEditing: true,
        showDeleteConfirmDialog: true
    };

    const resourceFields = {
        id: 'resourceId',
        name: 'resourceName',
        unit: 'Unit'
    };

    const toolbar = ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll'];

    const 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' }
    ];

    const splitterSettings = { columnIndex: 1 };

    const projectStartDate = new Date('03/25/2019');
    const projectEndDate = new Date('07/28/2019');

    return (
        <GanttComponent
            height="450px"
            dataSource={data}
            taskFields={taskFields}
            columns={columns}
            treeColumnIndex={1}
            editSettings={editSettings}
            allowSelection={true}
            projectStartDate={projectStartDate}
            projectEndDate={projectEndDate}
            highlightWeekends={true}
            toolbar={toolbar}
            resources={resources}
            resourceFields={resourceFields}
            workUnit="Hour"
            splitterSettings={splitterSettings}
        >
            <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,
    TaskFieldsModel,
    ResourceFieldsModel,
    EditSettingsModel,
    SplitterSettingsModel
} from '@syncfusion/ej2-react-gantt';

import { data, resources } from './datasource';
function App() {

    const taskFields: TaskFieldsModel = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        endDate: 'EndDate',
        duration: 'Duration',
        progress: 'Progress',
        resourceInfo: 'resources',
        work: 'Work',
        parentID: 'ParentID'
    };

    const editSettings: EditSettingsModel = {
        allowAdding: true,
        allowEditing: true,
        allowDeleting: true,
        allowTaskbarEditing: true,
        showDeleteConfirmDialog: true
    };

    const resourceFields: ResourceFieldsModel = {
        id: 'resourceId',
        name: 'resourceName',
        unit: 'Unit'
    };

    const toolbar: string[] = ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll'];

    const columns: object[] = [
        { 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' }
    ];

    const splitterSettings: SplitterSettingsModel = { columnIndex: 1 };

    const projectStartDate = new Date('03/25/2019');
    const projectEndDate = new Date('07/28/2019');

    return (
        <GanttComponent
            height="450px"
            dataSource={data}
            taskFields={taskFields}
            columns={columns}
            treeColumnIndex={1}
            editSettings={editSettings}
            allowSelection={true}
            projectStartDate={projectStartDate}
            projectEndDate={projectEndDate}
            highlightWeekends={true}
            toolbar={toolbar}
            resources={resources}
            resourceFields={resourceFields}
            workUnit="Hour"
            splitterSettings={splitterSettings}
        >
            <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/34.1.29/tailwind3.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>
</head>

<body>
        <div id='root'>
            <div id='loader'>Loading....</div>
        </div>
</body>

</html>

Configure task types

The taskType property controls how work, duration, and resourceUnit fields interact during edits, with FixedUnit as the default unless taskFields.work is mapped (sets FixedWork). Inject EditService to enable editing. The available task types are:

  • FixedDuration: Duration remains constant; editing work or resource units adjusts the other (e.g., increasing work increases resource allocation).
  • FixedWork: Work remains constant; editing duration or resource units adjusts the other (e.g., reducing duration increases resource allocation).
  • FixedUnit: Resource units remain constant; editing work or duration adjusts the other (e.g., increasing work extends duration).

For example, a FixedWork task with 40 hours and two resources at 50% each spans 5 days; shortening duration to 4 days increases resource units to 62.5%. Task types affect taskbar rendering and critical path calculations, ensuring accurate scheduling.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
    GanttComponent,
    Inject,
    Edit,
    Selection,
    Toolbar
} from '@syncfusion/ej2-react-gantt';
import { data, resources } from './datasource';

function App() {

    const taskFields = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        endDate: 'EndDate',
        duration: 'Duration',
        progress: 'Progress',
        dependency: 'Predecessor',
        resourceInfo: 'resources',
        work: 'Work',
        parentID: 'ParentID'
    };

    const resourceFields = {
        id: 'resourceId',
        name: 'resourceName',
        unit: 'Unit'
    };

    const editSettings = {
        allowAdding: true,
        allowEditing: true,
        allowDeleting: true,
        allowTaskbarEditing: true,
        showDeleteConfirmDialog: true
    };

    const toolbar = ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll'];

    const 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' }
    ];

    const projectStartDate = new Date('03/25/2019');
    const projectEndDate = new Date('07/28/2019');

    const splitterSettings = { columnIndex: 1 };

    return (
        <GanttComponent
            height="450px"
            dataSource={data}
            taskFields={taskFields}
            columns={columns}
            treeColumnIndex={1}
            editSettings={editSettings}
            allowSelection={true}
            projectStartDate={projectStartDate}
            projectEndDate={projectEndDate}
            highlightWeekends={true}
            toolbar={toolbar}
            resources={resources}
            resourceFields={resourceFields}
            workUnit="Hour"
            taskType="FixedWork"
            splitterSettings={splitterSettings}
        >
            <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,
    TaskFieldsModel,
    EditSettingsModel,
    ResourceFieldsModel,
    SplitterSettingsModel
} from '@syncfusion/ej2-react-gantt';
import { data, resources } from './datasource';

function App() {

    const taskFields: TaskFieldsModel = {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        endDate: 'EndDate',
        duration: 'Duration',
        progress: 'Progress',
        dependency: 'Predecessor',
        resourceInfo: 'resources',
        work: 'Work',
        parentID: 'ParentID'
    };

    const resourceFields: ResourceFieldsModel = {
        id: 'resourceId',
        name: 'resourceName',
        unit: 'Unit'
    };

    const editSettings: EditSettingsModel = {
        allowAdding: true,
        allowEditing: true,
        allowDeleting: true,
        allowTaskbarEditing: true,
        showDeleteConfirmDialog: true
    };

    const toolbar: string[] = ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll'];

    const columns: Object[] = [
        { 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' }
    ];

    const projectStartDate = new Date('03/25/2019');
    const projectEndDate = new Date('07/28/2019');

    const splitterSettings: SplitterSettingsModel = { columnIndex: 1 };

    return (
        <GanttComponent
            height="450px"
            dataSource={data}
            taskFields={taskFields}
            columns={columns}
            treeColumnIndex={1}
            editSettings={editSettings}
            allowSelection={true}
            projectStartDate={projectStartDate}
            projectEndDate={projectEndDate}
            highlightWeekends={true}
            toolbar={toolbar}
            resources={resources}
            resourceFields={resourceFields}
            workUnit="Hour"
            taskType="FixedWork"
            splitterSettings={splitterSettings}
        >
            <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/34.1.29/tailwind3.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>
</head>

<body>
        <div id='root'>
            <div id='loader'>Loading....</div>
        </div>
</body>

</html>

Following table explains how the work, duration and resource unit fields will get updated on changing any of the fields

Task Type Changes in Duration Changes in work Changes in Resource Units
Fixed Duration Work field updates Resource unit updates Work field updates
Fixed Work Resource unit updates.Note: For manually scheduled task work will update. Duration field updates. Note: For manually scheduled task resource unit updates. Duration will update. Note: For manually scheduled task work field updates.
Fixed Unit Work field updates Duration field updates. Note: For manually scheduled task resource unit updates. Duration will update. Note: For manually scheduled task work field updates.

Work limitations

Work and task types have the following constraints:

  • Milestones (zero-duration tasks) do not support work calculations, as they lack duration.
  • Manually scheduled tasks override automatic calculations, allowing manual control over work, duration, or resourceUnit, which may lead to scheduling inconsistencies.
  • Editing work or task types requires Edit service for dialogs or taskbar interactions.
  • Invalid workUnit values (e.g., not Hour, Day, or Minute) may cause calculation errors.
  • Work calculations rely on resourceInfo for accurate resource unit allocation.

See also