Skip to main content

GanttChart

TkGanttChart is a display-only Gantt chart component with expandable tasks, configurable view types (weekly, monthly, quarterly, yearly), two-layer headers, indicators, weekend/holiday highlighting, and customisable tooltips / task bars.

import { TkGanttChart } from '@takeoff-ui/react'

Playground

Preview

Generated Code

<TkGanttChart
tasks={[{"id":"1","name":"Research","startDate":"2026-04-01","endDate":"2026-04-10","progress":100},{"id":"2","name":"Design","startDate":"2026-04-08","endDate":"2026-04-18","progress":75},{"id":"3","name":"Development","startDate":"2026-04-15","endDate":"2026-05-05","progress":40},{"id":"4","name":"Testing","startDate":"2026-05-01","endDate":"2026-05-12","progress":0},{"id":"5","name":"Deployment","startDate":"2026-05-10","endDate":"2026-05-15","progress":0}]}
secondaryHeaderMode="days"
weekStartDay="1"
rowHeight="40"
panelWidth="320"
highlightWeekends
showTodayIndicator
/>
<TkGanttChart
:tasks="[{"id":"1","name":"Research","startDate":"2026-04-01","endDate":"2026-04-10","progress":100},{"id":"2","name":"Design","startDate":"2026-04-08","endDate":"2026-04-18","progress":75},{"id":"3","name":"Development","startDate":"2026-04-15","endDate":"2026-05-05","progress":40},{"id":"4","name":"Testing","startDate":"2026-05-01","endDate":"2026-05-12","progress":0},{"id":"5","name":"Deployment","startDate":"2026-05-10","endDate":"2026-05-15","progress":0}]"
secondaryHeaderMode="days"
weekStartDay="1"
rowHeight="40"
panelWidth="320"
:highlightWeekends.prop="true"
:showTodayIndicator.prop="true"
/>
<tk-gantt-chart
[tasks]="[{"id":"1","name":"Research","startDate":"2026-04-01","endDate":"2026-04-10","progress":100},{"id":"2","name":"Design","startDate":"2026-04-08","endDate":"2026-04-18","progress":75},{"id":"3","name":"Development","startDate":"2026-04-15","endDate":"2026-05-05","progress":40},{"id":"4","name":"Testing","startDate":"2026-05-01","endDate":"2026-05-12","progress":0},{"id":"5","name":"Deployment","startDate":"2026-05-10","endDate":"2026-05-15","progress":0}]"
secondaryHeaderMode="days"
weekStartDay="1"
rowHeight="40"
panelWidth="320"
[highlightWeekends]="true"
[showTodayIndicator]="true"
/>

Controls

Basic

A basic Gantt chart with simple tasks showing name, start/end dates, and progress.

View Code
const tasks = [
{ id: '1', name: 'Research', startDate: '2026-04-01', endDate: '2026-04-10', progress: 100 },
{ id: '2', name: 'Design', startDate: '2026-04-08', endDate: '2026-04-18', progress: 75 },
{ id: '3', name: 'Development', startDate: '2026-04-15', endDate: '2026-05-05', progress: 40 },
{ id: '4', name: 'Testing', startDate: '2026-05-01', endDate: '2026-05-12', progress: 0 },
{ id: '5', name: 'Deployment', startDate: '2026-05-10', endDate: '2026-05-15', progress: 0 },
];

<TkGanttChart tasks={tasks} />

View Type

The viewType prop controls the timeline zoom level. Available options are weekly, monthly, quarterly, and yearly. When not set, the component auto-fits based on the task date range.

View Code
const [viewType, setViewType] = useState('monthly');

const tasks = [
{ id: '1', name: 'Sprint Planning', startDate: '2026-04-01', endDate: '2026-04-03', progress: 100 },
{ id: '2', name: 'Development', startDate: '2026-04-04', endDate: '2026-05-15', progress: 60 },
{ id: '3', name: 'QA Testing', startDate: '2026-05-10', endDate: '2026-06-10', progress: 20 },
{ id: '4', name: 'Release', startDate: '2026-06-01', endDate: '2026-07-01', progress: 0 },
];

