我当时公司需求是要求在甘特图上能显示任务情况的,即显示开始和结束时间,和实际任务开始和结束时间,还有请假,出差,加班,节假日情况,在网上找了一圈发现dhtmlx-gantt,dhtmlx-gantt付费不能完全能满足需求,但是小人不敢提,结果摸索后发现这是使用html生成的图表,修改起来很方便,所以我来分享一下免费版的,又满足要求的甘特图

一.文档地址

官方文档

二.安装

npm i dhtmlx-gantt

三.分析部分

任务情况无非有就几种:(蓝色是实际时间,红色是计划时间)

    1. 实际开始时间早于计划开始时间,实际结束时间也早于计划开始时间(l21)

    2. 实际开始时间早于计划开始时间,实际结束时间在计划时间之内 (j21)

    3. 实际开始时间早于计划开始时间,实际结束时间也晚于计划结束时间 (b21)

    4. 实际开始和结束时间都在计划时间之内(b12)

    5. 实际开始时间在计划时间之内,实际结束时间也晚于计划结束时间 (j12)

    6. 实际开始和结束时间都晚于计划结束时间(l12)

四.效果图

 先上效果图

五.代码部分

  

 dhtmlx-gantt参数方法什么的就自己看官网了哈,这里就不多做解释了,直接上代码

index.vue 部分

头部样式和定义甘特图容器

引入

import moment from 'moment';

// import { Empty } from 'ant-design-vue';

import gantt from "dhtmlx-gantt"; // 引入模块

import "dhtmlx-gantt/codebase/dhtmlxgantt.css"; //皮肤

import {data} from './data.js'

处理甘特图右侧进度条类型样式方法和判断

// 设置每一部分的颜色

renderLabel(progress, type, state,val,num,objText,status) {

// progress, type, state,val实际还是计划,num,objText完成度,status状态

// const self =this

let hour = moment().format("k");

var relWidth = progress * 100;

var n=num*100

var cssClass = "custom_progress ";

let otherLength = '0px' // 额外长度

// let doingLenght = 34

// 实际

if(val==='progress3'){

if(status === 'doing'){

if(objText==='100%'){

cssClass += "nearly_done1";

otherLength = '34px'

}else{

cssClass += "near_done1"

if(Number(hour)<8){

otherLength = '0px'

}else if(Number(hour)>=8 && Number(hour)<18){

let num=34*(Number(hour) -8)/8

otherLength = num+'px'

}else{

otherLength = '34px'

}

}

}else{

if (type === 1) {

cssClass += "nearly_done1";

} else if (type === 2) {

if (state) {

cssClass += "in_progress1";

} else {

cssClass += "in_progress_w1";

}

} else {

cssClass += "idle1";

}

}

}else{

if (type === 1) {

cssClass += "nearly_done";

} else if (type === 2) {

if (state) {

cssClass += "in_progress";

} else {

cssClass += "in_progress_w";

}

} else {

cssClass += "idle";

}

}

if(val==='progress3'){

let widthLenght

if(status === 'doing'){

widthLenght = `calc(${relWidth+'%'} + ${otherLength} - 34px)`

}else{

widthLenght = `calc(${relWidth+'%'} + ${otherLength})`

}

return (

"

" +

"

"

);

}else{

return (

`

${objText!=undefined?objText:''}
`

);

}

}

// 根据定义类型判断颜色顺序

gantt.templates.task_text = (start, end, task)=> {

let colorType = task.colorType

if (colorType === 'j12' || colorType === 'one') {

return (

this.renderLabel(task.progress1, 1, task.state,'progress1',0,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 3, task.state,'progress3',task.pro.cprogress1,task.ratio,task.taskStatus) // 实际

);

} else if (colorType === 'j21') {

return (

this.renderLabel(task.progress1, 1, task.state,'progress1',task.pro.cprogress1,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 1, task.state,'progress3',0,task.ratio,task.taskStatus)

);

} else if (colorType === 'b12') {

return (

this.renderLabel(task.progress1, 1, task.state,'progress1',0,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 1, task.state,'progress3',task.pro.cprogress1,task.ratio,task.taskStatus)

);

} else if (colorType === 'b21') {

return (

this.renderLabel(task.progress1, 2, task.state,'progress1',task.pro.cprogress1,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 2, task.state,'progress3',0,task.ratio,task.taskStatus)

);

} else if (colorType === 'l12') {

return (

this.renderLabel(task.progress1, 1, task.state,'progress1',0,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 3, task.state,'progress3',task.pro.cprogress1+task.pro.cprogress2,task.ratio,task.taskStatus)

);

} else if (colorType === 'l21') {

return (

this.renderLabel(task.progress1, 3, task.state,'progress1',task.pro.cprogress2+task.pro.cprogress1,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 1, task.state,'progress3',0,task.ratio,task.taskStatus)

);

} else {

return (

this.renderLabel(task.progress1, 3, task.state,'progress1',task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 3, task.state,'progress3',task.ratio,task.taskStatus)

);

}

};

 请假样式方法

