vue+dhtmlx-gantt 实现甘特图(快速入门甘特图)
作者:Microi风闲
文章介绍dhtmlxGantt甘特图组件的Vue3集成方法,涵盖功能特点(拖放、多视图、数据导出、任务依赖)、数据配置方式(父子级结构、时间计算)、初始化步骤及使用场景,适用于复杂项目管理,提供代码示例与效果图参考,对vue dhtmlx-gantt甘特图相关知识感兴趣的朋友一起看看吧
一、前言
dhtmlxGantt
是一款功能强大的甘特图组件,支持 Vue 3
集成。它提供了丰富的功能,适合复杂的项目管理需求。
1 什么是甘特图
甘特图(Gantt chart)又称为横道图、条状图(Bar chart)。以提出者亨利·L·甘特先生的名字命名,是项目管理、生产排程、节点管理中非常常见的一个功能。
甘特图内在思想简单,即以图示的方式通过活动列表和时间刻度形象地表示出任何特定项目的活动顺序与持续时间。基本是一条线条图,横轴表示时间,纵轴表示活动(项目),线条表示在整个期间上计划和实际的活动完成情况。它直观地表明任务计划在什么时候进行,及实际进展与计划要求的对比。管理者由此可便利地弄清一项任务(项目)还剩下哪些工作要做,并可评估工作进度。
2 为什么要用甘特图
在很多较大且时间跨度较长的工程、IT、市场营销、电商运营等项目中,都会涉及诸多对人员、时间、质量等方面的控制,而且很多时候还需要跨部门进行协作,所以,如何把控整个项目管理流程就显得非常重要。
而使用甘特图就可以实现这样一个目的。
特点
- 支持拖放操作
- 多种视图模式(天、周、月、年)
- 数据导出功能(PDF、PNG、Excel)
- 任务依赖关系管理
使用场景
适合需要高度定制化和复杂功能的企业级项目管理工具。
资源
- GitHub: dhtmlxGantt
- 文档: dhtmlxGantt 文档
二、使用说明
2.1 引入依赖
npm install dhtmlx-gantt
2.2 引入组件
<template> <div> <div ref="gantt" style="height:500px;" /> </div> </template>
2.3 引入dhtmlx-gantt
import gantt from 'dhtmlx-gantt' import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
2.4 甘特图数据配置
- 父级时间是根据子级
start_date
以及duration
自动计算 progress
:完成度的最大值为1open
:是否展开文件parent
:父级id
start_date
:开始时间(日月年)text
:左边数据展示文件名称(可以自定义添加展示字段,在后面列配置项可以配置)
📢注意: 数据格式类似于树形组件,子级需要父级的
id
tasks: { data: [ // { // id: 11, // text: 'Project #1', // // type: gantt.config.types.project, // progress: 0.5,//完成度 // open: true,//默认打开 // number: '20240227',//显示字段 // }, // { // toolTipsTxt: '任务#101-001', // id: 12,//任务id // text: '任务#1',//任务名称 // start_date: '03-04-2022',//开始时间 日月年 // duration: '5',//任务时常 // parent: '11',//父级id // progress: 1,//完成度 // open: true,//默认打开 // }, // { // id: 13, // text: '任务#2', // start_date: '03-04-2022', // // type: gantt.config.types.project, // parent: '11', // progress: 0.255, // open: true, // }, // { // id: 14, // text: '任务#3', // start_date: '01-04-2022', // duration: '6', // parent: '11', // progress: 0.8, // open: true, // }, // { // id: 15, // text: '任务#4', // // type: gantt.config.types.project, // parent: '11', // progress: 0.2, // open: true, // }, // { // id: 16, // text: 'Final milestone', // start_date: '15-04-2022', // // type: gantt.config.types.milestone, // parent: '11', // progress: 0, // open: true, // }, // { // id: 17, // text: '任务#2.1', // start_date: '03-04-2022', // duration: '2', // parent: '13', // progress: 1, // open: true, // }, // { // id: 18, // text: '任务#2.2', // start_date: '06-04-2022', // duration: '3', // parent: '13', // progress: 0.8, // open: true, // }, // { // id: 19, // text: '任务#2.3', // start_date: '10-04-2022', // duration: '4', // parent: '13', // progress: 0.2, // open: true, // }, // { // id: 20, // text: '任务#2.4', // start_date: '10-04-2022', // duration: '4', // parent: '13', // progress: 0, // open: true, // }, // { // id: 21, // text: '任务#4.1', // start_date: '03-04-2022', // duration: '4', // parent: '15', // progress: 0.5, // open: true, // }, // { // id: 22, // text: '任务#4.2', // start_date: '03-04-2022', // duration: '4', // parent: '15', // progress: 0.1, // open: true, // }, // { // id: 23, // text: 'Mediate milestone', // start_date: '14-04-2022', // // type: gantt.config.types.milestone, // parent: '15', // progress: 0, // open: true, // }, ],
tasks
中 link
连线配置
tasks: { // #字段解释 // 格式 id:数据id // source:开始链接的项目id ----为tasks.data中数据的id // target:要链接项目的id ----为tasks.data中数据的id // type: 0--进行-开始 `尾部链接头部` // 1--开始-开始 `头部链接头部` // 2--进行-进行 `尾部链接尾部` // 3--开始-进行 `头部链接尾部` // 任务之间连接 links: [ { id: '10', source: '11', target: '12', type: '1' }, { id: '11', source: '11', target: '13', type: '1' }, { id: '12', source: '11', target: '14', type: '1' }, { id: '13', source: '11', target: '15', type: '1' }, { id: '14', source: '23', target: '16', type: '0' }, { id: '15', source: '13', target: '17', type: '1' }, { id: '16', source: '17', target: '18', type: '0' }, { id: '17', source: '18', target: '19', type: '0' }, { id: '18', source: '19', target: '20', type: '0' }, { id: '19', source: '15', target: '21', type: '2' }, { id: '20', source: '15', target: '22', type: '2' }, { id: '21', source: '15', target: '23', type: '0' }, ], },
2.5 初始化配置
弹窗汉化
gantt.locale.labels = { dhx_cal_today_button: "今天", day_tab: "日", week_tab: "周", month_tab: "月", new_event: "新建日程", icon_save: "保存", icon_cancel: "关闭", icon_details: "详细", icon_edit: "编辑", icon_delete: "删除", confirm_closing: "请确认是否撤销修改!", //Your changes will be lost, are your sure? confirm_deleting: "是否删除计划?", section_description: "描述:", section_time: "时间范围:", section_type: "类型:", section_text: "计划名称:", section_test: "测试:", section_projectClass: "项目类型:", taskProjectType_0: "项目任务", taskProjectType_1: "普通任务", section_head: "负责人:", section_priority: '优先级:', taskProgress: '任务状态', taskProgress_0: "未开始", taskProgress_1: "进行中", taskProgress_2: "已完成", taskProgress_3: "已延期", taskProgress_4: "搁置中", section_template: 'Details', /* grid columns */ column_text: "计划名称", column_start_date: "开始时间", column_duration: "持续时间", column_add: "", column_priority: "难度", /* link confirmation */ link: "关联", confirm_link_deleting: "将被删除", message_ok: '确定', message_cancel: '取消', link_start: " (开始)", link_end: " (结束)", type_task: "任务", type_project: "项目", type_milestone: "里程碑", minutes: "分钟", hours: "小时", days: "天", weeks: "周", months: "月", years: "年" }
清空旧数据
gantt.clearAll(); // 清空旧数据
📢注意:其中值得一提的就是更新数据,需要清空旧数
初始化数据
// 初始化 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: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"] } console.log(gantt); //自适应甘特图的尺寸大小, 使得在不出现滚动条的情况下, 显示全部任务 gantt.config.autosize = true //只读模式 gantt.config.readonly = false //是否显示左侧树表格 gantt.config.show_grid = true // //表格列设置 gantt.config.columns = [ { name: 'text', label: '阶段名字', tree: true, width: '150', 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" },*/ ] // 自动延长时间刻度 gantt.config.fit_tasks = true // 允许拖放 gantt.config.drag_project = true // 定义时间格式 gantt.config.scales = [ { unit: 'month', step: 1, date: ' %Y,%F' }, { unit: 'day', step: 1, date: ' %D ,%j' }, ] // //当task的长度改变时,自动调整图表坐标轴区间用于适配task的长度 gantt.config.fit_tasks = true // 添加弹窗属性 gantt.config.lightbox.sections = [ { name: 'description', height: 70, map_to: 'text', type: 'textarea', focus: true, }, { name: 'type', type: 'typeselect', map_to: 'type' }, { name: 'time', type: 'duration', map_to: 'auto' }, ]; console.log(this.tasks.data, '检查任务数据'); // 检查任务数据 // 初始化 gantt.init(this.$refs.gantt) /* *******重点******* */ gantt.clearAll(); // 清空旧数据 /* ****************** */ // 数据解析 gantt.parse(this.tasks) },
更新数据
loadData(arg) { if (!this.url.list) { this.$message.error("请设置url.list属性!") return } //加载数据 若传入参数1则加载第一页的内容 let params = { planId: this.planId, } this.loading = true; this.tasks.data = [] getAction(this.url.list, params).then((res) => { if (res.success) { console.log(res, '甘特图数据'); res.result.forEach(obj => { obj.open = false }) this.tasks.data = res.result this.init() } if (res.code === 510) { this.$message.warning(res.message) } this.loading = false; }) },
三、代码示例
3.1 Vue2完整示例
<template> <div> <div ref="gantt" style="height:500px;" /> </div> </template> <script> import gantt from 'dhtmlx-gantt' import 'dhtmlx-gantt/codebase/dhtmlxgantt.css' import { JeecgListMixin } from '@/mixins/JeecgListMixin' import { getAction, putAction } from '@/api/manage' export default { props: { planId: { type: String, required: true, } }, // mixins: [JeecgListMixin], data() { return { // 甘特图配置 tasks: { data: [ // { // id: 11, // text: 'Project #1', // // type: gantt.config.types.project, // progress: 0.5,//完成度 // open: true,//默认打开 // number: '20240227',//显示字段 // }, // { // toolTipsTxt: '任务#101-001', // id: 12,//任务id // text: '任务#1',//任务名称 // start_date: '03-04-2022',//开始时间 日月年 // duration: '5',//任务时常 // parent: '11',//父级id // progress: 1,//完成度 // open: true,//默认打开 // }, // { // id: 13, // text: '任务#2', // start_date: '03-04-2022', // // type: gantt.config.types.project, // parent: '11', // progress: 0.255, // open: true, // }, // { // id: 14, // text: '任务#3', // start_date: '01-04-2022', // duration: '6', // parent: '11', // progress: 0.8, // open: true, // }, // { // id: 15, // text: '任务#4', // // type: gantt.config.types.project, // parent: '11', // progress: 0.2, // open: true, // }, // { // id: 16, // text: 'Final milestone', // start_date: '15-04-2022', // // type: gantt.config.types.milestone, // parent: '11', // progress: 0, // open: true, // }, // { // id: 17, // text: '任务#2.1', // start_date: '03-04-2022', // duration: '2', // parent: '13', // progress: 1, // open: true, // }, // { // id: 18, // text: '任务#2.2', // start_date: '06-04-2022', // duration: '3', // parent: '13', // progress: 0.8, // open: true, // }, // { // id: 19, // text: '任务#2.3', // start_date: '10-04-2022', // duration: '4', // parent: '13', // progress: 0.2, // open: true, // }, // { // id: 20, // text: '任务#2.4', // start_date: '10-04-2022', // duration: '4', // parent: '13', // progress: 0, // open: true, // }, // { // id: 21, // text: '任务#4.1', // start_date: '03-04-2022', // duration: '4', // parent: '15', // progress: 0.5, // open: true, // }, // { // id: 22, // text: '任务#4.2', // start_date: '03-04-2022', // duration: '4', // parent: '15', // progress: 0.1, // open: true, // }, // { // id: 23, // text: 'Mediate milestone', // start_date: '14-04-2022', // // type: gantt.config.types.milestone, // parent: '15', // progress: 0, // open: true, // }, ], // #字段解释 // 格式 id:数据id // source:开始链接的项目id ----为tasks.data中数据的id // target:要链接项目的id ----为tasks.data中数据的id // type: 0--进行-开始 `尾部链接头部` // 1--开始-开始 `头部链接头部` // 2--进行-进行 `尾部链接尾部` // 3--开始-进行 `头部链接尾部` // 任务之间连接 links: [ { id: '10', source: '11', target: '12', type: '1' }, { id: '11', source: '11', target: '13', type: '1' }, { id: '12', source: '11', target: '14', type: '1' }, { id: '13', source: '11', target: '15', type: '1' }, { id: '14', source: '23', target: '16', type: '0' }, { id: '15', source: '13', target: '17', type: '1' }, { id: '16', source: '17', target: '18', type: '0' }, { id: '17', source: '18', target: '19', type: '0' }, { id: '18', source: '19', target: '20', type: '0' }, { id: '19', source: '15', target: '21', type: '2' }, { id: '20', source: '15', target: '22', type: '2' }, { id: '21', source: '15', target: '23', type: '0' }, ], }, url: { list: "/projectManage/projectPlan/queryProjectPlanGTT", // delete: "/projectManage/projectModule/delete", // deleteBatch: "/projectManage/projectModule/deleteBatch", // exportXlsUrl: "/projectManage/projectModule/exportXls", // importExcelUrl: "/projectManage/projectModule/importExcel", // budgetExportXlsUrl: "/projectManage/projectModule/budgetExportXls", // budgetImportUrl: "/projectManage/projectModule/budgetImportExcel", }, } }, watch: { }, created() { console.log(this.planId, '参数'); }, mounted() { this.loadData(); }, methods: { // 初始化 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.locale.labels = { dhx_cal_today_button: "今天", day_tab: "日", week_tab: "周", month_tab: "月", new_event: "新建日程", icon_save: "保存", icon_cancel: "关闭", icon_details: "详细", icon_edit: "编辑", icon_delete: "删除", confirm_closing: "请确认是否撤销修改!", //Your changes will be lost, are your sure? confirm_deleting: "是否删除计划?", section_description: "描述:", section_time: "时间范围:", section_type: "类型:", section_text: "计划名称:", section_test: "测试:", section_projectClass: "项目类型:", taskProjectType_0: "项目任务", taskProjectType_1: "普通任务", section_head: "负责人:", section_priority: '优先级:', taskProgress: '任务状态', taskProgress_0: "未开始", taskProgress_1: "进行中", taskProgress_2: "已完成", taskProgress_3: "已延期", taskProgress_4: "搁置中", section_template: 'Details', /* grid columns */ column_text: "计划名称", column_start_date: "开始时间", column_duration: "持续时间", column_add: "", column_priority: "难度", /* link confirmation */ link: "关联", confirm_link_deleting: "将被删除", message_ok: '确定', message_cancel: '取消', link_start: " (开始)", link_end: " (结束)", type_task: "任务", type_project: "项目", type_milestone: "里程碑", minutes: "分钟", hours: "小时", days: "天", weeks: "周", months: "月", years: "年" } console.log(gantt); //自适应甘特图的尺寸大小, 使得在不出现滚动条的情况下, 显示全部任务 gantt.config.autosize = true //只读模式 gantt.config.readonly = false //是否显示左侧树表格 gantt.config.show_grid = true // //表格列设置 gantt.config.columns = [ { name: 'text', label: '阶段名字', tree: true, width: '150', 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" },*/ ] // 自动延长时间刻度 gantt.config.fit_tasks = true // 允许拖放 gantt.config.drag_project = true // 定义时间格式 gantt.config.scales = [ { unit: 'month', step: 1, date: ' %Y,%F' }, { unit: 'day', step: 1, date: ' %D ,%j' }, ] // //当task的长度改变时,自动调整图表坐标轴区间用于适配task的长度 gantt.config.fit_tasks = true // 添加弹窗属性 gantt.config.lightbox.sections = [ { name: 'description', height: 70, map_to: 'text', type: 'textarea', focus: true, }, { name: 'type', type: 'typeselect', map_to: 'type' }, { name: 'time', type: 'duration', map_to: 'auto' }, ]; console.log(this.tasks.data, '检查任务数据'); // 检查任务数据 // 初始化 gantt.init(this.$refs.gantt) /* *******重点******* */ gantt.clearAll(); // 清空旧数据 /* ****************** */ // 数据解析 gantt.parse(this.tasks) }, loadData(arg) { if (!this.url.list) { this.$message.error("请设置url.list属性!") return } //加载数据 若传入参数1则加载第一页的内容 let params = { planId: this.planId, } this.loading = true; this.tasks.data = [] getAction(this.url.list, params).then((res) => { if (res.success) { console.log(res, '甘特图数据'); res.result.forEach(obj => { obj.open = false }) this.tasks.data = res.result this.init() } if (res.code === 510) { this.$message.warning(res.message) } this.loading = false; }) }, }, } </script> <style lang="less" scoped> .firstLevelTask { border: none; .gantt_task_content { // font-weight: bold; font-size: 13px; } } .secondLevelTask { border: none; } .thirdLevelTask { border: 2px solid #da645d; color: #da645d; background: #da645d; } .milestone-default { border: none; background: rgba(0, 0, 0, 0.45); } .milestone-unfinished { border: none; background: #5692f0; } .milestone-finished { border: none; background: #84bd54; } .milestone-canceled { border: none; background: #da645d; } html, body { margin: 0px; padding: 0px; height: 100%; overflow: hidden; } .container { height: 900px; .left-container { height: 100%; } } .left-container { height: 600px; } .gantt_scale_line { border-top: 0; } .weekend { //background:#f4f7f4!important; color: #000000 !important; } .gantt_selected .weekend { background: #f7eb91 !important; } .gantt_task_content { text-align: left; padding-left: 10px; } //上面任务条样式 .gantt_task_scale { height: 45px !important; } .gantt_task .gantt_task_scale .gantt_scale_cell { line-height: 30px !important; height: 28px !important; } </style>
3.2 Vue3 完整示例
<template> <div style="height: 100%; background-color: white"> <div ref="ganttRef" style="width: 100%; height: 600px"></div> </div> </template> <script setup name="gantt-widget"> import { ref, reactive, onMounted } from 'vue' import { gantt } from 'dhtmlx-gantt' import 'dhtmlx-gantt/codebase/dhtmlxgantt.css' import { formatDate } from '@/utils/util.js' import { defineProps } from 'vue' const props = defineProps({ widgetObj: { type: Object, required: true, }, }) const ganttRef = ref() const tasks = ref({}) //动态加载数据 const fetchData = () => { tasks.value = tasks.value = { tasks: [ { id: 10, text: 'RFQ&项目启动', type: 'project', progress: 0.1, open: true, person: '张三', }, { id: 12, text: '产品需求 #1.0.1', start_date: '02-01-2025', duration: 3, parent: 10, progress: 1, person: '张三', }, { id: 13, text: '产品数据 #1.0.2', start_date: '05-01-2025', duration: 3, parent: 10, progress: 0.8, person: '张三', }, { id: 14, text: '环境数据 #1.0.3', start_date: '08-01-2025', duration: 3, parent: 10, progress: 0, person: '张三', }, { id: 15, text: '项目评估指令 #1.1', start_date: '11-01-2025', duration: 3, parent: 10, progress: 0, person: '张三', }, { id: 16, text: '成立项目小组 #1.2.1', start_date: '12-01-2025', duration: 2, parent: 10, progress: 0, person: '张三', }, { id: 17, text: '可行性评估 #1.2.2', start_date: '13-01-2025', duration: 3, parent: 10, progress: 0, person: '张三', }, { id: 18, text: '输入评审 #1.2.3', start_date: '14-01-2025', duration: 2, parent: 10, progress: 0, person: '张三', }, { id: 19, text: '初始产品方案 #1.2.4', start_date: '16-01-2025', duration: 2, parent: 10, progress: 0, person: '张三', }, { id: 20, text: '产品设计&开发', type: 'project', progress: 0, person: '张三', open: false, }, { id: 21, text: '设计输入信息管理#3.0.1', start_date: '18-01-2025', duration: 2, parent: 20, progress: 0, person: '张三', }, { id: 22, text: '产品设计过往教训展开 #3.0.2', start_date: '20-01-2025', duration: 2, parent: 20, progress: 0, person: '张三', }, { id: 23, text: '产品设计进度管理 #3.0.3', start_date: '22-01-2025', duration: 2, parent: 20, progress: 0, person: '张三', }, { id: 24, text: '产品设计方案 #3.0.4', start_date: '24-01-2025', duration: 2, parent: 20, progress: 0, person: '张三', }, { id: 25, text: '产品特殊特性识别 #3.0.5', start_date: '26-01-2025', duration: 2, parent: 20, progress: 0, person: '张三', }, { id: 26, text: '产品设计方案评审 #3.0.6', start_date: '28-01-2025', duration: 2, parent: 20, progress: 0, person: '张三', }, { id: 30, text: '过程设计&开发', type: 'project', progress: 0, person: '张三', open: false, }, { id: 31, text: '场地规划 #5.0.1', start_date: '28-02-2025', duration: 3, parent: 30, progress: 0, person: '张三', }, { id: 32, text: '场地评审 #5.0.2', start_date: '28-02-2025', duration: 3, parent: 30, progress: 0, person: '张三', }, { id: 33, text: '过程检验标准 #5.0.3', start_date: '29-02-2025', duration: 3, parent: 30, progress: 0, person: '张三', }, { id: 40, text: '产品&过程验证', type: 'project', open: false, progress: 0, person: '张三', }, { id: 41, text: '量具重复再现性分析 #6.0.1', start_date: '29-02-2025', duration: 3, parent: 40, progress: 0, person: '张三', }, { id: 42, text: '检具使用验收 #6.0.2', start_date: '01-03-2025', duration: 3, parent: 40, progress: 0, person: '张三', }, { id: 43, text: '工装-厂外预验收 #6.1.1', start_date: '02-03-2025', duration: 3, parent: 40, progress: 0, person: '张三', }, { id: 44, text: '设备-厂外预验收 #6.2.1', start_date: '03-03-2025', duration: 3, parent: 40, progress: 0, person: '张三', }, { id: 45, text: '模具-厂外预验收 #6.3.1', start_date: '04-03-2025', duration: 3, parent: 40, progress: 0, person: '张三', }, { id: 50, text: '过程验证', type: 'project', open: false, progress: 0, person: '张三', }, { id: 51, text: '小批量试生产总结 #7.0.1', start_date: '28-04-2025', duration: 3, parent: 50, progress: 0, person: '张三', }, { id: 52, text: '产品尺寸记录 #7.0.2', start_date: '29-04-2025', duration: 3, parent: 50, progress: 0, person: '张三', }, { id: 52, text: '过程能力研究 #7.0.3', start_date: '30-04-2025', duration: 3, parent: 50, progress: 0, person: '张三', }, { id: 60, text: '反馈,纠正和改进', type: 'project', open: false, progress: 0, person: '张三', }, { id: 61, text: '模工检移交 #8.0.1', start_date: '28-05-2025', duration: 3, parent: 60, progress: 0, person: '张三', }, { id: 62, text: '项目移交会议 #8.0.2', start_date: '29-05-2025', duration: 3, parent: 60, progress: 0, person: '张三', }, { id: 63, text: '取得量产交付计划 #8.1.1', start_date: '30-05-2025', duration: 3, parent: 60, progress: 0, person: '张三', }, ], links: [ { id: 10, source: 12, target: 13, type: 1 }, { id: 11, source: 13, target: 14, type: 1 }, { id: 12, source: 14, target: 15, type: 1 }, ], } } //初始化配置 const initGantt = () => { gantt.plugins({ tooltip: true, quick_info: true }) // 汉化窗口 gantt.locale.labels = { dhx_cal_today_button: '今天', day_tab: '日', week_tab: '周', month_tab: '月', new_event: '新建日程', icon_save: '保存', icon_cancel: '关闭', icon_details: '详细', icon_edit: '编辑', icon_delete: '删除', confirm_closing: '请确认是否撤销修改!', //Your changes will be lost, are your sure? confirm_deleting: '是否删除计划?', section_description: '描述:', section_time: '时间范围:', section_type: '类型:', section_text: '计划名称:', section_test: '测试:', section_projectClass: '项目类型:', taskProjectType_0: '项目任务', taskProjectType_1: '普通任务', section_head: '负责人:', section_priority: '优先级:', taskProgress: '任务状态', taskProgress_0: '未开始', taskProgress_1: '进行中', taskProgress_2: '已完成', taskProgress_3: '已延期', taskProgress_4: '搁置中', section_template: 'Details', /* grid columns */ column_text: '计划名称', column_start_date: '开始时间', column_duration: '持续时间', column_add: '', column_priority: '难度', /* link confirmation */ link: '关联', confirm_link_deleting: '将被删除', message_ok: '确定', message_cancel: '取消', link_start: ' (开始)', link_end: ' (结束)', type_task: '任务', type_project: '项目', type_milestone: '里程碑', minutes: '分钟', hours: '小时', days: '天', weeks: '周', months: '月', years: '年', } // 格式化日期 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: [ '星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', ], } // 当task的长度改变时,自动调整图表坐标轴区间用于适配task的长度 gantt.config.fit_tasks = true // 允许拖放 gantt.config.drag_project = true // 定义时间格式 gantt.config.scales = [ { unit: 'month', step: 1, date: '%F, %Y' }, { unit: 'day', step: 1, date: '%j, %D' }, ] // gantt.config.scale_height = 80 // gantt.config.row_height = 60 // gantt.config.bar_height = 40 gantt.i18n.setLocale('cn') // gantt.config.autosize = true // gantt.config.readonly = true gantt.config.show_grid = true gantt.config.show_task_tooltips = true gantt.config.show_progress = true gantt.config.branches = { open: 'open', closed: 'closed', } gantt.templates.tooltip_text = (start, end, task) => ` <div> <div>任务:${task.text}</div> <div>开始时间:${formatDate(task.start_date, '{y}-{m}-{d}')}</div> <div>结束时间:${formatDate(task.end_date, '{y}-{m}-{d}')}</div> <div>进度:${task.progress * 100}%</div> </div>` gantt.config.columns = [ { name: 'text', label: '任务名称', width: '250', tree: true, align: 'left', }, { name: 'start_date', label: '起始时间', width: '100', align: 'center' }, { name: 'duration', label: '持续时间', width: '80', align: 'center' }, { name: 'progress', label: '进度', width: '100', align: 'center', template: function (obj) { return obj.progress * 100 + '%' }, }, { name: 'person', label: '负责人', width: '80', align: 'center' }, ] gantt.config.lightbox_zindex = 10000 // 添加弹窗属性 gantt.config.lightbox.sections = [ { name: 'description', height: 70, map_to: 'text', type: 'textarea', focus: true, }, { name: 'type', type: 'typeselect', map_to: 'type' }, { name: 'time', type: 'duration', map_to: 'auto' }, ] // 初始化 gantt.init(ganttRef.value) // 清空旧数据 gantt.clearAll() // 数据解析 gantt.parse(tasks.value) } onMounted(() => { fetchData() initGantt() }) </script> <style lang="scss" scoped> .gantt_cal_light { z-index: 9999 !important; } .gantt_cal_cover { z-index: 10000 !important; } </style>
四、效果图
到此这篇关于vue+dhtmlx-gantt 实现甘特图-快速入门【甘特图】的文章就介绍到这了,更多相关vue dhtmlx-gantt 甘特图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!