<TkGanttChart tasks={tasks} viewType="weekly" />
<TkGanttChart tasks={tasks} viewType="monthly" />
<TkGanttChart tasks={tasks} viewType="quarterly" />
<TkGanttChart tasks={tasks} viewType="yearly" />

Nested Tasks

Tasks can have nested children to create expandable sub-task hierarchies. Click the expand button to toggle child task visibility.

View Code
const tasks = [
{
id: '1',
name: 'Backend',
startDate: '2026-04-01',
endDate: '2026-05-10',
progress: 60,
children: [
{ id: '1-1', name: 'API Design', startDate: '2026-04-01', endDate: '2026-04-10', progress: 100 },
{ id: '1-2', name: 'Database Schema', startDate: '2026-04-08', endDate: '2026-04-18', progress: 80 },
{ id: '1-3', name: 'Implementation', startDate: '2026-04-15', endDate: '2026-05-10', progress: 30 },
],
},
{
id: '2',
name: 'Frontend',
startDate: '2026-04-10',
endDate: '2026-05-15',
progress: 40,
children: [
{ id: '2-1', name: 'Wireframes', startDate: '2026-04-10', endDate: '2026-04-18', progress: 100 },
{ id: '2-2', name: 'UI Development', startDate: '2026-04-18', endDate: '2026-05-08', progress: 50 },
{ id: '2-3', name: 'Integration', startDate: '2026-05-05', endDate: '2026-05-15', progress: 0 },
],
},
{ id: '3', name: 'Deployment', startDate: '2026-05-12', endDate: '2026-05-20', progress: 0 },
];

<TkGanttChart tasks={tasks} />

Segments

A task can display multiple time segments on the same row using the segments property. Each segment has its own startDate, endDate, label, and progress.

View Code
const tasks = [
{
id: '1',
name: 'Design Phase',
startDate: '2026-04-01',
endDate: '2026-04-30',
segments: [
{ startDate: '2026-04-01', endDate: '2026-04-10', label: 'Research', progress: 100 },
{ startDate: '2026-04-15', endDate: '2026-04-25', label: 'Prototyping', progress: 60 },
],
},
{
id: '2',
name: 'Development',
startDate: '2026-04-10',
endDate: '2026-05-20',
segments: [
{ startDate: '2026-04-10', endDate: '2026-04-22', label: 'Sprint 1', progress: 100 },
{ startDate: '2026-04-25', endDate: '2026-05-08', label: 'Sprint 2', progress: 40 },
{ startDate: '2026-05-10', endDate: '2026-05-20', label: 'Sprint 3', progress: 0 },
],
},
{ id: '3', name: 'Release', startDate: '2026-05-18', endDate: '2026-05-25', progress: 0 },
];

<TkGanttChart tasks={tasks} />

Indicators

Use the indicators prop to render vertical lines on the timeline for important dates like milestones or deadlines. The showTodayIndicator prop automatically adds a today marker.

View Code
const tasks = [
{ id: '1', name: 'Research', startDate: '2026-04-01', endDate: '2026-04-12', progress: 100 },
{ id: '2', name: 'Design', startDate: '2026-04-10', endDate: '2026-04-22', progress: 50 },
{ id: '3', name: 'Development', startDate: '2026-04-20', endDate: '2026-05-10', progress: 20 },
];

const indicators = [
{ date: '2026-04-07', label: 'Kickoff', color: '#2563eb', lineStyle: 'solid' },
{ date: '2026-04-25', label: 'Milestone', color: '#f59e0b', lineStyle: 'dashed' },
{ date: '2026-05-05', label: 'Deadline', color: '#ef4444', lineStyle: 'solid' },
];

<TkGanttChart tasks={tasks} indicators={indicators} showTodayIndicator={true} />

Holidays

The holidays prop highlights specific dates on the timeline. Combined with highlightWeekends, non-working days are visually distinguished.

