Taskbar in EJ2 TypeScript Gantt Chart Control

27 May 202624 minutes to read

The taskbar in the EJ2 TypeScript Gantt Chart control visually represents tasks on the timeline, showing duration, progress, and dependencies, enabling intuitive project management. Taskbars support customization through properties like taskbarHeight for sizing and queryTaskbarInfo event for conditional formatting based on task data like progress. Multi-taskbar support in resource view, enabled by enableMultiTaskbar, summarizes child task progress in collapsed parent taskbars. Connector lines, styled via connectorLineWidth and connectorLineBackground, illustrate dependencies. Tooltips, controlled by tooltipSettings, provide hover details for taskbars, baselines, and timelines, with templates for custom content. Editing interactions include dragging for rescheduling (via allowTaskbarDragAndDrop) and resizing for duration, progress changes, triggering events like taskbarEditing and taskbarEdited for validation.

Customize taskbar height

Taskbar height for child and parent tasks is set using the taskbarHeight property, which accepts pixel values and must be less than rowHeight to avoid overflow.

The following example demonstrates how to set a custom taskbar height of 40 pixels, delivering consistent appearance across tasks while preserving full responsiveness.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '430px',
    taskbarHeight: 50,
    rowHeight: 60,
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        dependency: 'Predecessor',
        parentID: 'ParentID'
    }
});

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>

Apply conditional formatting

Conditional formatting replaces default taskbar appearance using the queryTaskbarInfo event, accessing task data to modify colors, progress bars, or styles based on criteria like progress.

This example demonstrates formatting taskbars based on progress, where args.data.progress in the event handler dynamically sets args.taskbarBgColor and args.progressBarBgColor to visually highlight critical tasks or milestones.

import { Gantt, Selection, Filter, Toolbar, IQueryTaskbarInfoEventArgs } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

Gantt.Inject(Selection, Filter, Toolbar);

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '430px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        endDate: 'EndDate',
        duration: 'Duration',
        progress: 'Progress',
        dependency: 'Predecessor',
        parentID: 'ParentID'
    },
    queryTaskbarInfo: (args: IQueryTaskbarInfoEventArgs) => {
        let record: any = args.data;

        if (record.Progress === 50) {
            args.progressBarBgColor = 'red';
        } else if (record.Progress === 70) {
            args.progressBarBgColor = 'yellow';
        } else if (record.Progress === 80) {
            args.progressBarBgColor = 'lightgreen';
        }
    }
});

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>

Customize gripper icons

Gripper icons for taskbar editing (start, end, progress) are customized by targeting CSS classes like .e-gantt-left-resize-gripper or .e-gantt-right-resize-gripper with custom styles, overriding default icons for branded appearances.

In the following example, the progress gripper icon is customized by targeting the .e-gantt-progress-resize-gripper class. The custom styles also ensure touch-friendly sizing to support responsive and accessible user interactions.

import { Gantt, Edit } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

Gantt.Inject(Edit);

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '400px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID',
        dependency: 'Predecessor'
    },
    editSettings: {
        allowEditing: true,
        editMode: 'Auto',
        allowTaskbarEditing: true
    }
});

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>

Control taskbar and notes icon visibility

Taskbars and notes icons can be hidden dynamically using the queryTaskbarInfo and queryCellInfo events, enabling conditional visibility based on task data (e.g., hiding milestones or empty notes for cleaner timelines). Hiding taskbars affects only the timeline element, not the row or labels, and requires taskFields.notes for notes icon rendering.

The following example hides taskbars for specific tasks and notes icons for empty notes:

import { Gantt, QueryTaskbarInfoEventArgs, QueryCellInfoEventArgs } from '@syncfusion/ej2-gantt';
import { data } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: data,
    height: '430px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID',
        notes: 'Info'
    },
    queryTaskbarInfo: (args: QueryTaskbarInfoEventArgs) => {
        let task: any = args.data;
        if (task.TaskID >= 7 && task.TaskID <= 10) {
            (args.taskbarElement as HTMLElement).style.visibility = 'hidden';
        }
    },
    queryCellInfo: (args: QueryCellInfoEventArgs) => {
        let task: any = args.data;
        if (args.column.field === 'Info' && (!task.Info || task.Info.trim() === '')) {
            let notesIcon = (args.cell as HTMLElement).querySelector('.e-notes-info') as HTMLElement;
            if (notesIcon) {
                notesIcon.style.visibility = 'hidden';
            }
        }
    },
    columns: [
        { field: 'TaskID', width: 80 },
        { field: 'TaskName', headerText: 'Task Name' },
        { field: 'StartDate' },
        { field: 'Duration' },
        { field: 'Progress' },
        { field: 'Info', headerText: 'Notes' }
    ]
});

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>

