|
| 1 | +import { Meta, Canvas, ArgTypes } from '@storybook/addon-docs/blocks' |
| 2 | +import * as GanttChartStories from './GanttChartComponent.stories' |
| 3 | + |
| 4 | +<Meta of={GanttChartStories} /> |
| 5 | + |
| 6 | +# Gantt Chart |
| 7 | + |
| 8 | +A flexible, virtualized Gantt chart that supports daily and weekly views, layered activity types, and translation-ready labels. |
| 9 | + |
| 10 | +## Overview |
| 11 | + |
| 12 | +The GanttChart component renders a calendar grid with month and week headers, and a virtualized list of rows. Activities can be rendered as stripes, primary bars, or compact stacked minis. Weekly view collapses the grid to week columns and expands month headers across overlapping weeks. |
| 13 | + |
| 14 | +### Key Features |
| 15 | + |
| 16 | +- **Daily & Weekly Views**: Toggle with `viewMode`. |
| 17 | +- **Layered Activities**: Stripe, bar, and mini styles with overlap rules. |
| 18 | +- **Stacked Minis**: Overlapping minis grow row height automatically. |
| 19 | +- **Virtualized Rows**: Smooth scrolling for large datasets. |
| 20 | +- **Translation Ready**: All user-facing labels are passed through `t()`. |
| 21 | +- **Configurable Sidebar**: Adjust the label column width via `leftHeaderWidthPx`. |
| 22 | + |
| 23 | +## Basic Usage |
| 24 | + |
| 25 | +<Canvas of={GanttChartStories.Default} /> |
| 26 | + |
| 27 | +```vue |
| 28 | +<template> |
| 29 | + <GanttChartComponent |
| 30 | + :start-date="startDate" |
| 31 | + :end-date="endDate" |
| 32 | + :rows="rows" |
| 33 | + :links="links" |
| 34 | + header-label="gantt_chart.header" |
| 35 | + /> |
| 36 | +</template> |
| 37 | +
|
| 38 | +<script setup lang="ts"> |
| 39 | +import { ref } from 'vue' |
| 40 | +import GanttChartComponent from '@/components/GanttChartComponent/GanttChartComponent.vue' |
| 41 | +
|
| 42 | +const startDate = ref(new Date(2026, 0, 1)) |
| 43 | +const endDate = ref(new Date(2026, 0, 2)) |
| 44 | +const rows = ref([ |
| 45 | + { |
| 46 | + id: 1, |
| 47 | + header: 'gantt_chart.row', |
| 48 | + activities: [ |
| 49 | + { |
| 50 | + id: 'planned', |
| 51 | + label: 'gantt_chart.activity', |
| 52 | + startDate: new Date(2026, 0, 1), |
| 53 | + endDate: new Date(2026, 0, 4), |
| 54 | + visualType: 'stripe', |
| 55 | + color: 'rgba(59, 130, 246, 0.2)', |
| 56 | + }, |
| 57 | + { |
| 58 | + id: 'optimized', |
| 59 | + label: 'gantt_chart.activity', |
| 60 | + startDate: new Date(2026, 0, 2), |
| 61 | + endDate: new Date(2026, 0, 8), |
| 62 | + visualType: 'bar', |
| 63 | + colorClass: 'bg-emerald-400/80', |
| 64 | + }, |
| 65 | + ], |
| 66 | + }, |
| 67 | +]) |
| 68 | +const links = ref([{ fromId: 'planned', toId: 'optimized' }]) |
| 69 | +</script> |
| 70 | +``` |
| 71 | + |
| 72 | +## Weekly View |
| 73 | + |
| 74 | +```vue |
| 75 | +<GanttChartComponent |
| 76 | + :start-date="startDate" |
| 77 | + :end-date="endDate" |
| 78 | + :rows="rows" |
| 79 | + view-mode="week" |
| 80 | + :show-weekend-shading="false" |
| 81 | +/> |
| 82 | +``` |
| 83 | + |
| 84 | +- Weekly view renders a single week cell per column. |
| 85 | +- Activities fill any week they overlap (inclusive by week). |
| 86 | +- Month headers can span overlapping weeks. |
| 87 | + |
| 88 | +## Activity Types |
| 89 | + |
| 90 | +Activities support a `visualType`: |
| 91 | + |
| 92 | +- `stripe`: diagonal background context |
| 93 | +- `bar`: primary rounded bar |
| 94 | +- `mini`: compact bar, stacked into lanes when overlapping |
| 95 | + |
| 96 | +## Tooltips and Clicks |
| 97 | + |
| 98 | +```vue |
| 99 | +<GanttChartComponent |
| 100 | + :start-date="startDate" |
| 101 | + :end-date="endDate" |
| 102 | + :rows="rows" |
| 103 | + :links="links" |
| 104 | + :activity-tooltip="(activity, row) => `${row?.id}: ${activity.label}`" |
| 105 | + :activity-click="(activity, row) => console.log(activity, row)" |
| 106 | +/> |
| 107 | +``` |
| 108 | + |
| 109 | +## API Reference |
| 110 | + |
| 111 | +<ArgTypes of={GanttChartStories} /> |
| 112 | + |
| 113 | +```ts |
| 114 | +export type GanttChartActivityData = { |
| 115 | + id?: string | number |
| 116 | + label?: string |
| 117 | + startDate: Date |
| 118 | + endDate: Date |
| 119 | + visualType?: 'stripe' | 'bar' | 'mini' |
| 120 | + color?: string |
| 121 | + colorClass?: string |
| 122 | +} |
| 123 | + |
| 124 | +export type GanttChartRowData = { |
| 125 | + id?: string | number |
| 126 | + label?: string |
| 127 | + header?: string |
| 128 | + activities: GanttChartActivityData[] |
| 129 | +} |
| 130 | + |
| 131 | +export type GanttChartLinkData = { |
| 132 | + id?: string | number |
| 133 | + fromId: string | number |
| 134 | + toId: string | number |
| 135 | + type?: 'finish-start' | 'start-start' |
| 136 | + color?: string |
| 137 | +} |
| 138 | +``` |
| 139 | +
|
| 140 | +## Translation Notes |
| 141 | +
|
| 142 | +- `headerLabel`, `row.header`, `row.label`, and `activity.label` are treated as translation keys. |
| 143 | +- Week labels use the key `gantt_chart.week` by default. |
0 commit comments