Work Breakdown Structure (WBS) in EJ2 TypeScript Gantt Chart
27 May 202614 minutes to read
The Work Breakdown Structure (WBS) organizes project tasks hierarchically by assigning unique codes to each task. This improves task visibility and management, especially in large-scale construction or enterprise-level software projects.
Configuration and implementation
To enable WBS in the Gantt Chart control:
- Enable WBS Codes: Set enableWBS to true to automatically generate unique task codes and define their predecessors.
- Auto-Update Codes: Set enableAutoWbsUpdate to true to maintain accurate WBS codes during operations such as sorting, editing, or drag-and-drop.
import { Gantt, Selection, Toolbar, DayMarkers, Edit, Filter, Sort, ContextMenu } from '@syncfusion/ej2-gantt';
import { WBSData } from './datasource.ts';
Gantt.Inject(Selection, Toolbar, DayMarkers, Edit, Filter, Sort, ContextMenu);
let gantt: Gantt = new Gantt({
dataSource: WBSData,
allowSorting: true,
enableContextMenu: true,
enableWBS: true,
enableAutoWbsUpdate: true,
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
parentID: 'ParentId'
},
treeColumnIndex: 2,
editSettings: {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
},
columns: [
{ field: 'TaskID', headerText: 'Task ID', visible: false },
{ field: 'WBSCode', headerText: 'WBS Code', width: '150px' },
{ field: 'TaskName', headerText: 'Task Name', allowReordering: false, width: '260px' },
{ field: 'StartDate', headerText: 'Start Date', width: '140px' },
{ field: 'WBSPredecessor', headerText: 'WBS Predecessor', width: '190px' },
{ field: 'Duration', headerText: 'Duration', allowEditing: false, width: '130px' },
{ field: 'Progress', headerText: 'Progress' },
],
eventMarkers: [
{
day: new Date('04/2/2024'),
label: 'Project Initiation'
}
],
toolbar: ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll'],
allowPdfExport: true,
allowSelection: true,
splitterSettings: {
columnIndex: 4,
},
selectionSettings: {
mode: 'Row',
type: 'Single',
enableToggle: false
},
tooltipSettings: {
showTooltip: true
},
filterSettings: {
type: 'Menu'
},
allowFiltering: true,
gridLines: "Both",
highlightWeekends: true,
timelineSettings: {
showTooltip: true,
topTier: {
unit: 'Week',
format: 'dd/MM/yyyy'
},
bottomTier: {
unit: 'Day',
count: 1
}
},
labelSettings: {
taskLabel: '${Progress}%'
},
taskbarHeight: 20,
rowHeight: 40,
height: '550px',
allowUnscheduledTasks: true,
projectStartDate: new Date('03/31/2024'),
projectEndDate: new Date('05/30/2024'),
});
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.1.29/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>Managing WBS code updates
To optimize performance, WBS code updates can be controlled using the actionBegin and dataBound events. This is especially useful during operations like row drag-and-drop, where auto-update is triggered only during that specific action to ensure efficient and accurate code handling.
In the following example, WBS auto-update is enabled only during the row drag and drop action using these events.
import { Gantt, Selection, Toolbar, DayMarkers, Edit, Filter, Sort, ContextMenu, RowDD, ActionBeginEventArgs } from '@syncfusion/ej2-gantt';
import { WBSData } from './datasource.ts';
Gantt.Inject(Selection, Toolbar, DayMarkers, Edit, Filter, Sort, ContextMenu, RowDD);
let isRowDropped: boolean = false;
let gantt: Gantt = new Gantt({
dataSource: WBSData,
allowSorting: true,
enableContextMenu: true,
enableWBS: true,
enableAutoWbsUpdate: false,
allowRowDragAndDrop: true,
dataBound: function () {
if (isRowDropped) {
gantt.enableAutoWbsUpdate = false;
isRowDropped = false;
}
},
actionBegin: function (args: ActionBeginEventArgs) {
if (args.requestType === "beforeDrop") {
isRowDropped = true;
gantt.enableAutoWbsUpdate = false;
}
},
taskFields: {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
progress: 'Progress',
dependency: 'Predecessor',
parentID: 'ParentId'
},
treeColumnIndex: 2,
editSettings: {
allowAdding: true,
allowEditing: true,
allowDeleting: true,
allowTaskbarEditing: true,
showDeleteConfirmDialog: true
},
columns: [
{ field: 'TaskID', headerText: 'Task ID', visible: false },
{ field: 'WBSCode', headerText: 'WBS Code', width: '150px' },
{ field: 'TaskName', headerText: 'Task Name', allowReordering: false, width: '260px' },
{ field: 'StartDate', headerText: 'Start Date', width: '140px' },
{ field: 'WBSPredecessor', headerText: 'WBS Predecessor', width: '190px' },
{ field: 'Duration', headerText: 'Duration', allowEditing: false, width: '130px' },
{ field: 'Progress', headerText: 'Progress' },
],
eventMarkers: [
{
day: new Date('04/2/2024'),
label: 'Project Initiation'
}
],
toolbar: ['Add', 'Edit', 'Update', 'Delete', 'Cancel', 'ExpandAll', 'CollapseAll'],
allowPdfExport: true,
allowSelection: true,
splitterSettings: {
columnIndex: 4,
},
selectionSettings: {
mode: 'Row',
type: 'Single',
enableToggle: false
},
tooltipSettings: {
showTooltip: true
},
filterSettings: {
type: 'Menu'
},
allowFiltering: true,
gridLines: "Both",
highlightWeekends: true,
timelineSettings: {
showTooltip: true,
topTier: {
unit: 'Week',
format: 'dd/MM/yyyy'
},
bottomTier: {
unit: 'Day',
count: 1
}
},
labelSettings: {
taskLabel: '${Progress}%'
},
taskbarHeight: 20,
rowHeight: 40,
height: '550px',
allowUnscheduledTasks: true,
projectStartDate: new Date('03/31/2024'),
projectEndDate: new Date('05/30/2024'),
});
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.1.29/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>Limitations
The WBS feature has a few limitations in the Gantt Chart control:
- Editing of the WBS code and WBS predecessor columns is not supported.
- Load on demand is not supported with the WBS feature.
- WBS Code and WBS Predecessor fields cannot be mapped directly from the data source.