如何使用 vue vxe-table 甘特图 vxe-gantt 渲染显示多行任务,预计完成日期和实际完成日期多条任务条

0 阅读3分钟

如何使用 vue vxe-table 甘特图 vxe-gantt 渲染显示多行任务,预计完成日期和实际完成日期多条任务条,可以自定义任务条颜色,拖拽调整日期等

gantt.vxeui.com

extend_gantt_chart_demo_multi_bar

使用树结构渲染子任务和隐藏树节点按钮来实现一行拆分多条任务条,每条任务条还可以通过css变量来设置颜色 --vxe-ui-gantt-view-task-bar-completed-background-color

<template>
  <div>
    <vxe-gantt v-bind="ganttOptions"></vxe-gantt>
  </div>
</template>

<script setup>
import { reactive } from 'vue'
import { VxeGanttTaskType } from 'vxe-gantt'
import XEUtils from 'xe-utils'

const ganttOptions = reactive({
  border: true,
  height: 500,
  loading: false,
  cellConfig: {
    height: 60 // 设置单元格高度,确保满足2个任务条的高度
  },
  rowConfig: {
    keyField: 'id' // 行主键
  },
  treeConfig: {
    transform: true, // 自动将列表转为树结构
    rowField: 'id', // 自定义树节点关联的主键
    parentField: 'parentId' // 自定义树节点关联的父节点的字段名
  },
  taskConfig: {
    titleField: 'title', // 自定义标题字段名
    startField: 'start', // 自定义开始日期字段名
    endField: 'end', // 自定义结束期字段名
    progressField: 'progress', // 自定义进度值字段名
    typeField: 'type' // 自定义渲染类型字段名
  },
  taskBarSubviewConfig: {
    // 自定义子任务视图任务条的样式
    barStyle ({ row }) {
      if (row.flag === 1) {
        return {
          transform: 'translateY(-24px)'
        }
      }
      if (row.flag === 2) {
        return {
          transform: 'translateY(1px)',
          '--vxe-ui-gantt-view-task-bar-completed-background-color': '#31d231'
        }
      }
    }
  },
  taskBarConfig: {
    showContent: true, // 是否在任务条显示内容
    moveable: true, // 是否允许拖拽任务移动日期
    resizable: true, // 是否允许拖拽任务调整日期
    linkCreatable: true, // 是否允许自定义创建依赖线
    barStyle: {
      round: true // 圆角
    }
  },
  taskViewConfig: {
    tableStyle: {
      width: 480 // 表格宽度
    }
  },
  columns: [
    { field: 'title', title: '任务名称', minWidth: 100 },
    { field: 'planStartDate', title: '计划开始时间', width: 100 },
    { field: 'planEndDate', title: '计划结束时间', width: 100 },
    { field: 'actualStartDate', title: '实际开始时间', width: 100 },
    { field: 'actualEndDate', title: '实际结束时间', width: 100 }
  ],
  data: []
})

// 模拟后端接口
const loadList = () => {
  ganttOptions.loading = true
  setTimeout(() => {
    const list = [
      { id: 10001, parentId: null, title: '任务1', planStartDate: '2024-03-03', planEndDate: '2024-03-15', actualStartDate: '2024-03-03', actualEndDate: '2024-03-12' },
      { id: 10002, parentId: null, title: '任务2', planStartDate: '2024-03-10', planEndDate: '2024-03-25', actualStartDate: '2024-03-08', actualEndDate: '2024-03-16' },
      { id: 10003, parentId: null, title: '任务3', planStartDate: '2024-03-20', planEndDate: '2024-04-10', actualStartDate: '2024-03-22', actualEndDate: '2024-04-01' },
      { id: 10004, parentId: null, title: '任务4', planStartDate: '2024-03-28', planEndDate: '2024-04-19', actualStartDate: '2024-03-28', actualEndDate: '2024-04-12' },
      { id: 10005, parentId: null, title: '任务5', planStartDate: '2024-04-05', planEndDate: '2024-04-28', actualStartDate: '2024-04-01', actualEndDate: '2024-04-24' }
    ]
    // 转成子任务视图
    const ganttData = []
    list.forEach(item => {
      const currRow = XEUtils.assign({}, item, { type: VxeGanttTaskType.Subview })
      const planRow = XEUtils.assign({}, item, {
        id: 10000000 + item.id,
        title: '计划',
        parentId: item.id,
        start: item.planStartDate,
        end: item.planEndDate,
        flag: 1
      })
      const actualRow = XEUtils.assign({}, item, {
        id: 20000000 + item.id,
        parentId: item.id,
        title: '实际',
        start: item.actualStartDate,
        end: item.actualEndDate,
        flag: 2
      })
      ganttData.push(currRow)
      ganttData.push(planRow)
      ganttData.push(actualRow)
    })
    ganttOptions.data = ganttData
    ganttOptions.loading = false
  }, 200)
}

loadList()
</script>

gitee.com/x-extends/v…