| New file | 
 |  |  | 
 |  |  | $(document).on("dblclick",".row",function(){ | 
 |  |  |  | 
 |  |  |         var index = $(".row").index(this) // 确定在表格中的第几行 | 
 |  |  |     console.log('this:'+this,'index:'+index) | 
 |  |  |         var rowName = $(this).children(".projects").html() // 当前行中类名为projects的类中的文字 | 
 |  |  |         var project = data[index] // 把data中的第index个项目 赋值给project | 
 |  |  |         if(project.projectName==rowName){ | 
 |  |  |             // 比较时间 | 
 |  |  |             var currT = new Date() // 当前时间 | 
 |  |  |             var staT = new Date(project.projectStartTime.substring(0,10)) // 项目开始时间 | 
 |  |  |             var endT = new Date(project.projectEndTime.substring(0,10)) // 项目结束时间 | 
 |  |  |             var nodes = project.projectPlans | 
 |  |  |             // 判断项目计划节点时间是否有空值 | 
 |  |  |             for(var i=0;i<nodes.length;i++){ | 
 |  |  |                 if(nodes[i].startTime$==''||nodes[i].endTime$==''){ | 
 |  |  |                     show = false | 
 |  |  |                     break | 
 |  |  |                 }else{ | 
 |  |  |                     show = true | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             if(show==true){ | 
 |  |  |                 $("#details").attr("style","display:block") | 
 |  |  |             }else if(show==false){ | 
 |  |  |                 $("#tips").attr("style","display:block") | 
 |  |  |             } | 
 |  |  |             // 项目名称 | 
 |  |  |             $("#details h2").html(project.projectName) | 
 |  |  |             // 预计节点时间 | 
 |  |  |             var tab = '' | 
 |  |  |             var tabLeft3 = '' | 
 |  |  |             var day = 86400000 // 一天是 86400000毫秒 | 
 |  |  |             var days = (endT - staT + day ) / day // 项目节点天数 | 
 |  |  |  | 
 |  |  |             var bigDays = [] | 
 |  |  |             for(var i = 0;i<nodes.length;i++){ | 
 |  |  |                 var projectsName = nodes[i].flowId$ // 节点名称                    改第一个请求用 | 
 |  |  |                 var proRET = new Date(nodes[i].realEndTime$.substring(0,10)) // 节点实际结束时间 | 
 |  |  |                 var tab2 ='<tr id="td-node'+i+'-gz">'+'<tr id="td-node'+i+'-gz-2">'+'</tr>' | 
 |  |  |                 tab = tab +tab2 | 
 |  |  |                 var tabLeft2 = '<tr class="tab-body">' | 
 |  |  |                                     +'<td>'+projectsName+'</td>' | 
 |  |  |                                     +'<td>'+nodes[i].startTime$.substring(0,10)+'</td>' | 
 |  |  |                                     +'<td>'+nodes[i].endTime$.substring(0,10)+'</td>' | 
 |  |  |                 tabLeft3 = tabLeft3 + tabLeft2 | 
 |  |  |                 var overtime = endT-proRET | 
 |  |  |                 if(overtime<0){ | 
 |  |  |                     bigDays.push(proRET) | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             let max = bigDays[0] | 
 |  |  |             for(var i = 0;i<bigDays.length;i++){ | 
 |  |  |                 max = max <max[i+1] ? max[i+1] : max | 
 |  |  |             } | 
 |  |  |             var tab1 = | 
 |  |  |                 '<thead>' | 
 |  |  |                     +'<tr id="th-gz">' + '</tr>' | 
 |  |  |                 +'</thead>' | 
 |  |  |                 +'<tbody id="tabBody">' | 
 |  |  |                     +'<tr id="tot">' +'</tr>' | 
 |  |  |                     +'<tr id="tot-2">'+'</tr>' | 
 |  |  |             var tab3 = tab1+tab+'</tbody>' | 
 |  |  |             /* 甘特图左侧 项目内容表 */ | 
 |  |  |             var tabLeft =     '<thead>' // 表头 | 
 |  |  |                                 +'<tr class="tab-head">' | 
 |  |  |                                     +'<th>'+'项目名称'+'</th>' | 
 |  |  |                                     +'<th>'+'开始时间'+'</th>' | 
 |  |  |                                     +'<th>'+'结束时间'+'</th>' | 
 |  |  |                                 +'</tr>' | 
 |  |  |                             +'</thead>' | 
 |  |  |                             +'<tbody>' // 表身 (项目节点始末) | 
 |  |  |                                 +'<tr class="tab-body">' | 
 |  |  |                                     +'<td style="height: 40px">'+'项目总时长'+'</td>' | 
 |  |  |                                     +'<td style="height: 40px">'+project.projectStartTime.substring(0,10)+'</td>' | 
 |  |  |                                     +'<td style="height: 40px">'+project.projectEndTime.substring(0,10)+'</td>' | 
 |  |  |                                 +'</tr>' | 
 |  |  |  | 
 |  |  |             var tabLeft4 = tabLeft + tabLeft3 +'</tbody>' | 
 |  |  |             $("#details-tab-left").empty() | 
 |  |  |             $("#details-tab-left").append(tabLeft4) | 
 |  |  |             $("#details-tab").empty() | 
 |  |  |             $("#details-tab").append(tab3); | 
 |  |  |             // 填充单元格 | 
 |  |  |             var nodeId = ["#tot-2"] | 
 |  |  |             var nodeId4 = [] | 
 |  |  |             for(let k = 0;k<nodes.length;k++){ | 
 |  |  |                 var getId = "#"+"td-node"+k+"-gz" | 
 |  |  |                 var getId2 = "#"+"td-node"+k+"-gz-2" | 
 |  |  |                 nodeId.push(getId) | 
 |  |  |                 nodeId.push(getId2) | 
 |  |  |             } | 
 |  |  |             for(let k = 0;k<nodes.length;k++){ | 
 |  |  |                 var getId = "#"+"td-node"+k+"-gz" | 
 |  |  |                 var getId2 = "#"+"td-node"+k+"-gz-2" | 
 |  |  |                 nodeId4.push(getId) | 
 |  |  |                 nodeId4.push(getId2) | 
 |  |  |                 k++ | 
 |  |  |             } | 
 |  |  | 			 | 
 |  |  |             if(max>endT){ | 
 |  |  |                  days = (max-staT+day)/day | 
 |  |  |                 endT=max | 
 |  |  |                 getDateArr(staT,endT) | 
 |  |  |             }else{ | 
 |  |  |                 getDateArr(staT,endT); | 
 |  |  |             } | 
 |  |  |             let newDataArr = [] | 
 |  |  |             var strr ='' | 
 |  |  |             // 年份 | 
 |  |  |             if(monthDays.length<2){ // 一个月 | 
 |  |  |                 var gz=monthDays[0]-staT.getDate()+1 // 当前月份剩余天数 | 
 |  |  |                 stt = '<th class="loadBox" colspan="'+gz+'">'+newMonthArr[0]+'</th>' // 有多少天就横跨多少个格子 | 
 |  |  |                 $("#th-gz").append(stt) | 
 |  |  |             }else if (monthDays.length<3){ // 两个月 | 
 |  |  |                 var gz=monthDays[0]-staT.getDate()+1// 当前月份剩余天数 | 
 |  |  |                 stt = '<th class="loadBox" colspan="'+gz+'">'+newMonthArr[0]+'</th>' // 有多少天就横跨多少个格子 | 
 |  |  |                 var gz2 = monthDays[1]-(monthDays[1]-endT.getDate()) // 剩余的天数=当月天数-(当月天数-结束日期) | 
 |  |  |                 stt2 = '<th class="loadBox" colspan="'+gz2+'">'+newMonthArr[1]+'</th>' | 
 |  |  |                 strr =stt +stt2 | 
 |  |  |                 $("#th-gz").append(strr) | 
 |  |  |             }else { // 三个月及以上 | 
 |  |  |                 var gz=monthDays[0]-staT.getDate()+1// 当前月份剩余天数 | 
 |  |  |                 stt = '<th class="loadBox" colspan="'+gz+'">'+newMonthArr[0]+'</th>' // 有多少天就横跨多少个格子 | 
 |  |  |                 var gz2 = monthDays[monthDays.length-1]-(monthDays[monthDays.length-1]-endT.getDate()) // 剩余的天数=当月天数-(当月天数-结束日期) | 
 |  |  |                 stt2 = '<th class="loadBox" colspan="'+gz2+'">'+newMonthArr[newMonthArr.length-1]+'</th>' | 
 |  |  |                 // 去除第一个月 和最后一个月 | 
 |  |  |                 monthDays.shift() | 
 |  |  |                 monthDays.pop() | 
 |  |  |                 newMonthArr.shift() | 
 |  |  |                 newMonthArr.pop() | 
 |  |  |                 var std = '' | 
 |  |  |                 for (var j=0;j<monthDays.length;j++){ | 
 |  |  |                     stt3 = '<th class="loadBox" colspan="'+monthDays[j]+'">'+newMonthArr[j]+'</th>' | 
 |  |  |                     std = std + stt3 | 
 |  |  |                 } | 
 |  |  |                 strr = stt + std +stt2 | 
 |  |  |                 $("#th-gz").append(strr) | 
 |  |  |             } | 
 |  |  |             // 项目时间单元格 | 
 |  |  |             for(let i=0;i<days;i++){ | 
 |  |  |                 str = '<th class="loadBox-2">'+dateArr[i]+'</th>' | 
 |  |  |                 $("#tot").append(str); | 
 |  |  |                 // $(".loadBox").attr('style','width:50px') | 
 |  |  |             } | 
 |  |  |             // 节点时间单元格 | 
 |  |  |             for (let j=0;j<days;j++){ | 
 |  |  |                 tds = '<td class="gz-color'+j+' time-color">'+'</td>' | 
 |  |  |                 for(let k in nodeId){ | 
 |  |  |                     $(nodeId[k]).append(tds) | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             var nodeId2 = [],nodeId3 = [] | 
 |  |  |             for(let k = 0;k<nodes.length;k++){ | 
 |  |  |                 var getId2 = "#"+"td-node"+k+"-gz" | 
 |  |  |                 var getId3 = "#"+"td-node"+k+"-gz-2" | 
 |  |  |                 nodeId2.push(getId2) | 
 |  |  |                 nodeId3.push(getId3) | 
 |  |  |             } | 
 |  |  |             for(var i=0;i<nodeId4.length;i++){ | 
 |  |  |                 $(nodeId4[i]).attr("style","background:#eeeeef") | 
 |  |  |             } | 
 |  |  |             // for(var j = 0;j < days;j++){ | 
 |  |  |             //     $("#tot").find("td").eq(j+3).attr("style","background:#3597D6") | 
 |  |  |             // } | 
 |  |  |             var runDay = Math.ceil((currT - staT)/ day) | 
 |  |  |             if(runDay>0){ | 
 |  |  |                 for(var j = 0;j < runDay;j++){ | 
 |  |  |                     $("#tot-2").find("td").eq(j).attr("style","background:#8bddde") | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             for(var i = 0;i<nodes.length;i++){ | 
 |  |  |                 var proST = new Date(nodes[i].startTime$.substring(0,10)) // 计划开始日期 | 
 |  |  |                 var proET = new Date(nodes[i].endTime$.substring(0,10)) // 计划结束日期 | 
 |  |  |                 var proET2 = new Date(proET.getTime()-day*2) // 计划结束日期-2天 | 
 |  |  |                 var proRST =new Date(nodes[i].realStartTime$.substring(0,10)) // 实际开始日期 | 
 |  |  |                 var proRET =new Date(nodes[i].realEndTime$.substring(0,10)) // 实际结束日期 | 
 |  |  |                 var nodeDay = (proET-proST+day)/day // 计划工作天数 | 
 |  |  |                 var nodeRSDay = (proET-proRST+day)/day // 节点实际工作天数 | 
 |  |  |                         var nodeREDay = (proRET-proST+day)/day // 实际结束减计划开始时间 | 
 |  |  |                 var nodeRealDay = (proRET-proRST+day)/day //实际时间段 | 
 |  |  |                 var intDay = (proST-staT)/day // 预计开始时间与项目开始时间的间隔 | 
 |  |  |                 var intRealDay = (proRST-staT)/day // 实际开始与项目开始时间的间隔 | 
 |  |  |                 var intRealEndDay = (proRET-staT)/day // 实际结束与项目开始的间隔 | 
 |  |  |                 var nodeRunDay = Math.ceil((currT-proST)/ day) | 
 |  |  |                 var nodeRealRunDay = Math.ceil((currT-proRST)/ day) | 
 |  |  |                 var nodeRun = Math.ceil((currT-proET-day)/ day) | 
 |  |  |                 var notRealStartDay = proRET-(proET-proST) // 推算的实际开始日期 | 
 |  |  |                 var intNotRealStartTime = (new Date(notRealStartDay)-staT)/day // 推算的开始日期与项目开始日期的时间段 | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  | 
 |  |  |                 // 与当前时间的时间差 | 
 |  |  |                 for(var j=0;j<nodeDay;j++){ | 
 |  |  |                     $(nodeId2[i]).find('td').eq(intDay+j).attr("style","background:#5998f5") | 
 |  |  |                 } | 
 |  |  |                     // 实际开始日期与实际结束日期都填写  按实际时间进渲染 | 
 |  |  |                 if(proRST != "Invalid Date" && proRET !="Invalid Date"){ | 
 |  |  | 					 | 
 |  |  |                     for(var j=0;j<nodeRealDay;j++){ | 
 |  |  |                         if(proRET<=proET2){ // 实际结束日期<=计划结束日期 | 
 |  |  |                             $(nodeId3[i]).find('td').eq(intRealDay+j).attr("style","background:#00cc88") | 
 |  |  |                         }else if(proRET>proET2 && proRET<=proET){ // 实际结束日期>计划结束日期 | 
 |  |  |                             $(nodeId3[i]).find('td').eq(intRealDay+j).attr("style","background:#00cc88") | 
 |  |  |                         }else { // 实际结束日期>计划结束日期+2天 | 
 |  |  |                             $(nodeId3[i]).find('td').eq(intRealDay+j).attr("style","background:#e63939") | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |                     // 实际开始时间已填 实际结束时间未填  (实际结束时间按预计结束时间填)改 当前时间与实际开始时间的间隔 | 
 |  |  |                 }else if(proRST != "Invalid Date" && proRET =="Invalid Date"){ | 
 |  |  |                     for(var j=0;j<nodeRealRunDay;j++){ | 
 |  |  |                         if(nodeRun>0){ | 
 |  |  |                             $(nodeId3[i]).find('td').eq(intRealDay+j).attr("style","background:#CC3333") | 
 |  |  |                         }else if(nodeRun>-3 && nodeRun<=0){ | 
 |  |  |                             $(nodeId3[i]).find('td').eq(intRealDay+j).attr("style","background:#ccc739") | 
 |  |  |                         }else{ | 
 |  |  |                             $(nodeId3[i]).find('td').eq(intRealDay+j).attr("style","background:#8bddde") | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |                         // 实际开始时间未填 实际结束时间已填  实际开始时间按计划开始时间 | 
 |  |  |                 }else if(proRST == "Invalid Date" && proRET !="Invalid Date"){ | 
 |  |  |                     if(proRET<=proST){ // 实际结束日期<=计划开始日期  暂时不填充 | 
 |  |  |                         // for(var j=0;j<nodeDay;j++){ // 天数是节点计划天数 | 
 |  |  |                         //     $(nodeId3[i]).find('td').eq(intNotRealStartTime+j).attr("style","background:#49C7D3") // 实际开始日期是 实际结束日期-计划天数 | 
 |  |  |                         // } | 
 |  |  |                     }else if(proRET<=proET){ //实际结束日期<=计划结束日期 | 
 |  |  |                         for(var j=0;j<nodeREDay;j++) { // 天数是 实际结束日期-计划开始日期 | 
 |  |  |                             $(nodeId3[i]).find('td').eq(intDay + j).attr("style", "background:#00cc88")// 实际开始日期是 实际结束日期-计划天数 | 
 |  |  |                         } | 
 |  |  |                     }else{ // 实际结束日期>计划结束日期 | 
 |  |  |                         for(var j=0;j<nodeREDay;j++) { // 天数是 实际结束日期-计划开始日期 | 
 |  |  |                             $(nodeId3[i]).find('td').eq(intDay + j).attr("style", "background:#CC3333")// 实际开始日期是 实际结束日期-计划天数 | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |                     // 实际开始时间未填 实际结束时间未填 | 
 |  |  |                 }else if(proRST == "Invalid Date" && proRET =="Invalid Date"){ | 
 |  |  |  | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |             // 鼠标经过 | 
 |  |  |             $(document).on('mouseover','.time-color',function () { | 
 |  |  |                 // console.log($(this).attr('class')) | 
 |  |  |                 var cls = $(this).attr('class').split(' ')[0] | 
 |  |  |                 var cll = '.'+cls | 
 |  |  |                 $(cll).addClass('over-color') | 
 |  |  |             }) | 
 |  |  |             // 鼠标离开 | 
 |  |  |             $(document).on('mouseout','.time-color',function () { | 
 |  |  |                 // console.log($(this).attr('class')) | 
 |  |  |                 var cls = $(this).attr('class').split(' ')[0] | 
 |  |  |                 var cll = '.'+cls | 
 |  |  |                 $(cll).removeClass('over-color') | 
 |  |  |             }) | 
 |  |  |             // 滚轮 | 
 |  |  | 			 | 
 |  |  | 			 | 
 |  |  | 			 | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  | 
 |  |  |             function getDateArr(start,end) { | 
 |  |  |                     let option = new Date(start) // 开始时间 | 
 |  |  |                     let nowDate = new Date(end) // 结束时间 | 
 |  |  |                     let times = option.getTime() // 获取当前时间戳(毫秒) | 
 |  |  |                     let ms = (nowDate - option ) / 86400000 // 相差的总天是的毫秒数(天数) | 
 |  |  |                     let days = Math.ceil(ms) // 向上取整数 | 
 |  |  |                     dateArr = [] // 创建日期数组 | 
 |  |  |                     monthArr = [] | 
 |  |  |                     monthDays=[] | 
 |  |  |                     let num = 0 | 
 |  |  |                     while (num<=days){ | 
 |  |  |                         let needDate = new Date(times) | 
 |  |  |                         times += 86400000 // 加一天 | 
 |  |  |                         let dayDAY = needDate.getDate(); // 获取当前时间的日期  1号 2号 3号 4号 等 | 
 |  |  |                         dayDAY = dayDAY<10 ? '0'+dayDAY : dayDAY | 
 |  |  |                         dateArr.push(dayDAY) | 
 |  |  |                         let month = needDate.getMonth()+1 | 
 |  |  |                         month = month<10 ? '0'+month : month | 
 |  |  |                         let year = needDate.getFullYear() | 
 |  |  |                         yMonth = year+'-'+month | 
 |  |  |                         monthArr.push(yMonth)	  | 
 |  |  |                         num++; // 计次用 | 
 |  |  |                     } | 
 |  |  |                     function unique (monthArr) { | 
 |  |  |                       return Array.from(new Set(monthArr)) | 
 |  |  |                     } | 
 |  |  |                     newMonthArr = unique(monthArr) | 
 |  |  |                     for(var i=0;i<newMonthArr.length;i++){ | 
 |  |  |                         s = newMonthArr[i].split("-") | 
 |  |  |                         var d = new Date(s[0],s[1],0); | 
 |  |  |                         a = d.getDate() | 
 |  |  |                         monthDays.push(a) | 
 |  |  |                     } | 
 |  |  |             } | 
 |  |  |             } | 
 |  |  |             }) | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  |