@canvas-components/gantt-table 0.1.1 → 0.1.2

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.md CHANGED
@@ -2,4 +2,187 @@
2
2
 
3
3
  纯原生 Canvas 甘特图核心,目录组织参考 `@canvas-components/list-table`:配置位于 `schema`,布局与日期计算位于 `domain`,绘制位于 `rendering`,命中测试位于 `interaction`。
4
4
 
5
- 首版支持时间轴、任务条、进度、依赖线、滚动、任务选中及拖拽平移日期。React 接入位于独立的 `@canvas-components/react-gantt-table` 适配包中。
5
+ 首版支持时间轴、任务条、进度、依赖线、横纵滚动、固定时间表头与任务列、任务选中、拖拽平移日期和任务条宽度调整。开启 `editable` 后,可在未排期任务行中拖拽添加任务条,移动或缩放已有任务条,并用 Delete/Backspace 删除选中任务条(清除 `start` / `end`,保留任务行)。选中任务后还可以从左右连接锚点拖到另一任务条,新建或修改依赖;依赖线可独立选中并用 Delete/Backspace 删除。通过 `snapToColumn` 可让移动与缩放吸附到最小日维度,拖拽结果始终限制在时间轴范围内;开启 `rowDraggable` 后可在固定任务列中拖拽调整行顺序,相邻行会以动画让出目标位置,并通过 `onTaskReorder` 返回新顺序。`weekendBackground` 可控制是否显示周末底色,颜色可通过 `theme.weekendBackgroundColor` 调整。滚动位置会根据内容和视口尺寸自动约束,也可以通过实例的 `scrollTo(left, top)` 方法定位。React 接入位于独立的 `@canvas-components/react-gantt-table` 适配包中。
6
+
7
+ ## React 配置示例
8
+
9
+ ```tsx
10
+ import { useState } from "react";
11
+ import { ReactGanttTable } from "@canvas-components/react-gantt-table";
12
+ import type { GanttTask } from "@canvas-components/gantt-table";
13
+
14
+ const taskContent = {
15
+ render: (task: GanttTask) => `${task.title} · ${task.progress ?? 0}%`,
16
+ style: { color: "#ffffff", fontWeight: 600, textAlign: "center" },
17
+ } satisfies Pick<GanttTask, "render" | "style">;
18
+
19
+ export function ProjectPlan() {
20
+ const [tasks, setTasks] = useState<GanttTask[]>([
21
+ {
22
+ id: "research",
23
+ title: "需求调研",
24
+ start: "2026-09-01",
25
+ end: "2026-09-04",
26
+ progress: 100,
27
+ ...taskContent,
28
+ },
29
+ {
30
+ id: "design",
31
+ title: "交互设计",
32
+ start: "2026-09-04",
33
+ end: "2026-09-09",
34
+ progress: 60,
35
+ ...taskContent,
36
+ },
37
+ ]);
38
+ const [dependencies, setDependencies] = useState([
39
+ { from: "research", to: "design", type: "finish-to-start" as const },
40
+ ]);
41
+
42
+ return (
43
+ <ReactGanttTable
44
+ tasks={tasks}
45
+ dependencies={dependencies}
46
+ startDate="2026-08-31"
47
+ endDate="2026-10-01"
48
+ scale="day"
49
+ taskColumnWidth={180}
50
+ editable
51
+ taskColumnResizable
52
+ taskResizable
53
+ snapToColumn
54
+ rowDraggable
55
+ weekendBackground
56
+ theme={{ weekendBackgroundColor: "#fafafa" }}
57
+ onTaskChange={(changedTask) => {
58
+ setTasks((current) =>
59
+ current.map((task) =>
60
+ task.id === changedTask.id ? { ...changedTask } : task,
61
+ ),
62
+ );
63
+ }}
64
+ onTaskReorder={(reorderedTasks) => {
65
+ setTasks(reorderedTasks.map((task) => ({ ...task })));
66
+ }}
67
+ onDependenciesChange={(nextDependencies) => {
68
+ setDependencies(nextDependencies.map((item) => ({ ...item })));
69
+ }}
70
+ style={{ height: 360 }}
71
+ />
72
+ );
73
+ }
74
+ ```
75
+
76
+ ## 原生配置示例
77
+
78
+ ```ts
79
+ import { Gantt } from "@canvas-components/gantt-table";
80
+
81
+ const tasksWithContent = tasks.map((task) => ({
82
+ ...task,
83
+ render: (currentTask) =>
84
+ `${currentTask.title} · ${currentTask.progress ?? 0}%`,
85
+ style: { color: "#ffffff", fontWeight: 600, textAlign: "center" },
86
+ }));
87
+
88
+ const gantt = new Gantt(container, {
89
+ tasks: tasksWithContent,
90
+ dependencies,
91
+ startDate: "2026-08-31",
92
+ endDate: "2026-10-01",
93
+ scale: "week",
94
+ editable: true,
95
+ taskColumnResizable: true,
96
+ taskResizable: true,
97
+ snapToColumn: true,
98
+ rowDraggable: true,
99
+ weekendBackground: true,
100
+ onTaskChange: (task) => console.log(task),
101
+ onTaskReorder: (nextTasks) => console.log(nextTasks),
102
+ onDependenciesChange: (nextDependencies) => console.log(nextDependencies),
103
+ });
104
+
105
+ gantt.mount();
106
+ gantt.scrollTo(320, 0);
107
+ // gantt.destroy();
108
+ ```
109
+
110
+ ## 常用配置
111
+
112
+ | 配置 | 说明 | 默认值 |
113
+ | ------------------------------------------- | ------------------------------------ | ------------- |
114
+ | `scale` | 时间轴维度:`day`、`week`、`month` | `day` |
115
+ | `headerLevels` | 时间轴多层表头配置 | 当前 `scale` |
116
+ | `headerHeight` | 每层表头的默认高度 | `56` |
117
+ | `editable` | 开启任务条新增、移动、缩放与键盘删除 | `false` |
118
+ | `taskResizable` | 编辑模式下允许移动及拖拽两端调整日期 | `true` |
119
+ | `snapToColumn` | 鼠标释放后吸附到最小日维度 | `false` |
120
+ | `rowDraggable` | 在固定任务列中拖拽改变任务顺序 | `false` |
121
+ | `multiTask` | 开启一行多个任务条模式 | `false` |
122
+ | `taskColumnResizable` | 允许拖拽改变固定任务列宽度 | `true` |
123
+ | `taskColumnMinWidth` / `taskColumnMaxWidth` | 固定任务列宽度限制 | `120` / `480` |
124
+ | `weekendBackground` | 是否显示周末底色 | `true` |
125
+ | `theme.weekendBackgroundColor` | 周末背景颜色 | `#fafafa` |
126
+ | `GanttTask.render` | 自定义当前任务条内部内容 | - |
127
+ | `GanttTask.style` | 当前任务条内部文字样式 | - |
128
+ | `onTaskChange` | 任务条新增、移动、缩放或删除完成回调 | - |
129
+ | `onTaskReorder` | 行拖拽排序完成回调 | - |
130
+ | `onDependenciesChange` | 依赖连线新增、修改或删除回调 | - |
131
+
132
+ 任务可通过 `color` 单独设置未完成区域颜色,通过 `progressColor` 设置已完成区域颜色,`progress` 接受 `0` 到 `100` 的进度百分比。未配置任务级颜色时,分别回退到 `theme.taskColor` 与 `theme.taskProgressColor`。
133
+
134
+ 每个任务可通过同级的 `render(task, rowIndex)` 与 `style` 分别配置内部内容和文字样式。`render` 返回字符串、数字或空值;`style` 支持 `color`、`fontSize`、`fontWeight`、`fontFamily` 和 `textAlign`。内容会裁剪在任务条的圆角范围内,空间不足时自动显示省略号。
135
+
136
+ 默认每个顶层 `GanttTask` 对应一行和一个任务条。开启 `multiTask` 后,顶层任务作为行定义,固定列显示其 `title`,并通过 `tasks` 配置同一行内的多个任务条:
137
+
138
+ ```tsx
139
+ <ReactGanttTable
140
+ multiTask
141
+ tasks={[
142
+ {
143
+ id: "development-row",
144
+ title: "核心开发",
145
+ tasks: [
146
+ {
147
+ id: "api",
148
+ title: "接口开发",
149
+ start: "2026-09-09",
150
+ end: "2026-09-13",
151
+ },
152
+ {
153
+ id: "ui",
154
+ title: "界面开发",
155
+ start: "2026-09-13",
156
+ end: "2026-09-17",
157
+ },
158
+ ],
159
+ },
160
+ ]}
161
+ />
162
+ ```
163
+
164
+ 多任务模式下,选择、移动、缩放、删除、`onTaskChange` 和依赖连线均以行内任务为单位;固定列拖拽仍以顶层行为单位。若需要在空白区域拖拽创建任务条,可在行内预先提供未设置 `start` / `end` 的任务。
165
+
166
+ 通过 `headerLevels` 可由上至下配置多层时间表头。支持 `year`、`quarter`、`month`、`week` 和 `day`,每层可单独设置 `height` 或通过 `formatter(start, end)` 自定义文案。未配置时保持当前 `scale` 对应的单层表头:
167
+
168
+ ```tsx
169
+ <ReactGanttTable
170
+ headerHeight={36}
171
+ headerLevels={[
172
+ { unit: "month", height: 42 },
173
+ { unit: "week" },
174
+ {
175
+ unit: "day",
176
+ formatter: (start) => String(start.getDate()),
177
+ },
178
+ ]}
179
+ />
180
+ ```
181
+
182
+ 左侧任务列表头会自动纵向合并并覆盖全部时间表头层级;横向滚动时,各层表头与时间网格保持同步固定。
183
+
184
+ 任务的 `start` 和 `end` 可省略,用于展示尚未排期的空白行。编辑模式下在该行时间轴区域按住并水平拖拽即可创建任务条;选中后按 Delete 或 Backspace 会再次清除这两个字段。请在 `onTaskChange` 中同步受控数据。
185
+
186
+ 依赖关系的 `type` 支持 `finish-to-start`、`start-to-start`、`finish-to-finish`,默认使用 `finish-to-start`。每条依赖可以通过 `color` 单独设置连线颜色;未配置时回退到 `theme.milestoneColor`。
187
+
188
+ 编辑模式下先选中任务,任务条两侧会显示连接锚点。拖动左锚点到另一任务的开始端会创建 `start-to-start`;拖动右锚点到目标开始端会创建 `finish-to-start`,拖到目标完成端会创建 `finish-to-finish`。同一对任务重复连接时会更新原连线类型并保留其自定义颜色。