Troubleshooting
Source code
---import '@revolist/gantt/styles.css';import GanttScheduling from '@revolist/revogrid-examples/components/gantt/GanttScheduling.vue';---
<GanttScheduling client:only="vue" />import { defineCustomElements } from '@revolist/revogrid/loader';defineCustomElements();
import { GanttPlugin, createDefaultTaskTableColumn } from '@revolist/gantt';import type { GanttTaskSourceRow, DependencyEntity } from '@revolist/gantt';type CalendarEntity = NonNullable< import('@revolist/gantt').GanttPluginConfig['calendars']>[number];import { currentTheme } from '../composables/useRandomData';
const { isDark } = currentTheme();
const PROJECT_ID = 'project-web-redesign';const CALENDAR_ID = 'cal-us';
// Calendar-aware scheduling: durations are in working days (Mon–Fri, excluding holidays)const ganttConfig = { id: PROJECT_ID, name: 'Website Redesign', version: '1', currency: 'USD', timeZone: 'America/New_York', primaryCalendarId: CALENDAR_ID, updatedAt: '2026-04-06T00:00:00Z', statusDate: '2026-04-06', zoomPreset: 'day-week' as const, scheduling: { excludeHolidaysFromDuration: true, // durations skip weekends and holidays }, visuals: { shadeNonWorkingTime: true, // shade weekend columns on the timeline projectLineDate: '2026-04-06', // vertical status-date line },};
// US calendar with public holidaysconst calendars: CalendarEntity[] = [ { id: CALENDAR_ID, name: 'US Standard', timeZone: 'America/New_York', workingDays: [1, 2, 3, 4, 5], // Mon–Fri holidays: [ '2026-05-25', // Memorial Day '2026-07-04', // Independence Day ], hoursPerDay: 8, },];
const tasks: GanttTaskSourceRow[] = [ { id: 't1', parentId: null, name: 'Design', type: 'summary', workflowStatus: 'in-progress', startDate: '2026-04-06', endDate: '2026-04-24', duration: 15, percentDone: 60, calendarId: CALENDAR_ID, tags: [], }, { id: 't2', parentId: 't1', name: 'Wireframes', type: 'task', workflowStatus: 'done', startDate: '2026-04-06', endDate: '2026-04-10', duration: 5, percentDone: 100, calendarId: CALENDAR_ID, tags: [], }, { id: 't3', parentId: 't1', name: 'Design Review', type: 'milestone', workflowStatus: 'done', startDate: '2026-04-10', endDate: '2026-04-10', duration: 0, percentDone: 100, calendarId: CALENDAR_ID, tags: ['milestone'], }, { id: 't4', parentId: 't1', name: 'Visual Design', type: 'task', workflowStatus: 'in-progress', startDate: '2026-04-13', endDate: '2026-04-24', duration: 10, percentDone: 40, calendarId: CALENDAR_ID, tags: [], }, { id: 't5', parentId: null, name: 'Development', type: 'summary', workflowStatus: 'not-started', startDate: '2026-04-27', endDate: '2026-05-28', duration: 24, percentDone: 0, calendarId: CALENDAR_ID, tags: [], }, { id: 't6', parentId: 't5', name: 'Frontend', type: 'task', workflowStatus: 'not-started', // constraint: cannot start before May 4 (waiting on external API) startDate: '2026-05-04', endDate: '2026-05-20', duration: 13, percentDone: 0, calendarId: CALENDAR_ID, tags: [], constraintType: 'start-no-earlier-than', constraintDate: '2026-05-04', }, { id: 't7', parentId: 't5', name: 'Backend', type: 'task', workflowStatus: 'not-started', startDate: '2026-04-27', endDate: '2026-05-28', duration: 24, percentDone: 0, calendarId: CALENDAR_ID, tags: [], deadlineDate: '2026-05-22', // deadline marker — project expects early delivery }, { id: 't8', parentId: null, name: 'Launch', type: 'milestone', workflowStatus: 'not-started', startDate: '2026-05-28', endDate: '2026-05-28', duration: 0, percentDone: 0, calendarId: CALENDAR_ID, tags: ['milestone'], },];
const dependencies: DependencyEntity[] = [ { id: 'd1', predecessorTaskId: 't2', successorTaskId: 't3', type: 'finish-to-start', lagDays: 0, }, { id: 'd2', predecessorTaskId: 't3', successorTaskId: 't4', type: 'finish-to-start', lagDays: 1, }, { id: 'd3', predecessorTaskId: 't4', successorTaskId: 't6', type: 'finish-to-start', lagDays: 1, }, { id: 'd4', predecessorTaskId: 't4', successorTaskId: 't7', type: 'finish-to-start', lagDays: 1, }, { id: 'd5', predecessorTaskId: 't6', successorTaskId: 't8', type: 'finish-to-start', lagDays: 0, }, { id: 'd6', predecessorTaskId: 't7', successorTaskId: 't8', type: 'finish-to-start', lagDays: 0, },];
export function load(parentSelector: string) { const grid = document.createElement('revo-grid');
grid.theme = isDark() ? 'darkCompact' : 'compact'; grid.hideAttribution = true; grid.plugins = [GanttPlugin]; grid.gantt = ganttConfig; grid.ganttCalendars = calendars; grid.ganttDependencies = dependencies; grid.source = tasks; grid.columns = [ createDefaultTaskTableColumn('wbs'), createDefaultTaskTableColumn('name'), ];
document.querySelector(parentSelector)?.appendChild(grid);}<template> <RevoGrid hide-attribution style="height: 500px" :theme="isDark ? 'darkCompact' : 'compact'" :plugins="plugins" :source="tasks" :columns="columns" :gantt.prop="ganttConfig" :gantt-dependencies.prop="dependencies" :gantt-calendars.prop="calendars" /></template>
<script setup lang="ts">import { ref } from 'vue';import RevoGrid from '@revolist/vue3-datagrid';import { GanttPlugin, createDefaultTaskTableColumn } from '@revolist/gantt';import type { GanttTaskSourceRow, DependencyEntity } from '@revolist/gantt';type CalendarEntity = NonNullable< import('@revolist/gantt').GanttPluginConfig['calendars']>[number];import { currentThemeVue } from '../composables/useRandomData';
const { isDark } = currentThemeVue();
const PROJECT_ID = 'project-web-redesign';const CALENDAR_ID = 'cal-us';
const plugins = ref([GanttPlugin]);
const ganttConfig = ref({ id: PROJECT_ID, name: 'Website Redesign', version: '1', currency: 'USD', timeZone: 'America/New_York', primaryCalendarId: CALENDAR_ID, updatedAt: '2026-04-06T00:00:00Z', statusDate: '2026-04-06', zoomPreset: 'day-week' as const, scheduling: { excludeHolidaysFromDuration: true, }, visuals: { shadeNonWorkingTime: true, projectLineDate: '2026-04-06', },});
const calendars = ref<CalendarEntity[]>([ { id: CALENDAR_ID, name: 'US Standard', timeZone: 'America/New_York', workingDays: [1, 2, 3, 4, 5], holidays: ['2026-05-25', '2026-07-04'], hoursPerDay: 8, },]);
const tasks = ref<GanttTaskSourceRow[]>([ { id: 't1', parentId: null, name: 'Design', type: 'summary', workflowStatus: 'in-progress', startDate: '2026-04-06', endDate: '2026-04-24', duration: 15, percentDone: 60, calendarId: CALENDAR_ID, tags: [], }, { id: 't2', parentId: 't1', name: 'Wireframes', type: 'task', workflowStatus: 'done', startDate: '2026-04-06', endDate: '2026-04-10', duration: 5, percentDone: 100, calendarId: CALENDAR_ID, tags: [], }, { id: 't3', parentId: 't1', name: 'Design Review', type: 'milestone', workflowStatus: 'done', startDate: '2026-04-10', endDate: '2026-04-10', duration: 0, percentDone: 100, calendarId: CALENDAR_ID, tags: ['milestone'], }, { id: 't4', parentId: 't1', name: 'Visual Design', type: 'task', workflowStatus: 'in-progress', startDate: '2026-04-13', endDate: '2026-04-24', duration: 10, percentDone: 40, calendarId: CALENDAR_ID, tags: [], }, { id: 't5', parentId: null, name: 'Development', type: 'summary', workflowStatus: 'not-started', startDate: '2026-04-27', endDate: '2026-05-28', duration: 24, percentDone: 0, calendarId: CALENDAR_ID, tags: [], }, { id: 't6', parentId: 't5', name: 'Frontend', type: 'task', workflowStatus: 'not-started', startDate: '2026-05-04', endDate: '2026-05-20', duration: 13, percentDone: 0, calendarId: CALENDAR_ID, tags: [], constraintType: 'start-no-earlier-than', constraintDate: '2026-05-04', }, { id: 't7', parentId: 't5', name: 'Backend', type: 'task', workflowStatus: 'not-started', startDate: '2026-04-27', endDate: '2026-05-28', duration: 24, percentDone: 0, calendarId: CALENDAR_ID, tags: [], deadlineDate: '2026-05-22', }, { id: 't8', parentId: null, name: 'Launch', type: 'milestone', workflowStatus: 'not-started', startDate: '2026-05-28', endDate: '2026-05-28', duration: 0, percentDone: 0, calendarId: CALENDAR_ID, tags: ['milestone'], },]);
const dependencies = ref<DependencyEntity[]>([ { id: 'd1', predecessorTaskId: 't2', successorTaskId: 't3', type: 'finish-to-start', lagDays: 0, }, { id: 'd2', predecessorTaskId: 't3', successorTaskId: 't4', type: 'finish-to-start', lagDays: 1, }, { id: 'd3', predecessorTaskId: 't4', successorTaskId: 't6', type: 'finish-to-start', lagDays: 1, }, { id: 'd4', predecessorTaskId: 't4', successorTaskId: 't7', type: 'finish-to-start', lagDays: 1, }, { id: 'd5', predecessorTaskId: 't6', successorTaskId: 't8', type: 'finish-to-start', lagDays: 0, }, { id: 'd6', predecessorTaskId: 't7', successorTaskId: 't8', type: 'finish-to-start', lagDays: 0, },]);
const columns = ref([ createDefaultTaskTableColumn('wbs'), createDefaultTaskTableColumn('name'),]);</script>import React, { useMemo } from 'react';import { RevoGrid } from '@revolist/react-datagrid';import { GanttPlugin, createDefaultTaskTableColumn } from '@revolist/gantt';import type { GanttTaskSourceRow, DependencyEntity } from '@revolist/gantt';type CalendarEntity = NonNullable< import('@revolist/gantt').GanttPluginConfig['calendars']>[number];import { currentTheme } from '../composables/useRandomData';
const { isDark } = currentTheme();
const PROJECT_ID = 'project-web-redesign';const CALENDAR_ID = 'cal-us';
const tasks: GanttTaskSourceRow[] = [ { id: 't1', parentId: null, name: 'Design', type: 'summary', workflowStatus: 'in-progress', startDate: '2026-04-06', endDate: '2026-04-24', duration: 15, percentDone: 60, calendarId: CALENDAR_ID, tags: [], }, { id: 't2', parentId: 't1', name: 'Wireframes', type: 'task', workflowStatus: 'done', startDate: '2026-04-06', endDate: '2026-04-10', duration: 5, percentDone: 100, calendarId: CALENDAR_ID, tags: [], }, { id: 't3', parentId: 't1', name: 'Design Review', type: 'milestone', workflowStatus: 'done', startDate: '2026-04-10', endDate: '2026-04-10', duration: 0, percentDone: 100, calendarId: CALENDAR_ID, tags: ['milestone'], }, { id: 't4', parentId: 't1', name: 'Visual Design', type: 'task', workflowStatus: 'in-progress', startDate: '2026-04-13', endDate: '2026-04-24', duration: 10, percentDone: 40, calendarId: CALENDAR_ID, tags: [], }, { id: 't5', parentId: null, name: 'Development', type: 'summary', workflowStatus: 'not-started', startDate: '2026-04-27', endDate: '2026-05-28', duration: 24, percentDone: 0, calendarId: CALENDAR_ID, tags: [], }, { id: 't6', parentId: 't5', name: 'Frontend', type: 'task', workflowStatus: 'not-started', startDate: '2026-05-04', endDate: '2026-05-20', duration: 13, percentDone: 0, calendarId: CALENDAR_ID, tags: [], constraintType: 'start-no-earlier-than', constraintDate: '2026-05-04', }, { id: 't7', parentId: 't5', name: 'Backend', type: 'task', workflowStatus: 'not-started', startDate: '2026-04-27', endDate: '2026-05-28', duration: 24, percentDone: 0, calendarId: CALENDAR_ID, tags: [], deadlineDate: '2026-05-22', }, { id: 't8', parentId: null, name: 'Launch', type: 'milestone', workflowStatus: 'not-started', startDate: '2026-05-28', endDate: '2026-05-28', duration: 0, percentDone: 0, calendarId: CALENDAR_ID, tags: ['milestone'], },];
const dependencies: DependencyEntity[] = [ { id: 'd1', predecessorTaskId: 't2', successorTaskId: 't3', type: 'finish-to-start', lagDays: 0, }, { id: 'd2', predecessorTaskId: 't3', successorTaskId: 't4', type: 'finish-to-start', lagDays: 1, }, { id: 'd3', predecessorTaskId: 't4', successorTaskId: 't6', type: 'finish-to-start', lagDays: 1, }, { id: 'd4', predecessorTaskId: 't4', successorTaskId: 't7', type: 'finish-to-start', lagDays: 1, }, { id: 'd5', predecessorTaskId: 't6', successorTaskId: 't8', type: 'finish-to-start', lagDays: 0, }, { id: 'd6', predecessorTaskId: 't7', successorTaskId: 't8', type: 'finish-to-start', lagDays: 0, },];
const calendars: CalendarEntity[] = [ { id: CALENDAR_ID, name: 'US Standard', timeZone: 'America/New_York', workingDays: [1, 2, 3, 4, 5], holidays: ['2026-05-25', '2026-07-04'], hoursPerDay: 8, },];
function GanttScheduling() { const ganttConfig = useMemo( () => ({ id: PROJECT_ID, name: 'Website Redesign', version: '1', currency: 'USD', timeZone: 'America/New_York', primaryCalendarId: CALENDAR_ID, updatedAt: '2026-04-06T00:00:00Z', statusDate: '2026-04-06', zoomPreset: 'day-week' as const, scheduling: { excludeHolidaysFromDuration: true, }, visuals: { shadeNonWorkingTime: true, projectLineDate: '2026-04-06', }, }), [], );
const columns = useMemo( () => [ createDefaultTaskTableColumn('wbs'), createDefaultTaskTableColumn('name'), ], [], );
return ( <RevoGrid style={{ height: '500px' }} theme={isDark() ? 'darkCompact' : 'compact'} hideAttribution plugins={[GanttPlugin]} source={tasks} columns={columns} gantt={ganttConfig} ganttDependencies={dependencies} ganttCalendars={calendars} /> );}
export default GanttScheduling;import { Component, NO_ERRORS_SCHEMA, ViewEncapsulation } from '@angular/core';import { RevoGrid } from '@revolist/angular-datagrid';import { GanttPlugin, createDefaultTaskTableColumn } from '@revolist/gantt';import type { GanttTaskSourceRow, DependencyEntity } from '@revolist/gantt';type CalendarEntity = NonNullable< import('@revolist/gantt').GanttPluginConfig['calendars']>[number];import { currentTheme } from '../composables/useRandomData';
const PROJECT_ID = 'project-web-redesign';const CALENDAR_ID = 'cal-us';
@Component({ selector: 'gantt-scheduling-grid', standalone: true, imports: [RevoGrid], // Allows Angular demos to bind RevoGrid plugin props that are not wrapper inputs. schemas: [NO_ERRORS_SCHEMA], template: ` <revo-grid style="min-height: 500px" [theme]="theme" [hideAttribution]="true" [plugins]="plugins" [source]="tasks" [columns]="columns" [gantt]="ganttConfig" [ganttDependencies]="dependencies" [ganttCalendars]="calendars" ></revo-grid> `, encapsulation: ViewEncapsulation.None,})export class GanttSchedulingGridComponent { theme = currentTheme().isDark() ? 'darkCompact' : 'compact'; plugins = [GanttPlugin];
ganttConfig = { id: PROJECT_ID, name: 'Website Redesign', version: '1', currency: 'USD', timeZone: 'America/New_York', primaryCalendarId: CALENDAR_ID, updatedAt: '2026-04-06T00:00:00Z', statusDate: '2026-04-06', zoomPreset: 'day-week' as const, scheduling: { excludeHolidaysFromDuration: true, }, visuals: { shadeNonWorkingTime: true, projectLineDate: '2026-04-06', }, };
calendars: CalendarEntity[] = [ { id: CALENDAR_ID, name: 'US Standard', timeZone: 'America/New_York', workingDays: [1, 2, 3, 4, 5], holidays: ['2026-05-25', '2026-07-04'], hoursPerDay: 8, }, ];
tasks: GanttTaskSourceRow[] = [ { id: 't1', parentId: null, name: 'Design', type: 'summary', workflowStatus: 'in-progress', startDate: '2026-04-06', endDate: '2026-04-24', duration: 15, percentDone: 60, calendarId: CALENDAR_ID, tags: [], }, { id: 't2', parentId: 't1', name: 'Wireframes', type: 'task', workflowStatus: 'done', startDate: '2026-04-06', endDate: '2026-04-10', duration: 5, percentDone: 100, calendarId: CALENDAR_ID, tags: [], }, { id: 't3', parentId: 't1', name: 'Design Review', type: 'milestone', workflowStatus: 'done', startDate: '2026-04-10', endDate: '2026-04-10', duration: 0, percentDone: 100, calendarId: CALENDAR_ID, tags: ['milestone'], }, { id: 't4', parentId: 't1', name: 'Visual Design', type: 'task', workflowStatus: 'in-progress', startDate: '2026-04-13', endDate: '2026-04-24', duration: 10, percentDone: 40, calendarId: CALENDAR_ID, tags: [], }, { id: 't5', parentId: null, name: 'Development', type: 'summary', workflowStatus: 'not-started', startDate: '2026-04-27', endDate: '2026-05-28', duration: 24, percentDone: 0, calendarId: CALENDAR_ID, tags: [], }, { id: 't6', parentId: 't5', name: 'Frontend', type: 'task', workflowStatus: 'not-started', startDate: '2026-05-04', endDate: '2026-05-20', duration: 13, percentDone: 0, calendarId: CALENDAR_ID, tags: [], constraintType: 'start-no-earlier-than', constraintDate: '2026-05-04', }, { id: 't7', parentId: 't5', name: 'Backend', type: 'task', workflowStatus: 'not-started', startDate: '2026-04-27', endDate: '2026-05-28', duration: 24, percentDone: 0, calendarId: CALENDAR_ID, tags: [], deadlineDate: '2026-05-22', }, { id: 't8', parentId: null, name: 'Launch', type: 'milestone', workflowStatus: 'not-started', startDate: '2026-05-28', endDate: '2026-05-28', duration: 0, percentDone: 0, calendarId: CALENDAR_ID, tags: ['milestone'], }, ];
dependencies: DependencyEntity[] = [ { id: 'd1', predecessorTaskId: 't2', successorTaskId: 't3', type: 'finish-to-start', lagDays: 0, }, { id: 'd2', predecessorTaskId: 't3', successorTaskId: 't4', type: 'finish-to-start', lagDays: 1, }, { id: 'd3', predecessorTaskId: 't4', successorTaskId: 't6', type: 'finish-to-start', lagDays: 1, }, { id: 'd4', predecessorTaskId: 't4', successorTaskId: 't7', type: 'finish-to-start', lagDays: 1, }, { id: 'd5', predecessorTaskId: 't6', successorTaskId: 't8', type: 'finish-to-start', lagDays: 0, }, { id: 'd6', predecessorTaskId: 't7', successorTaskId: 't8', type: 'finish-to-start', lagDays: 0, }, ];
columns = [ createDefaultTaskTableColumn('wbs'), createDefaultTaskTableColumn('name'), ];}Common checks:
- Missing
ganttCalendarsor mismatchedcalendarId. - Duplicate IDs in tasks/dependencies/resources/assignments.
- Dependency points to missing task ID.
- A circular dependency chain such as
Setup load balancer -> Configure firewall -> Setup load balancer. The scheduler reports this asdependency-cycle; inspect the issue’staskIdsanddependencyIds, then remove or change one of the links. - Invalid task date ranges or malformed constraints.
- No visible timeline because viewport/zoom span does not include task dates.
Task Jumps While Dragging
Section titled “Task Jumps While Dragging”If a task appears to jump during drag or resize, first check for dependency validation issues. Automatic tasks normally clamp to the earliest date allowed by their predecessors. A circular dependency cannot produce a valid predecessor order, so RevoGrid reports dependency-cycle and leaves dependency clamping disabled until the cycle is fixed.
Use the scheduling result passed to your diagnostics flow to locate the invalid links:
const cycleIssue = schedulerResult.issues.find( (issue) => issue.code === 'dependency-cycle',);
if (cycleIssue) { console.table({ tasks: cycleIssue.taskIds.join(', '), dependencies: cycleIssue.dependencyIds.join(', '), });}Validation and diagnostics are produced by:
engine/scheduler-engine/validation.tsengine/scheduler-types.ts