1. 引入依赖

npm install dhtmlx-gantt@7.1.7

  1. 页面代码
<template>
  <div class="ganttShow">
    <div class="common-query">
      <div class="common-query-demo">
        <span>产品名称</span>
        <el-input placeholder="请输入产品名称" v-model="query.orderName"></el-input>
      </div>
  
      <div class="common-query-demo">
        <span>交货期</span>
        <el-date-picker v-model="query.deliDate" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" unlink-panels></el-date-picker>
      </div>
      <div class="common-query-demo">
        <el-button icon="el-icon-search" @click="queryEdit">查询</el-button>
      </div>
    </div>
    <div class="ganttShow-body">
      <div class="common-btn">
        <span>试算时间:2020-05-29 12:25:30</span>
        <el-button type="primary" @click="HungCommenced">挂起/开工</el-button>
      </div>
      <div class="ganttShow-box" :style="ganttStyle">
        <div id="gantt_here" style="height: 100%"></div>
      </div>
      <div class="ganttShow-foot">
        <div class="ganttShow-foot-desc">
          <img src="@assets/img/normal.png" />
          <span>排程正常</span>
        </div>
        <div class="ganttShow-foot-desc">
          <img src="@assets/img/overtime.png" />
          <span>产生加班</span>
        </div>
        <div class="ganttShow-foot-desc">
          <img src="@assets/img/warring.png" />
          <span>不满足交期</span>
        </div>
        <div class="ganttShow-foot-desc">
          <img src="@assets/img/shelve.png" />
          <span>挂起</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { reactive, toRefs, onMounted, onUnmounted } from 'vue'
import { gantt } from 'dhtmlx-gantt' // 引入模块
import '@gantt/skins/dhtmlxgantt_meadow.css' // 皮肤
import '@gantt/locale/locale_cn' // 本地化
import { ganttShowData } from '@api/pplant/ganttShow'
import { ElMessage } from 'element-plus'

