15 · 甘特图¶
GanttChart 用于展示带时间区间的任务排程,支持任务依赖、进度、基线计划、里程碑、分组图例、层级任务和时间窗口导航。
基础任务¶
start := time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC)
day := func(offset int) time.Time { return start.AddDate(0, 0, offset) }
tasks := []ui.GanttTask{
ui.NewGanttTask("design", "设计", day(0), day(5)).
Group("产品").Progress(.8),
ui.NewGanttTask("build", "开发", day(4), day(12)).
Group("工程").DependsOn("design"),
ui.NewGanttMilestone("launch", "发布", day(12)).
Group("发布").DependsOn("build"),
}
chart := ui.GanttChart("release-plan", tasks).
TimeRange(day(-1), day(14)).
Legend(true).
TaskLabels(true).
TaskAxis("任务").
TimeAxis("2025 年 1 月")
NewGanttTask 的结束时间必须晚于开始时间;零时长节点使用 NewGanttMilestone。
DependsOn 使用任务 key,组件会拒绝空 key、未知任务、自依赖和依赖环。
基线与进度¶
基线显示在当前任务条下方,进度显示为当前任务条的实色部分。颜色可通过 Group 或 Color 指定,默认颜色来自主题。
层级任务¶
ui.NewGanttTask("platform", "平台", day(0), day(20)),
ui.NewGanttTask("api", "公共 API", day(2), day(10)).Parent("platform"),
ui.NewGanttTask("ui", "工作台", day(6), day(16)).Parent("platform"),
父任务会显示展开/折叠控件。没有回调时折叠状态由组件保留;需要受控状态时使用:
初始状态可以由 NewGanttTask(...).Collapsed(true) 设置。父任务引用必须存在,且不能形成父子循环。
时间窗口¶
chart.TimeWindow(day(2), day(10)).OnTimeWindowChange(func(start, end time.Time) {
// 保存或同步当前窗口
_ = ui.GanttTimeWindow{Start: start, End: end}
})
启用回调后,图表支持滚轮缩放、拖拽平移和双击恢复完整范围。TimeWindow 只作为初始/受控窗口;组件不会在每次重绘时覆盖用户的手势结果。
拖拽编辑¶
任务条中部可拖拽移动,左右边缘可调整开始或结束时间。编辑必须显式启用,并通过回调把变更写回 Model:
chart.Editable(true).OnTaskChange(func(change ui.GanttTaskChange) {
// 用 change.Key 定位任务,并保存 change.Start / change.End
// change.PreviousStart / change.PreviousEnd 可用于审计或撤销
})
组件只在释放鼠标时提交一次 OnTaskChange,拖动过程显示本地预览。里程碑不支持区间拖拽。
主题与布局¶
甘特图的行高、条高、圆角、层级缩进、折叠控件尺寸、依赖线和图例间距都在 Theme.Components.GanttChart 中。应用应通过主题覆盖这些 token,而不是在业务代码中绘制覆盖层。
完整示例:examples/gantt_charts。