home / skills / dennisadriaans / vue-chrts / gantt-chart

gantt-chart skill

/.claude/skills/gantt-chart

This skill helps you visualize project timelines with customizable GanttChart components, enabling clear scheduling, tracking, and categorization of tasks.

npx playbooks add skill dennisadriaans/vue-chrts --skill gantt-chart

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
7.3 KB
---
name: gantt-chart
description: Build GanttChart (timeline) components. Use for project timelines, schedules, and temporal data visualization.
---

# GanttChart

GanttChart displays temporal data as horizontal bars on a timeline. Perfect for project schedules, resource allocation, and time-based event visualization.

## Mental Model

```
┌─────────────────────────────────────────────────────────────┐
│  TIMELINE STRUCTURE                                         │
│                                                             │
│  Labels      │ Timeline Bars                                │
│  ───────────────────────────────────────────────────────   │
│  Task A      │ ████████░░░░░░░░░░░░░░░░░░                  │
│  Task B      │ ░░░░░░░░████████████░░░░░░                  │
│  Task C      │ ░░░░░░░░░░░░░░░████████████                  │
│              │                                              │
│              │ Jan    Feb    Mar    Apr    May              │
│                                                             │
│  Each bar: x (start) + length (duration) + type (category) │
└─────────────────────────────────────────────────────────────┘
```

## Data Structure

```typescript
interface TimelineItem {
  label: string      // row label
  start: number      // x position (timestamp or index)
  duration: number   // bar length
  category: string   // determines color from categories
}
```

## Complete Example

```vue
<script setup lang="ts">
import { GanttChart, LegendPosition } from 'vue-chrts'

interface ProjectTask {
  name: string
  start: number      // start date as timestamp
  duration: number   // duration in days
  phase: string      // category for coloring
}

const tasks: ProjectTask[] = [
  { name: 'Research', start: Date.parse('2024-01-01'), duration: 14, phase: 'planning' },
  { name: 'Design', start: Date.parse('2024-01-10'), duration: 21, phase: 'planning' },
  { name: 'Backend Dev', start: Date.parse('2024-01-25'), duration: 30, phase: 'development' },
  { name: 'Frontend Dev', start: Date.parse('2024-02-01'), duration: 35, phase: 'development' },
  { name: 'Testing', start: Date.parse('2024-03-01'), duration: 14, phase: 'testing' },
  { name: 'Deployment', start: Date.parse('2024-03-15'), duration: 7, phase: 'deployment' },
]

const categories = {
  planning: { name: 'Planning', color: '#3b82f6' },
  development: { name: 'Development', color: '#10b981' },
  testing: { name: 'Testing', color: '#f59e0b' },
  deployment: { name: 'Deployment', color: '#8b5cf6' }
}

// Convert duration from days to milliseconds for x-axis scale
const dayInMs = 24 * 60 * 60 * 1000
</script>

<template>
  <GanttChart
    :data="tasks"
    :categories="categories"
    :x="(d) => d.start"
    :length="(d) => d.duration * dayInMs"
    :type="(d) => d.phase"
    :height="300"
    :labelWidth="150"
    :legendPosition="LegendPosition.TopRight"
    :lineWidth="20"
    :rowHeight="36"
  />
</template>
```

## Key Props Reference

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `data` | `T[]` | required | Array of timeline items |
| `categories` | `Record<string, BulletLegendItem>` | required | Color mapping for types |
| `x` | `(d: T) => number` | required | Accessor for start position |
| `length` | `(d: T) => number` | required | Accessor for bar duration |
| `type` | `(d: T) => string` | required | Accessor for category/type |
| `height` | `number` | - | Chart height in pixels |
| `labelWidth` | `number` | `220` | Width of label column |
| `lineWidth` | `number` | `12` | Height of timeline bars |
| `rowHeight` | `number` | `24` | Height of each row |
| `showLabels` | `boolean` | `true` | Show row labels |
| `xNumTicks` | `number` | auto | Number of x-axis ticks |
| `title` | `string` | - | Chart title |
| `hideTooltip` | `boolean` | `false` | Hide tooltips |
| `getTooltipText` | `(label, index, data) => string` | - | Custom tooltip content |
| `tooltipTitleFormatter` | `(data: T) => string` | - | Custom tooltip title |
| `legendPosition` | `LegendPosition` | `TopRight` | Legend placement |

## Accessor Functions Explained

