Installation and Setup
Source code
TypeScript ts
// src/components/gantt/GanttBasic.ts
import { defineCustomElements } from '@revolist/revogrid/loader';
defineCustomElements();
import { GanttPlugin, createDefaultTaskTableColumn } from '@revolist/revogrid-enterprise';
import { currentTheme } from '../composables/useRandomData';
import { calendars, dependencies, ganttConfig, tasks, taskTableColumnProps } from './gantt-basic-data';
import './gantt-basic.css';
const { isDark } = currentTheme();
const columns = taskTableColumnProps.map((prop) => createDefaultTaskTableColumn(prop));
export function load(parentSelector: string) {
const parent = document.querySelector(parentSelector);
if (!parent) {
return () => {};
}
const root = document.createElement('section');
const grid = document.createElement('revo-grid');
root.className = 'gantt-basic-demo';
grid.className = 'gantt-basic-grid';
grid.theme = isDark() ? 'darkCompact' : 'compact';
grid.hideAttribution = true;
grid.canMoveColumns = true;
grid.plugins = [GanttPlugin];
grid.gantt = ganttConfig;
grid.ganttCalendars = calendars;
grid.ganttDependencies = dependencies;
grid.columns = columns;
root.appendChild(grid);
parent.appendChild(root);
grid.source = tasks.map((task) => ({ ...task }));
return () => root.remove();
}
Data ts
import type {
CalendarEntity,
DependencyEntity,
GanttToolbarColumnOption,
GanttTaskSourceRow,
TaskTableColumnProp,
} from '@revolist/revogrid-enterprise';
export const PROJECT_ID = 'project-web-redesign';
export const CALENDAR_ID = 'cal-standard';
export const ganttConfig = {
id: PROJECT_ID,
name: 'Website Redesign',
version: '1',
currency: 'USD',
timeZone: 'UTC',
primaryCalendarId: CALENDAR_ID,
updatedAt: '2026-04-06T00:00:00Z',
zoomPreset: 'week' as const,
allowTaskCreate: true,
};
export const taskTableColumnProps: TaskTableColumnProp[] = [
'wbs',
'name',
'status',
];
const initiallyVisibleColumnProps = new Set<TaskTableColumnProp>(taskTableColumnProps);
const allToolbarColumns = [
{ prop: 'status', label: 'Status' },
{ prop: 'name', label: 'Task' },
{ prop: 'wbs', label: 'WBS' },
] satisfies Array<Omit<GanttToolbarColumnOption, 'visible'>>;
export const toolbarColumns: GanttToolbarColumnOption[] = [...allToolbarColumns]
.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))
.map((column) => ({
...column,
visible: initiallyVisibleColumnProps.has(column.prop as TaskTableColumnProp),
}));
export const calendars: CalendarEntity[] = [
{
id: CALENDAR_ID,
name: 'Standard',
timeZone: 'UTC',
workingDays: [1, 2, 3, 4, 5],
holidays: [],
hoursPerDay: 8,
},
];
export const tasks: GanttTaskSourceRow[] = [
{
id: 't1', parentId: null,
name: 'Discovery', type: 'summary',
status: 'done',
startDate: '2026-04-06', endDate: '2026-04-17', duration: 10,
percentDone: 100, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't2', parentId: 't1',
name: 'Stakeholder Interviews', type: 'task',
status: 'done',
startDate: '2026-04-06', endDate: '2026-04-08', duration: 3,
percentDone: 100, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't3', parentId: 't1',
name: 'Analytics Review', type: 'task',
status: 'done',
startDate: '2026-04-07', endDate: '2026-04-10', duration: 4,
percentDone: 100, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't4', parentId: 't1',
name: 'Content Inventory', type: 'task',
status: 'done',
startDate: '2026-04-09', endDate: '2026-04-14', duration: 4,
percentDone: 100, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't5', parentId: 't1',
name: 'Requirements Workshop', type: 'task',
status: 'done',
startDate: '2026-04-13', endDate: '2026-04-16', duration: 4,
percentDone: 100, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't6', parentId: 't1',
name: 'Discovery Sign-off', type: 'milestone',
status: 'done',
startDate: '2026-04-17', endDate: '2026-04-17', duration: 0,
percentDone: 100, calendarId: CALENDAR_ID, tags: ['milestone'],
},
{
id: 't7', parentId: null,
name: 'Design', type: 'summary',
status: 'in-progress',
startDate: '2026-04-20', endDate: '2026-05-08', duration: 15,
percentDone: 55, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't8', parentId: 't7',
name: 'Information Architecture', type: 'task',
status: 'done',
startDate: '2026-04-20', endDate: '2026-04-23', duration: 4,
percentDone: 100, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't9', parentId: 't7',
name: 'Wireframes', type: 'task',
status: 'done',
startDate: '2026-04-24', endDate: '2026-04-29', duration: 4,
percentDone: 100, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't10', parentId: 't7',
name: 'Design System Updates', type: 'task',
status: 'in-progress',
startDate: '2026-04-27', endDate: '2026-05-01', duration: 5,
percentDone: 70, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't11', parentId: 't7',
name: 'Visual Design', type: 'task',
status: 'in-progress',
startDate: '2026-04-30', endDate: '2026-05-07', duration: 6,
percentDone: 45, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't12', parentId: 't7',
name: 'Prototype Review', type: 'task',
status: 'not-started',
startDate: '2026-05-05', endDate: '2026-05-07', duration: 3,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't13', parentId: 't7',
name: 'Design Approval', type: 'milestone',
status: 'not-started',
startDate: '2026-05-08', endDate: '2026-05-08', duration: 0,
percentDone: 0, calendarId: CALENDAR_ID, tags: ['milestone'],
},
{
id: 't14', parentId: null,
name: 'Development', type: 'summary',
status: 'not-started',
startDate: '2026-05-11', endDate: '2026-06-05', duration: 20,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't15', parentId: 't14',
name: 'Frontend Shell', type: 'task',
status: 'not-started',
startDate: '2026-05-11', endDate: '2026-05-15', duration: 5,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't16', parentId: 't14',
name: 'CMS Integration', type: 'task',
status: 'not-started',
startDate: '2026-05-11', endDate: '2026-05-20', duration: 8,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't17', parentId: 't14',
name: 'Reusable Page Sections', type: 'task',
status: 'not-started',
startDate: '2026-05-18', endDate: '2026-05-27', duration: 8,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't18', parentId: 't14',
name: 'Search Experience', type: 'task',
status: 'not-started',
startDate: '2026-05-19', endDate: '2026-05-26', duration: 6,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't19', parentId: 't14',
name: 'Analytics Events', type: 'task',
status: 'not-started',
startDate: '2026-05-25', endDate: '2026-05-29', duration: 5,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't20', parentId: 't14',
name: 'Accessibility Pass', type: 'task',
status: 'not-started',
startDate: '2026-05-28', endDate: '2026-06-02', duration: 4,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't21', parentId: 't14',
name: 'Performance Tuning', type: 'task',
status: 'not-started',
startDate: '2026-06-01', endDate: '2026-06-04', duration: 4,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't22', parentId: 't14',
name: 'Feature Complete', type: 'milestone',
status: 'not-started',
startDate: '2026-06-05', endDate: '2026-06-05', duration: 0,
percentDone: 0, calendarId: CALENDAR_ID, tags: ['milestone'],
},
{
id: 't23', parentId: null,
name: 'QA and Release Prep', type: 'summary',
status: 'not-started',
startDate: '2026-06-08', endDate: '2026-06-18', duration: 9,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't24', parentId: 't23',
name: 'Test Plan', type: 'task',
status: 'not-started',
startDate: '2026-06-08', endDate: '2026-06-10', duration: 3,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't25', parentId: 't23',
name: 'Cross-browser QA', type: 'task',
status: 'not-started',
startDate: '2026-06-10', endDate: '2026-06-15', duration: 4,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't26', parentId: 't23',
name: 'Content QA', type: 'task',
status: 'not-started',
startDate: '2026-06-11', endDate: '2026-06-16', duration: 4,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't27', parentId: 't23',
name: 'Release Candidate', type: 'milestone',
status: 'not-started',
startDate: '2026-06-18', endDate: '2026-06-18', duration: 0,
percentDone: 0, calendarId: CALENDAR_ID, tags: ['milestone'],
},
{
id: 't28', parentId: null,
name: 'Launch', type: 'task',
status: 'not-started',
startDate: '2026-06-19', endDate: '2026-06-23', duration: 3,
percentDone: 0, calendarId: CALENDAR_ID, tags: [],
},
{
id: 't29', parentId: null,
name: 'Post-launch Review', type: 'milestone',
status: 'not-started',
startDate: '2026-06-26', endDate: '2026-06-26', duration: 0,
percentDone: 0, calendarId: CALENDAR_ID, tags: ['milestone'],
},
];
export const dependencies: DependencyEntity[] = [
{ id: 'd1', predecessorTaskId: 't2', successorTaskId: 't5', type: 'finish-to-start', lagDays: 0 },
{ id: 'd2', predecessorTaskId: 't3', successorTaskId: 't5', type: 'finish-to-start', lagDays: 0 },
{ id: 'd3', predecessorTaskId: 't4', successorTaskId: 't6', type: 'finish-to-start', lagDays: 0 },
{ id: 'd4', predecessorTaskId: 't5', successorTaskId: 't6', type: 'finish-to-start', lagDays: 0 },
{ id: 'd5', predecessorTaskId: 't6', successorTaskId: 't8', type: 'finish-to-start', lagDays: 1 },
{ id: 'd6', predecessorTaskId: 't8', successorTaskId: 't9', type: 'finish-to-start', lagDays: 0 },
{ id: 'd7', predecessorTaskId: 't9', successorTaskId: 't11', type: 'finish-to-start', lagDays: 0 },
{ id: 'd8', predecessorTaskId: 't10', successorTaskId: 't12', type: 'finish-to-start', lagDays: 0 },
{ id: 'd9', predecessorTaskId: 't11', successorTaskId: 't13', type: 'finish-to-start', lagDays: 0 },
{ id: 'd10', predecessorTaskId: 't12', successorTaskId: 't13', type: 'finish-to-start', lagDays: 0 },
{ id: 'd11', predecessorTaskId: 't13', successorTaskId: 't15', type: 'finish-to-start', lagDays: 1 },
{ id: 'd12', predecessorTaskId: 't15', successorTaskId: 't17', type: 'finish-to-start', lagDays: 0 },
{ id: 'd13', predecessorTaskId: 't16', successorTaskId: 't18', type: 'finish-to-start', lagDays: 0 },
{ id: 'd14', predecessorTaskId: 't17', successorTaskId: 't20', type: 'finish-to-start', lagDays: 0 },
{ id: 'd15', predecessorTaskId: 't18', successorTaskId: 't19', type: 'finish-to-start', lagDays: 0 },
{ id: 'd16', predecessorTaskId: 't19', successorTaskId: 't21', type: 'finish-to-start', lagDays: 0 },
{ id: 'd17', predecessorTaskId: 't20', successorTaskId: 't21', type: 'finish-to-start', lagDays: 0 },
{ id: 'd18', predecessorTaskId: 't21', successorTaskId: 't22', type: 'finish-to-start', lagDays: 0 },
{ id: 'd19', predecessorTaskId: 't22', successorTaskId: 't24', type: 'finish-to-start', lagDays: 1 },
{ id: 'd20', predecessorTaskId: 't24', successorTaskId: 't25', type: 'finish-to-start', lagDays: 0 },
{ id: 'd21', predecessorTaskId: 't24', successorTaskId: 't26', type: 'finish-to-start', lagDays: 0 },
{ id: 'd22', predecessorTaskId: 't25', successorTaskId: 't27', type: 'finish-to-start', lagDays: 0 },
{ id: 'd23', predecessorTaskId: 't26', successorTaskId: 't27', type: 'finish-to-start', lagDays: 0 },
{ id: 'd24', predecessorTaskId: 't27', successorTaskId: 't28', type: 'finish-to-start', lagDays: 0 },
{ id: 'd25', predecessorTaskId: 't28', successorTaskId: 't29', type: 'finish-to-start', lagDays: 2 },
];
Vue vue
<template>
<section class="gantt-basic-demo">
<RevoGrid
class="gantt-basic-grid"
hide-attribution
:can-move-columns="true"
:theme="isDark ? 'darkCompact' : 'compact'"
:plugins="plugins"
:source="tasks"
:columns="columns"
:gantt.prop="ganttConfig"
:gantt-dependencies.prop="dependencies"
:gantt-calendars.prop="calendars"
/>
</section>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import RevoGrid from '@revolist/vue3-datagrid';
import { GanttPlugin, createDefaultTaskTableColumn } from '@revolist/revogrid-enterprise';
import { currentThemeVue } from '../composables/useRandomData';
import { calendars as basicCalendars, dependencies as basicDependencies, ganttConfig as basicGanttConfig, tasks as basicTasks, taskTableColumnProps } from './gantt-basic-data';
import './gantt-basic.css';
const { isDark } = currentThemeVue();
const plugins = ref([GanttPlugin]);
const ganttConfig = ref(basicGanttConfig);
const calendars = ref(basicCalendars);
const tasks = ref(basicTasks.map((task) => ({ ...task })));
const dependencies = ref(basicDependencies);
const columns = ref(taskTableColumnProps.map((prop) => createDefaultTaskTableColumn(prop)));
</script>
React tsx
// src/components/gantt/GanttBasic.tsx
import React, { useMemo } from 'react';
import { RevoGrid } from '@revolist/react-datagrid';
import { GanttPlugin, createDefaultTaskTableColumn } from '@revolist/revogrid-enterprise';
import { currentTheme } from '../composables/useRandomData';
import { calendars, dependencies, ganttConfig, tasks, taskTableColumnProps } from './gantt-basic-data';
import './gantt-basic.css';
const { isDark } = currentTheme();
function GanttBasic() {
const project = useMemo(() => ganttConfig, []);
const source = useMemo(() => tasks.map((task) => ({ ...task })), []);
const columns = useMemo(() => taskTableColumnProps.map((prop) => createDefaultTaskTableColumn(prop)), []);
return (
<section className="gantt-basic-demo">
<RevoGrid
className="gantt-basic-grid"
theme={isDark() ? 'darkCompact' : 'compact'}
hideAttribution
canMoveColumns
plugins={[GanttPlugin]}
source={source}
columns={columns}
gantt={project}
ganttDependencies={dependencies}
ganttCalendars={calendars}
/>
</section>
);
}
export default GanttBasic;
Angular ts
// src/components/gantt/GanttBasicAngular.ts
import { Component, NO_ERRORS_SCHEMA, ViewEncapsulation } from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import { GanttPlugin, createDefaultTaskTableColumn } from '@revolist/revogrid-enterprise';
import { currentTheme } from '../composables/useRandomData';
import { calendars as basicCalendars, dependencies as basicDependencies, ganttConfig as basicGanttConfig, tasks as basicTasks, taskTableColumnProps } from './gantt-basic-data';
@Component({
selector: 'gantt-basic-grid',
standalone: true,
// Allows Angular demos to bind RevoGrid plugin props that are not wrapper inputs.
schemas: [NO_ERRORS_SCHEMA],
imports: [RevoGrid],
template: `
<section class="gantt-basic-demo">
<revo-grid
class="gantt-basic-grid"
[theme]="theme"
[hideAttribution]="true"
[canMoveColumns]="true"
[plugins]="plugins"
[source]="tasks"
[columns]="columns"
[gantt]="ganttConfig"
[ganttDependencies]="dependencies"
[ganttCalendars]="calendars"
></revo-grid>
</section>
`,
styleUrls: ['./gantt-basic.css'],
encapsulation: ViewEncapsulation.None,
})
export class GanttBasicGridComponent {
theme = currentTheme().isDark() ? 'darkCompact' : 'compact';
plugins = [GanttPlugin];
ganttConfig = basicGanttConfig;
calendars = basicCalendars;
tasks = basicTasks.map((task) => ({ ...task }));
dependencies = basicDependencies;
columns = taskTableColumnProps.map((prop) => createDefaultTaskTableColumn(prop));
}
Installation
Section titled “Installation”To use the Enterprise Gantt features, you must first install the enterprise package:
pnpm add @revolist/revogrid-enterpriseRegistering the Plugin
Section titled “Registering the Plugin”Register the GanttPlugin in your grid instance. This adds the scheduling engine, timeline projection, and Gantt-specific data handling to RevoGrid.
import { GanttPlugin } from '@revolist/revogrid-enterprise';
grid.plugins = [GanttPlugin];Basic Project Setup
Section titled “Basic Project Setup”A Gantt project requires a core configuration object, at least one calendar, and a task source. Below is a minimal setup:
grid.gantt = { id: 'project-1', name: 'Project Alpha', version: '1', currency: 'USD', timeZone: 'UTC', primaryCalendarId: 'cal-standard', updatedAt: new Date().toISOString(),};
grid.ganttCalendars = [{ id: 'cal-standard', name: 'Standard', timeZone: 'UTC', workingDays: [1, 2, 3, 4, 5], // Monday to Friday holidays: [], hoursPerDay: 8,}];
grid.source = [ { id: 'task-1', name: 'Initial Research', startDate: '2026-04-06', duration: 5 }];Once the basic project is initialized, you can incrementally add Dependencies, Resources, and Baselines.
Task Table Columns
Section titled “Task Table Columns”Gantt specific columns can be added to your grid using the createDefaultTaskTableColumn utility. These columns are designed to work with the scheduling engine and timeline.
import { createDefaultTaskTableColumn } from '@revolist/revogrid-enterprise';
grid.columns = [ createDefaultTaskTableColumn('wbs'), createDefaultTaskTableColumn('name'), createDefaultTaskTableColumn('startDate'), createDefaultTaskTableColumn('duration'), createDefaultTaskTableColumn('predecessors'),];Key Column Concepts:
Section titled “Key Column Concepts:”- Inputs: Columns like
name,startDate, anddurationare typically editable and drive the scheduler. - Projected Outputs: Columns like
earlyStartDate,lateStartDate, andtotalSlackDaysare computed by the scheduler and are read-only. - Custom Columns: You can mix standard RevoGrid columns with Gantt-specific columns in the same
grid.columnsarray.