- <template>
- <section class="my-gantt">
- <div class="time-box">
- <el-radio-group v-model="data.timeState" @change="changeTime">
- <el-radio-button
- v-for="(time, t_index) in data.timeList"
- :key="t_index"
- :label="time.code"
- size="default"
- border
- >{{ time.name }}</el-radio-button
- >
- </el-radio-group>
- </div>
- <div id="gantt_here" class="gantt-container"></div>
- </section>
- </template>
-
- <script setup>
- import { reactive, toRefs, onBeforeMount, onMounted, watchEffect, defineExpose } from 'vue'
-
- import { gantt } from 'dhtmlx-gantt'
- import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
-
- const data = reactive({
- timeList: [
- // {
- // name: "周",
- // code: "week",
- // },
- {
- name: '月',
- code: 'month'
- },
- {
- name: '季',
- code: 'quarter'
- },
- {
- name: '年',
- code: 'year'
- }
- ],
- timeState: 'month',
- demoData: {
- data: [
- {
- id: 520,
- projectName: '项目1',
- startTime: '2023-09-25',
- endTime: '2023-10-31',
- showEndTime: '2023-11-01',
- projectStatus: '暂无任务',
- projectProgress: 0,
- projectRatio: '',
- projectTotalTime: 0,
- projectUsedTime: 0,
- functionName: '',
- xmdj: '2',
- cityName: '成都',
- name: '1',
- projectMap: {},
- parent: 0,
- start_date: '2023-09-24 16:00:00.000',
- end_date: '2023-10-31 16:00:00.000',
- progress: 0.5,
- duration: 37
- },
- {
- id: 517,
- projectName: '项目2',
- startTime: '2023-09-18',
- endTime: '2023-10-23',
- showEndTime: '2023-10-24',
- projectStatus: '暂无任务',
- projectProgress: 0,
- projectRatio: '',
- projectTotalTime: 0,
- projectUsedTime: 0,
- functionName: '',
- xmdj: '0',
- cityName: '深圳',
- name: '2',
- projectMap: {},
- parent: 0,
- start_date: '2023-09-17 16:00:00.000',
- end_date: '2023-10-23 16:00:00.000',
- progress: 0.2
- },
- {
- id: 505,
- projectName: '项目3',
- startTime: '2023-09-04',
- endTime: '2023-09-30',
- showEndTime: '2023-10-01',
- projectStatus: '滞后',
- projectProgress: 0.76,
- projectRatio: 0.12,
- projectTotalTime: 3267.6,
- projectUsedTime: 2477.7,
- functionName: '现状还原',
- xmdj: '3',
- cityName: '成都',
- name: '3',
- projectMap: {},
- parent: 0,
- start_date: '2023-09-03 16:00:00.000',
- end_date: '2023-09-30 16:00:00.000',
- progress: 0.1
- },
- {
- id: 508,
- projectName: '项目4',
- startTime: '2023-09-04',
- endTime: '2023-10-20',
- showEndTime: '2023-10-21',
- projectStatus: '滞后',
- projectProgress: 0.57,
- projectRatio: 0.04,
- projectTotalTime: 3582.5,
- projectUsedTime: 2033.2,
- functionName: '生活圈',
- xmdj: '1',
- cityName: '成都',
- name: '4',
- projectMap: {},
- parent: 0,
- start_date: '2023-09-03 16:00:00.000',
- end_date: '2023-10-20 16:00:00.000',
- progress: 0.15
- },
- {
- id: 511,
- projectName: '项目5',
- startTime: '2023-09-01',
- endTime: '2023-10-31',
- showEndTime: '2023-11-01',
- projectStatus: '滞后',
- projectProgress: 0.07,
- projectRatio: 0.03,
- projectTotalTime: 2150.5,
- projectUsedTime: 140,
- functionName: '悬浮球',
- xmdj: '1',
- cityName: '成都',
- name: '5',
- projectMap: {},
- parent: 0,
- start_date: '2023-07-31 16:00:00.000',
- end_date: '2023-10-31 16:00:00.000',
- progress: 0.28
- },
- {
- id: 507,
- projectName: '项目6',
- startTime: '2023-08-28',
- endTime: '2023-10-01',
- showEndTime: '2023-10-02',
- projectStatus: '滞后',
- projectProgress: 0.48,
- projectRatio: 0.21,
- projectTotalTime: 4957,
- projectUsedTime: 2367,
- functionName: '产品原型图',
- xmdj: '1',
- cityName: '三亚',
- name: '6',
- projectMap: {
- 美术: 1
- },
- parent: 0,
- start_date: '2023-07-27 16:00:00.000',
- end_date: '2023-10-01 16:00:00.000',
- progress: 0.33
- },
- {
- id: 1,
- projectName: '项目7',
- startTime: '2023-08-28',
- endTime: '2023-10-25',
- showEndTime: '2023-10-26',
- projectStatus: '滞后',
- projectProgress: 0.27,
- projectRatio: 0.15,
- projectTotalTime: 2027.5,
- projectUsedTime: 557,
- functionName: '测量工具',
- xmdj: '1',
- cityName: '佛山',
- name: '7',
- projectMap: {},
- parent: 0,
- start_date: '2023-06-27 16:00:00.000',
- end_date: '2023-10-25 16:00:00.000',
- progress: 0.67
- },
- {
- id: 2,
- projectName: '项目7',
- startTime: '2023-08-28',
- endTime: '2023-10-25',
- showEndTime: '2023-10-26',
- projectStatus: '滞后',
- projectProgress: 0.27,
- projectRatio: 0.15,
- projectTotalTime: 2027.5,
- projectUsedTime: 557,
- functionName: '测量工具',
- xmdj: '1',
- cityName: '佛山',
- name: '7',
- projectMap: {},
- parent: 0,
- start_date: '2023-06-27 16:00:00.000',
- end_date: '2023-10-25 16:00:00.000',
- progress: 0.67
- },
- {
- id: 3,
- projectName: '项目7',
- startTime: '2023-08-28',
- endTime: '2023-10-25',
- showEndTime: '2023-10-26',
- projectStatus: '滞后',
- projectProgress: 0.27,
- projectRatio: 0.15,
- projectTotalTime: 2027.5,
- projectUsedTime: 557,
- functionName: '测量工具',
- xmdj: '1',
- cityName: '佛山',
- name: '7',
- projectMap: {},
- parent: 0,
- start_date: '2023-06-27 16:00:00.000',
- end_date: '2023-10-25 16:00:00.000',
- progress: 0.67
- },
- {
- id: 4,
- projectName: '项目7',
- startTime: '2023-08-28',
- endTime: '2023-10-25',
- showEndTime: '2023-10-26',
- projectStatus: '滞后',
- projectProgress: 0.27,
- projectRatio: 0.15,
- projectTotalTime: 2027.5,
- projectUsedTime: 557,
- functionName: '测量工具',
- xmdj: '1',
- cityName: '佛山',
- name: '7',
- projectMap: {},
- parent: 0,
- start_date: '2023-06-27 16:00:00.000',
- end_date: '2023-10-25 16:00:00.000',
- progress: 0.67
- },
- {
- id: 5,
- projectName: '项目7',
- startTime: '2023-08-28',
- endTime: '2023-10-25',
- showEndTime: '2023-10-26',
- projectStatus: '滞后',
- projectProgress: 0.27,
- projectRatio: 0.15,
- projectTotalTime: 2027.5,
- projectUsedTime: 557,
- functionName: '测量工具',
- xmdj: '1',
- cityName: '佛山',
- name: '7',
- projectMap: {},
- parent: 0,
- start_date: '2023-06-27 16:00:00.000',
- end_date: '2023-10-25 16:00:00.000',
- progress: 0.67
- },
- {
- id: 6,
- projectName: '项目7',
- startTime: '2023-08-28',
- endTime: '2023-10-25',
- showEndTime: '2023-10-26',
- projectStatus: '滞后',
- projectProgress: 0.27,
- projectRatio: 0.15,
- projectTotalTime: 2027.5,
- projectUsedTime: 557,
- functionName: '测量工具',
- xmdj: '1',
- cityName: '佛山',
- name: '7',
- projectMap: {},
- parent: 0,
- start_date: '2023-06-27 16:00:00.000',
- end_date: '2023-10-25 16:00:00.000',
- progress: 0.67
- },
- {
- id: 7,
- projectName: '项目7',
- startTime: '2023-08-28',
- endTime: '2023-10-25',
- showEndTime: '2023-10-26',
- projectStatus: '滞后',
- projectProgress: 0.27,
- projectRatio: 0.15,
- projectTotalTime: 2027.5,
- projectUsedTime: 557,
- functionName: '测量工具',
- xmdj: '1',
- cityName: '佛山',
- name: '7',
- projectMap: {},
- parent: 0,
- start_date: '2023-06-27 16:00:00.000',
- end_date: '2023-10-25 16:00:00.000',
- progress: 0.67
- },
- {
- id: 8,
- projectName: '项目7',
- startTime: '2023-08-28',
- endTime: '2023-10-25',
- showEndTime: '2023-10-26',
- projectStatus: '滞后',
- projectProgress: 0.27,
- projectRatio: 0.15,
- projectTotalTime: 2027.5,
- projectUsedTime: 557,
- functionName: '测量工具',
- xmdj: '1',
- cityName: '佛山',
- name: '7',
- projectMap: {},
- parent: 0,
- start_date: '2023-06-27 16:00:00.000',
- end_date: '2023-10-25 16:00:00.000',
- progress: 0.67
- },
- {
- id: 9,
- projectName: '项目7',
- startTime: '2023-08-28',
- endTime: '2023-10-25',
- showEndTime: '2023-10-26',
- projectStatus: '滞后',
- projectProgress: 0.27,
- projectRatio: 0.15,
- projectTotalTime: 2027.5,
- projectUsedTime: 557,
- functionName: '测量工具',
- xmdj: '1',
- cityName: '佛山',
- name: '7',
- projectMap: {},
- parent: 0,
- start_date: '2023-06-27 16:00:00.000',
- end_date: '2023-10-25 16:00:00.000',
- progress: 0.67
- }
- ]
- }
- })
-
- const zoomConfig = {
- levels: [
- {
- name: 'day',
- scale_height: 60,
- scales: [{ unit: 'day', step: 1, format: '%d %M' }]
- },
- {
- name: 'week',
- scale_height: 60,
- scales: [
- {
- unit: 'week',
- step: 1,
- format: function (date) {
- let dateToStr = gantt.date.date_to_str('%m-%d')
- let endDate = gantt.date.add(date, -6, 'day')
- let weekNum = gantt.date.date_to_str('%W')(date) //第几周
- return dateToStr(endDate) + ' 至 ' + dateToStr(date)
- }
- },
- {
- unit: 'day',
- step: 1,
- format: '%d', // + "周%D"
- css: function (date) {
- if (date.getDay() == 0 || date.getDay() == 6) {
- return 'day-item weekend weekend-border-bottom'
- } else {
- return 'day-item'
- }
- }
- }
- ]
- },
- {
- name: 'month',
- scale_height: 60,
- min_column_width: 18,
- scales: [
- { unit: 'month', format: '%Y-%m' },
- {
- unit: 'day',
- step: 1,
- format: '%d',
- css: function (date) {
- if (date.getDay() == 0 || date.getDay() == 6) {
- return 'day-item weekend weekend-border-bottom'
- } else {
- return 'day-item'
- }
- }
- }
- ]
- },
- {
- name: 'quarter',
- height: 60,
- min_column_width: 110,
- scales: [
- {
- unit: 'quarter',
- step: 1,
- format: function (date) {
- let yearStr = new Date(date).getFullYear() + '年'
- let dateToStr = gantt.date.date_to_str('%M')
- let endDate = gantt.date.add(gantt.date.add(date, 3, 'month'), -1, 'day')
- return yearStr + dateToStr(date) + ' - ' + dateToStr(endDate)
- }
- },
- {
- unit: 'week',
- step: 1,
- format: function (date) {
- let dateToStr = gantt.date.date_to_str('%m-%d')
- let endDate = gantt.date.add(date, 6, 'day')
- let weekNum = gantt.date.date_to_str('%W')(date)
- return dateToStr(date) + ' 至 ' + dateToStr(endDate)
- }
- }
- ]
- },
- {
- name: 'year',
- scale_height: 50,
- min_column_width: 150,
- scales: [
- { unit: 'year', step: 1, format: '%Y年' },
- { unit: 'month', format: '%Y-%m' }
- ]
- }
- ]
- }
-
- //初始化甘特图
- const initGantt = () => {
- let dateToStr = gantt.date.date_to_str('%Y.%m.%d')
- gantt.config.grid_width = 350
- gantt.config.add_column = false //添加符号
-
- //时间轴图表中,如果不设置,只有行边框,区分上下的任务,设置之后带有列的边框,整个时间轴变成格子状。
- gantt.config.autofit = false
- gantt.config.row_height = 60
- gantt.config.bar_height = 34
- // gantt.config.fit_tasks = true //自动延长时间刻度,以适应所有显示的任务
- gantt.config.auto_types = true //将包含子任务的任务转换为项目,将没有子任务的项目转换回任务
- gantt.config.xml_date = '%Y-%m-%d' //甘特图时间数据格式
- gantt.config.readonly = true //是否只读
-
- gantt.templates.task_text = function (start, end, task) {
- return task.projectName
- }
-
- gantt.config.columns = [
- {
- name: 'projectName',
- label: '项目名称',
- tree: true,
- width: '*'
- },
- {
- name: '',
- label: '时间',
- align: 'center',
- width: 150,
- template: function (item) {
- return `<div class="project-time">${
- dateToStr(item.start_date) + '-' + item.endTime.replace(/[-]/g, '.')
- }</div>`
- }
- }
- ]
-
- gantt.i18n.setLocale('cn') //设置语言
- gantt.init('gantt_here') //初始化
- gantt.parse(data.demoData) //填充数据
- scrollInit()
- gantt.ext.zoom.init(zoomConfig) //配置初始化扩展
- gantt.ext.zoom.setLevel('month') //切换到指定的缩放级别
- }
-
- //拖拽滚动视图
- const scrollInit = () => {
- const nav = document.querySelectorAll('.gantt_task')[0]
- const parNav = document.querySelectorAll('.gantt_hor_scroll')[0]
- parNav.scrollLeft = 0
- let flag
- let downX
- let scrollLeft
- nav.addEventListener('mousedown', function (event) {
- flag = true
- downX = event.clientX // 获取到点击的x下标
- scrollLeft = this.scrollLeft // 获取当前元素滚动条的偏移量
- })
- nav.addEventListener('mousemove', function (event) {
- if (flag) {
- let moveX = event.clientX
- let scrollX = moveX - downX
- parNav.scrollLeft = scrollLeft - scrollX
- }
- })
- // 鼠标抬起停止拖动
- nav.addEventListener('mouseup', function () {
- flag = false
- })
- // 鼠标离开元素停止拖动
- nav.addEventListener('mouseleave', function (event) {
- flag = false
- })
- }
-
- const changeTime = () => {
- gantt.ext.zoom.setLevel(data.timeState)
- }
-
- onBeforeMount(() => {})
- onMounted(() => {
- initGantt()
- })
- watchEffect(() => {})
- defineExpose({
- ...toRefs(data)
- })
- </script>
- <style scoped lang="scss">
- .my-gantt {
- height: 800px;
- width: 100vw;
- .time-box {
- text-align: center;
- margin-bottom: 20px;
- }
- ::v-deep .gantt-container {
- width: 100%;
- height: 100%;
- .weekend {
- background: #ff9e2f;
- color: #fff;
- }
- }
- }
- </style>