Configure work in Angular Gantt component
13 Oct 202524 minutes to read
The work feature in the Angular Gantt 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 EditService 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 EditService 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 { GanttModule } from '@syncfusion/ej2-angular-gantt'
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
@Component({
imports: [GanttModule],
standalone: true,
selector: 'app-root',
template:
`<ejs-gantt height="430px" [dataSource]="data" [taskFields]="taskSettings" [columns]="columns" [treeColumnIndex]="1" [editSettings]="editSettings" height="450px" [allowSelection]="true" [projectStartDate]="projectStartDate" [projectEndDate]="projectEndDate" [highlightWeekends]="true" [toolbar]="toolbar" [resourceFields] = "resourceFields" [resources]="resources" resourceNameMapping='resourceName' resourceIDMapping='resourceId' resourceUnitMapping='Unit' workUnit="Hour">
</ejs-gantt> `,
encapsulation: ViewEncapsulation.None
})
export class AppComponent implements OnInit {
public data?: object[];
public resources?: object[];
public taskSettings?: object;
public labelSettings?: object;
public projectStartDate?: Date;
public projectEndDate?: Date;
public editSettings?: object;
public resourceFields?: object;
public toolbar: string[] | undefined;
public columns?: object[];
public ngOnInit(): void {
this.data = [
{
TaskID: 1,
TaskName: 'Project initiation',
StartDate: new Date('03/29/2019'),
EndDate: new Date('04/21/2019'),
subtasks: [
{
TaskID: 2, TaskName: 'Identify site location', StartDate: new Date('03/29/2019'), Duration: 2,
Progress: 30, Work: 16, resources: [{ resourceId: 1, Unit: 70 }, 6]
},
{
TaskID: 3, TaskName: 'Perform soil test', StartDate: new Date('03/29/2019'), Duration: 4,
resources: [2, 3, 5], Work: 96
},
{
TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('03/29/2019'), Duration: 1,
Work: 16, resources: [8, { resourceId: 9, Unit: 50 }], Progress: 30
},
]
},
{
TaskID: 5,
TaskName: 'Project estimation', StartDate: new Date('03/29/2019'), EndDate: new Date('04/21/2019'),
subtasks: [
{
TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('03/29/2019'),
Duration: 3, Progress: 30, resources: [{ resourceId: 4, Unit: 50 }], Work: 30
},
{
TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/01/2019'), Duration: 3,
Work: 48, resources: [4, 8]
},
{
TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/01/2019'),
Duration: 2, Work: 60, resources: [12, { resourceId: 5, Unit: 70 }]
}
]
},
{
TaskID: 9, TaskName: 'Sign contract', StartDate: new Date('04/01/2019'), Duration: 1,
Progress: 30, resources: [12], Work: 24
}
];
this.resources = [
{ 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' }
];
this.taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
resourceInfo: 'resources',
work: 'Work',
child: 'subtasks'
};
this.editSettings = {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
};
this.resourceFields = {
id: 'resourceId',
name: 'resourceName',
unit: 'Unit'
};
this.toolbar = ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll'];
this.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' }
];
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));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 { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { GanttModule } from '@syncfusion/ej2-angular-gantt'
@Component({
imports: [GanttModule],
standalone: true,
selector: 'app-root',
template:
` <ejs-gantt height="430px" [dataSource]="data" [taskFields]="taskSettings" [columns]="columns" [treeColumnIndex]="1" [editSettings]="editSettings"
height="450px" [allowSelection]="true" [projectStartDate]="projectStartDate" [projectEndDate]="projectEndDate" [highlightWeekends]="true"
[toolbar]="toolbar" [resourceFields] = "resourceFields" resourceNameMapping='resourceName' resourceIDMapping='resourceId' resourceUnitMapping='Unit' [resources]="resources" workUnit="Hour" taskType= "FixedWork">
</ejs-gantt> `,
encapsulation: ViewEncapsulation.None
})
export class AppComponent implements OnInit{
public data?: object[];
public resources?: object[];
public taskSettings?: object;
public labelSettings?: object;
public projectStartDate?: Date;
public projectEndDate?: Date;
public editSettings?: object;
public resourceFields?: object;
public toolbar: string[] | undefined;
public columns?: object[];
public ngOnInit(): void {
this.data = [
{
TaskID: 1,
TaskName: 'Project initiation',
StartDate: new Date('03/29/2019'),
EndDate: new Date('04/21/2019'),
subtasks: [
{
TaskID: 2, TaskName: 'Identify site location', StartDate: new Date('03/29/2019'), Duration: 2,
Progress: 30, Work: 16, resources: [{ resourceId: 1, Unit: 70 }, 6]
},
{
TaskID: 3, TaskName: 'Perform soil test', StartDate: new Date('03/29/2019'), Duration: 4,
resources: [2, 3, 5], Work: 96
},
{
TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('03/29/2019'), Duration: 1,
Work: 16, resources: [8, { resourceId: 9, Unit: 50 }], Progress: 30
},
]
},
{
TaskID: 5,
TaskName: 'Project estimation', StartDate: new Date('03/29/2019'), EndDate: new Date('04/21/2019'),
subtasks: [
{
TaskID: 6, TaskName: 'Develop floor plan for estimation', StartDate: new Date('03/29/2019'),
Duration: 3, Progress: 30, resources: [{ resourceId: 4, Unit: 50 }], Work: 30
},
{
TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/01/2019'), Duration: 3,
Work: 48, resources: [4, 8]
},
{
TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/01/2019'),
Duration: 2, Work: 60, resources: [12, { resourceId: 5, Unit: 70 }]
}
]
},
{
TaskID: 9, TaskName: 'Sign contract', StartDate: new Date('04/01/2019'), Duration: 1,
Progress: 30, resources: [12], Work: 24
}
];
this.resources = [
{ 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' }
];
this.taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
resourceInfo: 'resources',
child: 'subtasks'
};
this.editSettings = {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
};
this.resourceFields = {
id: 'resourceId',
name: 'resourceName',
unit: 'Unit'
};
this.toolbar = ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll'];
this.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' }
];
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Following table explains how the work, duration and resource unit fields will gets 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, orresourceUnit, which may lead to scheduling inconsistencies. - Editing work or task types requires
EditServicefor dialogs or taskbar interactions. - Invalid
workUnitvalues (e.g., not Hour, Day, or Minute) may cause calculation errors. - Work calculations rely on resourceInfo for accurate resource unit allocation.