This code hides taskbars for tasks with IDs 7–10 (e.g., estimation tasks) and notes icons for empty Info fields, using queryTaskbarInfo and queryCellInfo. The .e-notes-info class ensures robust icon targeting, and taskFields.notes enables notes rendering.

Prevent taskbar editing for specific tasks

Taskbar editing, including dragging, resizing, or adding dependencies, can be prevented for specific tasks (e.g., locked milestones or completed tasks) using the actionBegin event for validation and queryTaskbarInfo to hide editing UI elements like grippers and connector points. This ensures visual and functional restrictions, with ARIA attributes updated for accessibility.

The following example disables taskbar editing for Task ID 4 by canceling drag, resize, and dependency actions in the actionBegin event and hiding resize grippers and connector points in queryTaskbarInfo using CSS classes. Editing remains enabled for other tasks through the Edit service injection and the allowTaskbarEditing property, while global CSS ensures the styles are applied to the Gantt Chart component’s DOM.

import { Gantt, Edit, Selection, IActionBeginEventArgs, IQueryTaskbarInfoEventArgs } from '@syncfusion/ej2-gantt';

Gantt.Inject(Edit, Selection);

let gantt: Gantt = new Gantt({
    dataSource: [
      { TaskId: 1, TaskName: 'Product Concept', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskId: 2, TaskName: 'Defining the product and its usage', StartDate: new Date('04/02/2019'), Duration: 3, Progress: 30, ParentId: 1 },
      { TaskId: 3, TaskName: 'Defining target audience', StartDate: new Date('04/02/2019'), Duration: 3, ParentId: 1 },
      { TaskId: 4, TaskName: 'Prepare product sketch and notes', StartDate: new Date('04/02/2019'), Duration: 2, Progress: 30, Predecessor: '2', ParentId: 1 },
      { TaskId: 5, TaskName: 'Concept Approval', StartDate: new Date('04/02/2019'), Duration: 0, Predecessor: '3,4', Indicators: [{ date: '04/10/2019', name: '#briefing', title: 'Product concept briefing' }] },
      { TaskId: 6, TaskName: 'Market Research', StartDate: new Date('04/02/2019'), EndDate: new Date('04/21/2019') },
      { TaskId: 7, TaskName: 'Demand Analysis', StartDate: new Date('04/04/2019'), EndDate: new Date('04/21/2019'), ParentId: 6 },
      { TaskId: 8, TaskName: 'Customer strength', StartDate: new Date('04/04/2019'), Duration: 4, Progress: 30, Predecessor: '5', ParentId: 7 },
      { TaskId: 9, TaskName: 'Market opportunity analysis', StartDate: new Date('04/04/2019'), Duration: 4, Predecessor: '5', ParentId: 7 },
      { TaskId: 10, TaskName: 'Competitor Analysis', StartDate: new Date('04/04/2019'), Duration: 4, Progress: 30, Predecessor: '7,8', ParentId: 6 }
    ],
    height: '430px',
    projectStartDate: new Date('03/28/2019'),
    projectEndDate: new Date('04/18/2019'),
    taskFields: {
        id: 'TaskId',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentId'
    },
    labelSettings: {
        leftLabel: 'TaskName'
    },
    editSettings: {
        allowTaskbarEditing: true
    },
    queryTaskbarInfo: (args: IQueryTaskbarInfoEventArgs) => {
        if ((args.data as any).TaskId === 4) {
            args.taskbarElement.style.cursor = 'default';
            args.taskbarElement.classList.add(
                'e-prevent-reschedule',
                'e-prevent-add-relation-left',
                'e-prevent-add-relation-right'
            );
        }
    },
    actionBegin: (args: IActionBeginEventArgs) => {
        if (
            (args.data as any).TaskId === 4 &&
            [
                'ChildDrag',
                'ProgressResizing',
                'LeftResizing',
                'RightResizing',
                'ConnectorPointLeftDrag',
                'ConnectorPointRightDrag'
            ].includes(args.taskBarEditAction as string)
        ) {
            args.cancel = true;
        }
    }
});

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/32.1.19/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>
    <style>
        .e-gantt-chart .e-prevent-reschedule .e-right-resize-gripper,
        .e-gantt-chart .e-prevent-reschedule .e-left-resize-gripper,
        .e-gantt-chart .e-prevent-reschedule .e-progress-resize-gripper {
            display: none !important;
        }
        .e-gantt-chart .e-prevent-add-relation-left .e-left-connectorpoint-outer-div {
            display: none !important;
        }
        .e-gantt-chart .e-prevent-add-relation-right .e-right-connectorpoint-outer-div {
            display: none !important;
        }
    </style>