View Code
const tasks = [
{ id: '1', name: 'Sprint 1', startDate: '2026-04-01', endDate: '2026-04-15', progress: 80 },
{ id: '2', name: 'Sprint 2', startDate: '2026-04-16', endDate: '2026-04-30', progress: 30 },
];

const holidays = [
{ date: '2026-04-10', label: 'Company Holiday' },
{ date: '2026-04-23', label: 'National Holiday' },
];

<TkGanttChart tasks={tasks} holidays={holidays} highlightWeekends={true} />

Columns

Customise the left-side panel columns using the columns prop. Each column definition includes field, header, optional width, and an optional html render function.

View Code
const tasks = [
{ id: '1', name: 'Task A', startDate: '2026-04-01', endDate: '2026-04-14', progress: 100 },
{ id: '2', name: 'Task B', startDate: '2026-04-10', endDate: '2026-04-25', progress: 50 },
{ id: '3', name: 'Task C', startDate: '2026-04-20', endDate: '2026-05-05', progress: 20 },
];

const columns = [
{ field: 'name', header: 'Task', width: '160px' },
{ field: 'startDate', header: 'Start', width: '100px' },
{ field: 'endDate', header: 'End', width: '100px' },
{
field: 'progress',
header: 'Progress',
width: '80px',
html: (task) => `<strong>${task.progress ?? 0}%</strong>`,
},
];

<TkGanttChart tasks={tasks} columns={columns} panelWidth={440} />

Hide Panel

Set hidePanel to true to hide the left-side task list panel and show only the timeline.

View Code
const tasks = [
{ id: '1', name: 'Research', startDate: '2026-04-01', endDate: '2026-04-10', progress: 100 },
{ id: '2', name: 'Design', startDate: '2026-04-08', endDate: '2026-04-18', progress: 75 },
{ id: '3', name: 'Development', startDate: '2026-04-15', endDate: '2026-05-05', progress: 40 },
];

<TkGanttChart tasks={tasks} hidePanel={true} />

Highlight Weekends

The highlightWeekends prop visually distinguishes weekends on the timeline. It is set to true by default. This demo shows how it looks when it is set to false.

View Code
const tasks = [
{ id: '1', name: 'Task A', startDate: '2026-04-01', endDate: '2026-04-14', progress: 100 },
{ id: '2', name: 'Task B', startDate: '2026-04-10', endDate: '2026-04-25', progress: 50 },
{ id: '3', name: 'Task C', startDate: '2026-04-20', endDate: '2026-05-05', progress: 20 },
];

<TkGanttChart tasks={tasks} highlightWeekends={false} />

Custom Task Bar

The taskBarHtml prop allows you to fully customize the content and style of each task bar.

View Code
const tasks = [
{ id: '1', name: 'Research', startDate: '2026-04-01', endDate: '2026-04-10', progress: 100 },
{ id: '2', name: 'Design', startDate: '2026-04-08', endDate: '2026-04-18', progress: 75 },
{ id: '3', name: 'Development', startDate: '2026-04-15', endDate: '2026-05-05', progress: 40 },
];

const taskBarHtml = (task) => {
const p = task.progress ?? 0;
const bg = `linear-gradient(to right, #4caf50 ${p}%, #83d397${p}%)`;
return `<div style="display:flex;align-items:center;gap:4px;border-radius:4px;padding:0 8px;background:${bg};">
<tk-icon icon="rocket" color="#fff" size="small"></tk-icon>
<span style="font-weight:bold;color:#fff;">${task.name}</span>
</div>`;
};

<TkGanttChart tasks={tasks} taskBarHtml={taskBarHtml} />

Custom Tooltip

With the tooltipHtml prop, you can pass custom HTML for tooltips when hovering over tasks.