```typescript
// The three required accessors tell GanttChart how to read your data

const data = [
  { task: 'Write docs', startDate: 100, days: 5, status: 'active' }
]

// x: where does the bar start?
const x = (d) => d.startDate

// length: how long is the bar?
const length = (d) => d.days

// type: which category for coloring?
const type = (d) => d.status
```

## Common Patterns

### Simple Task List

```vue
<script setup>
const tasks = [
  { name: 'Task 1', start: 0, duration: 3, status: 'done' },
  { name: 'Task 2', start: 2, duration: 4, status: 'active' },
  { name: 'Task 3', start: 5, duration: 2, status: 'pending' },
]

const categories = {
  done: { name: 'Completed', color: '#10b981' },
  active: { name: 'In Progress', color: '#3b82f6' },
  pending: { name: 'Pending', color: '#9ca3af' }
}
</script>

<template>
  <GanttChart
    :data="tasks"
    :categories="categories"
    :x="(d) => d.start"
    :length="(d) => d.duration"
    :type="(d) => d.status"
    :height="200"
    :showLabels="true"
    :labelWidth="120"
  />
</template>
```

### Sprint Timeline

```vue
<script setup>
const sprintData = [
  { story: 'User Auth', sprint: 1, points: 5, team: 'backend' },
  { story: 'Dashboard UI', sprint: 1, points: 8, team: 'frontend' },
  { story: 'API Integration', sprint: 2, points: 5, team: 'backend' },
  { story: 'Testing', sprint: 3, points: 3, team: 'qa' },
]

const categories = {
  backend: { name: 'Backend', color: '#10b981' },
  frontend: { name: 'Frontend', color: '#3b82f6' },
  qa: { name: 'QA', color: '#f59e0b' }
}

// Convert sprint number to x position
const sprintToX = (d) => (d.sprint - 1) * 14 // 14 days per sprint
const pointsToDuration = (d) => d.points * 1 // 1 day per point
</script>

<template>
  <GanttChart
    :data="sprintData"
    :categories="categories"
    :x="sprintToX"
    :length="pointsToDuration"
    :type="(d) => d.team"
    :height="250"
  />
</template>
```

### With Custom Tooltips

```vue
<template>
  <GanttChart
    :data="tasks"
    :categories="categories"
    :x="(d) => d.start"
    :length="(d) => d.duration"
    :type="(d) => d.phase"
    :getTooltipText="(label, index, data) => {
      const task = data[index]
      return `${task.name}\nDuration: ${task.duration} days\nPhase: ${task.phase}`
    }"
  />
</template>
```

## Gotchas

1. **Three required accessors**: `x`, `length`, and `type` are all required functions
2. **Same units for x and length**: Both must use the same scale (timestamps, days, indices, etc.)
3. **Categories must cover all types**: Every value returned by `type()` needs a category entry
4. **Labels from data array**: Row labels come from the data array order; customize with label accessor
5. **Height vs rowHeight**: `height` is total chart height; `rowHeight` affects individual row spacing

Overview

This skill builds GanttChart (timeline) components for Vue 3 projects. It visualizes temporal data as horizontal bars, making project timelines, schedules, and resource allocation easy to read and interact with.

How this skill works

Provide an array of timeline items and three accessor functions: x (start position), length (duration), and type (category). The chart maps each item to a labeled row, draws bars scaled along an x-axis, and colors bars by category using a categories map. Optional props control size, labels, legend placement, and tooltips.

When to use it

  • Visualizing project schedules and task timelines.
  • Showing team or resource allocation across time.
  • Displaying sprint plans or release roadmaps.
  • Comparing phases (planning, development, testing) by duration.
  • Creating interactive timelines with custom tooltips and legends.

Best practices

  • Always supply the three required accessors: x, length, and type.
  • Use consistent units for x and length (timestamps, days, or indices).
  • Define a category entry for every type value returned by type().
  • Convert durations into milliseconds when using date timestamps.
  • Tune labelWidth, rowHeight, and lineWidth for readable labels and bars.

Example use cases

  • Project plan: map tasks with start dates and durations to show overlaps and dependencies.
  • Sprint timeline: convert sprint numbers to x positions and points to durations.
  • Release pipeline: color bars by phase (planning, development, testing, deployment).
  • Resource planning: show allocations per team member or role over time.
  • Simple task list: render small schedules with compact rowHeight and labelWidth.

FAQ

What are the required props to render the chart?

You must pass data plus three accessors: x (start), length (duration), and type (category). Also provide categories mapping for colors.

Can I use dates for x and length?

Yes. Convert durations to the same unit as x (for example, use timestamps for start and milliseconds for duration).