</head>

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

</html>

Customize taskbar templates

Taskbar templates allow full replacement of the default taskbar UI, enabling custom designs such as progress bars, badges, or icons. You can customize task rendering using the taskbarTemplate property for child tasks. You can also use parentTaskbarTemplate for parent tasks and milestoneTemplate for milestones. The taskbarTemplate function receives a props object that contains task-specific details and computed ganttProperties, such as the taskbar width and progress value. These properties can be used to dynamically calculate dimensions and control the visual presentation of the taskbar. For advanced conditional styling or logic, the queryTaskbarInfo event can be used.

This example renders a custom taskbar with a progress bar and a badge showing the task’s progress percentage. The progress bar width is calculated from the taskbar width and progress value in props.ganttProperties, ensuring each taskbar displays accurate progress at runtime.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '430px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    labelSettings: {
        leftLabel: 'TaskName'
    },
    projectStartDate: new Date('03/28/2019'),
    projectEndDate: new Date('04/18/2019'),
    taskbarTemplate: (props: any) => {
        let width: number = props.ganttProperties.width;
        let progress: number = props.ganttProperties.progress || 0;
        let progressWidth: number = (progress * width) / 100;

        return `
            <div class="e-gantt-child-taskbar-inner-div e-gantt-child-taskbar"
                style="height:22px;margin-top:-1px;width:${width}px">
                <div class="e-gantt-child-progressbar-inner-div e-gantt-child-progressbar"
                    style="height:100%;width:${progressWidth}px"></div>
                <span class="e-badge e-badge-secondary e-badge-notification e-badge-overlap">%</span>
            </div>`;
    }
});

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>
<div id='loader'>Loading....</div>
<div id='container'>
   <div id='Gantt'></div>
</div>
</body>

</html>

Enable multi-taskbar support

In project view, multi-taskbar support, enabled by enableMultiTaskbar, renders parent taskbars summarizing child progress when collapsed, providing aggregated visualization.

The following example enables multi-taskbar:

import { GanttData } from './datasource.ts';
import { Gantt, Edit, Selection} from '@syncfusion/ej2-gantt';

Gantt.Inject(Edit, Selection);

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID',
        expandState: 'isExpand'
    },
    enableMultiTaskbar: true
});
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>

This feature aggregates child progress in parent taskbars, updating dynamically on child changes.

Customize connector lines

Connector lines for dependencies are styled using connectorLineWidth for thickness and connectorLineBackground for color, enhancing dependency visibility.

The following example demonstrates connector customization. The specified properties are applied globally to all connectors, while the queryTaskbarInfo event supports per-dependency customization through the args.connectorLineBackground property.

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        dependency: 'Predecessor',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    connectorLineBackground: "red",
    connectorLineWidth: 3
});
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>

Configure tooltips

Tooltips for taskbars, connectors, baselines, and event markers are enabled by default via tooltipSettings.showTooltip, set to true. Disable for specific elements or customize content with templates.

The following example enables tooltips:

import { Gantt, DayMarkers } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
Gantt.Inject(DayMarkers);

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        baselineStartDate: "BaselineStartDate",
        baselineEndDate: "BaselineEndDate",
        progress: 'Progress',
        dependency: 'Predecessor',
        parentID: 'ParentID'
    },
    eventMarkers: [
        {
            day: '04/10/2019',
            label: 'Project approval and kick-off'
        }
    ],
    renderBaseline: true,
    baselineColor: 'red',
    tooltipSettings: {
        showTooltip: true
    }
});
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>

Tooltips display on hover, with touch-and-hold support for mobile via the tooltip popup.

Disable taskbar tooltip

You can disable the taskbar tooltip using the beforeTooltipRender event by setting args.cancel to true.

import { Gantt } from '@syncfusion/ej2-gantt';
import { data } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: data,
    height: '430px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        dependency: 'Predecessor',
        parentID: 'ParentID',
        baselineStartDate: 'BaselineStartDate',
        baselineEndDate: 'BaselineEndDate'
    },
    tooltipSettings: {
        showTooltip: true
    },
    beforeTooltipRender: (args: any) => {
        if (
            args.args.target.classList.contains('e-gantt-child-taskbar') ||
            args.args.target.classList.contains('e-gantt-parent-taskbar') ||
            args.args.target.classList.contains('e-taskbar-left-resizer') ||
            args.args.target.classList.contains('e-taskbar-right-resizer')
        ) {
            args.cancel = true;
        }
    }
});

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>

Customize tooltip templates

You can customize the following tooltip types in the Gantt chart using the tooltipSettings configuration:

Taskbar tooltip

Taskbar tooltips are customized using tooltipSettings.taskbar template, accessing task data for formatted content.

The following example customizes taskbar tooltips:

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    tooltipSettings: {
        showTooltip: true,
        taskbar: '#taskbarTooltip'
    }
});
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>
    <script type="text/x-jsrender" id="taskbarTooltip">
	    <div>TaskID: ${TaskID}</div>
    </script>
   <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

The template uses data to display fields like TaskName and Progress, ensuring responsive display.

Connector line tooltip

Connector tooltips, customized via tooltipSettings.connectorLine, show dependency details like type and offset.

The following example customizes connector tooltips:

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        dependency: 'Predecessor',
        parentID: 'ParentID'
    },
    tooltipSettings: {
        showTooltip: true,
        connectorLine: '#dependencyLineTooltip'
    }
});
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>
    <script type="text/x-jsrender" id="dependencyLineTooltip">
        <div>Offset : ${offsetString}</div>
    </script>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>
    </div>
</body>

</html>

Baseline tooltip

A baseline tooltip can be customized using the tooltipSettings.baseline property.

The following example customizes baseline tooltips:

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';
let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        baselineStartDate: "BaselineStartDate",
        baselineEndDate: "BaselineEndDate",
        progress: 'Progress',
        parentID: 'ParentID'
    },
    tooltipSettings: {
        showTooltip: true,
        baseline: '#baselineTooltip'
    },
    renderBaseline: true,
    baselineColor: 'red'
});
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>
   
    <script type="text/x-jsrender" id="baselineTooltip">
        <div>Baseline StartDate : ${this.getFormatedDate(BaselineStartDate)}</div>
    </script>
    
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Timeline tooltip

Timeline tooltips, customized with tooltipSettings.timeline, display date details.

The following example customizes timeline tooltips:

import { Gantt } from '@syncfusion/ej2-gantt';
import { GanttData } from './datasource.ts';

