公司的甘特图需求,研究了几个组件后,选择使用 dhtmlx-gantt 进行实现,dhtmlx-gantt使用其实是偏简单的,文档虽然是英文,但配合翻译也是可以看懂的,下面将公司需求的代码实现粘贴出来,并简单介绍一下使用方法,希望对你有帮助。
看一下目前实现的效果:
需求是不需要bar连线的,所以将bar连线注释掉了,连线也是可以有的
组件官网地址: https://dhtmlx.com/
2024-11-13更新:
样式不一致:
有朋友私信问我表格样式不一样,在第一项前面无法出现图标,我看了一下发现是组件版本更新的问题,官方在新版内取消了默认的图标,如果喜欢上图的样式,就安装 dhtmlx-gantt 的 8 版本,如果 不需要图标就安装目前最新的 9 版本。
没有细看,我将组件更新后,功能都是好用的,新版用法应该差不多,可能新增了一些api,有时间后我会去更新。目前发现的区别是:新版在树节点前取消了默认图标、tooltip新版为黑色背景,8版本为白色背景
目录
一、首先 npm 安装插件
二、创建一个vue组件
三、业务页面内 引用自定义组件:
四、dhtmlx-gantt 基本配置项
格式化表头日期展示:
甘特图的尺寸自适应
只读模式
是否显示左侧表格
设置表头高度
设置bar的高度
设置行的高度
设置时间识别格式
表格列设置
为每个bar增加class
自动延长时间刻度
允许拖放
定义x轴时间维度
自动调整坐标轴
启用 tooltip 功能
性能提升
增加事件
五、完整代码
下面正式进入教程:
npm i dhtmlx-gantt
我这里命名为gantt.vue ,放在项目根目录的 /components 目录下
gantt.vue文件:
如果你的页面能展示出来基本样式,那么就成功啦,咱们继续下一步
下面讲一下 dhtmlx-gantt 的一些配置项,也可以说是我用到的配置项,更多的就要参考官方文档了
(注意,都要放在组件的 init方法中)
// 格式化日期
gantt.locale.date = {
month_full: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
month_short: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
day_full: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
day_short: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
};
指尽量不出现滚动条展示全部
gantt.config.autosize = false;
为false时支持编辑
gantt.config.readonly = true;
gantt.config.show_grid = true;
gantt.config.scale_height = 50;
gantt.config.bar_height = 26;
gantt.config.row_height = 32;
很重要,必须和你数据的格式一样
gantt.config.xml_date = "%Y-%m-%d %H:%i"
(配置项不用细说了吧,template 可以自定义列模板)
gantt.config.columns = [
{ name: 'text', label: '项目名称', tree: true, width: '200', align: 'left', template: (task)=>{
if(task.parent) {
return task.text
} else {
return `${task.text}`
}
}},
{ name: 'person', label: '项目成员', width: '100', align: 'center' },
// { name: 'post', label: '岗位名称', width: '100', align: 'center' },
// { name: 'department', label: '部门名称', width: '100', align: 'center' },
{ name: 'task', label: '项目任务', width: '100', align: 'center' },
// { name: 'number', label: '工单号', tree: false, width: '120', align: 'center', },
// {
// name: 'duration',
// label: '工期',
// align: 'center',
// template: function(obj) {
// return obj.duration + '天';
// }
// }
// {name:"start_date", label:"开始时间", align: "center" },
// {name:"end_date", label:"结束时间", align: "center" },
];
(希望不同的bar展示不同的颜色)
gantt.templates.task_class = function(start, end, item) {
switch (item.status) {
case '400': // 已完成
return 'gantt_success';
case '100': // 未开始
return 'gantt_begined';
case '200': // 进行中
return 'gantt_primary';
case '300': // 暂停
return 'gantt_warning';
default: // 已终止 500
return 'gantt_info';
}
};
然后在css内定义样式就好啦
gantt.config.fit_tasks = true;
gantt.config.drag_project = true;
做视图切换
// 年 格式
gantt.config.scales = [{ unit: 'year', step: 1, date: ' %Y 年' }];
// 月 格式
gantt.config.scales = [{ unit: 'year', step: 1, date: ' %Y 年' }, { unit: 'month', step: 1, date: '%F' }];
// 日 格式
gantt.config.scales = [{ unit: 'month', step: 1, date: ' %Y 年 %F' }, { unit: 'day', step: 1, date: '%d' }];
当task的长度改变时,自动调整图表坐标轴区间用于适配task的长度
gantt.config.fit_tasks = true;
gantt.plugins({
tooltip: true // 启用 tooltip 插件
});
gantt.templates.tooltip_text = (start, end, task) => {
};
// 仅仅渲染在屏幕可见的那部分时间轴。在处理时间轴非常长的时候,可以提升性能
gantt.config.smart_scales = true
// 按需渲染, 仅仅渲染在屏幕可见的那部分任务和依赖线。这个在显示大量的任务时,性能比较高。
gantt.config.smart_rendering = true
事件很多,具体看官方文档,我这里加了双击事件
// 给每行增加双击事件 ,亲测事件会重复注册,用这个方法拦截一下
if (this.onTaskDblClick) gantt.detachEvent(this.onTaskDblClick);
// 双击bar任务事件(单击会有问题,点击展开时也会触发)
this.onTaskDblClick = gantt.attachEvent("onTaskDblClick", (id, e) => {
this.$emit('rowDbClick',id)
return true;
}, { id: 'onTaskDblClick' })
ganttPerson.vue
业务代码:
{{ propItem.label }}