Component
Vue Gantt Chart and Resource Scheduler
<DomGantt>People, projects, and roadmaps. One timeline, from hours to months.
Interactive examples
Plan work across time
Try team resources, a project Gantt, a roadmap, meeting rooms, or equipment hire. Draw a booking, drag it through time, and resize its dotted right edge. Resources can change rows; named features stay on theirs.
Studio resource planner
Drag bookings through time or onto another person. Use the dotted right edge to resize.
Drag across a row to plan. Use + to enter dates. Keyboard: arrows to move, Shift + arrows to extend, Enter to add, Escape to cancel.
Maya Chen
Design director
Oliver James
Product designer
Amara Okafor
Developer
Leo Martin
Developer
Ella Wilson
Project manager
Drag a booking to move it. Drag its dotted right edge to change its duration. Changes stay in this example until the page reloads.
Data contract
Your records, another view
rows supplies the people or features down the left. items supplies scheduled work; itemRowKey connects each item to a row. For a roadmap, create one row per feature and give its item the same row id. A resource planner can have many bookings per person. Overlaps stack automatically.
Every item needs a start plus an exclusive end or positive duration. durationUnit defaults to whole calendar days; use hours or minutes for precise work. Explicit ends take precedence. Date-only strings are local midnight. Dates and ISO timestamps display in the browser’s local time. Invalid or reversed spans are omitted; rows without dates remain available for planning.
Field mappings accept logical field names or resolver functions, sharing the data grid and activity timeline conventions. The component does not fetch or mutate records. Handle row-create, time-range-select, and item-click in your application, using your own forms, store, and persistence.
const people = [{ id: 'maya', name: 'Maya Chen' }];
const bookings = [
{ id: 'booking-1', ownerId: 'maya', title: 'Website design', startDate: '2026-09-14', duration: 5 },
{ id: 'booking-2', ownerId: 'maya', title: 'Review', startDate: '2026-09-21T10:00', endDate: '2026-09-21T12:00' },
];
<DomGantt
:rows="people"
:items="bookings"
item-row-key="ownerId"
start-date="2026-09-07"
:days="84"
:working-hours="[6, 18]"
plan-mode
draggable-items
resizable-items
allow-row-change
@row-create="addPerson"
@time-range-select="openBookingForm"
@item-click="editBooking"
@item-move="saveBookingChange"
@item-resize="saveBookingChange"
/>Time & interaction
Zoom without losing your place
Weeks shows daily cells; Months compresses days for a broader overview; Days shows individual hours. Scroll horizontally or use the previous/next controls. Zoom and visibility changes preserve the date at the left edge. The Today action and exposed scrollToDate(date) method navigate inside the supplied startDate / days window.
:working-hours="[6, 18]" describes 06:00–18:00. Other hours and configured weekendDays are muted but valid. Hide them independently, then expand them from the toolbar. Hidden time compresses the axis; it does not shorten stored durations. A Friday-to-Monday selection still spans the weekend in real time. A current-time marker is shown only when that instant is within a displayed cell.
Plan mode supports pointer dragging in either direction, with edge scrolling. Week and month zoom snap to dates; hourly views snap to selectionStep minutes. Touch keeps native scrolling; each row’s + button requests a form with a suggested span. Arrow keys, Shift + arrows, and Enter provide keyboard range selection. Escape cancels.
Enable draggableItems for horizontal movement and resizableItems for the dotted right-edge grip. Enable allowRowChange only when rows represent resources, such as people; leave it off when each row is a named feature. These options are independent of creation mode. The examples bind movement and resizing to their Plan mode toggle.
item-move and item-resize emit the original item, source and target rows, previous dates, and proposed dates. Apply the change in your own store. Pointer previews do not mutate records; Escape or a drop outside the rows cancels. A move preserves local wall-clock endpoints in week/month zoom and elapsed duration in hourly zoom. A resize keeps the start fixed, with a minimum of one visible selection step. Hidden time remains part of the interval.
The meeting-room example starts at hourly zoom with 15-minute snapping and 08:00–18:00 working days. Equipment hire shows reservations across days and weekends, with service periods occupying the same resources. Both examples reject overlapping bookings when creating, moving, resizing, or editing. These checks live in the example application; a production booking service should enforce its availability rules when saving.
On a focused item, Alt + left/right moves through time; Alt + up/down changes resource rows when enabled. On the resize grip, left/right adjusts the end. Touch users can resize with the explicit grip or tap the item to edit dates in the example form. Grips appear at the true end only, so scrolling into the middle of a long item does not expose a misleading resize handle.
Like DomWeekPlanner, a selected range is intent: no item is created until your application accepts it. The example uses DomDialog to name, edit, or cancel work. This component covers scheduling; dependency rules, automatic resource allocation, and critical-path calculations belong to the application.
Reference
Props, events, and slots
Props
Control props
| Name | Type | TS | Default | Description |
|---|---|---|---|---|
rows | array | Array<unknown> | [] | Application-owned people, projects, or feature rows. |
items | array | Array<unknown> | [] | Application-owned scheduled items. Multiple items may share a row. |
rowKey | string | function | string | 'id' | — |
rowLabelKey | string | function | string | 'name' | — |
itemKey | string | function | string | 'id' | — |
itemRowKey | string | function | string | 'rowId' | — |
titleKey | string | function | string | 'title' | — |
startKey | string | function | string | 'startDate' | — |
endKey | string | function | string | 'endDate' | — |
durationKey | string | function | string | 'duration' | — |
toneKey | string | function | string | 'tone' | — |
durationUnit | 'days' | 'hours' | 'minutes' | string | 'days' | Whole local calendar days, or elapsed hours/minutes. An explicit end wins. |
startDate | string | date | number | string | '' | First local date of the scrollable range. Supply a stable value for SSR. |
days | number | number | 84 | Scrollable range in calendar days, from 1 to 3660. Change this or startDate to load another window. |
zoom | 'months' | 'weeks' | 'days' | string | 'weeks' | Initial or v-model zoom. Days displays individual hours. |
planMode | boolean | boolean | false | Enable named row creation and pointer/keyboard time selection. |
draggableItems | boolean | boolean | false | Allow items to move through time. Emits item-move; the application saves the change. |
allowRowChange | boolean | boolean | false | Allow moving items between rows when draggableItems is enabled. Enable for resource bookings; leave off for feature-based Gantt rows. |
resizableItems | boolean | boolean | false | Show a right-edge grip for shortening or extending an item. Emits item-resize. |
workingHours | array | Array<unknown> | [6,18] | Local start and exclusive end hour, e.g. [6, 18]. Outside hours are muted in day zoom. |
weekendDays | array | Array<unknown> | [0,6] | Non-working weekdays: Sunday = 0, Saturday = 6. Muted, still selectable. |
hideNonWorkingHours | boolean | boolean | false | Compress out-of-hours time in day zoom. The toolbar can expand it again. |
hideWeekends | boolean | boolean | false | Compress configured non-working weekdays at every zoom. |
selectionStep | number | number | 30 | Hourly-view selection snap in minutes (1–60). Other views snap to visible calendar days. |
rowHeight | number | number | 64 | Minimum row height in pixels. Overlapping items expand the row. |
viewportHeight | number | number | 460 | — |
rowHeading | string | string | 'People / work' | — |
addRowLabel | string | string | 'Add row' | — |
showToolbar | boolean | boolean | true | — |
showCurrentTime | boolean | boolean | true | — |
loading | boolean | boolean | false | — |
ariaLabel | string | string | 'Planning timeline' | — |
Auto-generated from Gantt.props and inline _edit hints.
Events
| Name | Payload | Description |
|---|---|---|
| @time-range-select | GanttRangePayload | A requested span with source row, rowKey, Date start/end, elapsed durationMinutes, and original event. End is exclusive; the application creates the item. |
| @row-create | { name: string } | Validated row name. The application assigns an id and adds its row. |
| @item-click | GanttItemPayload | Source item and row, resolved dates, and original event for an application-owned editor. |
| @item-move | GanttItemChangePayload | Proposed dates and source/target rows after a drag or keyboard move. Source records remain unchanged until the application accepts the event. |
| @item-resize | GanttItemChangePayload | Proposed exclusive end after right-edge resizing. The start and row are preserved. |
| @update:zoom | 'months' | 'weeks' | 'days' | Toolbar zoom changed, preserving the date at the left of the viewport. |
| @update:planMode | boolean | Plan mode changed. |
| @update:hideNonWorkingHours | boolean | Out-of-hours visibility changed. |
| @update:hideWeekends | boolean | Non-working day visibility changed. |
| @visible-range-change | { startDate: Date, endDate: Date } | Visible date window after scrolling or zooming, for application-owned data loading. |
Names auto-detected from defineEmits and source emit() calls; payload and description from __doc.events when present.
Slots
| Name | Scope | Description |
|---|---|---|
| #row | { row, rowKey, label } | Replace a row label, for example with a member avatar and role. |
| #item | { item, row, startDate, endDate } | Replace bar content inside its focusable item button. Avoid nested interactive controls. |
| #toolbar | — | Append application filters or actions. |
| #empty | — | Replace the empty collection message. |
Keyboard
- ← / →Move the focused row’s time cursor one selection step.
- Shift + ← / →Extend a time selection.
- EnterRequest the selected time span.
- EscapeCancel a pointer or keyboard selection.
- Alt + ← / →Move a focused draggable item one time increment.
- Alt + ↑ / ↓Move a focused item to the previous/next resource row when row changes are enabled.
- ← / → on resize gripShorten or extend an item by one time increment.