Configuration
Columns
The sheet (left panel) displays task data in columns. Columns can be shown, hidden, reordered, and resized.
Default Columns
| name | Task name (editable, shows tree hierarchy). |
| icons | Type, resource, and warning icons (read-only). |
| length | Duration (editable, e.g. '5d', '8h'). |
| start | Start date (editable). |
| end | End date (editable). |
| progress | Progress percentage (editable). |
| resources | Assigned resources (editable). |
| work | Work effort (editable). |
| cost | Cost (editable). |
// Access a column
const col = gantt.sheet.getColumnByCode('name');
// Hide / remove columns
gantt.sheet.hideColumn('icons');
gantt.sheet.removeColumn('cost');
// Save and restore column layout (order, widths, visibility)
const state = gantt.saveColumns();
localStorage.setItem('columns', JSON.stringify(state));
// Later...
const saved = JSON.parse(localStorage.getItem('columns'));
gantt.loadColumns(saved);Custom Columns
Add columns that display and edit custom properties on tasks. Three convenience methods cover common data types:
// String column (plain text editor)
gantt.sheet.addCustomStringColumn('department', 'Department');
// Integer column (number editor, integer only)
gantt.sheet.addCustomIntegerColumn('storyPoints', 'Story Points');
// Decimal column (number editor, decimals allowed)
gantt.sheet.addCustomDecimalColumn('estimatedHours', 'Est. Hours');
// Date column (locale-aware date editor)
gantt.sheet.addCustomDateColumn('deadline', 'Deadline');Each custom column automatically reads from and writes to the task's custom property matching the column code. Values are editable inline.
Fully Custom Column
For full control over rendering and editing, create a TableColumn directly with a custom renderer and editor:
import { TableColumn, DefaultTableCellRenderer, TextCellEditor } from '@timelinekit/core';
const column = new TableColumn(
'status', // code
'Status', // display name
(task) => task.getPropertyValue('status') ?? '', // valueFormatter
new DefaultTableCellRenderer(), // renderer
new TextCellEditor( // editor
(task) => task.getPropertyValue('status'), // getter
(task, value) => task.setPropertyValue('status', value) // setter
),
(task) => task.type !== 'summary', // isEditable
120, // width
60 // minWidth
);
gantt.sheet.addColumn(column);Custom Date Picker
The default date editor uses a plain text input with locale-aware formatting. To replace it with a calendar picker, subscribe to the sheetCellInputEdit$ event and transform the input element when a date column enters edit mode:
// Use browser's native date picker for Start / End columns
gantt.events.sheetCellInputEdit$.subscribe((args) => {
if (args.columnCode === 'start' || args.columnCode === 'end') {
const input = args.input as HTMLInputElement;
const currentDate = args.columnCode === 'start'
? args.item.startTime : args.item.endTime;
input.type = 'date';
if (currentDate) {
input.value = currentDate.toISOString().slice(0, 10);
}
input.addEventListener('change', () => {
const parsed = new Date(input.value + 'T00:00:00');
if (!isNaN(parsed.getTime())) {
args.editor.endEdit(parsed, 'none');
}
});
input.showPicker();
}
});The same pattern works for third-party date picker libraries (e.g. Flatpickr, Pikaday) — instead of changing input.type, attach the library to the input element and call args.editor.endEdit(date, 'none') when the user selects a date.
Time Scale & Zoom
The timeline supports multiple zoom levels from minutes to years. The time axis unit determines the grid granularity.
Time Axis Units
| minute | Minute-level granularity. |
| hour | Hourly grid. |
| day | Daily grid (common default). |
| week | Weekly grid. |
| month | Monthly grid. |
| quarter | Quarterly grid. |
| half | Half-year grid. |
| year | Yearly grid. |
// Auto zoom to fit is enabled by default — the chart automatically
// adjusts the zoom level when projectTimeline or data changes via load().
// Disable if you want to control the zoom level manually:
gantt.autoZoomToFit = false;
// Zoom in / out
gantt.zoomIn();
gantt.zoomOut();
// Fit all tasks in view
gantt.zoomToFit();
// Fit specific tasks
gantt.zoomToFit([task1, task2]);
// Scroll to a date
gantt.scrollToDate(new Date('2027-03-01'));
// Scroll to a task (horizontal + vertical)
gantt.scrollToTask(task);
// Jump to project start
gantt.goToProjectStart();
// Set project timeline bounds
gantt.projectTimeline = new DateRange(new Date('2027-01-01'), new Date('2027-12-31'));Working Calendar
The working calendar defines which days and hours are work time. It affects task duration calculations, scheduling, and non-working time visualization.
import { WorkingCalendar, WorkingShift, TimeOfDay } from '@timelinekit/core';
const calendar = new WorkingCalendar();
// Working days (default: Mon–Fri)
calendar.workingDays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'];
// Start of week (default: 'sunday')
calendar.startOfWeek = 'monday';
// Work shifts (e.g. 9:00–12:00, 13:00–17:00)
calendar.shifts = [
new WorkingShift(new TimeOfDay(9, 0), new TimeOfDay(12, 0)),
new WorkingShift(new TimeOfDay(13, 0), new TimeOfDay(17, 0)),
];
// National holidays
calendar.nationalHolidays = [
new Date('2027-01-01'),
new Date('2027-12-25'),
];
// Apply to the chart
gantt.workingCalendar = calendar;Calendar Properties
| workingDays: DayOfWeek[] | Days of the week that are working days. Default: Mon–Fri. |
| shifts: WorkingShift[] | Working time ranges within each day. Default: 8:00–12:00, 13:00–17:00. |
| startOfWeek: DayOfWeek | First day of the week for calendar display. Default: 'sunday'. |
| nationalHolidays: Date[] | Dates that are non-working regardless of the day of the week. |
| defaultLengthUnit: LengthUnit | Default unit for new task durations. Default: 'day'. |
Calendar Utilities
| calendar.isWorkingDay(date) | Returns true if the date is a working day. |
| calendar.getHoursPerDay() | Total working hours per day (from shifts). |
| calendar.getHoursBetween(date1, date2) | Working hours between two dates. |
| calendar.addHours(date, hours) | Add working hours to a date, skipping non-work time. |
Task Labels
Display text labels on or next to task bars in the chart area. Labels can show the task name, assigned resources, progress, or a combination. Configure position and content separately for tasks, summaries, and milestones via the theme.
const theme = gantt.settings.theme;
// Show task name + progress inside task bars (or to the right if too narrow)
theme.chart.content.taskLabelPosition = 'insideOrRight';
theme.chart.content.taskLabelContent = 'nameAndProgress';
// Summary tasks: show name to the right
theme.chart.content.summaryLabelPosition = 'right';
theme.chart.content.summaryLabelContent = 'name';
// Milestones: show name to the right
theme.chart.content.milestoneLabelPosition = 'right';
theme.chart.content.milestoneLabelContent = 'name';
// Re-apply the theme to trigger a re-render
gantt.settings.theme = theme;Label Position
| 'none' | No label (default). |
| 'inside' | Inside the task bar (truncated if it doesn't fit). |
| 'right' | To the right of the task bar. |
| 'insideOrRight' | Inside if it fits, otherwise to the right. |
Label Content
| 'name' | Task name. |
| 'resource' | Assigned resource names. |
| 'progress' | Progress percentage (e.g. '75%'). |
| 'nameAndProgress' | Name and progress (e.g. 'Design 75%'). |
| 'nameAndResource' | Name and resource (e.g. 'Design — Alice'). |
For full label styling options (color, font, padding), see the Theming & Styles guide.
Markers & Today Line
Markers are vertical lines on the timeline highlighting important dates — deadlines, sprint boundaries, releases, etc.
// Show today line
gantt.showTodayLine = true;
// Add custom markers
gantt.addMarker({
date: new Date('2027-02-14'),
label: 'Release v1.0',
color: '#ef4444',
lineStyle: 'dashed',
});
gantt.addMarker({
date: new Date('2027-03-01'),
label: 'Sprint 3',
color: '#3b82f6',
lineStyle: 'solid',
lineWidth: 2,
});
// Remove a specific marker
gantt.removeMarker(marker);
// Clear all markers
gantt.clearMarkers();
// Get all markers
const markers = gantt.markers;