export default {
  name: 'ganttShow',
  setup() {
    // 定义的变量
    const state = reactive({
      query: {
        orderName: '',
        number: '',
        deliDate: ''
      },
      ganttStyle: {
        height: ''
      },
      tableData: [],
      optioms: [],
      tasks: {
        data: []
      }
    })

    // 表格数据请求
    function getGanttShowData() {
      ganttShowData().then(res => {
        state.tasks.data = res.data
        state.optioms = res.options
        Init()
      })
    }

    function Init() {
      // 当task的长度改变时,自动调整图表坐标轴区间用于适配task的长度
      gantt.config.fit_tasks = true
      // 禁止用户拖动条形图来改变位置
      gantt.config.drag_move = false
      // 禁止用户推拽条形图上用来调整进度百分比的小按钮
      gantt.config.show_progress = false
      // 禁止通过拖拽的方式新增任务依赖的线条
      gantt.config.show_links = false
      // 允许用户通过拖拽任务的条形图的两端来改变工期
      gantt.config.drag_resize = false
      // 设置左侧表格的宽度
      gantt.config.grid_width = 300
      // 时间轴列的最小宽度
      gantt.config.min_column_width = 25
      // 时间轴图表中,任务条形图的高度
      gantt.config.bar_height = 10
      // 时间轴图表中,包头部分的高度
      gantt.config.scale_height = 50
      // 时间轴图表中,甘特图的高度
      gantt.config.row_height = 20
      // // 定义弹出框select选择内容
      var opts = state.optioms
      // 定义lightbox弹出框
      gantt.locale.labels.section_cause = '修改原因' // 自定义字段
      gantt.locale.labels.section_remark = '备注' // 自定义字段
      gantt.config.lightbox.sections = [
        {
          name: 'description',
          height: 38,
          map_to: 'text',
          type: 'template'
        },
        {
          name: 'cause',
          height: 28,
          map_to: 'cause',
          type: 'select',
          options: opts
        },
        {
          name: 'remark',
          height: 38,
          map_to: 'remark',
          type: 'textarea',
          focus: true
        },
        {
          name: 'time',
          height: 38,
          type: 'time',
          map_to: 'auto',
          time_format: ['%Y', '%m', '%d', '%H:%i']
        }
      ]
      // 弹框的日期格式处理
      gantt.config.date_format = '%Y-%m-%d %H:%i'
      gantt.config.task_date = '%Y-%m-%d %H:%i'
      // 工期计算的基本单位
      gantt.config.duration_unit = 'minute'
      gantt.config.duration_step = 1
      // 设置x轴日期
      gantt.config.scale_unit = 'month'
      gantt.config.step = 1
      gantt.config.date_scale = '%Y-%m'
      // 设置时间以分钟为单位
      gantt.config.time_step = 1
      // 在时间线上增加一行显示日
      gantt.config.subscales = [
        {
          unit: 'day',
          step: 1,
          date: '%d'
        }
      ]
      // 显示到进度条上的文本为空
      gantt.templates.task_text = function () {
        return null
      }
      // 自定义按钮
      gantt.attachEvent('onGanttReady', function () {
        gantt.config.buttons_left = ['gantt_save_btn']
      })
      gantt.attachEvent('onGanttReady', function () {
        gantt.config.buttons_right = ['gantt_cancel_btn']
      })
      // 初始化列 (自定义的时候需要更改源码匹配自己新增name字段 否则undefined)
      gantt.config.columns = [
        {
          name: 'text', // 自定义字段
          label: '订单名称', // 用于界面展示的名称
          tree: true // 当前列节点是否带图标
        }
      ]
      // 鼠标经过时弹出框提示
      gantt.plugins({
        tooltip: true
      })
      // 设置父任务条形图颜色与子任务区别
      gantt.templates.task_class = function (start, end, item) {
        return item.$level == 0 ? 'gantt_project' : ''
      }
      // 设置父任务ID不可操作
      gantt.attachEvent('onBeforeLightbox', function (id) {
        var task = gantt.getTask(id)
        if (task.progress == 1) {
          return false
        }
        return true
      })
      // 悬浮提示框内容设置
      gantt.templates.tooltip_text = function (start, end, task) {
        // alert(task.start_date)
        // alert(start)
        return (task.text + '<br /><b>开始时间:</b>' + task.start_date + '<br /><b>结束时间:</b>' + task.end_date)
      }
      // 突出周末
      gantt.templates.timeline_cell_class = function (item, date) {
        // debugger
        if (date.getDay() == 0 || date.getDay() == 6) {
          return 'weekend'
        }
      }
      // 显示当天
      gantt.plugins({
        marker: true
      })

      // 显示交货期
      var dateToStr = gantt.date.date_to_str(gantt.config.task_date)
      // js获取时间月份减去1
      var start = new Date(2020, 4, 5, 18, 0, 0) // 实际交货期为5-6
      gantt.addMarker({
        start_date: start,
        css: 'today',
        text: '交货期',
        title: '交货期: ' + dateToStr(start)
      })

      // 显示当天
      var today = new Date()
      gantt.addMarker({
        start_date: today,
        css: 'today',
        text: '今天'
        // title: '今天: ' + dateToStr(today),
      })
      // 设置请求时间格式
      gantt.config.xml_date = '%Y-%m-%d %H:%i'
      // 初始化
      gantt.init('gantt_here')
      // 数据解析
      gantt.parse(state.tasks)
    }

    function HungCommenced() {
      ElMessage.error('暂定!')
    }

    // 查询
    function queryEdit() {
      ElMessage.success('恭喜您,查询成功!')
    }

    function getHeight() {
      state.ganttStyle.height = window.innerHeight - 332 + 'px'
    }

    // 页面加载时调用函数
    onMounted(() => {
      // 请求表格数据
      getGanttShowData()
      // 注册监听器
      window.addEventListener('resize', getHeight)
      // 调用函数
      getHeight()
    })

    onUnmounted(() => {
      // 注销监听器
      window.removeEventListener('resize', getHeight)
    })

    return {
      ...toRefs(state),
      HungCommenced,
      queryEdit
    }
  }
}
</script>

<style lang='scss'>
.ganttShow {
  width: 100%;
  height:100%;

  .ganttShow-body {
    height: calc(100% - 120px);
    margin-top: 20px;
    box-shadow: $box-shadow;
    background: #fff;
    padding: 20px;

    .ganttShow-box{
      margin-top:20px;
    }

    .ganttShow-foot{
      margin-top:20px;
      display: flex;

      .ganttShow-foot-desc{
        margin:0 20px;

        span{
          margin-left:20px;
        }
      }

      .ganttShow-foot-desc:first-child{
        margin-left:0;
      }
    }
  }
}
</style>

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.

3.效果展示
vue3+dhtmlx-gantt实现甘特图_前端