@lee576/vue3-gantt 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en-US.md +166 -70
- package/README.md +165 -84
- package/dist/vue3-gantt.css +1 -1
- package/dist/vue3-gantt.es.js +5500 -4522
- package/dist/vue3-gantt.es.js.map +1 -1
- package/dist/vue3-gantt.umd.js +87 -87
- package/dist/vue3-gantt.umd.js.map +1 -1
- package/package.json +1 -1
package/README.en-US.md
CHANGED
|
@@ -12,6 +12,14 @@ A feature-rich, highly customizable Vue 3 Gantt chart component that supports ta
|
|
|
12
12
|
|
|
13
13
|
## Interface Preview
|
|
14
14
|
|
|
15
|
+
<div align="center">
|
|
16
|
+
<img src="https://github.com/user-attachments/assets/34562bf8-0709-44aa-a05d-6e970ea8b57f" alt="Vue3 Gantt Chart - Light Theme" />
|
|
17
|
+
<p><em>Light Theme - Complete Task Management Interface</em></p>
|
|
18
|
+
|
|
19
|
+
<img src="https://github.com/user-attachments/assets/d6a60ba1-9f5b-479a-b402-68014ec7c935" alt="Vue3 Gantt Chart - Dark Theme" />
|
|
20
|
+
<p><em>Dark Theme - Eye-friendly Mode</em></p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
15
23
|
```
|
|
16
24
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
17
25
|
│ Vue3 Gantt Professional Component │
|
|
@@ -27,27 +35,63 @@ A feature-rich, highly customizable Vue 3 Gantt chart component that supports ta
|
|
|
27
35
|
└─────────────────┴───────────────────────────────────────────────────────────┘
|
|
28
36
|
```
|
|
29
37
|
|
|
30
|
-
**Key
|
|
31
|
-
- 🎯 Left task list + Right Gantt
|
|
32
|
-
- 📊 Visual progress bars
|
|
33
|
-
- 🔗
|
|
34
|
-
- 🎨 Multi-
|
|
35
|
-
- 🖱️ Drag
|
|
36
|
-
- 🌍
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- **
|
|
45
|
-
- **
|
|
46
|
-
- **
|
|
47
|
-
- **
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
38
|
+
**Key Highlights:**
|
|
39
|
+
- 🎯 **Dual-Column Layout** - Left task list + Right Gantt timeline, clear information at a glance
|
|
40
|
+
- 📊 **Visual Progress** - Real-time progress bars with drag-to-adjust completion
|
|
41
|
+
- 🔗 **Smart Dependencies** - Four dependency types (FS/SS/FF/SF) with auto-drawn links
|
|
42
|
+
- 🎨 **Multi-Theme** - 5 built-in themes, dark mode and custom theme support
|
|
43
|
+
- 🖱️ **Rich Interactions** - Drag move, resize, parent-child task linkage
|
|
44
|
+
- 🌍 **Internationalization** - Built-in 8 languages, easily extensible
|
|
45
|
+
- ⚡ **High Performance** - Virtual scrolling, handles massive task data effortlessly
|
|
46
|
+
- 💎 **Milestones** - Diamond markers for key nodes with dependency support
|
|
47
|
+
|
|
48
|
+
## ✨ Core Features
|
|
49
|
+
|
|
50
|
+
### 📅 Multiple View Modes
|
|
51
|
+
Four time granularities for different scenarios:
|
|
52
|
+
- **Month View** - Long-term project planning, displayed by day
|
|
53
|
+
- **Week View** - Medium-term project tracking, displayed by week
|
|
54
|
+
- **Day View** - Short-term task management, precise to day
|
|
55
|
+
- **Hour View** - Fine task scheduling, displayed by hour
|
|
56
|
+
|
|
57
|
+
### 🔗 Task Dependency Management
|
|
58
|
+
- **Finish-to-Start (FS)** - Successor task starts after predecessor finishes
|
|
59
|
+
- **Start-to-Start (SS)** - Both tasks start simultaneously
|
|
60
|
+
- **Finish-to-Finish (FF)** - Both tasks finish simultaneously
|
|
61
|
+
- **Start-to-Finish (SF)** - Predecessor finishes after successor starts
|
|
62
|
+
|
|
63
|
+
### 💎 Milestone Features
|
|
64
|
+
- Diamond icon markers for project key nodes
|
|
65
|
+
- Support as dependency source and target
|
|
66
|
+
- Auto-detect (start time = end time) or manual marking
|
|
67
|
+
|
|
68
|
+
### 🎨 Theme System
|
|
69
|
+
- 5 beautiful built-in themes (Metro/Dark/Modern/Classic/Colorful)
|
|
70
|
+
- Dark mode support, eye-friendly
|
|
71
|
+
- Complete CSS variable support, easy customization
|
|
72
|
+
- Theme settings auto-saved to browser
|
|
73
|
+
|
|
74
|
+
### 🌍 Internationalization
|
|
75
|
+
- Built-in 8 languages (CN/EN/JP/KR/FR/DE/ES/RU)
|
|
76
|
+
- Instant switching, no page refresh needed
|
|
77
|
+
- All UI elements fully translated
|
|
78
|
+
- Timeline headers auto-localized
|
|
79
|
+
- Easy to extend new languages
|
|
80
|
+
|
|
81
|
+
### 🖱️ Interactive Operations
|
|
82
|
+
- **Drag Move** - Modify task start and end dates
|
|
83
|
+
- **Resize** - Drag edges to adjust task duration
|
|
84
|
+
- **Progress Adjust** - Drag triangle slider to adjust completion
|
|
85
|
+
- **Parent-Child Linkage** - Child tasks follow when parent moves
|
|
86
|
+
- **Split Panel** - Adjustable left-right area ratio
|
|
87
|
+
|
|
88
|
+
### ⚡ Performance Optimization
|
|
89
|
+
- Virtual scroll rendering, supports massive task data
|
|
90
|
+
- Throttled updates, avoids frequent redraws
|
|
91
|
+
- Cached computations, improves response speed
|
|
92
|
+
- On-demand link rendering, optimized drawing performance
|
|
93
|
+
|
|
94
|
+
## 🚀 Installation
|
|
51
95
|
|
|
52
96
|
### Option 1: Install via npm (Recommended)
|
|
53
97
|
|
|
@@ -67,6 +111,7 @@ pnpm add @lee576/vue3-gantt
|
|
|
67
111
|
```bash
|
|
68
112
|
# Clone repository
|
|
69
113
|
git clone https://github.com/lee576/vue3-gantt.git
|
|
114
|
+
cd vue3-gantt
|
|
70
115
|
|
|
71
116
|
# Install dependencies
|
|
72
117
|
npm install
|
|
@@ -75,64 +120,118 @@ npm install
|
|
|
75
120
|
npm run dev
|
|
76
121
|
```
|
|
77
122
|
|
|
78
|
-
##
|
|
123
|
+
## 📚 Quick Start
|
|
79
124
|
|
|
80
|
-
|
|
81
|
-
- dayjs ^1.11.13
|
|
82
|
-
- interactjs ^1.10.27
|
|
83
|
-
- svg.js ^2.7.1
|
|
84
|
-
- vue ^3.5.13
|
|
85
|
-
- zod ^3.24.2
|
|
125
|
+
### 1️⃣ Import Component
|
|
86
126
|
|
|
87
|
-
|
|
127
|
+
```typescript
|
|
128
|
+
import { createApp } from 'vue';
|
|
129
|
+
import Gantt from '@lee576/vue3-gantt';
|
|
130
|
+
import '@lee576/vue3-gantt/style.css';
|
|
88
131
|
|
|
89
|
-
|
|
132
|
+
const app = createApp(App);
|
|
133
|
+
app.use(Gantt); // Global registration
|
|
134
|
+
```
|
|
90
135
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
136
|
+
Or import in component:
|
|
137
|
+
|
|
138
|
+
```vue
|
|
139
|
+
<script setup lang="ts">
|
|
140
|
+
import { ref } from 'vue';
|
|
95
141
|
import Gantt, {
|
|
96
142
|
type DataConfig,
|
|
97
143
|
type StyleConfig,
|
|
98
|
-
type EventConfig
|
|
144
|
+
type EventConfig,
|
|
145
|
+
LinkType
|
|
99
146
|
} from '@lee576/vue3-gantt';
|
|
100
|
-
// Import styles
|
|
101
147
|
import '@lee576/vue3-gantt/style.css';
|
|
102
|
-
|
|
148
|
+
</script>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 2️⃣ Configure Container Height (Important!)
|
|
152
|
+
|
|
153
|
+
> ⚠️ **Important**: The component **must have an explicit container height** to display properly.
|
|
103
154
|
|
|
104
|
-
|
|
155
|
+
**Recommended methods (choose one):**
|
|
105
156
|
|
|
106
157
|
```vue
|
|
158
|
+
<!-- Method 1: Use viewport height (Easiest) -->
|
|
159
|
+
<template>
|
|
160
|
+
<div style="height: 100vh;">
|
|
161
|
+
<gantt :dataConfig="dataConfig" :styleConfig="styleConfig" />
|
|
162
|
+
</div>
|
|
163
|
+
</template>
|
|
164
|
+
|
|
165
|
+
<!-- Method 2: Use fixed height -->
|
|
166
|
+
<template>
|
|
167
|
+
<div style="height: 800px;">
|
|
168
|
+
<gantt :dataConfig="dataConfig" :styleConfig="styleConfig" />
|
|
169
|
+
</div>
|
|
170
|
+
</template>
|
|
171
|
+
|
|
172
|
+
<!-- Method 3: Flex layout -->
|
|
107
173
|
<template>
|
|
108
|
-
<
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
174
|
+
<div style="display: flex; flex-direction: column; height: 100vh;">
|
|
175
|
+
<div>Header</div>
|
|
176
|
+
<div style="flex: 1;"> <!-- Auto-fill remaining space -->
|
|
177
|
+
<gantt :dataConfig="dataConfig" :styleConfig="styleConfig" />
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
113
180
|
</template>
|
|
114
181
|
```
|
|
115
182
|
|
|
116
|
-
|
|
117
|
-
|
|
183
|
+
<details>
|
|
184
|
+
<summary>💡 Why set height?</summary>
|
|
185
|
+
|
|
186
|
+
The component uses `height: 100%` internally. According to CSS specifications, percentage height requires the parent element to have an explicit height to calculate. Without a height on the parent container, the component will collapse.
|
|
187
|
+
|
|
188
|
+
**Solutions:**
|
|
189
|
+
- Use `100vh` (viewport height)
|
|
190
|
+
- Use fixed pixel value (e.g., `800px`)
|
|
191
|
+
- Use Flex layout's `flex: 1`
|
|
192
|
+
- Configure `html, body { height: 100%; }` then use `100%`
|
|
193
|
+
|
|
194
|
+
</details>
|
|
195
|
+
|
|
196
|
+
### 3️⃣ Basic Configuration
|
|
197
|
+
|
|
198
|
+
```vue
|
|
199
|
+
<template>
|
|
200
|
+
<div style="height: 100vh;">
|
|
201
|
+
<gantt
|
|
202
|
+
:dataConfig="dataConfig"
|
|
203
|
+
:styleConfig="styleConfig"
|
|
204
|
+
:eventConfig="eventConfig"
|
|
205
|
+
/>
|
|
206
|
+
</div>
|
|
207
|
+
</template>
|
|
208
|
+
|
|
209
|
+
<script setup lang="ts">
|
|
210
|
+
import { ref, onMounted } from 'vue';
|
|
211
|
+
import dayjs from 'dayjs';
|
|
212
|
+
import Gantt, {
|
|
213
|
+
type DataConfig,
|
|
214
|
+
type StyleConfig,
|
|
215
|
+
type EventConfig,
|
|
216
|
+
LinkType
|
|
217
|
+
} from '@lee576/vue3-gantt';
|
|
218
|
+
import '@lee576/vue3-gantt/style.css';
|
|
219
|
+
|
|
220
|
+
// 🎨 Style Configuration
|
|
118
221
|
const styleConfig = ref<StyleConfig>({
|
|
119
222
|
headersHeight: 100, // Header height
|
|
120
223
|
rowHeight: 60, // Row height
|
|
121
224
|
setBarColor: (row) => {
|
|
122
|
-
// Custom task bar
|
|
123
|
-
const colorMap = {
|
|
124
|
-
|
|
125
|
-
'important': 'blue',
|
|
126
|
-
'normal': 'gray'
|
|
127
|
-
};
|
|
128
|
-
return colorMap[row.level] ?? 'black';
|
|
225
|
+
// Custom task bar colors
|
|
226
|
+
const colorMap = { 'urgent': '#ef4444', 'important': '#3b82f6', 'normal': '#6b7280' };
|
|
227
|
+
return colorMap[row.level] ?? '#000';
|
|
129
228
|
}
|
|
130
229
|
});
|
|
131
230
|
|
|
132
|
-
// Data
|
|
231
|
+
// 📊 Data Configuration
|
|
133
232
|
const dataConfig = ref<DataConfig>({
|
|
134
|
-
queryStartDate: '',
|
|
135
|
-
queryEndDate: '',
|
|
233
|
+
queryStartDate: dayjs().startOf('month').format('YYYY-MM-DD'),
|
|
234
|
+
queryEndDate: dayjs().endOf('month').format('YYYY-MM-DD'),
|
|
136
235
|
dataSource: [],
|
|
137
236
|
dependencies: [],
|
|
138
237
|
mapFields: {
|
|
@@ -147,42 +246,39 @@ const dataConfig = ref<DataConfig>({
|
|
|
147
246
|
},
|
|
148
247
|
taskHeaders: [
|
|
149
248
|
{ title: 'No.', width: 80, property: 'no', show: true },
|
|
150
|
-
{ title: 'Task Name', width:
|
|
249
|
+
{ title: 'Task Name', width: 200, property: 'task', show: true },
|
|
151
250
|
{ title: 'Priority', width: 90, property: 'priority', show: true },
|
|
152
251
|
{ title: 'Start Date', width: 150, property: 'startdate', show: true },
|
|
153
252
|
{ title: 'End Date', width: 150, property: 'enddate', show: true },
|
|
154
|
-
{ title: 'Duration', width: 90, property: 'takestime', show: true }
|
|
155
253
|
]
|
|
156
254
|
});
|
|
157
255
|
|
|
158
|
-
// Event
|
|
256
|
+
// ⚡ Event Configuration
|
|
159
257
|
const eventConfig = ref<EventConfig>({
|
|
160
|
-
addRootTask: (row) => console.log('Add root task', row),
|
|
161
|
-
addSubTask: (task) => console.log('Add subtask', task),
|
|
162
|
-
removeTask: (task) => console.log('Remove task', task),
|
|
163
|
-
editTask: (task) => console.log('Edit task', task),
|
|
164
258
|
queryTask: async (startDate, endDate, mode) => {
|
|
165
259
|
// Query task data
|
|
166
|
-
|
|
260
|
+
const tasks = await fetchTasks(startDate, endDate);
|
|
261
|
+
dataConfig.value.dataSource = tasks;
|
|
167
262
|
},
|
|
168
263
|
barDate: (id, startDate, endDate) => {
|
|
169
|
-
console.log('Task date changed', id, startDate, endDate);
|
|
170
|
-
},
|
|
171
|
-
allowChangeTaskDate: (allow) => {
|
|
172
|
-
console.log('Allow date change', allow);
|
|
264
|
+
console.log('Task date changed', { id, startDate, endDate });
|
|
173
265
|
},
|
|
174
266
|
updateProgress: (detail) => {
|
|
175
267
|
console.log('Progress updated', detail);
|
|
176
268
|
}
|
|
177
269
|
});
|
|
178
270
|
|
|
271
|
+
// Initialize and load data
|
|
179
272
|
onMounted(() => {
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
eventConfig.value.queryTask(
|
|
273
|
+
const start = dayjs().startOf('month').format('YYYY-MM-DD');
|
|
274
|
+
const end = dayjs().endOf('month').format('YYYY-MM-DD');
|
|
275
|
+
eventConfig.value.queryTask?.(start, end, 'month');
|
|
183
276
|
});
|
|
277
|
+
</script>
|
|
184
278
|
```
|
|
185
279
|
|
|
280
|
+
## 📖 Configuration Guide
|
|
281
|
+
|
|
186
282
|
## Configuration Details
|
|
187
283
|
|
|
188
284
|
### StyleConfig
|
package/README.md
CHANGED
|
@@ -21,47 +21,78 @@
|
|
|
21
21
|
|
|
22
22
|
## 界面预览
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
│ 子任务1.1 - 需求│ ████████████ 100% │
|
|
32
|
-
│ 主任务2 - 开发阶段│ ████████████████████████████ 60% │
|
|
33
|
-
│ 主任务3 - 测试阶段│ ████████████████ 45% │
|
|
34
|
-
│ 主任务4 - 部署上线│ ████████ 30% │
|
|
35
|
-
│ 主任务5 - 维护优化│ ████ 0% │
|
|
36
|
-
└─────────────────┴───────────────────────────────────────────────────────────┘
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
**主要特点:**
|
|
40
|
-
- 🎯 左侧任务列表 + 右侧甘特图时间轴
|
|
41
|
-
- 📊 可视化进度条显示任务完成度
|
|
42
|
-
- 🔗 任务间依赖关系连线
|
|
43
|
-
- 🎨 多主题支持(浅色/深色/彩色等)
|
|
44
|
-
- 🖱️ 拖拽调整任务时间和进度
|
|
45
|
-
- 🌍 多语言支持(中文/English/日本語/한국어/Français/Deutsch/Español/Русский)
|
|
46
|
-
|
|
47
|
-
## 特性
|
|
24
|
+
<div align="center">
|
|
25
|
+
<img src="https://github.com/user-attachments/assets/34562bf8-0709-44aa-a05d-6e970ea8b57f" alt="Vue3 Gantt Chart - Light Theme" />
|
|
26
|
+
<p><em>浅色主题 - 完整的任务管理界面</em></p>
|
|
27
|
+
|
|
28
|
+
<img src="https://github.com/user-attachments/assets/d6a60ba1-9f5b-479a-b402-68014ec7c935" alt="Vue3 Gantt Chart - Dark Theme" />
|
|
29
|
+
<p><em>深色主题 - 护眼模式</em></p>
|
|
30
|
+
</div>
|
|
48
31
|
|
|
49
|
-
|
|
50
|
-
- **任务依赖关系** - 支持 FS、SS、FF、SF 四种依赖类型
|
|
51
|
-
- **里程碑功能** - 菱形图标标记项目关键节点,支持作为依赖源和目标
|
|
52
|
-
- **主题系统** - 内置 5 种主题,支持自定义主题
|
|
53
|
-
- **国际化支持** - 内置 8 种语言,可扩展更多语言
|
|
54
|
-
- **进度管理** - 可视化进度条,支持拖拽调整进度
|
|
55
|
-
- **交互操作** - 支持任务拖拽、调整大小、父子任务联动
|
|
56
|
-
- **响应式设计** - 可调整分割面板比例
|
|
57
|
-
- **高性能** - 虚拟滚动优化,支持大量任务数据
|
|
32
|
+
```
|
|
58
33
|
|
|
59
|
-
|
|
34
|
+
**核心亮点:**
|
|
35
|
+
- 🎯 **双栏布局** - 左侧任务列表 + 右侧甘特图时间轴,信息一目了然
|
|
36
|
+
- 📊 **可视化进度** - 实时进度条显示,支持拖拽调整完成度
|
|
37
|
+
- 🔗 **智能依赖** - 四种依赖类型(FS/SS/FF/SF),自动绘制连线
|
|
38
|
+
- 🎨 **多主题切换** - 5种内置主题,支持深色模式和自定义主题
|
|
39
|
+
- 🖱️ **交互丰富** - 拖拽移动、调整大小、父子任务联动
|
|
40
|
+
- 🌍 **国际化** - 内置8种语言,轻松扩展更多语言
|
|
41
|
+
- ⚡ **高性能** - 虚拟滚动优化,轻松处理大量任务数据
|
|
42
|
+
- 💎 **里程碑** - 菱形标记关键节点,支持依赖关系
|
|
43
|
+
|
|
44
|
+
## ✨ 核心特性
|
|
45
|
+
|
|
46
|
+
### 📅 多视图模式
|
|
47
|
+
支持四种时间粒度,满足不同场景需求:
|
|
48
|
+
- **月视图** - 长期项目规划,按天显示
|
|
49
|
+
- **周视图** - 中期项目跟踪,按周显示
|
|
50
|
+
- **日视图** - 短期任务管理,精确到天
|
|
51
|
+
- **时视图** - 精细任务调度,按小时显示
|
|
52
|
+
|
|
53
|
+
### 🔗 任务依赖管理
|
|
54
|
+
- **完成-开始 (FS)** - 前置任务完成后,后续任务才能开始
|
|
55
|
+
- **开始-开始 (SS)** - 两个任务同时开始
|
|
56
|
+
- **完成-完成 (FF)** - 两个任务同时完成
|
|
57
|
+
- **开始-完成 (SF)** - 后续任务开始后,前置任务才能完成
|
|
58
|
+
|
|
59
|
+
### 💎 里程碑功能
|
|
60
|
+
- 菱形图标标记项目关键节点
|
|
61
|
+
- 支持作为依赖关系的源和目标
|
|
62
|
+
- 自动识别(开始时间=结束时间)或手动标记
|
|
63
|
+
|
|
64
|
+
### 🎨 主题系统
|
|
65
|
+
- 内置 5 种精美主题(Metro/Dark/Modern/Classic/Colorful)
|
|
66
|
+
- 支持深色模式,护眼舒适
|
|
67
|
+
- 完整的 CSS 变量支持,轻松自定义主题
|
|
68
|
+
- 主题设置自动保存到浏览器
|
|
69
|
+
|
|
70
|
+
### 🌍 国际化支持
|
|
71
|
+
- 内置 8 种语言(中/英/日/韩/法/德/西/俄)
|
|
72
|
+
- 即时切换,无需刷新页面
|
|
73
|
+
- 所有界面元素完整翻译
|
|
74
|
+
- 时间轴表头自动本地化
|
|
75
|
+
- 易于扩展新语言
|
|
76
|
+
|
|
77
|
+
### 🖱️ 交互操作
|
|
78
|
+
- **拖拽移动** - 修改任务开始和结束日期
|
|
79
|
+
- **调整大小** - 拖拽边缘调整任务时长
|
|
80
|
+
- **进度调整** - 拖拽三角滑块调整完成度
|
|
81
|
+
- **父子联动** - 父任务移动时子任务自动跟随
|
|
82
|
+
- **分割面板** - 可调整左右区域比例
|
|
83
|
+
|
|
84
|
+
### ⚡ 性能优化
|
|
85
|
+
- 虚拟滚动渲染,支持海量任务数据
|
|
86
|
+
- 节流更新机制,避免频繁重绘
|
|
87
|
+
- 计算结果缓存,提升响应速度
|
|
88
|
+
- 按需渲染连线,优化绘制性能
|
|
89
|
+
|
|
90
|
+
## 🚀 安装使用
|
|
60
91
|
|
|
61
92
|
### 方式一:通过 npm 安装(推荐)
|
|
62
93
|
|
|
63
94
|
```bash
|
|
64
|
-
# 使用 npm
|
|
95
|
+
# 使用 npm
|
|
65
96
|
npm install @lee576/vue3-gantt
|
|
66
97
|
|
|
67
98
|
# 或使用 yarn
|
|
@@ -74,8 +105,9 @@ pnpm add @lee576/vue3-gantt
|
|
|
74
105
|
### 方式二:从源码构建
|
|
75
106
|
|
|
76
107
|
```bash
|
|
77
|
-
#
|
|
108
|
+
# 克隆仓库
|
|
78
109
|
git clone https://github.com/lee576/vue3-gantt.git
|
|
110
|
+
cd vue3-gantt
|
|
79
111
|
|
|
80
112
|
# 安装依赖
|
|
81
113
|
npm install
|
|
@@ -84,64 +116,118 @@ npm install
|
|
|
84
116
|
npm run dev
|
|
85
117
|
```
|
|
86
118
|
|
|
87
|
-
##
|
|
119
|
+
## 📚 快速开始
|
|
88
120
|
|
|
89
|
-
|
|
90
|
-
- dayjs ^1.11.13
|
|
91
|
-
- interactjs ^1.10.27
|
|
92
|
-
- svg.js ^2.7.1
|
|
93
|
-
- vue ^3.5.13
|
|
94
|
-
- zod ^3.24.2
|
|
121
|
+
### 1️⃣ 引入组件
|
|
95
122
|
|
|
96
|
-
|
|
123
|
+
```typescript
|
|
124
|
+
import { createApp } from 'vue';
|
|
125
|
+
import Gantt from '@lee576/vue3-gantt';
|
|
126
|
+
import '@lee576/vue3-gantt/style.css';
|
|
97
127
|
|
|
98
|
-
|
|
128
|
+
const app = createApp(App);
|
|
129
|
+
app.use(Gantt); // 全局注册
|
|
130
|
+
```
|
|
99
131
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
132
|
+
或在组件中单独引入:
|
|
133
|
+
|
|
134
|
+
```vue
|
|
135
|
+
<script setup lang="ts">
|
|
136
|
+
import { ref } from 'vue';
|
|
104
137
|
import Gantt, {
|
|
105
138
|
type DataConfig,
|
|
106
139
|
type StyleConfig,
|
|
107
|
-
type EventConfig
|
|
140
|
+
type EventConfig,
|
|
141
|
+
LinkType
|
|
108
142
|
} from '@lee576/vue3-gantt';
|
|
109
|
-
// 引入样式文件
|
|
110
143
|
import '@lee576/vue3-gantt/style.css';
|
|
111
|
-
|
|
144
|
+
</script>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 2️⃣ 配置容器高度(重要!)
|
|
112
148
|
|
|
113
|
-
|
|
149
|
+
> ⚠️ **注意**:组件**必须有明确的容器高度**才能正常显示。
|
|
150
|
+
|
|
151
|
+
**推荐方法(任选其一):**
|
|
114
152
|
|
|
115
153
|
```vue
|
|
154
|
+
<!-- 方法1:使用视口高度(最简单) -->
|
|
155
|
+
<template>
|
|
156
|
+
<div style="height: 100vh;">
|
|
157
|
+
<gantt :dataConfig="dataConfig" :styleConfig="styleConfig" />
|
|
158
|
+
</div>
|
|
159
|
+
</template>
|
|
160
|
+
|
|
161
|
+
<!-- 方法2:使用固定高度 -->
|
|
116
162
|
<template>
|
|
117
|
-
<
|
|
118
|
-
:styleConfig="styleConfig"
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
163
|
+
<div style="height: 800px;">
|
|
164
|
+
<gantt :dataConfig="dataConfig" :styleConfig="styleConfig" />
|
|
165
|
+
</div>
|
|
166
|
+
</template>
|
|
167
|
+
|
|
168
|
+
<!-- 方法3:Flex 布局 -->
|
|
169
|
+
<template>
|
|
170
|
+
<div style="display: flex; flex-direction: column; height: 100vh;">
|
|
171
|
+
<div>Header</div>
|
|
172
|
+
<div style="flex: 1;"> <!-- 自动填充剩余空间 -->
|
|
173
|
+
<gantt :dataConfig="dataConfig" :styleConfig="styleConfig" />
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
122
176
|
</template>
|
|
123
177
|
```
|
|
124
178
|
|
|
125
|
-
|
|
126
|
-
|
|
179
|
+
<details>
|
|
180
|
+
<summary>💡 为什么需要设置高度?</summary>
|
|
181
|
+
|
|
182
|
+
组件内部使用了 `height: 100%`,根据 CSS 规范,百分比高度需要父元素有明确的高度才能计算。如果父容器没有设置高度,组件会高度坑塌。
|
|
183
|
+
|
|
184
|
+
**解决方案**:
|
|
185
|
+
- 使用 `100vh`(视口高度)
|
|
186
|
+
- 使用固定像素值(如 `800px`)
|
|
187
|
+
- 使用 Flex 布局的 `flex: 1`
|
|
188
|
+
- 配置 `html, body { height: 100%; }` 后使用 `100%`
|
|
189
|
+
|
|
190
|
+
</details>
|
|
191
|
+
|
|
192
|
+
### 3️⃣ 基本配置
|
|
193
|
+
|
|
194
|
+
```vue
|
|
195
|
+
<template>
|
|
196
|
+
<div style="height: 100vh;">
|
|
197
|
+
<gantt
|
|
198
|
+
:dataConfig="dataConfig"
|
|
199
|
+
:styleConfig="styleConfig"
|
|
200
|
+
:eventConfig="eventConfig"
|
|
201
|
+
/>
|
|
202
|
+
</div>
|
|
203
|
+
</template>
|
|
204
|
+
|
|
205
|
+
<script setup lang="ts">
|
|
206
|
+
import { ref, onMounted } from 'vue';
|
|
207
|
+
import dayjs from 'dayjs';
|
|
208
|
+
import Gantt, {
|
|
209
|
+
type DataConfig,
|
|
210
|
+
type StyleConfig,
|
|
211
|
+
type EventConfig,
|
|
212
|
+
LinkType
|
|
213
|
+
} from '@lee576/vue3-gantt';
|
|
214
|
+
import '@lee576/vue3-gantt/style.css';
|
|
215
|
+
|
|
216
|
+
// 🎨 样式配置
|
|
127
217
|
const styleConfig = ref<StyleConfig>({
|
|
128
218
|
headersHeight: 100, // 表头高度
|
|
129
219
|
rowHeight: 60, // 行高
|
|
130
220
|
setBarColor: (row) => {
|
|
131
221
|
// 自定义任务条颜色
|
|
132
|
-
const colorMap = {
|
|
133
|
-
|
|
134
|
-
'重要': 'blue',
|
|
135
|
-
'一般': 'gray'
|
|
136
|
-
};
|
|
137
|
-
return colorMap[row.level] ?? 'black';
|
|
222
|
+
const colorMap = { '紧急': '#ef4444', '重要': '#3b82f6', '一般': '#6b7280' };
|
|
223
|
+
return colorMap[row.level] ?? '#000';
|
|
138
224
|
}
|
|
139
225
|
});
|
|
140
226
|
|
|
141
|
-
// 数据配置
|
|
227
|
+
// 📊 数据配置
|
|
142
228
|
const dataConfig = ref<DataConfig>({
|
|
143
|
-
queryStartDate: '',
|
|
144
|
-
queryEndDate: '',
|
|
229
|
+
queryStartDate: dayjs().startOf('month').format('YYYY-MM-DD'),
|
|
230
|
+
queryEndDate: dayjs().endOf('month').format('YYYY-MM-DD'),
|
|
145
231
|
dataSource: [],
|
|
146
232
|
dependencies: [],
|
|
147
233
|
mapFields: {
|
|
@@ -156,40 +242,35 @@ const dataConfig = ref<DataConfig>({
|
|
|
156
242
|
},
|
|
157
243
|
taskHeaders: [
|
|
158
244
|
{ title: '序号', width: 80, property: 'no', show: true },
|
|
159
|
-
{ title: '任务名称', width:
|
|
245
|
+
{ title: '任务名称', width: 200, property: 'task', show: true },
|
|
160
246
|
{ title: '优先级', width: 90, property: 'priority', show: true },
|
|
161
247
|
{ title: '开始时间', width: 150, property: 'startdate', show: true },
|
|
162
248
|
{ title: '结束时间', width: 150, property: 'enddate', show: true },
|
|
163
|
-
{ title: '耗时', width: 90, property: 'takestime', show: true }
|
|
164
249
|
]
|
|
165
250
|
});
|
|
166
251
|
|
|
167
|
-
// 事件配置
|
|
252
|
+
// ⚡ 事件配置
|
|
168
253
|
const eventConfig = ref<EventConfig>({
|
|
169
|
-
addRootTask: (row) => console.log('添加根任务', row),
|
|
170
|
-
addSubTask: (task) => console.log('添加子任务', task),
|
|
171
|
-
removeTask: (task) => console.log('删除任务', task),
|
|
172
|
-
editTask: (task) => console.log('编辑任务', task),
|
|
173
254
|
queryTask: async (startDate, endDate, mode) => {
|
|
174
255
|
// 查询任务数据
|
|
175
|
-
|
|
256
|
+
const tasks = await fetchTasks(startDate, endDate);
|
|
257
|
+
dataConfig.value.dataSource = tasks;
|
|
176
258
|
},
|
|
177
259
|
barDate: (id, startDate, endDate) => {
|
|
178
|
-
console.log('任务日期变更', id, startDate, endDate);
|
|
179
|
-
},
|
|
180
|
-
allowChangeTaskDate: (allow) => {
|
|
181
|
-
console.log('允许修改日期', allow);
|
|
260
|
+
console.log('任务日期变更', { id, startDate, endDate });
|
|
182
261
|
},
|
|
183
262
|
updateProgress: (detail) => {
|
|
184
263
|
console.log('进度更新', detail);
|
|
185
264
|
}
|
|
186
265
|
});
|
|
187
266
|
|
|
267
|
+
// 初始化加载数据
|
|
188
268
|
onMounted(() => {
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
eventConfig.value.queryTask(
|
|
269
|
+
const start = dayjs().startOf('month').format('YYYY-MM-DD');
|
|
270
|
+
const end = dayjs().endOf('month').format('YYYY-MM-DD');
|
|
271
|
+
eventConfig.value.queryTask?.(start, end, '月');
|
|
192
272
|
});
|
|
273
|
+
</script>
|
|
193
274
|
```
|
|
194
275
|
|
|
195
276
|
## 配置详解
|