使用的插件:dhtmlx-gantt
下载方式:npm i dhtmlx-gantt
插件官网:Gantt API Gantt Docs (dhtmlx.com)
作品展示
直接上全部代码
<template> <div class="card"> <el-card> <div class="ard"> <el-radio-group v-model="radio2"> <el-radio-button label="全部" /> <el-radio-button label="进行中" /> <el-radio-button label="已超时" /> <el-radio-button label="已完成" /> </el-radio-group> <div class="asd"> <p>开始时间:</p> <el-date-picker v-model="value1" type="date" placeholder="点击选择时间" :size="size" /> </div> <div class="asd"> <p>结束时间:</p> <el-date-picker v-model="value1" type="date" placeholder="点击选择时间" :size="size" /> </div> <div class="asd"> <p>选择任务类型:</p> <el-select v-model="value" class="m-2" placeholder="下拉选择" style="width: 170px"> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </div> <el-button style="margin-left: 10px;" type="primary" :icon="Filter">筛选</el-button> <el-button type="primary" :icon="Plus">新增</el-button> </div> </el-card> <el-card class="box-card"> <div class="cardtop"> <div class="margins"> <p><el-color-picker v-model="objs.asd1" show-alpha />攻击组</p> <p><el-color-picker v-model="objs.asd2" show-alpha />防御组</p> <p><el-color-picker v-model="objs.asd3" show-alpha />目标组</p> </div> <el-radio-group v-model="radio1" size="small"> <el-radio-button label="年" /> <el-radio-button label="月" /> <el-radio-button label="日" /> </el-radio-group> </div> <div id="gantt_here" style="margin-top: 10px;" class="gantt-container"></div> </el-card> </div> </template> <script setup> import { reactive, toRefs, ref, onBeforeMount, onMounted, watchEffect, defineExpose } from 'vue' import { gantt } from 'dhtmlx-gantt' import 'dhtmlx-gantt/codebase/dhtmlxgantt.css' import { Plus, Filter } from '@element-plus/icons-vue' const data = reactive({}) const radio1 = ref('年') const radio2 = ref('全部') const value1 = ref('') const value = ref('') let objs = reactive({ asd1: '#f2e6c2', asd2: '#b5e09b', asd3: '#baefe2' }) let dialogVisible = ref(false) //初始化甘特图 const initGantt = () => { var tasks = { data: [ { id: 1, taskname: '明天吃烩菜', parent: 0, start_date: "01-04-2018", progress: 0.3, duration: 1, types: 1, text: '李大厨', color: objs.asd1, tsakrank: 0, }, { id: 2, taskname: '明天吃鱼肉', parent: 0, start_date: "01-04-2018", progress: 0.42, duration: 5, types: 2, color: objs.asd2, text: '王大厨', tsakrank: 1, }, { id: 3, taskname: '明天吃西餐', parent: 0, start_date: "01-04-2018", progress: 0.65, duration: 5, types: 3, text: '赵大厨', color: objs.asd3, tsakrank: 2, }, { id: 4, taskname: '购买水军发动舆论偏差', parent: 1, start_date: "01-04-2018", progress: 0.1, duration: 1, types: 1, text: '李大厨', color: objs.asd1 }, { id: 5, taskname: '编辑一边有效证据的文章', parent: 2, start_date: "01-04-2018", progress: 0.1, duration: 3, types: 2, text: '王大厨', color: objs.asd2 }, { id: 6, taskname: '寻找目标人物关键证据', parent: 3, start_date: "01-04-2018", progress: 0.1, duration: 3, types: 3, text: '赵大厨', color: objs.asd3 }, { id: 7, taskname: '发布目标任务黑料', parent: 1, start_date: "03-04-2018", progress: 0.2, duration: 2, types: 1, text: '李大厨', color: objs.asd1 }, { id: 8, taskname: '打造慈善公益效果', parent: 2, start_date: "04-04-2018", progress: 0.1, duration: 3, types: 2, text: '王大厨', color: objs.asd2 }, { id: 9, taskname: '查看目标亲朋好友博客', parent: 3, start_date: "02-04-2018", progress: 0.1, duration: 6, types: 3, text: '赵大厨', color: objs.asd3 }, ], // links: [ // { id: 1, source: 1, target: 2, type: "1" }, // { id: 2, source: 2, target: 3, type: "0" }, // { id: 3, source: 3, target: 4, type: "1" }, // { id: 4, source: 4, target: 5, type: "0" }, // ] }; gantt.config.grid_width = 350 gantt.config.add_column = false //添加符号 gantt.config.autosize = true//自适应尺寸 gantt.config.autofit = true// 表格列宽自适应 gantt.config.autoscroll = true// 把任务或者连线拖拽到浏览器屏幕外时,自动触发滚动效果 gantt.config.drag_progress = false//取消任务进度条进度拖动 gantt.config.scale_height = 60 gantt.config.row_height = 60 gantt.config.bar_height = 34 gantt.config.fit_tasks = true //自动延长时间刻度,以适应所有显示的任务 gantt.config.auto_types = true //将包含子任务的任务转换为项目,将没有子任务的项目转换回任务 gantt.i18n.setLocale('cn') //设置语言 //时间栏配置 gantt.config.scales = [ { unit: 'month', step: 1, format: '%Y年%m月' }, { unit: 'day', step: 1, format: '%m/%d' }, ] //左侧列表配置 gantt.config.columns = [ { name: "taskname", label: "任务名称", align: 'left', tree: true, width: 140 }, { name: "progress", label: "任务优先", align: 'center', width: 80, template: function (task) { let obj = { color: task.tsakrank === 0 ? '#ff2b00' : task.tsakrank === 1 ? '#ffab00' : '#409eff', icon: task.tsakrank === 0 ? 'icon-youxianjiP0' : task.tsakrank === 1 ? 'icon-youxianjiP1' : 'icon-youxianjiP2', } return `<div class="jindu" style="color:${obj.color};"><i style="font-size:24px;" class="iconfont ${obj.icon}"></i></div>` } }, { name: "type", label: "任务类别", align: 'center', width: 100, template: function (task) { let obj = { color: task.types === 1 ? '#f29d38' : task.types === 2 ? '#65c16f' : '#1890ff', icon: task.types === 1 ? 'icon-gongji' : task.types === 2 ? 'icon-kaiqifangyu' : 'icon-icon--mubiaoku', text: task.types === 1 ? '攻击' : task.types === 2 ? '防御' : '目标' } return `<div class="tasktype" style="color:${obj.color};font-size:14px;"> <i class="iconfont ${obj.icon}"></i> <span style="margin-left:3px;"> ${obj.text}</span> </div>` } }, { name: "progress", label: "任务进度", align: 'center', width: 80, template: function (task) { return `<div class="jindu" style="width:100%;height:30px;padding-left:10px;font-size:13px;color:black;"><span>${(task.progress * 100).toFixed(0) + "%"}</span></div>`; } }, ] //鼠标移入弹框 // gantt.templates.tooltip_text = function (start, end, task) { // return ` // <div style="width: 200px;height: 200px;"> // <p>任务名称:这是一个任务</p> // <p>任务策划:张三</p> // <p>当前状态:进行中</p> // <p>任务类别:攻击</p> // <p>开始时间:2020-12-11</p> // <p>结束时间:2021-04-13</p> // </div> // ` // }; //更改父项图标 gantt.templates.grid_folder = (item) => { return "" } gantt.plugins({ marker: true }); var date_to_str = gantt.date.date_to_str(gantt.config.task_date); var today = new Date(); gantt.addMarker({ start_date: today, css: "today", text: "今天", title: "今天: " + date_to_str(today) }); //更改子项图标 gantt.templates.grid_file = (item) => { return "" } //任务条显示内容 gantt.templates.task_text = function (start, end, task) { return ` <div style="color:#454545;font-size:14px;font-weight:700;">执行:${task.text}</div> ` } //任务条左侧配置 // gantt.templates.leftside_text = function (start, end, task) { // return `<div class="jindu" style="width:100%;height:30px;background-color:#e6f4ff;padding-left:10px;font-size:13px;color:#629eff;"><span>当前进度${(task.progress * 100).toFixed(0) + "%"}</span></div>`; // }; //展开树图标 gantt.templates.grid_open = function (item) { return `<i style="font-size:14px;background:none; color:#1890ff; padding-left:10px;" class="gantt_tree_icon gantt_${item.$open ? "close" : "open"} iconfont ${item.$open ? 'icon-zhankaishousuo' : 'icon-zhankaishousuo1'}"></i>` }; gantt.init('gantt_here') //初始化 gantt.parse(tasks) //填充数据 //双击事件 gantt.attachEvent("onTaskDblClick", function (id, e) { // 在这里编写处理双击事件的代码 console.log("双击了任务:" + id); dialogVisible.value = true }); } onBeforeMount(() => { }) onMounted(() => { initGantt() }) watchEffect(() => { }) defineExpose({ ...toRefs(data) }) </script> <style scoped lang="scss"> ::-webkit-scrollbar { width: 10px; } ::-webkit-scrollbar-track { background-color: #f1f1f1; } ::-webkit-scrollbar-thumb { background-color: #888; border-radius: 5px; } ::-webkit-scrollbar-thumb:hover { background-color: #555; } .renwus { width: 100%; height: 200px; display: flex; align-items: center; justify-content: space-around; flex-wrap: wrap; overflow: auto; } .renwu { width: 100%; height: 200px; display: flex; align-items: center; justify-content: space-around; flex-wrap: wrap; } :deep(.el-progress-circle) { width: 100px !important; height: 80px !important; } .ps { padding: 0; margin: 0; } .percentage-value { display: block; margin-top: 10px; font-size: 28px; } .percentage-label { display: block; margin-top: 10px; font-size: 12px; } .demo-progress .el-progress--line { margin-bottom: 15px; width: 350px; } .demo-progress .el-progress--circle { margin-right: 15px; } .cardtop { width: 100%; height: 100%; display: flex; justify-content: space-between; align-items: center; .margins { display: flex; font-size: 12px; p { margin-left: 10px; :deep(.el-color-picker .el-color-picker__icon) { opacity: 0; } :deep(.el-color-picker__trigger) { border: none; width: 25px; height: 25px; } } } } .box-card { margin-top: 20px; } .card { width: 1500px; height: 1000px; margin: 0 auto; .ard { width: 100%; height: 40px; display: flex; align-items: center; } .icons { width: 80px; height: 30px; display: flex; align-items: center; justify-content: center; border: 1px solid #a0cfff; color: #46a2ff; margin-right: 10px; border-radius: 7px; background-color: #ecf5ff; i { color: #1890ff; font-size: 14px; margin-right: 5px; } } } .asd { width: 300px; height: 33px; border-radius: 5px; border: 1px dotted #ccc; margin-left: 20px; display: flex; align-items: center; p { color: #606266; margin-left: 5px; } :deep(.el-input__wrapper) { border: none; box-shadow: none !important; } :deep(.el-date-editor.el-input) { width: 200px !important; } :deep(.el-select__wrapper) { border: none; box-shadow: none !important; } } :deep(.gantt_layout_cell) { border-radius: 7px; } :deep(.gantt_tree_indent) { opacity: 0; } :deep(.gantt_grid_scale .gantt_grid_head_cell) { color: #606266; font-size: 15px; font-weight: 700; border-right: 1px solid #ccc !important; } :deep(.gantt_scale_cell) { color: #454545 !important; } :deep(.gantt_grid_data .gantt_cell) { border-right: 1px solid #ccc !important; padding: 0; } :deep(.gantt_task_progress_wrapper) { border-radius: 5px; } :deep(.gantt_task_line.gantt_project) { border-radius: 5px; border: none; } :deep(.gantt_data_area div) { border-radius: 5px; // border:none; } :deep(.gantt_tree_content) { display: flex; align-items: center; .jindu { width: 100%; display: flex; justify-content: center; align-items: center; color: #4482e3; border-radius: 10px; } .tasktype { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } } :deep(.gantt_task_line) { border: none; } :deep(.gantt_link_point) { display: none !important; } :deep(.gantt_task_progress) { height: 100%; } .toppingTask { width: 200px; height: 200px; background-color: #1890ff; } </style>
复制
不懂的直接区官网查看就好 什么api都有