// 请假放假情况

getLeave(){

// let year = this.year

gantt.templates.timeline_cell_class = function(task,date){

if(date.getDay()==0||date.getDay()==6){

return "weekend" ;

}

}

// axios.get(`请假url`).then(res=>{

// if(res.code===0){

let leaveList = [

{

realname:'王A',

'2022-01-20':2,

'2022-01-21':3,

'2022-01-24':4,

'2022-01-25':5,

}

]

// 请假设置

gantt.templates.timeline_cell_class = function(task,date){

if(date.getDay()==0||date.getDay()==6){

return "weekend" ;

}

// // if(self.date11){

for(let i=0;i<=leaveList.length-1;i++){

if(leaveList[i].realname === task.principal){

for(let key in leaveList[i]){

if(key!=='realname' && leaveList[i][key]!=0 && leaveList[i][key]!=1){

if(moment(date).format('YYYY-MM-DD')===key){

if(leaveList[i][key]===2){

return "weekend1" ;

}

if(leaveList[i][key]===3){

return "weekend3" ;

}

if(leaveList[i][key]===4){

return "weekend4" ;

}

if(leaveList[i][key]===5){

return "weekend5" ;

}

}

}

}

}

// // for(let j=0;j<=self.date11[i].supy.length-1;j++){

// // if(task.id===self.date11[i].id && moment(date).format('YYYY-MM-DD')===self.date11[i].supy[j]){

// // return "weekend1" ;

// // }

// // }

}

// }

};

// }else{

// // this.$message.error(res.msg)

// }

// })

}

方法,数据部分

