Skip to main content
The scales prop defines the rows of time headers displayed above the chart. Each entry in the array describes one header row, with the rows rendered top-to-bottom in the order you provide them.

Basic example

The most common configuration is a two-row scale showing months above and days below:
<script>
  import { Gantt } from "@svar-ui/svelte-gantt";

  const scales = [
    { unit: "month", step: 1, format: "%F %Y" },
    { unit: "day",   step: 1, format: "%j" },
  ];
</script>

<Gantt {tasks} {links} {scales} />

Multi-row scale

You can stack as many rows as needed. The following four-row configuration is taken directly from the complexScales demo dataset:
const complexScales = [
  { unit: "year",  step: 1, format: "%Y" },
  { unit: "month", step: 2, format: "%F %Y" },
  { unit: "week",  step: 1, format: "%w" },
  { unit: "day",   step: 1, format: "%j", css: dayStyle },
];
Passed to the component:
<Gantt
  {tasks}
  {links}
  scales={complexScales}
  start={new Date(2026, 3, 1)}
  end={new Date(2026, 4, 12)}
  cellWidth={60}
/>

Hour-level scale

For intraday scheduling, use hour as the smallest unit:
const scalesHour = [
  { unit: "day",  step: 1, format: "%M %j" },
  { unit: "hour", step: 1, format: "%H:%i" },
];

IScaleConfig fields

unit
'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year' | string
required
The time unit for this scale row. The smallest unit across all rows determines the base cell size (cellWidth). Custom units can be registered with registerScaleUnit.
step
number
required
Number of units per cell. For example, { unit: "month", step: 2 } creates one cell every two months.
format
string | (date: Date, next?: Date) => string
Format string or function controlling the label inside each cell.Format string tokens:
TokenOutput
%Y4-digit year (e.g. 2026)
%FFull month name (e.g. April)
%MShort month name (e.g. Apr)
%jDay of month without leading zero
%dDay of month with leading zero
%HHour (24-hour, with leading zero)
%iMinutes with leading zero
%wWeek number
%WWeek number (alternative)
%QQuarter label (e.g. Q1)
Function format receives the cell start date and the next cell start date, giving you full control:
import { format } from "date-fns";

const weekScaleTemplate = (a, b) =>
  `${format(a, "MMM d")} - ${format(b, "MMM d")}`;

const scales = [
  { unit: "month", step: 1, format: "%F %Y" },
  { unit: "week",  step: 1, format: weekScaleTemplate },
];
css
(date: Date) => string
Function that returns a CSS class name for a given cell date. Useful for highlighting weekends or other special days:
const dayStyle = date => {
  const day = date.getDay();
  return day === 5 || day === 6 ? "sday" : "";
};

const scales = [
  { unit: "month", step: 1, format: "%F %Y" },
  { unit: "day",   step: 1, format: "%j", css: dayStyle },
];

Custom scale units

If the built-in units do not meet your needs, register a custom unit with registerScaleUnit. A custom unit must implement the GanttScaleUnit interface:
type GanttScaleUnit = {
  start:  (date: Date) => Date;
  end:    (date: Date) => Date;
  isSame: (date1: Date, date2: Date) => boolean;
  add:    (date: Date, num: number) => Date;
  diff?:  (date1: Date, date2: Date) => number;
  smallerCount?: { [unit: string]: number | ((date: Date) => number) };
  biggerCount?:  { [unit: string]: number | ((date: Date) => number) };
};
The smallerCount and biggerCount maps inform the zoom logic how many of this unit fit into larger units and vice versa. Providing them ensures correct cell-width calculations when zooming.

Build docs developers (and LLMs) love