function getTooltipData(startDate: Date, endDate: Date, tier: string) {
    const gantt: any = (document.getElementsByClassName('e-gantt')[0] as any).ej2_instances[0];
    let activeTasks: any;
    if (tier === 'topTier') {
        activeTasks = gantt.currentViewData.filter(function (task: any) {
            const taskStart = new Date(task.StartDate);
            const taskEnd = new Date(task.EndDate);
            taskStart.setHours(0, 0, 0, 0);
            taskEnd.setHours(0, 0, 0, 0);
            return taskStart >= startDate && taskEnd <= endDate;
        });
    }
    else {
        activeTasks = gantt.currentViewData.filter(function (task: any) {
            const taskStart = new Date(task.StartDate);
            const taskEnd = new Date(task.EndDate);
            taskStart.setHours(0, 0, 0, 0);
            taskEnd.setHours(0, 0, 0, 0);
            return taskStart.getTime() === startDate.getTime() && taskEnd.getTime() === endDate.getTime();
        });
    }
    const milestones = activeTasks.filter(function (task: any) {
        return task.Duration === 0;
    });
    const totalProgress = activeTasks.reduce(function (acc: number, task: any) {
        return acc + (task.Progress ? task.Progress : 0);
    }, 0);
    const overallProgress = (activeTasks.length > 0) ? (totalProgress / activeTasks.length).toFixed(2) : 0;
    return {
        activeTasks: activeTasks.length,
        milestones: milestones.length,
        overallProgress: overallProgress
    };
}
(<{ topTierTooltip?: Function }>window).topTierTooltip = (value: string, date: string, tier: string) => {
    const gantt: any = (document.getElementsByClassName('e-gantt')[0] as any).ej2_instances[0];
    let endDate: Date;
    const startdate: Date = new Date(date);
        endDate = new Date(startdate.getTime());
        endDate.setDate(startdate.getDate() + 6);
    
    const data = getTooltipData(startdate, endDate, tier);
    return generateTooltipMarkup(value, data);
}
function generateTooltipMarkup(label: string, tooltipData: any) {
    const themeIsDark : boolean = document.body.classList.contains('tailwind3-dark') ||
    document.body.classList.contains('fluent2-dark') ||
    document.body.classList.contains('material3-dark') ||
    document.body.classList.contains('bootstrap5.3-dark') ||
    document.body.classList.contains('fluent2-highcontrast') ||
    document.body.classList.contains('highcontrast') ||
    document.body.classList.contains('fluent2-dark');

    var borderColor : string = themeIsDark ?  'black' : 'white';
    return (
        '<div style="padding: 5px;">' +
        '<div style="padding-bottom: 9px; text-align: center;border-bottom: 2px solid ' + borderColor + ';">' +
        '<span style="font-weight: bold; font-size: 14px;">' + label + '</span>' +
        '</div>' +
        '<div style="display: flex; padding-bottom: 5px;padding-top: 9px"">' +
        '<span style="font-weight: bold;">Active Tasks:</span>' +
        '<span style="padding-left: 2px;">' + tooltipData.activeTasks + '</span>' +
        '</div>' +
        '<div style="display: flex; padding-bottom: 5px;">' +
        '<span style="font-weight: bold;">Milestones:</span>' +
        '<span style="padding-left: 2px;">' + tooltipData.milestones + '</span>' +
        '</div>' +
        '<div style="display: flex; padding-bottom: 5px;">' +
        '<span style="font-weight: bold;">Overall Progress:</span>' +
        '<span style="padding-left: 2px;">' + tooltipData.overallProgress + '</span>' +
        '</div>' +
        '</div>'
    );
}
(<{ bottomTierTooltip?: Function }>window).bottomTierTooltip = (date: string, tier: string) => {
    const gantt: any = (document.getElementsByClassName('e-gantt')[0] as any).ej2_instances[0];
    const startdate: Date = new Date(date);
    let endDate: Date;
        endDate = new Date(startdate.getTime());
    
    const data = getTooltipData(startdate, endDate, tier);
    return generateTooltipMarkup(date, data);
}


let gantt: Gantt = new Gantt({
    dataSource: GanttData,
    height: '450px',
    taskFields: {
        id: 'TaskID',
        name: 'TaskName',
        startDate: 'StartDate',
        duration: 'Duration',
        progress: 'Progress',
        parentID: 'ParentID'
    },
    tooltipSettings: {
        showTooltip: true,
        timeline: '#timelinetemplateTooltip'
    }
});
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>
    <script type="text/x-jsrender" id="timelinetemplateTooltip">
        ${if(tier == 'topTier')}  
            <div>${topTierTooltip(value, date, tier)}</div>   
        ${/if}
        ${if(tier == 'bottomTier')} 
            <div>${bottomTierTooltip(date, tier)}</div>  
        ${/if}
    </script>
    
   <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='Gantt'></div>        
    </div>
</body>

</html>

Tooltip Touch interaction

To perform touch and hold action on a element, refer to tooltip popup.

See also