View Code
const tasks = [
{ id: '1', name: 'Research', startDate: '2026-04-01', endDate: '2026-04-10', progress: 100, customDetail: 'Market analysis' },
{ id: '2', name: 'Design', startDate: '2026-04-08', endDate: '2026-04-18', progress: 75, customDetail: 'UI/UX mockups' },
{ id: '3', name: 'Development', startDate: '2026-04-15', endDate: '2026-05-05', progress: 40, customDetail: 'Frontend & Backend' },
];

const tooltipHtml = (task) =>
`<div style="padding: 4px; display: flex; flex-direction: column; gap: 6px; min-width: 180px;">
<div style="display: flex; align-items: center; gap: 6px; border-bottom: 1px solid var(--tk-color-border-subtle); padding-bottom: 6px;">
<tk-icon name="calendar" style="color: #f9fafc"></tk-icon>
<span style="font-weight: bold; font-size: 14px;">${task.name}</span>
</div>
<div style="font-size: 12px; display: flex; flex-direction: column; gap: 4px;">
<div style="display: flex; justify-content: space-between;">
<span style="color: var(--tk-color-text-subtlest);">Timeline:</span>
<span>${task.startDate} / ${task.endDate}</span>
</div>
<div style="display: flex; justify-content: space-between;">
<span style="color: var(--tk-color-text-subtlest);">Deliverable:</span>
<strong>${task.customDetail}</strong>
</div>
</div>
<div style="margin-top: 4px;">
<div style="display: flex; justify-content: space-between; font-size: 11px; margin-bottom: 4px;">
<span style="color: var(--tk-color-text-subtlest);">Progress</span>
<strong>${task.progress}%</strong>
</div>
<div style="background: var(--tk-color-border-subtle); border-radius: 4px; height: 6px; width: 100%; overflow: hidden;">
<div style="background: var(--tk-color-primary); width: ${task.progress}%; height: 100%;"></div>
</div>
</div>
</div>`;

<TkGanttChart tasks={tasks} tooltipHtml={tooltipHtml} />

Locale

The locale prop allows you to localize the Gantt chart content, such as months and days. In this example, it's set to "tr-TR" with Turkish task data.

View Code
const tasks = [
{ id: '1', name: 'Araştırma', startDate: '2026-04-01', endDate: '2026-04-10', progress: 100 },
{ id: '2', name: 'Tasarım', startDate: '2026-04-08', endDate: '2026-04-18', progress: 75 },
{ id: '3', name: 'Geliştirme', startDate: '2026-04-15', endDate: '2026-05-05', progress: 40 },
];

<TkGanttChart tasks={tasks} locale="tr-TR" />

Sizing & Layout

You can customize the structural dimensions of the Gantt chart using the rowHeight and panelWidth props.

View Code
const tasks = [
{ id: '1', name: 'Phase 1 - Project Scoping', startDate: '2026-04-01', endDate: '2026-04-10', progress: 100 },
{ id: '2', name: 'Phase 2 - Design Concepts', startDate: '2026-04-05', endDate: '2026-04-20', progress: 60 },
{ id: '3', name: 'Phase 3 - Prototyping and Testing', startDate: '2026-04-15', endDate: '2026-04-30', progress: 10 },
];

<TkGanttChart
tasks={tasks}
rowHeight={64}
panelWidth={400}
/>

Week Start Day

By default, the Gantt chart starts the week on Monday (1). You can change this using the weekStartDay prop. This demo shows the effect of setting it to Sunday (0).

View Code
const tasks = [
{ id: '1', name: 'Task Alpha', startDate: '2026-04-05', endDate: '2026-04-19', progress: 40 },
{ id: '2', name: 'Task Beta', startDate: '2026-04-10', endDate: '2026-04-25', progress: 15 },
];

<TkGanttChart
tasks={tasks}
viewType="weekly"
weekStartDay={0}
/>

Secondary Header Mode

The secondaryHeaderMode prop configures the display format of the sub-header. In this example, the timeline is set to monthly with the secondary header showing weeks.

View Code
const tasks = [
{ id: '1', name: 'Phase 1', startDate: '2026-04-01', endDate: '2026-04-30', progress: 80 },
{ id: '2', name: 'Phase 2', startDate: '2026-05-01', endDate: '2026-05-31', progress: 10 },
];

<TkGanttChart
tasks={tasks}
viewType="monthly"
secondaryHeaderMode="weeks"
/>

API

Props

NameTypeDefaultDescription
IGanttColumn[]DEFAULT_COLUMNSColumn definitions for the left-side task list panel. Columns are fed from the task data.
CSSStylePropertiesnullCustom CSS style applied to the root container element.
booleanfalseWhether to hide the left-side task list panel.
booleantrueWhether to highlight weekend columns with a different background.
IGanttHoliday[][]Array of holiday dates to highlight on the timeline.
IGanttIndicator[][]Array of indicator lines rendered on the timeline (e.g. today, startDate, freezeDate).
string'default'Locale string for date formatting (e.g. 'tr-TR', 'en-US'). Uses native toLocaleString under the hood.
numberDEFAULT_PANEL_WIDTHWidth of the left-side task list panel in pixels.
numberDEFAULT_ROW_HEIGHTRow height in pixels.
"days", "weeks"'days'Secondary header display mode. - 'days' shows individual day numbers or day names - 'weeks' shows week numbers (W1, W2 … / H1, H2 … for Turkish locale)
booleantrueWhether to automatically show a today indicator line.
(task: IGanttTask)=>string, HTMLElementnullCustom task bar render function. Receives the task and should return an HTMLElement or an HTML string.
IGanttTask[][]Array of tasks to display. Each task may contain nested children for sub-tasks.
(task: IGanttTask)=>string, HTMLElementnullCustom tooltip render function. Receives the hovered task and should return an HTMLElement or an HTML string.
"monthly", "quarterly", "weekly", "yearly"nullTimeline view type. When not set the component auto-fits based on the task date range.
0, 1, 2, 3, 4, 5, 6DEFAULT_WEEK_START_DAYDay the week starts on (0 = Sunday … 6 = Saturday).

Events

NameDescription
tk-task-clickEmitted when a task bar is clicked. Detail contains the clicked task.
tk-task-toggleEmitted when a task row is expanded or collapsed.

Slots

NameDescription
emptyContent to show when there are no tasks

Interfaces

IGanttTask

Represents a single task in the Gantt chart.

interface IGanttTask {
/** Unique identifier for the task */
id: string;
/** Display name of the task */
name: string;
/** Start date of the task (ISO string or Date-parseable string) */
startDate: string;
/** End date of the task (ISO string or Date-parseable string) */
endDate: string;
/** Progress percentage (0–100) */
progress?: number;
/** Nested child tasks */
children?: IGanttTask[];
/** Custom inline styles for the task bar */
style?: CSSStyleProperties;
/** Arbitrary additional data attached to the task */
additionalData?: unknown;
/**
* Multiple time segments rendered on the same row.
* When provided, the task's own startDate/endDate are used only for
* positioning reference; actual bars are drawn per segment.
*/
segments?: IGanttTaskSegment[];
}

IGanttColumn

Column definition for the left-side task-list panel.

interface IGanttColumn {
/** Property key on IGanttTask (or nested path) to read data from */
field: string;
/** Column header label */
header: string;
/** Fixed width (CSS value, e.g. '120px') */
width?: string;
/** Custom HTML render function – receives the task, returns HTML string */
html?: (task: IGanttTask) => string;
}

IGanttIndicator

An indicator line drawn on the timeline (e.g. today, freeze-date).

interface IGanttIndicator {
/** Date of the indicator (ISO string or Date-parseable string) */
date: string;
/** Label shown above the indicator line */
label?: string;
/** CSS colour for the indicator line */
color?: string;
/** Line style */
lineStyle?: 'solid' | 'dashed';
}

IGanttHoliday

Holiday entry used to highlight non-working days.

interface IGanttHoliday {
/** Date of the holiday (ISO string or Date-parseable string) */
date: string;
/** Optional display label */
label?: string;
}