export default {

name: 'Home',

components: {

// HelloWorld

},

data(){

return{

phaseTime:'2022-02',

tasks:{

data:[]

},

date11:[],

simpleImage: '',

loading: true,

year:'2022-02',

searchMessage:{

principal:'',

projectName:'',

targetName:''

},

sortType:'', // 排序方式

showType:'projectName' //默认projectName 甘特图展现形式 负责人 principal 项目 projectName

}

},

methods:{

// 请假放假情况

getLeave(){

// let year = this.year

gantt.templates.timeline_cell_class = function(task,date){

if(date.getDay()==0||date.getDay()==6){

return "weekend" ;

}

}

// axios.get(`请假url`).then(res=>{

// if(res.code===0){

let leaveList = [

{

realname:'王A',

'2022-01-20':2,

'2022-01-21':3,

'2022-01-24':4,

'2022-01-25':5,

}

]

// 请假设置

gantt.templates.timeline_cell_class = function(task,date){

if(date.getDay()==0||date.getDay()==6){

return "weekend" ;

}

// // if(self.date11){

for(let i=0;i<=leaveList.length-1;i++){

if(leaveList[i].realname === task.principal){

for(let key in leaveList[i]){

if(key!=='realname' && leaveList[i][key]!=0 && leaveList[i][key]!=1){

if(moment(date).format('YYYY-MM-DD')===key){

if(leaveList[i][key]===2){

return "weekend1" ;

}

if(leaveList[i][key]===3){

return "weekend3" ;

}

if(leaveList[i][key]===4){

return "weekend4" ;

}

if(leaveList[i][key]===5){

return "weekend5" ;

}

}

}

}

}

// // for(let j=0;j<=self.date11[i].supy.length-1;j++){

// // if(task.id===self.date11[i].id && moment(date).format('YYYY-MM-DD')===self.date11[i].supy[j]){

// // return "weekend1" ;

// // }

// // }

}

// }

};

// }else{

// // this.$message.error(res.msg)

// }

// })

},

// 查询数据

initData() {

const self = this

// let year = self.year

// 处理数据

self.date11 =[{

id:'1',

supy:['2022-06-01','2022-06-02']

},{

id:'2',

supy:['2022-06-02','2022-06-03']

},]

this.tasks.data = []

this.loading = true

// 是按人搜索还是项目搜索

if(this.searchMessage.principal==''|| this.searchMessage.principal==null ){

this.showType = 'projectName'

}else{

this.showType = 'principal'

}

// http://10.20.11.218:5566

// axios.get(`/target/month/ganttChart?month=${year}&&principal=${self.searchMessage.principal}&&projectName=${self.searchMessage.projectName}&&targetName=${self.searchMessage.targetName}`).then(res=>{

this.loading = false

console.log(data, '000')

if(data){

let arr = data

// 假期设置

gantt.templates.scale_cell_class = function(date){

if(date.getDay()==0||date.getDay()==6){

return "weekend";

}

};

// 请假

this.getLeave()

// 处理数据

let newArr = []

// 处理数据

// 若含用户 searchMessage.principal 是用户搜索 如无 是 项目默认状态

if(this.searchMessage.principal==''|| this.searchMessage.principal==null ){

for(let i=0;i

let obj1= this.getDate(arr[i].startDate,arr[i].endDate,null,null,1)

// 获取当月天数

let minMouth = this.year+'-01'

let StartminTime

if(moment(minMouth).format("YYYY-MM-DD")>moment(arr[i].startDate).format("YYYY-MM-DD")){

StartminTime = moment(minMouth).format("MM-DD-YYYY,00:00:00")

}else{

StartminTime = moment(arr[i].startDate).format("MM-DD-YYYY,00:00:00")

}

newArr.push({

calendar_id:"custom",

id:arr[i].id,

start_date: new Date(StartminTime),

duration:obj1.duration,

projectName:arr[i].projectName,

progress1: Math.abs(obj1.progress1),

text:arr[i].name,

planStart: arr[i].startDate,

planEnd: arr[i].endDate,

open:true

})

for(let j=0; j

let monthList = arr[i].monthTargetGanttChartDOList[j]

// 参数 计划开始 计划结束 实际开始 实际结束 是否是父级(父级判断开始结束是否在当前月内) 状态

let obj = this.getDate(monthList.estStarted, monthList.estEndTed, monthList.realStarted, monthList.realEndTed,0,monthList.taskStatus)

gantt.addCalendar({

id:"custom", // optional

worktime: {

hours: ["8:00-17:00"],

days: [ 1, 1, 1, 1, 1, 1 ,1]

}

});

const calendar = gantt.getCalendar("custom");

calendar.setWorkTime({

date:new Date(2021,9,1),

hours:false

});

newArr.push({

id: i+1+'-'+j+1,

text: monthList.targetName,

targetName:monthList.targetName,

calendar_id:"custom",

start_date: new Date(moment(obj.minTime).format("YYYY-MM-DD,00:00:00")),

progress1: Math.abs(obj.progress1),

progress2: monthList.targetName,

progress3: Math.abs(obj.progress3),

duration: obj.duration,

projectName:monthList.projectName,

principal:monthList.principal,

taskName:monthList.taskName,

taskStatusName:monthList.taskStatusName,

taskStatus: monthList.taskStatus,

status: `${monthList.taskStatusName}`,

planStart: monthList.estStarted,

planEnd: `${monthList.estEndTed}`,

actualStart: monthList.realStarted,

actualEnd: monthList.realEndTed,

ratio: monthList.ratio,

state: obj.state,

parent:monthList.targetId,

colorType: obj.colorType,

pro:obj.progress,

open:true

})

}

}

}else{

// 根据用户进行搜索

let userList =[]

let newBrr =[]

for(let i=0;i

for(let j=0; j

let monthList = arr[i].monthTargetGanttChartDOList[j]

// 统计人名

// userList.push(monthList.principal)

// newBrr 数组 estStarted

newBrr.push(monthList)

}

}

// 排序

for(var i=0;i

for(var j=0;j

if(!(moment(newBrr[j].estStarted).isBefore(newBrr[j+1].estStarted))){

let tem = JSON.parse(JSON.stringify(newBrr[j]));

newBrr[j] = JSON.parse(JSON.stringify(newBrr[j+1]));

newBrr[j+1] = JSON.parse(JSON.stringify(tem));

}

}

}

newBrr.forEach((item,index)=>{

let monthList = item

// let monthList = arr[i].monthTargetGanttChartDOList[j]

// 统计人名

userList.push(monthList.principal)

// 参数 计划开始 计划结束 实际开始 实际结束 是否是父级(父级判断开始结束是否在当前月内) 状态

let obj = this.getDate(monthList.estStarted, monthList.estEndTed, monthList.realStarted, monthList.realEndTed,0,monthList.taskStatus)

gantt.addCalendar({

id:"custom", // optional

worktime: {

hours: ["8:00-17:00"],

days: [ 1, 1, 1, 1, 1, 1 ,1]

}

});

const calendar = gantt.getCalendar("custom");

calendar.setWorkTime({

date:new Date(2021,9,1),

hours:false

});

newArr.push({

// id: i+1+'-'+j+1,

id: index+1,

text: monthList.targetName,

targetName:monthList.targetName,

calendar_id:"custom",

start_date: new Date(moment(obj.minTime).format("YYYY-MM-DD,00:00:00")), //YYYY-MM-DD,h:mm:ss

progress1: Math.abs(obj.progress1),

progress2: monthList.targetName,

progress3: Math.abs(obj.progress3),

duration: obj.duration,

projectName:monthList.projectName,

principal:monthList.principal,

taskName:monthList.taskName,

taskStatusName:monthList.taskStatusName,

taskStatus: monthList.taskStatus,

status: `${monthList.taskStatusName}`,

planStart: monthList.estStarted,

planEnd: `${monthList.estEndTed}`,

actualStart: monthList.realStarted,

actualEnd: monthList.realEndTed,

ratio: monthList.ratio,

state: obj.state,

parent:monthList.principal,

colorType: obj.colorType,

pro:obj.progress,

open:true

})

let newUserList = new Set(userList)

newUserList.forEach(value=>{

// 添加父级

newArr.push({

calendar_id:"custom",

id:value,

principal:value,

open:true

})

})

})

}

this.tasks.data = newArr

if(this.tasks.data.length>0){

this.getGantt()

}

}else{

// this.$message.error(res.msg)

// this.loading = true

}

// })

},

// 处理百分比

percenToString(num) {

return Math.floor(num * 100) + "%";

},

// 设置每一部分的颜色

renderLabel(progress, type, state,val,num,objText,status) {

// progress, type, state,val实际还是计划,num,objText完成度,status状态

// const self =this

let hour = moment().format("k");

var relWidth = progress * 100;

var n=num*100

var cssClass = "custom_progress ";

let otherLength = '0px' // 额外长度

// let doingLenght = 34

// 实际

if(val==='progress3'){

if(status === 'doing'){

if(objText==='100%'){

cssClass += "nearly_done1";

otherLength = '34px'

}else{

cssClass += "near_done1"

if(Number(hour)<8){

otherLength = '0px'

}else if(Number(hour)>=8 && Number(hour)<18){

let num=34*(Number(hour) -8)/8

otherLength = num+'px'

}else{

otherLength = '34px'

}

}

}else{

if (type === 1) {

cssClass += "nearly_done1";

} else if (type === 2) {

if (state) {

cssClass += "in_progress1";

} else {

cssClass += "in_progress_w1";

}

} else {

cssClass += "idle1";

}

}

}else{

if (type === 1) {

cssClass += "nearly_done";

} else if (type === 2) {

if (state) {

cssClass += "in_progress";

} else {

cssClass += "in_progress_w";

}

} else {

cssClass += "idle";

}

}

if(val==='progress3'){

let widthLenght

if(status === 'doing'){

widthLenght = `calc(${relWidth+'%'} + ${otherLength} - 34px)`

}else{

widthLenght = `calc(${relWidth+'%'} + ${otherLength})`

}

return (

"

" +

"

"

);

}else{

return (

`

${objText!=undefined?objText:''}
`

);

}

},

// gantt配置

getGantt(){

const self = this

gantt.clearAll();

gantt.config.show_progress = true;

gantt.config.initial_scroll = false;

// 根据定义类型判断颜色顺序

gantt.templates.task_text = (start, end, task)=> {

let colorType = task.colorType

if (colorType === 'j12' || colorType === 'one') {

return (

this.renderLabel(task.progress1, 1, task.state,'progress1',0,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 3, task.state,'progress3',task.pro.cprogress1,task.ratio,task.taskStatus) // 实际

);

} else if (colorType === 'j21') {

return (

this.renderLabel(task.progress1, 1, task.state,'progress1',task.pro.cprogress1,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 1, task.state,'progress3',0,task.ratio,task.taskStatus)

);

} else if (colorType === 'b12') {

return (

this.renderLabel(task.progress1, 1, task.state,'progress1',0,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 1, task.state,'progress3',task.pro.cprogress1,task.ratio,task.taskStatus)

);

} else if (colorType === 'b21') {

return (

this.renderLabel(task.progress1, 2, task.state,'progress1',task.pro.cprogress1,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 2, task.state,'progress3',0,task.ratio,task.taskStatus)

);

} else if (colorType === 'l12') {

return (

this.renderLabel(task.progress1, 1, task.state,'progress1',0,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 3, task.state,'progress3',task.pro.cprogress1+task.pro.cprogress2,task.ratio,task.taskStatus)

);

} else if (colorType === 'l21') {

return (

this.renderLabel(task.progress1, 3, task.state,'progress1',task.pro.cprogress2+task.pro.cprogress1,task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 1, task.state,'progress3',0,task.ratio,task.taskStatus)

);

} else {

return (

this.renderLabel(task.progress1, 3, task.state,'progress1',task.ratio) +

// renderLabel(task.progress2, 2, task.state) +

this.renderLabel(task.progress3, 3, task.state,'progress3',task.ratio,task.taskStatus)

);

}

};

gantt.plugins({ marker: true, tooltip: true }); // 开启marker插件

var dateToStr = gantt.date.date_to_str(gantt.config.task_date);

var today = new Date(moment(new Date()).format('YYYY-MM-DD 12:00:00'));

// 添加固定时间线

gantt.addMarker({

start_date: today,

css: 'today',

text: '今日:' + moment(new Date()).format('YYYY-MM-DD'),

title: 'Today: ' + dateToStr(today)

});

// 提示框内容

gantt.templates.tooltip_text = function(start, end, task){

return (task.principal?`责任人:${task.principal}
`:'')+

(task.text?`阶段目标:${task.text}`:'')+

(task.projectName?`
所属项目:${task.projectName}`:'')+

(task.taskName?`
任务内容:${task.taskName}`:'')+

(task.planStart?`
计划开始:${task.planStart}`:'') +

(task.planEnd?`计划结束:${task.planEnd}`:'') +

(task.actualStart?`
实际开始:${task.actualStart}`:'') +

(task.actualEnd?`实际结束:${task.actualEnd}`:'')

};

// 渲染甘特图后触发

gantt.attachEvent("onGanttRender", function(){

gantt.showDate(new Date());

// 绑定计划目标

// document.getElementById('text-title').addEventListener("click",()=>{

// // alert("Gantt chart is completely rendered on the page...")

// })

// self.outOrNo()

});

// 工期计算基本单位

gantt.config.duration_unit = "day"

// 设置x轴日期

gantt.config.scale_unit = "day";

gantt.config.step = 1;

gantt.config.date_scale = "%d";

gantt.config.min_column_width = 34

// 当右侧不止显示年份时,可以添加展示月日,添加一个就加一行

gantt.config.subscales = [

{ unit: "month", step: 1, date: "%m" },

];

//甘特图右侧表头的高度

gantt.config.scale_height = 60;

//使用中文

gantt.i18n.setLocale("cn");

//自适应甘特图的尺寸大小, 使得在不出现滚动条的情况下, 显示全部任务

gantt.config.autosize = false;

//只读模式

gantt.config.readonly = true;

// 调节网格宽度

// gantt.config.grid_width = 400;

// gantt.config.resize_rows = true;

// gantt.config.grid_resize =true

// 显示网格

gantt.config.show_grid = true;

// gantt.config.grid_resize = true;

// 点击表格可排序

// gantt.config.sort = true

//表格列设置

if(self.showType==='projectName' ){

gantt.config.columns = [

{ name: "text",tree:true, resize:true, label: "目标", width: 210, align: "left" },

{ name: "projectName", resize:true, label: "项目", width: 190, align: "left" },

{ name: "principal", resize:true, label: "负责人", width: 70, align: "center" },

{ name: "taskName", resize:true, label: "任务", width: 100, align: "center" },

{ name: "planStart", resize:true, label: "计划开始", width: 80, align: "center" },

{ name: "planEnd", resize:true, label: "计划结束", width: 80, align: "center" },

// { name: "actualStart", resize:true, label: "实际开始", width: 80, align: "center" },

// { name: "actualEnd", resize:true, label: "实际结束", width: 80, align: "center" },

{ name: "status", resize:true, label: "状态", width: 60, align: "center" },

{ name: "ratio", resize:true, label: "完成度", width: 50, align: "center" },

];

}else{

gantt.config.columns = [

{ name: "principal",tree:true, resize:true, label: "负责人", width: 120, align: "center" },

{ name: "text", resize:true, label: "目标", width: 180, align: "left" },

{ name: "projectName", resize:true, label: "项目", width: 160, align: "left" },

{ name: "taskName", resize:true, label: "任务", width: 100, align: "center" },

{ name: "planStart", resize:true, label: "计划开始", width: 80, align: "center" },

{ name: "planEnd", resize:true, label: "计划结束", width: 80, align: "center" },

// { name: "actualStart", resize:true, label: "实际开始", width: 80, align: "center" },

// { name: "actualEnd", resize:true, label: "实际结束", width: 80, align: "center" },

{ name: "status", resize:true, label: "状态", width: 60, align: "center" },

{ name: "ratio", resize:true, label: "完成度", width: 60, align: "center" },

];

}

gantt.templates.grid_folder = function(item) {

return "

";

};

gantt.config.work_time = true;

//任务条上的文字大小 以及取消border自带样式

gantt.templates.task_class = function() {

return "firstLevelTask"

};

// 初始化

this.$nextTick(()=>{

gantt.init(self.$refs.dxgantt);

})

// gantt.init(self.$refs.dxgantt);

// 数据解析

gantt.parse(this.tasks);

gantt.render()

// if(document.querySelectorAll('.weekend1').length>0){

// document.querySelectorAll('.weekend1')[0].innerHTML = '请假'

// }

},

//

// 时间计算 ,status

getDate(Atime, Btime, Ctime, Dtime,n) {

let obj = {};

let minTime

let maxTime

let duration

let progress1 = 0;

let progress3 = 0;

let cprogress1 = 0;

let cprogress2 = 0;

let cprogress3 = 0;

let state = true;

let colorType = true;

// 获取当月天数

let maxMouth = this.year+'-'+moment(this.year, "YYYY-MM").daysInMonth()

let minMouth = this.year+'-01'

if(Ctime===null && Dtime===null){

// 未开始 或者 项目分类

if(n===1){

if(moment(maxMouth).format("YYYY-MM-DD")

maxTime = moment(maxMouth).add(1,'days').format("YYYY-MM-DD,00:00:00")

}else{

maxTime = moment(Btime).add(1,'days').format("YYYY-MM-DD,00:00:00")

}

if(moment(minMouth).format("YYYY-MM-DD")>moment(Atime).format("YYYY-MM-DD")){

minTime = moment(minMouth).format("YYYY-MM-DD,00:00:00")

}else{

minTime = moment(Atime).format("YYYY-MM-DD,00:00:00")

}

}else{

// 未开始

maxTime = moment(Btime).add(1,'days').format("YYYY-MM-DD,00:00:00")

minTime = moment(Atime).format("YYYY-MM-DD,00:00:00")

}

duration = this.difference(minTime, maxTime);

progress1 = 1

progress3 = 0

cprogress1 = 1

cprogress2 = 0

cprogress3 = 0

colorType = 'j12'

}else{

// 已结束 或 正在进行中

let cAtime = moment(Atime).format("YYYY-MM-DD,00:00:00")

let cBtime = moment(Btime).add(1,'days').format("YYYY-MM-DD,00:00:00")

let cCtime = moment(Ctime).format("YYYY-MM-DD,00:00:00")

let cDtime

if(Dtime==null){

// 正在进行中 .add(1,'days')

cDtime = moment(new Date()).add(1,'days').format("YYYY-MM-DD,00:00:00")

}else{

// 已结束 或 已完成

cDtime = moment(Dtime).add(1,'days').format("YYYY-MM-DD,00:00:00")

}

let arr = [cAtime, cBtime, cCtime, cDtime];

let timeArr = [];

arr.forEach((item) => {

timeArr.push(new Date(item));

});

minTime = moment(Math.min(...timeArr)).format("MM-DD-YYYY");

maxTime = moment(Math.max(...timeArr)).format("YYYY-MM-DD");

duration = this.difference(minTime, maxTime);

progress1 = (this.difference(cAtime, cBtime) / duration)

progress3 = (this.difference(cCtime, cDtime) / duration)

if (cAtime < cCtime && cCtime < cBtime && cBtime < cDtime) {

// console.log('12相交')

colorType = 'j12'

cprogress2 = (this.difference(cCtime, cBtime) / duration)

cprogress1 = (this.difference(cAtime, cCtime) / duration)

cprogress3 = (this.difference(cBtime, cDtime) / duration)

} else if (cBtime > cCtime && cBtime >= cDtime && cCtime >= cAtime && cDtime > cAtime) {

// console.log('1包含2')

colorType = 'b12'

state = true

cprogress2 = (this.difference(cCtime, cDtime) / duration)

cprogress1 = (this.difference(cAtime, cCtime) / duration)

cprogress3 = (this.difference(cDtime, cBtime) / duration)

} else if (cDtime >= cBtime && cDtime > cAtime && cAtime >= cCtime && cBtime > cCtime) {

// console.log('2包含1')

colorType = 'b21'

state = true

cprogress2 = (this.difference(cAtime, cBtime) / duration)

cprogress1 = (this.difference(cCtime, cAtime) / duration)

cprogress3 = (this.difference(cBtime, cDtime) / duration)

} else if (cBtime > cDtime && cDtime > cAtime && cAtime > cCtime) {

// console.log('21相交')

colorType = 'j21'

state = true

cprogress2 = (this.difference(cAtime, cDtime) / duration)

cprogress1 = (this.difference(cCtime, cAtime) / duration)

cprogress3 = (this.difference(cDtime, cBtime) / duration)

} else if (cBtime <= cCtime) {

// console.log('12相离')

colorType = 'l12'

state = false

cprogress2 = (this.difference(cBtime, cCtime) / duration)

cprogress1 = (this.difference(cAtime, cBtime) / duration)

cprogress3 = (this.difference(cCtime, cDtime) / duration)

} else if (cDtime <= cAtime) {

// console.log('21相离')

colorType = 'l21'

state = false

cprogress2 = (this.difference(cDtime, cAtime) / duration)

cprogress3 = (this.difference(cAtime, cBtime) / duration)

cprogress1 = (this.difference(cCtime, cDtime) / duration)

} else {

colorType = 'one'

console.log('状态错误')

}

}

obj = {

state: state,

minTime: minTime,

// maxTime: maxTime

duration: duration * 1,

progress1: progress1 * 1,

// progress2: progress2 * 1,

progress: {

cprogress1:cprogress1 * 1,

cprogress2:cprogress2 * 1,

cprogress3:cprogress3 * 1,

},

progress3: progress3 * 1,

colorType: colorType,

};

return obj;

},

// 计算时间差

difference(beginTime, endTime) {

var dateBegin = new Date(beginTime);

var dateEnd = new Date(endTime);

var dateDiff = dateEnd.getTime() - dateBegin.getTime(); //时间差的毫秒数

var dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000)); //计算出相差天数

return dayDiff;

},

