The GanttChart (Timeline) component lets you visualize project schedules as horizontal bars across a time axis, making it easy to track tasks and dependencies in your Nuxt app.
<script lang="ts" setup>
defineOptions({
tags: ['timeline', 'basic']
})
export type TimelineItem = {
name: string
color: string
startDate: number
endDate: number
department: 'Frontend' | 'Backend' | 'UX'
description?: string
label?: string
}
enum ProductType {
Frontend = 'Frontend',
Backend = 'Backend',
UX = 'UX'
}
const SPRINT_START_MS = 1728172800000
const SPRINT_END_MS = 1729296000000
const COLORS = {
Frontend: '#FF5733',
Backend: '#33FF57',
UX: '#3357FF'
}
const data: TimelineItem[] = [
{
name: 'AdSense Dashboard',
color: COLORS.Frontend,
startDate: SPRINT_START_MS + 2 * 86400000,
endDate: SPRINT_START_MS + 6 * 86400000,
department: 'Frontend' as const,
description:
'Develop a responsive dashboard for AdSense performance on mobile devices using modern frameworks.'
},
{
name: 'Vita UI',
color: COLORS.Frontend,
startDate: SPRINT_START_MS + 7 * 86400000,
endDate: SPRINT_END_MS - 1 * 86400000,
department: 'Frontend' as const,
description: 'Improve load times.'
},
{
name: 'AR Playground',
color: COLORS.Frontend,
startDate: SPRINT_START_MS + 1 * 86400000,
endDate: SPRINT_START_MS + 5 * 86400000,
department: 'Frontend' as const,
description: 'New augmented reality feature.'
},
{
name: 'Search Posts API',
color: COLORS.Backend,
startDate: SPRINT_START_MS,
endDate: SPRINT_START_MS + 4 * 86400000,
department: 'Backend' as const,
description: 'Optimize database.'
},
{
name: 'ML Prediction API',
color: COLORS.Backend,
startDate: SPRINT_START_MS + 5 * 86400000,
endDate: SPRINT_START_MS + 10 * 86400000,
department: 'Backend' as const,
description: 'Scalable REST endpoint'
},
{
name: 'Currents User Service',
color: COLORS.Backend,
startDate: SPRINT_START_MS + 3 * 86400000,
endDate: SPRINT_END_MS,
department: 'Backend' as const,
description:
'Migrate user profile and authentication services for Google Currents to the new microservice architecture.'
},
{
name: 'User Blocking Logic',
color: COLORS.Backend,
startDate: SPRINT_START_MS,
endDate: SPRINT_START_MS + 2 * 86400000,
department: 'Backend' as const,
description:
'Write the server-side logic and database schema for the Personal Blocklist feature in Search.'
},
{
name: 'Assistant Snapshot UI',
color: COLORS.UX,
startDate: SPRINT_START_MS + 1 * 86400000,
endDate: SPRINT_START_MS + 5 * 86400000,
department: 'UX' as const,
description:
'Create a comprehensive design system and component library for the new Google Assistant Snapshot predictive cards.'
},
{
name: 'Sites Creation Flow',
color: COLORS.UX,
startDate: SPRINT_START_MS + 6 * 86400000,
endDate: SPRINT_END_MS,
department: 'UX' as const,
description:
'Map out and prototype the optimal user flow for creating and publishing a new website in Google Sites.'
},
{
name: 'A/B Test Buttons',
color: COLORS.UX,
startDate: SPRINT_START_MS + 3 * 86400000,
endDate: SPRINT_START_MS + 8 * 86400000,
department: 'UX' as const,
description:
'Conduct A/B testing on button placement and microcopy for the YouTube Community Contributions feature.'
}
].sort((p1, p2) => p1.startDate - p2.startDate)
const x = (d: TimelineItem) => d.startDate
const length = (d: TimelineItem) => d.endDate - d.startDate
const type = (d: TimelineItem) => d.name
const categories: Record<string, BulletLegendItemInterface> = {
[ProductType.Frontend]: {
name: ProductType.Frontend,
color: 'var(--color-orange-400)'
},
[ProductType.Backend]: {
name: ProductType.Backend,
color: 'var(--color-blue-400)'
},
[ProductType.UX]: { name: ProductType.UX, color: 'var(--color-yellow-400)' }
}
</script>
<template>
<GanttChart
:data="data"
:show-labels="true"
:label-width="100"
:x="x"
:x-num-ticks="5"
:length="length"
:type="type"
:x-grid-line="true"
:categories="categories"
/>
</template>
:root {
--vis-timeline-row-odd-fill-color: transparent !important;
--vis-timeline-row-even-fill-color: transparent !important;
--vis-timeline-label-color: var(--ui-text-dimmed) !important
}
| Prop | Type | Default | Description |
|---|---|---|---|
data | T[] | Required | Array of timeline events. Each element represents a task or item on the timeline. |
categories | Record<string, BulletLegendItemInterface> | Required | Series configuration: name and color for each category. |
x | (d: T) => number | Required | Accessor function returning the start time/position for each item. |
length | (d: T) => number | Required | Accessor function returning the duration/length for each item. |
type | (d: T) => string | Required | Accessor function returning the category type for each item. |
height | number | undefined | Height of the chart in pixels. |
title | string | undefined | Optional title for the timeline chart. |
labelWidth | number | 220 | Width of the label area in pixels. |
showLabels | boolean | true | If true, displays labels for each timeline row. |
lineWidth | number | 12 | Width of the timeline bars in pixels. |
rowHeight | number | 24 | Height of each row in the timeline in pixels. |
xNumTicks | number | undefined | Desired number of ticks on the x-axis. |
xTickLine | boolean | false | Show tick lines on the x-axis. |
xTickFormat | (tick: number | Date, i?: number, ticks?: number[] | Date[]) => string | undefined | Custom formatter for x-axis tick labels. |
xMinMaxTicksOnly | boolean | false | If true, only show first and last ticks on the x-axis. |
xTickValues | number[] | Date[] | undefined | Force specific tick values on the x-axis. |
xGridLine | boolean | false | Show grid lines along the x-axis. |
xDomainLine | boolean | false | Show domain line on the x-axis. |
hideLegend | boolean | false | If true, hides the chart legend. |
legendPosition | LegendPosition | LegendPosition.TopRight | Position of the legend. |
legendStyle | string | Record<string, string> | undefined | Custom CSS style for the legend container. |
hideTooltip | boolean | false | If true, hides the chart tooltip. |
tooltipTitleFormatter | (data: T) => string | number | undefined | Custom formatter for tooltip titles. |
getTooltipText | (label: string, index: number, data: T[]) => string | undefined | Custom tooltip text generator function. |
crosshairConfig | CrosshairConfig | undefined | Crosshair configuration for customizing the crosshair line. |
xAxisConfig | AxisConfig | undefined | Axis configuration for customizing the x-axis appearance. |
yAxisConfig | AxisConfig | undefined | Axis configuration for customizing the y-axis appearance. |
tooltip | TooltipConfig | undefined | Tooltip configuration (hideDelay, showDelay, followCursor). |
duration | number | undefined | Animation duration in milliseconds. |
| Event | Payload | Description |
|---|---|---|
click | { event: MouseEvent, data: { index: number, item: T } } | Fired when a timeline bar is clicked. |
scroll | number | Fired when the timeline is scrolled, returns the scroll distance. |
labelHover | T | undefined | Fired when hovering over a label, returns the item data. |
| Slot | Props | Description |
|---|---|---|
labelTooltip | { values: T | undefined } | Custom tooltip content for label hover. |
fallback | {} | Fallback content while chart loads. |
The data should be an array of objects representing timeline items:
interface TimelineItem {
name: string
color: string
startDate: number
endDate: number
department: string
description?: string
label?: string
}
Categories define the visual appearance for each timeline category:
interface BulletLegendItemInterface {
name: string
color: string
}
type GanttCategories = Record<string, BulletLegendItemInterface>