效果图:

甘特图
gantt安装与使用
vue版---部分功能收费
-
安装gantt 或 引入文件
| npm install dhtmlx-gantt -save |
| |
| 或 |
| |
| import gantt from "/public/static/dhtmlxgantt/dhtmlxgantt.js"; |
| import "/public/static/dhtmlxgantt/locale/locale_cn.js"; |
复制
-
引入---组件
| <template> |
| #节点高度要给,gantt不根据内容撑开 |
| <div ref="gantt" class="gantt-container" style="min-height: calc(85vh - 100px); width: 100%; overflow: hidden"></div> |
| </template> |
| <script> |
| import gantt from "/public/static/dhtmlxgantt/dhtmlxgantt"; |
| import "/public/static/dhtmlxgantt/locale/locale_cn.js"; |
| </script> |
| |
复制
借鉴
- css文件地址 examples/dhtmlx_gantt/dhtmlxgantt.css · 残星落影/博客 - 码云 - 开源中国 (gitee.com)
- js文件地址 examples/dhtmlx_gantt/dhtmlx · 残星落影/博客 - 码云 - 开源中国 (gitee.com)
定义渲染数据
| let tasks = ref({ |
| data: [ |
| { |
| id: 1, |
| text: "计划#1", |
| start_date: "2023-09-28", |
| end_date: "2023-10-28", |
| sj_start_date: "2023-09-29", |
| sj_end_date: "2023-10-25", |
| open: true, |
| }, |
| { |
| id: 2, |
| text: "已完成", |
| start_date: "2023-09-28", |
| end_date: "2023-10-28", |
| sj_start_date: "2023-09-29", |
| sj_end_date: "2023-10-25", |
| parent: 1, |
| }, |
| { |
| id: 3, |
| text: "计划#2", |
| start_date: "2023-03-10", |
| end_date: "2023-5-20", |
| sj_start_date: "2023-03-10", |
| sj_end_date: "2023-5-18", |
| open: true, |
| }, |
| { |
| id: 4, |
| text: "已完成", |
| start_date: "2023-03-10", |
| end_date: "2023-5-20", |
| sj_start_date: "2023-03-10", |
| sj_end_date: "2023-5-18", |
| parent: 3, |
| }, |
| ], |
| }); |
复制
完整代码
| <script> |
| onMounted(() => { |
| gantt.config.autosize = true; |
| |
| gantt.config.readonly = true; |
| |
| gantt.config.show_grid = true; |
| |
| gantt.config.columns = [ |
| { |
| name: "id", |
| label: "编号", |
| align: "center", |
| tree: false, |
| width: "50", |
| }, |
| { |
| name: "text", |
| label: "计划名称", |
| tree: true, |
| width: "240", |
| }, |
| { |
| name: "start_date", |
| label: "计划开始", |
| align: "center", |
| tree: false, |
| width: "100", |
| }, |
| { |
| name: "end_date", |
| label: "计划完成", |
| align: "center", |
| tree: false, |
| width: "100", |
| }, |
| { |
| name: "sj_start_date", |
| label: "实际开始", |
| align: "center", |
| tree: false, |
| width: "100", |
| }, |
| { |
| name: "sj_end_date", |
| label: "实际完成", |
| align: "center", |
| tree: false, |
| width: "100", |
| }, |
| ]; |
| gantt.config.subscales = [ |
| { |
| unit: "day", |
| step: 1, |
| format: "%d日", |
| }, |
| ]; |
| gantt.attachEvent("onGanttReady", function () { |
| gantt.templates.tooltip_text = function (start: any, end: any, task: any) { |
| return ( |
| task.toolTipsTxt + |
| "<br/>" + |
| "阶段:" + |
| task.text + |
| "<br/>" + |
| gantt.templates.tooltip_date_format(start) |
| ); |
| }; |
| }); |
| |
| gantt.templates.task_text = function (start: any, end: any, task: any) { |
| return ( |
| "<div style='text-align:center;color:#fff'>" + |
| task.text + |
| "(" + |
| task.duration + |
| "天)" + |
| "</div>" |
| ); |
| }; |
| |
| gantt.templates.task_class = function (start: any, end: any, item: any) { |
| return item.$level == 0 ? "firstLevelTask" : "secondLevelTask"; |
| }; |
| gantt.templates.timeline_cell_class = function (item: any, date: any) { |
| if (date.getDay() == 0 || date.getDay() == 6) { |
| return "weekend"; |
| } |
| }; |
| gantt.config.layout = { |
| |
| css: "gantt_container", |
| rows: [ |
| { |
| cols: [ |
| { |
| view: "grid", |
| id: "grid", |
| scrollX: "scrollHor", |
| scrollY: "scrollVer", |
| }, |
| { resizer: true, width: 1 }, |
| { |
| view: "timeline", |
| id: "timeline", |
| scrollX: "scrollHor", |
| scrollY: "scrollVer", |
| }, |
| { view: "scrollbar", scroll: "y", id: "scrollVer" }, |
| ], |
| }, |
| { view: "scrollbar", scroll: "x", id: "scrollHor", height: 20 }, |
| ], |
| }; |
| |
| |
| gantt.config.task_height = 16; |
| gantt.config.row_height = 40; |
| |
| |
| |
| gantt.config.show_task_cells = true; |
| |
| gantt.config.fit_tasks = true; |
| gantt.config.min_column_width = 40; |
| gantt.config.auto_types = true; |
| gantt.config.xml_date = "%Y-%m-%d"; |
| gantt.config.scale_unit = "month"; |
| gantt.config.step = 1; |
| gantt.config.date_scale = "%Y年%M"; |
| gantt.config.start_on_monday = true; |
| gantt.config.scale_height = 90; |
| gantt.config.autoscroll = true; |
| gantt.config.readonly = true; |
| |
| gantt.attachEvent("onTaskLoading", function (task: any) { |
| task.sj_start_date = gantt.date.parseDate(task.sj_start_date, "xml_date"); |
| task.sj_end_date = gantt.date.parseDate(task.sj_end_date, "xml_date"); |
| return true; |
| }); |
| |
| gantt.init(proxy.$refs.gantt); |
| |
| gantt.parse(tasks.value); |
| addTaskLayer(); |
| }); |
| |
| |
| function addTaskLayer() { |
| gantt.addTaskLayer({ |
| renderer: { |
| render: function draw_planned(task: any) { |
| |
| if (task.sj_start_date && task.sj_end_date) { |
| var sizes = gantt.getTaskPosition( |
| task, |
| task.sj_start_date, |
| task.sj_end_date |
| ); |
| |
| var el = document.createElement("div"); |
| el.className = "baseline"; |
| el.style.left = sizes.left + "px"; |
| el.style.width = sizes.width + "px"; |
| el.style.top = sizes.top + gantt.config.task_height + 17 + "px"; |
| |
| return el; |
| } |
| return false; |
| }, |
| getRectangle: function (task: any, view: any) { |
| if (task.start_date && task.end_date) { |
| return gantt.getTaskPosition(task, task.start_date, task.end_date); |
| } |
| return null; |
| }, |
| }, |
| }); |
| } |
| |
| |
| function setScaleConfig(value: any) { |
| dayIndex.value = value; |
| if (value == "1") { |
| gantt.templates.timeline_cell_class = function (item: any, date: any) { |
| if (date.getDay() == 0 || date.getDay() == 6) { |
| return "weekend"; |
| } |
| }; |
| } else { |
| gantt.templates.timeline_cell_class = function (item: any, date: any) { |
| if (date.getDay() == 0 || date.getDay() == 6) { |
| return ""; |
| } |
| }; |
| } |
| switch (value) { |
| case "1": |
| gantt.config.xml_date = "%Y-%m-%d"; |
| gantt.config.scale_unit = "month"; |
| gantt.config.step = 1; |
| gantt.config.date_scale = "%Y年%M"; |
| gantt.config.subscales = [ |
| { |
| unit: "day", |
| step: 1, |
| date: "%d日", |
| }, |
| ]; |
| gantt.render(); |
| break; |
| case "2": |
| gantt.config.scale_unit = "week"; |
| gantt.config.step = 1; |
| gantt.config.date_scale = "%Y年%M"; |
| gantt.templates.date_scale = null; |
| gantt.config.subscales = [ |
| { |
| unit: "week", |
| step: 1, |
| date: "第%W周", |
| }, |
| { |
| unit: "day", |
| step: 1, |
| date: "%d日", |
| }, |
| ]; |
| gantt.render(); |
| break; |
| case "3": |
| gantt.config.scale_unit = "month"; |
| gantt.config.step = 1; |
| gantt.config.date_scale = "%Y年"; |
| gantt.templates.date_scale = null; |
| gantt.config.subscales = [ |
| { |
| unit: "month", |
| step: 1, |
| date: "%M", |
| }, |
| ]; |
| gantt.render(); |
| break; |
| case "4": |
| gantt.config.scale_unit = "year"; |
| gantt.config.step = 1; |
| gantt.config.date_scale = "%Y年"; |
| gantt.config.subscales = [ |
| { |
| unit: "month", |
| step: 1, |
| date: "%M", |
| }, |
| { |
| unit: "quarter", |
| step: 1, |
| format: function (date: any) { |
| var dateToStr = gantt.date.date_to_str("%M"); |
| var endDate = gantt.date.add( |
| gantt.date.add(date, 3, "month"), |
| -1, |
| "day" |
| ); |
| return dateToStr(date) + " - " + dateToStr(endDate); |
| }, |
| }, |
| ]; |
| gantt.render(); |
| break; |
| } |
| } |
| </script> |
| |
| css样式 |
| |
| <style lang="scss" scoped> |
| @import "/public/static/dhtmlxgantt/dhtmlxgantt.css"; |
| |
| :deep(.gantt_task_line, .gantt_line_wrapper) { |
| margin-top: -9px; |
| } |
| |
| :deep(.gantt_task_line) { |
| background-color: #3b97fe; |
| border: #3b97fe; |
| height: 15px !important; |
| border-radius: 100px; |
| border-radius: 100px; |
| } |
| |
| :deep(.gantt_task_line) { |
| margin-bottom: 10px !important; |
| } |
| |
| :deep(.gantt_task_progress) { |
| background: #ffd180; |
| border-top-right-radius: 100px; |
| border-radius: 100px; |
| } |
| :deep(.baseline) { |
| position: absolute; |
| border-radius: 100px; |
| margin-top: -12px; |
| height: 15px; |
| background: #67dd23; |
| } |
| :deep(.gantt_grid_scale .gantt_grid_head_cell) { |
| color: black !important; |
| } |
| :deep(.gantt_task .gantt_task_scale .gantt_scale_cell) { |
| color: black !important; |
| } |
| :deep(.gantt_layout_cell) { |
| ::-webkit-scrollbar { |
| height: 8px; |
| } |
| ::-webkit-scrollbar-track { |
| border-radius: 8px; |
| background-color: #f5f5f5; |
| } |
| |
| ::-webkit-scrollbar-thumb { |
| border-radius: 8px; |
| background-color: #b9b9b9; |
| } |
| } |
| |
| |
| :deep(.weekend) { |
| background: #f4f7f4; |
| } |
| :deep(.gantt_selected .weekend) { |
| background: #f7eb91; |
| } |
复制