// 搜索

onSearch(msg){

if(msg){

this.searchMessage = JSON.parse(JSON.stringify(msg))

}

this.initData()

},

// 重置

onResert(){

this.searchMessage ={

principal:'',

projectName:'',

targetName:''

}

this.showType = 'projectName'

this.initData()

}

},

activated(){

this.initData()

},

mounted () {

this.initData()

}

}

最后是样式部分

最后我在贴上自己使用的数据部分data.js

const data=[

{

"id": "id1234w",

"name": "任务1",

"projectName": "项目1",

"startDate": "2022-01-01",

"endDate": "2022-06-30",

"monthTargetGanttChartDOList": [

{

"targetId": "id1234w",

"targetName": "任务1",

"projectName": "项目1",

"principal": "王A",

"taskName": "任务12",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-06",

"realStarted": "2022-01-10",

"estEndTed": "2022-01-14",

"realEndTed": "2022-01-11",

"taskStatusName": "已关闭",

"lastEditedDate": "2022-01-20",

"ratio": "100%",

"taskStatus": "closed"

},

{

"targetId": "id1234w",

"targetName": "任务1",

"projectName": "项目1",

"principal": "王A",

"taskName": "任务123",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-12",

"realStarted": "2022-01-13",

"estEndTed": "2022-01-14",

"realEndTed": "2022-01-13",

"taskStatusName": "已关闭",

"lastEditedDate": "2022-01-20",

"ratio": "100%",

"taskStatus": "closed"

},

{

"targetId": "id1234w",

"targetName": "任务1",

"projectName": "项目1",

"principal": "王A",

"taskName": "任务124",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-12",

"realStarted": "2022-01-12",

"estEndTed": "2022-01-14",

"realEndTed": "2022-01-14",

"taskStatusName": "已关闭",

"lastEditedDate": "2022-01-20",

"ratio": "100%",

"taskStatus": "closed"

}

]

},

{

"id": "id1234w3",

"name": "任務1",

"projectName": "項目2",

"startDate": "2022-01-01",

"endDate": "2022-12-31",

"monthTargetGanttChartDOList": [

{

"targetId": "id1234w3",

"targetName": "任務1",

"projectName": "項目2",

"principal": "王A",

"taskName": "任务22",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-04",

"realStarted": "2022-01-11",

"estEndTed": "2022-01-14",

"realEndTed": "2022-01-14",

"taskStatusName": "已完成",

"lastEditedDate": "2022-01-21",

"ratio": "100%",

"taskStatus": "done"

},

{

"targetId": "id1234w3",

"targetName": "任務1",

"projectName": "項目2",

"principal": "王A",

"taskName": "任务223",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-04",

"realStarted": "2022-01-04",

"estEndTed": "2022-01-07",

"realEndTed": "2022-01-14",

"taskStatusName": "已完成",

"lastEditedDate": "2022-01-21",

"ratio": "100%",

"taskStatus": "done"

},

{

"targetId": "id1234w3",

"targetName": "任務1",

"projectName": "項目2",

"principal": "王A",

"taskName": "任务224",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-04",

"realStarted": "2022-01-03",

"estEndTed": "2022-01-06",

"realEndTed": "2022-01-17",

"taskStatusName": "已完成",

"lastEditedDate": "2022-01-21",

"ratio": "100%",

"taskStatus": "done"

}

]

},

{

"id": "id1234w34",

"name": "任務3",

"projectName": "项目3",

"startDate": "2022-01-03",

"endDate": "2022-01-28",

"monthTargetGanttChartDOList": [

{

"targetId": "id1234w34",

"targetName": "任務3",

"projectName": "项目3",

"principal": "王A",

"taskName": "任务31",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-03",

"realStarted": "2022-01-03",

"estEndTed": "2022-01-11",

"realEndTed": "2022-03-24",

"taskStatusName": "已关闭",

"lastEditedDate": "2022-03-24",

"ratio": "100%",

"taskStatus": "closed"

}

]

},

{

"id": "id1234w35",

"name": "任务4",

"projectName": "项目4",

"startDate": "2022-01-04",

"endDate": "2022-01-31",

"monthTargetGanttChartDOList": [

{

"targetId": "id1234w35",

"targetName": "任务4",

"projectName": "项目4",

"principal": "王A",

"taskName": "任务32",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-04",

"realStarted": "2022-01-06",

"estEndTed": "2022-01-05",

"realEndTed": "2022-01-06",

"taskStatusName": "已关闭",

"lastEditedDate": "2022-01-20",

"ratio": "100%",

"taskStatus": "closed"

},

{

"targetId": "id1234w35",

"targetName": "任务4",

"projectName": "项目4",

"principal": "王A",

"taskName": "任务33",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-10",

"realStarted": "2022-01-12",

"estEndTed": "2022-01-14",

"realEndTed": "2022-01-18",

"taskStatusName": "已完成",

"lastEditedDate": "2022-01-20",

"ratio": "100%",

"taskStatus": "done"

},

{

"targetId": "id1234w35",

"targetName": "任务4",

"projectName": "项目4",

"principal": "王A",

"taskName": "任务34",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-11",

"realStarted": "2022-01-11",

"estEndTed": "2022-01-12",

"realEndTed": "2022-01-14",

"taskStatusName": "已关闭",

"lastEditedDate": "2022-01-20",

"ratio": "100%",

"taskStatus": "closed"

},

{

"targetId": "id1234w35",

"targetName": "任务4",

"projectName": "项目4",

"principal": "王A",

"taskName": "任务35",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-11",

"realStarted": "2022-01-12",

"estEndTed": "2022-01-18",

"realEndTed": "2022-01-20",

"taskStatusName": "已完成",

"lastEditedDate": "2022-01-20",

"ratio": "100%",

"taskStatus": "done"

},

{

"targetId": "id1234w35",

"targetName": "任务4",

"projectName": "项目4",

"principal": "王A",

"taskName": "任务36",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-17",

"realStarted": "2022-01-18",

"estEndTed": "2022-01-18",

"realEndTed": "2022-01-18",

"taskStatusName": "已完成",

"lastEditedDate": "2022-01-20",

"ratio": "100%",

"taskStatus": "done"

},

{

"targetId": "id1234w35",

"targetName": "任务4",

"projectName": "项目4",

"principal": "王A",

"taskName": "任务37",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-17",

"realStarted": "2022-01-19",

"estEndTed": "2022-01-20",

"realEndTed": "2022-01-20",

"taskStatusName": "已完成",

"lastEditedDate": "2022-01-20",

"ratio": "100%",

"taskStatus": "done"

},

{

"targetId": "id1234w35",

"targetName": "任务4",

"projectName": "项目4",

"principal": "王A",

"taskName": "任务38",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-19",

"realStarted": "2022-01-19",

"estEndTed": "2022-01-21",

"realEndTed": "2022-01-21",

"taskStatusName": "已完成",

"lastEditedDate": "2022-01-25",

"ratio": "100%",

"taskStatus": "done"

},

{

"targetId": "id1234w35",

"targetName": "任务4",

"projectName": "项目4",

"principal": "王A",

"taskName": "任务39",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-25",

"realStarted": "2022-01-27",

"estEndTed": "2022-01-27",

"realEndTed": "2022-01-27",

"taskStatusName": "已完成",

"lastEditedDate": "2022-01-27",

"ratio": "100%",

"taskStatus": "done"

},

{

"targetId": "id1234w35",

"targetName": "任务4",

"projectName": "项目4",

"principal": "王A",

"taskName": "任务40",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-25",

"realStarted": "2022-01-22",

"estEndTed": "2022-01-27",

"realEndTed": "2022-01-22",

"taskStatusName": "已完成",

"lastEditedDate": "2022-01-22",

"ratio": "100%",

"taskStatus": "done"

},

{

"targetId": "id1234w35",

"targetName": "任务4",

"projectName": "项目4",

"principal": "王A",

"taskName": "任务51",

"freeTime": "",

"anomalyMarker": "",

"estWork": "",

"realWork": "",

"estStarted": "2022-01-25",

"realStarted": "2022-01-22",

"estEndTed": "2022-01-27",

// "realEndTed": "",

"taskStatusName": "已暂停",

"lastEditedDate": "2022-01-22",

"ratio": "100%",

"taskStatus": "pause"

}

]

}

]

export { data }

一个甘特图就完成啦

精彩链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: