Work Breakdown Structure (WBS) in EJ2 TypeScript Gantt Component

6 Aug 202514 minutes to read

The Work Breakdown Structure (WBS) organizes project tasks hierarchically in the Gantt component by assigning unique codes to each task. This system enhances visualization and management by clearly reflecting task relationships and levels. It is especially useful in complex environments like construction projects or enterprise-scale software development.


Configuration and implementation

  • Enable WBS Codes: Set the enableWBS property to true to automatically generate unique task codes and their predecessors.
  • Auto-Update Codes: Set the enableAutoWbsUpdate property to true to maintain WBS code accuracy during operations like sorting, filtering, 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/31.2.12/material.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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>
    </div>
</body>

</html>


Managing WBS code updates

For better performance, you can control when WBS codes are updated by using the actionBegin and dataBound events. This is particularly useful during actions like dragging and dropping rows.

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} 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) {
        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/31.2.12/material.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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></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 component:

  • 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.