Adding calendar
Overview
The functionality is available in PRO Edition only
PROThe Calendar module defines the working-time rules used by the Gantt chart. It provides all time-related calculations: how many hours are worked per day, which days are non-working, how task durations are computed, and how date arithmetic behaves in a project plan.
You can configure weekly schedules, introduce exceptions, or apply custom logic. The Gantt will automatically use this calendar to compute task start/end dates, shifts, progress updates, drag operations, and all duration-based calculations. By attaching a calendar to Gantt, you fully control its date-handling logic.
The Calendar operates at the day level. It allows you to set the number of working hours per day, but not the specific working hours schedule within the day (e.g., 09:00-13:00, 14:00-18:00).
The Calendar API description you can find here: Calendar.
Initializing the Calendar
Install and import the module:
import { Calendar } from "@svar/gantt-store";
Create a calendar instance:
const calendar = new Calendar();
Without configuration, the Calendar uses a standard 40-hour workweek (Mon-Fri).
Adding a default Calendar
You can attach a calendar directly to Gantt. This example shows a default configuration with a standard 8-hour working day for Monday-Friday:
import { useMemo } from "react";
import { Gantt } from "@svar/react-gantt";
import { Calendar } from "@svar/gantt-store";
import { getData } from "../data";
export default function DefaultCalendarDemo() {
const { tasks, links } = getData();
const calendar = useMemo(() => new Calendar({
weekHours: {
monday: 8,
tuesday: 8,
wednesday: 8,
thursday: 8,
friday: 8,
saturday: 0,
sunday: 0,
},
}), []);
return <Gantt tasks={tasks} links={links} calendar={calendar} />;
}
You should always provide valid date values for Gantt tasks. If updating a task through the update-task action, provide all date fields: start, end, and duration. Calendar supports only durationUnit: "day".
Adding a custom Calendar
You can adjust the weekly schedule, working hours, or behavior to match project-specific requirements:
import { useState, useRef, useMemo } from "react";
import { Gantt } from "@svar/react-gantt";
import { Calendar } from "@svar/gantt-store";
import { getData } from "../data";
export default function CustomCalendarDemo() {
// Load initial project data
const initial = getData();
const [tasks, setTasks] = useState(initial.tasks);
const [links] = useState(initial.links);
// Initialize custom calendar
const calendar = useMemo(() => new Calendar({
name: "Part-time schedule",
weekHours: {
monday: 4,
tuesday: 4,
wednesday: 4,
thursday: 4,
friday: 4,
saturday: 0,
sunday: 0,
},
}), []);
// Gantt API ref
const apiRef = useRef(null);
return (
<Gantt
ref={apiRef}
calendar={calendar}
tasks={tasks}
links={links}
/>
);
}
Using rules and exceptions
Rules allow overriding the default weekly schedule for specific dates or patterns. They are commonly used for holidays, special working days, or dynamic scheduling logic. The example below demonstrates:
- creating a custom weekly schedule
- adding one-time exceptions
- enabling a recurring “non-working Monday” rule from UI
- adjusting tasks that fall onto non-working dates
import { useState, useRef, useMemo } from "react";
import { Gantt } from "@svar/react-gantt";
import { Calendar } from "@svar/gantt-store";
import { Button } from "@svar-ui/react-core";
import { getData } from "../data";
export default function CalendarRulesDemo() {
const initial = getData();
const [tasks, setTasks] = useState(initial.tasks);
const [links] = useState(initial.links);
const calendar = useMemo(() => new Calendar({
weekHours: {
monday: 8,
tuesday: 8,
wednesday: 8,
thursday: 8,
friday: 8,
saturday: 0,
sunday: 0,
},
}), []);
// Add one-time rules / exceptions
calendar.addRule(date => {
const month = date.getMonth();
const day = date.getDate();
// Example: non-working day on April 3
if (month === 3 && day === 3) return 0;
// Example: special working 8-hour day on April 7
if (month === 3 && day === 7) return 8;
});
const apiRef = useRef(null);
function addNewRule() {
// Recurring rule: make Mondays non-working
calendar.addRule(date => {
const weekday = date.getDay();
if (weekday === 1) return 0;
});
// Recalculate and correct task start dates using calendar methods
if (!apiRef.current) return;
const serialized = apiRef.current.serialize().map(task => {
if (!calendar.isWorkingDay(task.start)) {
task.start = calendar.getNextWorkingDay(task.start);
}
return task;
});
setTasks(serialized);
}
return (
<div className="rows">
<div className="bar">
<Button type="primary" onClick={addNewRule}>Add rule</Button>
</div>
<div className="gtcell">
<Gantt
ref={apiRef}
calendar={calendar}
tasks={tasks}
links={links}
/>
</div>
</div>
);
}
Rules are evaluated on top of the weekly schedule and always take priority, allowing your calendar to reflect real-world conditions such as holidays, shortened days, and dynamic scheduling rules.
Whenever new rules or exceptions are added, you should resend valid tasks back into Gantt. This ensures that task positions, start dates, and durations are recalculated correctly based on the new working-time logic.
Related samples:
Related articles: