Resource view in Angular Gantt component
27 Apr 202424 minutes to read
The resource breakdown view is used to visualize the tasks assigned to each resource in hierarchy manner. Resources are displayed as parents and all the tasks assigned to each resource are displayed as its child records. It can be initialized by setting the viewType
property to ResourceView
.
Resource task
A task assigned to one or more resources are termed as resource task and it is added as child task to the respective resource. Already assigned task can also be shared or moved with other resources by adding a resource name to the task or removing resource name from the task by cell or dialog editing.
Note: Currently there is no support for unscheduled task in Resource view Gantt.
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GanttModule } from '@syncfusion/ej2-angular-gantt'
import { ToolbarService, EditService, SelectionService } from '@syncfusion/ej2-angular-gantt'
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { Gantt } from '@syncfusion/ej2-gantt';
@Component({
imports: [
GanttModule
],
providers: [ToolbarService, EditService, SelectionService],
standalone: true,
selector: 'app-root',
template:
`<ejs-gantt id="ganttDefault" height="430px" [dataSource]="data" [resources]="resources" [taskFields]="taskSettings" [resourceFields]="resourceFields" [editSettings]="editSettings" [columns]="columns" [toolbar]="toolbar" [labelSettings]="labelSettings" [splitterSettings]="splitterSettings" [allowSelection]='true' [allowResizing] = 'true' [highlightWeekends] = 'true' [treeColumnIndex]="1" [projectStartDate]="projectStartDate" [projectEndDate]="projectEndDate" viewType="ResourceView"></ejs-gantt>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
// Data for Gantt
public data?: object[];
public resources?: object[];
public taskSettings?: object;
public labelSettings?: object;
public projectStartDate?: Date;
public projectEndDate?: Date;
resourceFields: { id: string; name: string; unit: string; group: string; } | undefined;
editSettings: { allowAdding: boolean; allowEditing: boolean; allowDeleting: boolean; allowTaskbarEditing: boolean; showDeleteConfirmDialog: boolean; } | undefined;
columns: ({ field: string; visible: boolean; headerText?: undefined; width?: undefined; } | { field: string; headerText: string; width: number; visible?: undefined; } | { field: string; headerText: string; visible?: undefined; width?: undefined; } | { field: string; visible?: undefined; headerText?: undefined; width?: undefined; })[] | undefined;
toolbar: string[] | undefined;
splitterSettings: { columnIndex: number; } | undefined;
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: 10, resources: [{ resourceId: 1, resourceUnit: 50 }]
},
{
TaskID: 3, TaskName: 'Perform soil test', StartDate: new Date('03/29/2019'), Duration: 4,
resources: [{resourceId: 2, resourceUnit: 70}], Progress: 30, work: 20
},
{
TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('03/29/2019'), Duration: 1,
resources: [{resourceId: 3, resourceUnit: 25}, { resourceId: 1, resourceUnit: 75 }], Progress: 30, work: 10,
},
]
},
{
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, resourceUnit: 50 }, {resourceId: 2, resourceUnit: 70}], work: 30
},
{
TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/01/2019'), Duration: 3,
resources: [{resourceId: 6, resourceUnit: 40}], Progress: 30, work: 40
},
{
TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/01/2019'),
Duration: 2, resources: [{ resourceId: 5, resourceUnit: 75 }], Progress: 30, work: 60,
}
]
},
{
TaskID: 9, TaskName: 'Sign contract', StartDate: new Date('04/01/2019'), Duration: 1,
Progress: 30,
}
];
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',
work: 'work',
child: 'subtasks'
};
this.resourceFields = {
id: 'resourceId',
name: 'resourceName',
unit: 'Unit',
group: 'resourceGroup'
};
this.editSettings = {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
};
this.columns = [
{ field: 'TaskID', visible: false },
{ field: 'TaskName', headerText: 'Name', width: 250 },
{ field: 'work', headerText: 'Work' },
{ field: 'Progress' },
{ field: 'resourceGroup', headerText: 'Group' },
{ field: 'StartDate' },
{ field: 'Duration' }
];
this.toolbar = ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll'];
this.labelSettings = {
rightLabel: 'resources'
};
this.splitterSettings = {
columnIndex: 3
};
this.projectStartDate = new Date('03/25/2019');
this.projectEndDate = new Date('07/28/2019');
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
Resource overAllocation
When a resource is assigned too much of work to complete within a day of resource’s available time then it is called as overallocation.
The available working time of resources for completing the task in a day will be calculated based on the dayWorkingTime
property and resource unit
.
The range of overallocation dates can be highlighted by a square bracket. It can be enabled by setting the showOverallocation
property as true
. The following code example demonstrates how to hide or show the over allocation by clicking the custom button.
Note: By default, the
showOverAllocation
property value isfalse
.
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GanttModule } from '@syncfusion/ej2-angular-gantt'
import { ToolbarService, EditService, SelectionService } from '@syncfusion/ej2-angular-gantt'
import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttComponent } from '@syncfusion/ej2-angular-gantt';
import { ToolbarItem, EditSettingsModel, SelectionSettingsModel } from '@syncfusion/ej2-angular-gantt';
import { ClickEventArgs } from '@syncfusion/ej2-navigations';
@Component({
imports: [
GanttModule
],
providers: [ToolbarService, EditService, SelectionService],
standalone: true,
selector: 'app-root',
template:
`<ejs-gantt #gantt id="ganttDefault" [dataSource]="data" [resources]="resources" [taskFields]="taskSettings"
[resourceFields]="resourceFields" [editSettings]="editSettings" [columns]="columns" [toolbar]="toolbar" [labelSettings]="labelSettings"
[splitterSettings]="splitterSettings" [allowSelection]='true' [allowResizing] = 'true' [highlightWeekends] = 'true'
[treeColumnIndex]="1" [projectStartDate]="projectStartDate" [projectEndDate]="projectEndDate" viewType="ResourceView"
[showOverAllocation] = 'true' (toolbarClick)="toolbarClick($event)"></ejs-gantt>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
// Data for Gantt
public data?: object[];
public resources?: object[];
public taskSettings?: object;
public labelSettings?: object;
public projectStartDate?: Date;
public projectEndDate?: Date;
@ViewChild('gantt', {static: true})
public ganttObj?: GanttComponent;
resourceFields: { id: string; name: string; unit: string; group: string; } | undefined;
editSettings: { allowAdding: boolean; allowEditing: boolean; allowDeleting: boolean; allowTaskbarEditing: boolean; showDeleteConfirmDialog: boolean; } | undefined;
columns: ({ field: string; visible: boolean; headerText?: undefined; width?: undefined; } | { field: string; headerText: string; width: number; visible?: undefined; } | { field: string; headerText: string; visible?: undefined; width?: undefined; } | { field: string; visible?: undefined; headerText?: undefined; width?: undefined; })[] | undefined;
toolbar: (string | { text: string; tooltipText: string; id: string; })[] | undefined;
splitterSettings: any;
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: 3,
Progress: 30, work: 10, resources: [{ resourceId: 1, resourceUnit: 50 }]
},
{
TaskID: 3, TaskName: 'Perform soil test', StartDate: new Date('04/03/2019'), Duration: 4,
resources: [{ resourceId: 1, resourceUnit: 70 }], Predecessor: 2, Progress: 30, work: 20
},
{
TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/09/2019'), Duration: 4,
resources: [{ resourceId: 1, resourceUnit: 25 }], Predecessor: 3, Progress: 30, work: 10,
},
]
},
{
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('04/01/2019'),
Duration: 5, Progress: 30, resources: [{ resourceId: 2, resourceUnit: 50 }], work: 30
},
{
TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 4,
resources: [{ resourceId: 2, resourceUnit: 40 }], Predecessor: '6FS-2', Progress: 30, work: 40
},
{
TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/09/2019'),
Duration: 4, resources: [{ resourceId: 2, resourceUnit: 75 }], Predecessor: '7FS-1', Progress: 30, work: 60,
}
]
},
{
TaskID: 9,
TaskName: 'Site work',
StartDate: new Date('04/04/2019'),
EndDate: new Date('04/21/2019'),
subtasks: [
{
TaskID: 10, TaskName: 'Install temporary power service', StartDate: new Date('04/01/2019'), Duration: 14,
Progress: 30, resources: [{ resourceId: 3, resourceUnit: 75 }]
},
{
TaskID: 11, TaskName: 'Clear the building site', StartDate: new Date('04/08/2019'),
Duration: 9, Progress: 30, Predecessor: '10FS-9', resources: [3]
},
{
TaskID: 12, TaskName: 'Sign contract', StartDate: new Date('04/12/2019'),
Duration: 5, resources: [3], Predecessor: '11FS-5'
},
]
}
];
this.resources = [
{ resourceId: 1, resourceName: 'Martin Tamer', resourceGroup: 'Planning Team'},
{ resourceId: 2, resourceName: 'Rose Fuller', resourceGroup: 'Testing Team' },
{ resourceId: 3, resourceName: 'Margaret Buchanan', resourceGroup: 'Approval Team' }
];
this.taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
resourceInfo: 'resources',
work: 'work',
child: 'subtasks'
};
this.resourceFields = {
id: 'resourceId',
name: 'resourceName',
unit: 'Unit',
group: 'resourceGroup'
};
this.editSettings = {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
};
this.columns = [
{ field: 'TaskID', visible: false },
{ field: 'TaskName', headerText: 'Name', width: 250 },
{ field: 'work', headerText: 'Work' },
{ field: 'Progress' },
{ field: 'resourceGroup', headerText: 'Group' },
{ field: 'StartDate' },
{ field: 'Duration' }
];
this.toolbar = ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll',
{text: 'Show/Hide Overallocation', tooltipText: 'Show/Hide Overallocation', id: 'showhidebar'}];
this.labelSettings = {
rightLabel: 'resources',
taskLabel: 'Progress'
}
this.projectStartDate = new Date('03/25/2019');
this.projectEndDate = new Date('07/28/2019');
}
public toolbarClick(args: ClickEventArgs): void {
if (args.item.id === 'showhidebar') {
this.ganttObj!.showOverAllocation = this.ganttObj!.showOverAllocation ? false : true;
}
};
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
Unassigned task
A task not assigned to any one of the resource are termed as unassigned tasks. The unassigned tasks are grouped with a name as Unassigned Task
and displayed at the bottom of Gantt data collection . It is validated at load time during Gantt record creation by default based on a task resourceInfo
mapping property in the Gantt chart data source. If the resource is assigned to the unassigned grouped tasks, the task will be moved as child to the respective resource.
Enable taskbar drag and drop
In Gantt, you can enable taskbar drag and drop between resources by using the allowTaskbarDragAndDrop
property. This allows you to move a taskbar from one resource to another vertically, making it easier to schedule tasks and manage resources.
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { GanttModule } from '@syncfusion/ej2-angular-gantt'
import { ToolbarService, EditService, SelectionService } from '@syncfusion/ej2-angular-gantt'
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttComponent } from '@syncfusion/ej2-angular-gantt';
import { ToolbarItem, EditSettingsModel, SelectionSettingsModel } from '@syncfusion/ej2-angular-gantt';
@Component({
imports: [
GanttModule
],
providers: [ToolbarService, EditService, SelectionService],
standalone: true,
selector: 'app-root',
template:
`<ejs-gantt id="ganttDefault" [dataSource]="data" [resources]="resources" [taskFields]="taskSettings"
[resourceFields]="resourceFields" [editSettings]="editSettings" [columns]="columns" [toolbar]="toolbar" [labelSettings]="labelSettings"
[allowSelection]='true' [allowResizing] = 'true' [highlightWeekends] = 'true' [treeColumnIndex]="1" [allowTaskbarDragAndDrop] = 'true'
[projectStartDate]="projectStartDate" [projectEndDate]="projectEndDate" viewType="ResourceView" [showOverAllocation] = 'true'
[enableMultiTaskbar]= 'true' ></ejs-gantt>`,
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
// Data for Gantt
public data?: object[];
public resources?: object[];
public taskSettings?: object;
public labelSettings?: object;
public projectStartDate?: Date;
public projectEndDate?: Date;
editSettings: { allowAdding: boolean; allowEditing: boolean; allowDeleting: boolean; allowTaskbarEditing: boolean; showDeleteConfirmDialog: boolean; } | undefined;
columns: ({ field: string; ss: any; headerText?: undefined; width?: undefined; } | { field: string; headerText: string; width: number; ss?: undefined; } | { field: string; headerText: string; ss?: undefined; width?: undefined; } | { field: string; ss?: undefined; headerText?: undefined; width?: undefined; })[] | undefined;
toolbar: string[] | undefined;
resourceFields: { id: string; name: string; unit: string; group: string; } | undefined;
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: 3,
Progress: 30, work: 10, resources: [{ resourceId: 1, resourceUnit: 50 }]
},
{
TaskID: 3, TaskName: 'Perform soil test', StartDate: new Date('04/03/2019'), Duration: 4,
resources: [{ resourceId: 1, resourceUnit: 70 }], Predecessor: 2, Progress: 30, work: 20
},
{
TaskID: 4, TaskName: 'Soil test approval', StartDate: new Date('04/09/2019'), Duration: 4,
resources: [{ resourceId: 1, resourceUnit: 25 }], Predecessor: 3, Progress: 30, work: 10,
},
]
},
{
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('04/01/2019'),
Duration: 5, Progress: 30, resources: [{ resourceId: 2, resourceUnit: 50 }], work: 30
},
{
TaskID: 7, TaskName: 'List materials', StartDate: new Date('04/04/2019'), Duration: 4,
resources: [{ resourceId: 2, resourceUnit: 40 }], Predecessor: '6FS-2', Progress: 30, work: 40
},
{
TaskID: 8, TaskName: 'Estimation approval', StartDate: new Date('04/09/2019'),
Duration: 4, resources: [{ resourceId: 2, resourceUnit: 75 }], Predecessor: '7FS-1', Progress: 30, work: 60,
}
]
},
{
TaskID: 9,
TaskName: 'Site work',
StartDate: new Date('04/04/2019'),
EndDate: new Date('04/21/2019'),
subtasks: [
{
TaskID: 10, TaskName: 'Install temporary power service', StartDate: new Date('04/01/2019'), Duration: 14,
Progress: 30, resources: [{ resourceId: 3, resourceUnit: 75 }]
},
{
TaskID: 11, TaskName: 'Clear the building site', StartDate: new Date('04/08/2019'),
Duration: 9, Progress: 30, Predecessor: '10FS-9', resources: [3]
},
{
TaskID: 12, TaskName: 'Sign contract', StartDate: new Date('04/12/2019'),
Duration: 5, resources: [3], Predecessor: '11FS-5'
},
]
}
];
this.resources = [
{ resourceId: 1, resourceName: 'Martin Tamer', resourceGroup: 'Planning Team', isExpand: false},
{ resourceId: 2, resourceName: 'Rose Fuller', resourceGroup: 'Testing Team', isExpand: true},
{ resourceId: 3, resourceName: 'Margaret Buchanan', resourceGroup: 'Approval Team', isExpand: false }
];
this.taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
endDate: 'EndDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
resourceInfo: 'resources',
work: 'work',
expandState: 'isExpand',
child: 'subtasks'
};
this.resourceFields = {
id: 'resourceId',
name: 'resourceName',
unit: 'Unit',
group: 'resourceGroup'
};
this.editSettings = {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
};
this.columns = [
{ field: 'TaskID' },
{ field: 'TaskName', headerText: 'Name', width: 250 },
{ field: 'work', headerText: 'Work' },
{ field: 'Progress' },
{ field: 'resourceGroup', headerText: 'Group' },
{ field: 'StartDate' },
{ field: 'Duration' }
];
this.toolbar = ['ExpandAll', 'CollapseAll'];
this.labelSettings = {
rightLabel: 'resources',
taskLabel: 'TaskName'
};
this.projectStartDate = new Date('03/25/2019');
this.projectEndDate = new Date('07/28/2019');
}
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));