Flutter甘特图展示插件gantt_view的使用
Flutter甘特图展示插件gantt_view的使用
特性
- 固定的任务名称列
- 固定的日期图例行
- 可自定义的任务栏颜色
- 可自定义的任务栏高度
- 可自定义的任务栏间距
- 可自定义的任务栏圆角半径
- 能够在日视图和周视图之间切换
- 显示周末的不同颜色
- 可自定义周末颜色
- 自定义高亮日期
- 可自定义高亮日期颜色
- 任务栏悬停或点击时显示提示信息
- 可自定义提示样式
使用
所有需要做的就是传入一个带有List<GridRow>的GanttChart<T>小部件。List<GridRow>是一个包含<ActivityGridRow>和TaskGridRow的对象列表,构造方法的例子可以在example\lib\main.dart文件中找到。
该插件还提供了基本的主题选项,用于自定义GanttChart的外观,例如改变行的外观以及是否显示头部。
ActivityGridRow和TaskGridRow是GanttChart中可以显示的两种类型的行。ActivityGridRow是一种显示任务组标题的行,而TaskGridRow是一种显示任务的行。要自定义行的外观,可以向GanttChart小部件提供一个GanttRowStyle。GanttRowStyle有两个字段,activityLabelBuilder和taskLabelBuilder,分别用于自定义ActivityGridRow和TaskGridRow的外观。
其他自定义选项包括更改网格线的颜色、周末列的颜色以及高亮日期的颜色。GanttChart还可以在悬停或点击任务时显示提示信息。
GanttChart<ExampleEventItem>(
rows: _items.toRows(),
style: GanttStyle(
columnWidth: 100,
barHeight: 16,
timelineAxisType: TimelineAxisType.daily,
tooltipType: TooltipType.hover,
taskBarColor: Colors.blue.shade400,
activityLabelColor: Colors.blue.shade500,
taskLabelColor: Colors.blue.shade900,
taskLabelBuilder: (task) => TaskLabel(task),
gridColor: Colors.grey.shade300,
taskBarRadius: 8,
activityLabelBuilder: (activity) => ActivityLabel(activity),
axisDividerColor: Colors.grey.shade500,
tooltipColor: Colors.redAccent,
tooltipPadding:
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
weekendColor: Colors.grey.shade200,
snapToDay: false,
),
dateLines: [
GanttDateLine(
date: DateTime.timestamp(), width: 2, color: Colors.orangeAccent),
GanttDateLine(
date: DateTime.timestamp().add(const Duration(days: 2)),
),
],
)
样式
| 属性 | 类型 |
|---|---|
| taskBarColor | Color |
| taskBarRadius | double |
| taskLabelColor | Color |
| activityLabelColor | Color |
| chartTitleBuilder | Widget Function()? |
| taskLabelBuilder | Widget Function(TaskGridRow) |
| activityLabelBuilder | Widget Function(ActivityGridRow activity)? |
| yearLabelBuilder | Widget Function(int year) |
| monthLabelBuilder | Widget Function(Month month) |
| dayLabelBuilder | Widget Function(int day) |
| gridColor | Color? |
| weekendColor | Color? |
| holidayColor | Color |
| axisDividerColor | Color? |
| tooltipColor | Color |
| tooltipStyle | TextStyle |
| tooltipPadding | EdgeInsets |
| tooltipRadius | double |
| barHeight | double |
| columnWidth | double |
| tooltipWidth | double |
| labelColumnWidth | double |
| snapToDay | bool |
| showYear | bool |
| showMonth | bool |
| showDay | bool |
| timelineAxisType | TimelineAxisType |
| tooltipType | TooltipType |
其他信息
这是一个正在进行中的项目,尚未准备好用于生产环境。API可能会发生变化。欢迎提供反馈,也欢迎提交拉取请求。
待办事项
- ❌ 添加缩放功能
- ✅ 添加自定义单个任务栏颜色的功能
- ❌ 添加为整个图表定义自定义开始和结束时间的功能
- ❌ 测试
- ❌ 添加定义图例高度、标签列宽度的功能,覆盖自动计算的值
- ❌ 添加隐藏图例的功能
- ❌ 添加隐藏标题/标签的功能
- ❌ 添加设置一周第一天的功能
- ❌ 添加将高亮日和周末日设置为纯色的功能,以便任务栏不可见
- ❌ 添加滚动条
- ✅ 添加日期线以允许用户显示重要日期
当前已知问题
- ❌ 有时在实例化时,图表的平移偏移没有正确更新,导致平移速度比预期慢。
- ❌ 大量数据项列表可能导致图表渲染缓慢,原因如下:
- 将大量数据排序为活动和任务;
- 基于最长标签计算标签列的宽度;
- 目前通过为每个标签运行一个实用函数来获取宽度,然后取所有标签的最大宽度,这效率不高。
- ✅ 当调整大小时,图表可能会尝试渲染超出其边界的区域,而不是更新平移偏移到新边界。
- ❌ 非UTC时间的日期在跨越夏令时时区变更时可能会出现问题,因为图表不考虑夏令时。
- ❌ 在网页端,有时使用水平鼠标滚轮无法进行水平滚动。
示例代码
import 'package:example/data.dart';
import 'package:flutter/material.dart';
import 'package:gantt_view/gantt_view.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
useMaterial3: true,
),
home: const MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<ExampleEventItem> _items = Data.dummyData;
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: GanttChart<ExampleEventItem>(
rows: _items.toRows(),
showCurrentDate: true,
style: GanttStyle(
columnWidth: 50,
barHeight: 16,
timelineAxisType: TimelineAxisType.daily,
tooltipType: TooltipType.hover,
taskBarColor: Colors.blue.shade400,
activityLabelColor: Colors.blue.shade500,
taskLabelColor: Colors.blue.shade900,
taskLabelBuilder: (task) => Container(
padding: const EdgeInsets.all(4),
child: Text(
task.data.title,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
gridColor: Colors.grey.shade300,
taskBarRadius: 8,
activityLabelBuilder: (activity) => Container(
padding: const EdgeInsets.all(4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
activity.label!,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const Text(
'A subtitle',
style: TextStyle(
fontStyle: FontStyle.italic,
color: Colors.white,
),
),
],
),
),
axisDividerColor: Colors.grey.shade500,
tooltipColor: Colors.redAccent,
tooltipPadding:
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
weekendColor: Colors.grey.shade200,
dateLineColor: Colors.red,
snapToDay: false,
),
dateLines: [
GanttDateLine(
date: DateTime.timestamp(), width: 2, color: Colors.orangeAccent),
GanttDateLine(
date: DateTime.timestamp().add(const Duration(days: 2)),
),
],
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.redAccent,
onPressed: () => setState(() => _items.addAll(Data.dummyData)),
child: const Icon(Icons.restore, color: Colors.white),
),
);
}
}
extension on DateTime {
String get formattedDate => '$day/$month/$year';
}
extension on List<ExampleEventItem> {
List<GridRow> toRows() {
List<GridRow> rows = [];
Map<String, List<TaskGridRow<ExampleEventItem>>> labelTasks = {};
sort((a, b) => a.start.compareTo(b.start));
for (var item in this) {
final label = item.group;
(labelTasks[label] ??= []).add(TaskGridRow<ExampleEventItem>(
data: item,
startDate: item.start,
endDate: item.end,
tooltip: '${item.title}\n${item.start.formattedDate} - ${item.end.formattedDate}',
));
}
for (var label in labelTasks.keys) {
rows.add(ActivityGridRow(label));
rows.addAll(labelTasks[label]!);
}
return rows;
}
}
更多关于Flutter甘特图展示插件gantt_view的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复


