<template>
<section class="my-gantt">
<div id="gantt_here" class="gantt-container"></div>
</section>
</template>
<script setup>
import { onMounted } from 'vue'
import { gantt } from 'dhtmlx-gantt'
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
//初始化甘特图
const initGantt = () => {
// 清空之前的配置
gantt.clearAll()
gantt.plugins({
export_api: true,
marker: true, // 添加今日的Marker
tooltip: true, // 鼠标经过时信息
})
const demoData = {
data: [
{
id: 520,
projectName: '项目1',
start_date: '2024-09-24',
end_date: '2024-10-31',
progress: 0.5,
open: true,
personName: 'xxx',
},
{
id: 1,
projectName: '子项目1',
parent: 520,
start_date: '2024-06-27',
end_date: '2024-10-25',
progress: 0.67,
personName: 'xxx',
},
{
id: 517,
projectName: '项目2',
start_date: '2024-09-17',
end_date: '2024-10-23',
progress: 0.2,
personName: 'xxx',
},
{
id: 505,
projectName: '项目3',
start_date: '2024-09-03',
end_date: '2024-09-30',
progress: 0.1,
personName: 'xxx',
},
{
id: 508,
projectName: '项目4',
start_date: '2024-09-03',
end_date: '2024-10-20',
progress: 0.15,
personName: 'xxx',
},
{
id: 511,
projectName: '项目5',
start_date: '2024-07-31',
end_date: '2024-10-31',
progress: 0.28,
personName: 'xxx',
},
{
id: 513,
projectName: '项目6',
start_date: '2024-07-27',
end_date: '2024-07-28',
progress: 0.28,
personName: 'xxx',
},
{
id: 507,
projectName: '项目6',
start_date: '2024-07-27',
end_date: '2024-08-29',
progress: 0.33,
personName: 'xxx',
},
],
}
let dateToStr = gantt.date.date_to_str('%Y-%m-%d')
gantt.config.grid_width = 750 // 左侧表格整体的宽度
gantt.config.row_height = 50 // 左侧树表格内容 每行的高度
gantt.config.bar_height = 20 // 右侧任务条形图每行 bar条形图 的高度
gantt.config.xml_date = '%Y-%m-%d' //甘特图时间数据格式
gantt.config.readonly = true //是否只读
gantt.config.columns = [
{
name: 'projectName',
label: '标题',
tree: true,
width: '200',
visible: true,
},
{
name: 'progress',
label: '类型',
align: 'center',
template: function (item) {
return `<div class="project-time">${
item.parent == 0 ? '计划组' : '计划'
}</div>`
},
},
{
name: 'schedule',
label: '进度',
align: 'center',
template: function (item) {
return `<div class="project-time">${
Math.round(item.progress * 100) + '%'
}</div>`
},
},
{
name: 'personName',
label: '负责人',
align: 'center',
},
{
name: 'start_date',
label: '开始时间',
width: '150',
align: 'center',
template: function (item) {
return `<div class="project-time">${dateToStr(item.start_date)}</div>`
},
},
{
name: 'end_date',
label: '完成时间',
align: 'center',
width: '150',
template: function (item) {
return `<div class="project-time">${dateToStr(item.end_date)}</div>`
},
},
]
gantt.i18n.setLocale('cn') //设置语言
gantt.attachEvent('onGanttReady', function () {
gantt.addTaskLayer(function (task) {
let deadline = new Date(task.require_date)
if (+deadline < +task.start_date || +deadline < +task.end_date) {
console.log(deadline)
let start_date = deadline
if (+task.start_date > +deadline) {
start_date = task.start_date
}
const sizes = gantt.getTaskPosition(task, start_date, task.end_date)
const el = document.createElement('div')
el.className = 'progress_value'
el.style.left = sizes.left + 'px'
el.style.width = sizes.width + 'px'
el.style.top = sizes.top + 2 + 'px'
el.style.height = sizes.height + 'px'
return el
}
return false
})
})
const zoomConfig = {
levels: [
{
name: 'month',
scale_height: 40,
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'
}
},
},
],
},
],
}
gantt.init('gantt_here') //初始化
gantt.parse(demoData) //填充数据
gantt.ext.zoom.init(zoomConfig) //配置初始化扩展
gantt.ext.zoom.setLevel('month') //切换到指定的缩放级别
}
onMounted(() => {
initGantt()
// 开启服务
})
</script>
<style scoped lang="scss">
.my-gantt {
height: calc(100% - 90px);
width: 100%;
.time-box {
width: 100%;
text-align: right;
background: #fff;
}
::v-deep .gantt_task_row.gantt_selected .gantt_task_cell {
border-right-color: #ebebeb !important;
}
::v-deep .gantt-container {
width: 100%;
height: 100%;
.weekend {
background: #ff9e2f;
color: #fff;
}
}
::v-deep .gantt_grid_data .gantt_row.gantt_selected,
.gantt_grid_data .gantt_row.odd.gantt_selected,
.gantt_task_row.gantt_selected {
background: linear-gradient(
to bottom,
rgba(0, 100, 255, 0.05),
rgba(0, 100, 255, 0.05)
) !important;
}
::v-deep .gantt_task_row.gantt_selected {
background: linear-gradient(
to bottom,
rgba(0, 100, 255, 0.05),
rgba(0, 100, 255, 0.05)
) !important;
}
::v-deep .gantt_grid_data .gantt_row:hover {
background: linear-gradient(
to bottom,
rgba(0, 100, 255, 0.05),
rgba(0, 100, 255, 0.05)
) !important;
}
::v-deep .gantt_grid_scale .gantt_grid_head_cell {
border-right: 1px solid #cecece !important;
}
::v-deep .gantt_tree_content {
display: flex;
align-items: center;
justify-content: center;
}
}
.svg-all {
color: red;
}
.title-key {
font-size: 22px !important;
margin-top: 20px;
font-weight: 700;
}
::v-deep .gantt_task_progress {
background: #2cb2ae !important;
border-color: #2cb2ae !important;
}
::v-deep .gantt_task_progress_wrapper {
background-color: #95d8d6 !important;
border-color: #2cb2ae !important;
}
.left {
width: 40px;
height: 20px;
background: #2cb2ae;
border-radius: 8px;
}
.right {
width: 40px;
height: 20px;
background-color: #95d8d6;
border-radius: 8px;
}
.right-end {
width: 40px;
height: 20px;
background-color: red;
border-radius: 8px;
}
.ms-detail {
display: flex;
justify-content: flex-end;
padding-right: 20px;
}
.search-all {
display: flex;
justify-content: space-between;
background-color: #fff;
background-color: #fff;
padding: 20px;
}
.progress_value {
position: absolute;
background: red;
opacity: 0.7;
z-index: 1;
pointer-events: none;
}
</style>
为啥会报错 TypeError: gantt.addTaskLayer is not a function
用的是 "dhtmlx-gantt": "^8.0.9", 的包