效果圖javascript
JSPhtml
<%@page import="com.ata.util.base.Util"%> <%@page import="java.text.SimpleDateFormat"%> <%@page import="com.ata.model.atq.AtqProjectPlan"%> <%@page import="com.ata.model.atq.AtqProject"%> <%@page import="java.util.*"%> <%@ page language="java" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <%@page import="com.ata.util.base.Lan"%> <% Object lan=session.getAttribute("LAN"); LinkedHashMap<AtqProject,List> mapPlan = (LinkedHashMap<AtqProject,List>)request.getAttribute("mapPlan"); %> <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=7" /> <jsp:include page="/inc.jsp"></jsp:include> <script type="text/javascript" charset="utf-8"> </script> <script language="javascript" src="${pageContext.request.contextPath}/jslib/jsgantt_v12/jsgantt.js?<%=lan%>"></script> </head> <body class="easyui-layout" data-options="fit:true"> <div data-options="region:'north',border:false" style="position:relative"> <div style="background:#FFFEE6; color:#8F5700; padding:6px;"> <div class="icon-tip" style="width:16px;height:16px;margin-right:8px;float:left;"></div> <div><%=Lan.lan("點擊項目名稱能夠添加計劃事項,點擊計劃事項,能夠作修改或刪除操做。", lan)%></div> </div> </div> <div data-options="region:'center',border:false" style="position:relative" class="gantt" id="GanttChartDIV"></div> <script> var g = new JSGantt.GanttChart('g',document.getElementById('GanttChartDIV'), 'day'); //g.setShowRes(1); // Show/Hide Responsible (0/1) g.setShowDur(0); // Show/Hide Duration (0/1) g.setShowComp(1); // Show/Hide % Complete(0/1) g.setCaptionType('Resource'); // Set to Show Caption (None,Caption,Resource,Duration,Complete) //var gr = new Graphics(); if( g ) { // Parameters (pID, pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption) // You can also use the XML file parser JSGantt.parseXML('project.xml',g) <% SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy"); Iterator itr = mapPlan.keySet().iterator(); int pid=1; while(itr.hasNext()){ AtqProject proj = (AtqProject)itr.next(); out.println("g.AddTaskItem(new JSGantt.TaskItem("+pid+",'"+proj.getProjectName()+"','','','','append("+proj.getProjectId()+")', 0, '', 0, 1, 0, 1));"); List list = (List)mapPlan.get(proj); for(int i=0;i<list.size();i++){ AtqProjectPlan plan = (AtqProjectPlan)list.get(i); out.println("g.AddTaskItem(new JSGantt.TaskItem("+(pid*1000+i)+",'"+plan.getCaseName()+"','"+df.format(new Date(plan.getStartDate().getTime()))+"','"+df.format(new Date(plan.getEndDate().getTime())) +"','"+plan.getColor()+"','edit("+plan.getPlanId()+")', 0, '"+Util.nvl(plan.getPlanResourceName())+"',"+plan.getPercentage()+", 0, "+pid+", 1, '', 'This is another caption'));"); } pid++; } %> g.Draw(); g.DrawDependencies(); } else{ alert("not defined"); } function edit(ppid) { var p = parent.dj.dialog({ title : '<%=Lan.lan("修改計劃", lan)%>', href : '${pageContext.request.contextPath}/plan!planEdit.do?planId='+ppid, width : 600, height : 300, buttons : [ { text : '<%=Lan.lan("保存", lan)%>', handler : function() { var f = p.find('form'); f.form('submit', { url : '${pageContext.request.contextPath}/plan!edit.do', success : function(d) { var json = $.parseJSON(d); if (json.success) { p.dialog('close'); window.location.reload(); } parent.dj.messagerShow({ msg : json.msg, title : '<%=Lan.lan("提示", lan)%>' }); } }); } }, { text : '<%=Lan.lan("刪除", lan)%>', handler : function() { parent.dj.messagerConfirm('<%=Lan.lan("請確認", lan)%>', '<%=Lan.lan("您要刪除當前所選計劃項?", lan)%>', function(r) { if(!r)return; var f = p.find('form'); f.form('submit', { url : '${pageContext.request.contextPath}/plan!delete.do', success : function(d) { var json = $.parseJSON(d); if (json.success) { p.dialog('close'); window.location.reload(); } parent.dj.messagerShow({ msg : json.msg, title : '<%=Lan.lan("提示", lan)%>' }); } }); }); } },{ text : '<%=Lan.lan("取消", lan)%>', handler : function() { p.dialog('close'); } }] }); } function append(projectId) { var p = parent.dj.dialog({ title : '<%=Lan.lan("新增計劃", lan)%>', href : '${pageContext.request.contextPath}/plan!planAdd.do?projectId='+projectId, width : 600, height : 300, buttons : [ { text : '<%=Lan.lan("保存", lan)%>', handler : function() { var f = p.find('form'); f.form('submit', { url : '${pageContext.request.contextPath}/plan!add.do', success : function(d) { var json = $.parseJSON(d); if (json.success) { window.location.reload(); p.dialog('close'); } parent.dj.messagerShow({ msg : json.msg, title : '<%=Lan.lan("提示", lan)%>' }); } }); } },{ text : '<%=Lan.lan("取消", lan)%>', handler : function() { p.dialog('close'); } }] }); } </script> </body></html>
JSjava
var JSGantt; if (!JSGantt) JSGantt = {}; var sc=document.getElementsByTagName("script"); var lan=sc[sc.length-1].src.split('?')[1]; var vTimeout = 0; var vBenchTime = new Date().getTime(); JSGantt.isIE = function () { if(typeof document.all != 'undefined') return true; else return false; } JSGantt.TaskItem = function(pID, pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption, workDays) { var vID = pID; var vName = pName; var vStart = new Date(); var vEnd = new Date(); var vColor = pColor; var vLink = pLink; var vMile = pMile; var vRes = pRes; var vComp = pComp; var vGroup = pGroup; var vParent = pParent; var vOpen = pOpen; var vDepend = pDepend; var vCaption = pCaption; var vWdays = workDays; var vDuration = ''; var vLevel = 0; var vNumKid = 0; var vVisible = 1; var x1, y1, x2, y2; if (vGroup != 1) { vStart = JSGantt.parseDateStr(pStart,g.getDateInputFormat()); vEnd = JSGantt.parseDateStr(pEnd,g.getDateInputFormat()); } this.getID = function(){ return vID }; this.getName = function(){ return vName }; this.getStart = function(){ return vStart}; this.getEnd = function(){ return vEnd }; this.getColor = function(){ return vColor}; this.getLink = function(){ return vLink }; this.getMile = function(){ return vMile }; this.getDepend = function(){ if(vDepend) return vDepend; else return null }; this.getCaption = function(){ if(vCaption) return vCaption; else return ''; }; this.getResource = function(){ if(vRes) return vRes; else return ' '; }; this.getCompVal = function(){ if(vComp) return vComp; else return 0; }; this.getCompStr = function(){ if(vComp) return vComp+'%'; else return ''; }; this.getDuration = function(vFormat){ if (vMile) vDuration = '-'; else if (vFormat=='hour') { tmpPer = Math.ceil((this.getEnd() - this.getStart()) / ( 60 * 60 * 1000) ); if(tmpPer == 1) vDuration = '1 Hour'; else vDuration = tmpPer + ' Hours'; } else if (vFormat=='minute') { tmpPer = Math.ceil((this.getEnd() - this.getStart()) / ( 60 * 1000) ); if(tmpPer == 1) vDuration = '1 Minute'; else vDuration = tmpPer + ' Minutes'; } else { //if(vFormat == 'day') { tmpPer = Math.ceil((this.getEnd() - this.getStart()) / (24 * 60 * 60 * 1000) + 1); if(tmpPer == 1) vDuration = '1 Day'; else vDuration = tmpPer + '';//Days vDuration = vWdays+''; } //else if(vFormat == 'week') { // tmpPer = ((this.getEnd() - this.getStart()) / (24 * 60 * 60 * 1000) + 1)/7; // if(tmpPer == 1) vDuration = '1 Week'; // else vDuration = tmpPer + ' Weeks'; //} //else if(vFormat == 'month') { // tmpPer = ((this.getEnd() - this.getStart()) / (24 * 60 * 60 * 1000) + 1)/30; // if(tmpPer == 1) vDuration = '1 Month'; // else vDuration = tmpPer + ' Months'; //} //else if(vFormat == 'quater') { // tmpPer = ((this.getEnd() - this.getStart()) / (24 * 60 * 60 * 1000) + 1)/120; // if(tmpPer == 1) vDuration = '1 Qtr'; // else vDuration = tmpPer + ' Qtrs'; //} return( vDuration ) }; this.getParent = function(){ return vParent }; this.getGroup = function(){ return vGroup }; this.getOpen = function(){ return vOpen }; this.getLevel = function(){ return vLevel }; this.getNumKids = function(){ return vNumKid }; this.getStartX = function(){ return x1 }; this.getStartY = function(){ return y1 }; this.getEndX = function(){ return x2 }; this.getEndY = function(){ return y2 }; this.getVisible = function(){ return vVisible }; this.setDepend = function(pDepend){ vDepend = pDepend;}; this.setStart = function(pStart){ vStart = pStart;}; this.setEnd = function(pEnd) { vEnd = pEnd; }; this.setLevel = function(pLevel){ vLevel = pLevel;}; this.setNumKid = function(pNumKid){ vNumKid = pNumKid;}; this.setCompVal = function(pCompVal){ vComp = pCompVal;}; this.setStartX = function(pX) {x1 = pX; }; this.setStartY = function(pY) {y1 = pY; }; this.setEndX = function(pX) {x2 = pX; }; this.setEndY = function(pY) {y2 = pY; }; this.setOpen = function(pOpen) {vOpen = pOpen; }; this.setVisible = function(pVisible) {vVisible = pVisible; }; } // function that loads the main gantt chart properties and functions // pDiv: (required) this is a DIV object created in HTML // pStart: UNUSED - future use to force minimum chart date // pEnd: UNUSED - future use to force maximum chart date // pWidth: UNUSED - future use to force chart width and cause objects to scale to fit within that width // pShowRes: UNUSED - future use to turn on/off display of resource names // pShowDur: UNUSED - future use to turn on/off display of task durations // pFormat: (required) - used to indicate whether chart should be drawn in "day", "week", "month", or "quarter" format // pCationType - what type of Caption to show: Caption, Resource, Duration, Complete JSGantt.GanttChart = function(pGanttVar, pDiv, pFormat) { var vGanttVar = pGanttVar; var vDiv = pDiv; var vFormat = pFormat; var vShowRes = 1; var vShowDur = 1; var vShowComp = 1; var vShowStartDate = 1; var vShowEndDate = 1; var vDateInputFormat = "mm/dd/yyyy"; var vDateDisplayFormat = "yy/mm/dd"; var vNumUnits = 0; var vCaptionType; var vDepId = 1; var vTaskList = new Array(); var vFormatArr = new Array("day","week","month","quarter"); var vQuarterArr = new Array(1,1,1,2,2,2,3,3,3,4,4,4); var vMonthDaysArr = new Array(31,28,31,30,31,30,31,31,30,31,30,31); var vMonthArr = new Array("January","February","March","April","May","June","July","August","September","October","November","December"); this.setFormatArr = function() { vFormatArr = new Array(); for(var i = 0; i < arguments.length; i++) {vFormatArr[i] = arguments[i];} if(vFormatArr.length>4){vFormatArr.length=4;} }; this.setShowRes = function(pShow) { vShowRes = pShow; }; this.setShowDur = function(pShow) { vShowDur = pShow; }; this.setShowComp = function(pShow) { vShowComp = pShow; }; this.setShowStartDate = function(pShow) { vShowStartDate = pShow; }; this.setShowEndDate = function(pShow) { vShowEndDate = pShow; }; this.setDateInputFormat = function(pShow) { vDateInputFormat = pShow; }; this.setDateDisplayFormat = function(pShow) { vDateDisplayFormat = pShow; }; this.setCaptionType = function(pType) { vCaptionType = pType }; this.setFormat = function(pFormat){ vFormat = pFormat; this.Draw(); }; this.getShowRes = function(){ return vShowRes }; this.getShowDur = function(){ return vShowDur }; this.getShowComp = function(){ return vShowComp }; this.getShowStartDate = function(){ return vShowStartDate }; this.getShowEndDate = function(){ return vShowEndDate }; this.getDateInputFormat = function() { return vDateInputFormat }; this.getDateDisplayFormat = function() { return vDateDisplayFormat }; this.getCaptionType = function() { return vCaptionType }; this.CalcTaskXY = function () { var vList = this.getList(); var vTaskDiv; var vParDiv; var vLeft, vTop, vHeight, vWidth; for(i = 0; i < vList.length; i++) { vID = vList[i].getID(); vTaskDiv = document.getElementById("taskbar_"+vID); vBarDiv = document.getElementById("bardiv_"+vID); vParDiv = document.getElementById("childgrid_"+vID); if(vBarDiv) { vList[i].setStartX( vBarDiv.offsetLeft ); vList[i].setStartY( vParDiv.offsetTop+vBarDiv.offsetTop+6 ); vList[i].setEndX( vBarDiv.offsetLeft + vBarDiv.offsetWidth ); vList[i].setEndY( vParDiv.offsetTop+vBarDiv.offsetTop+6 ); } } } this.AddTaskItem = function(value) { vTaskList.push(value); } this.getList = function() { return vTaskList }; this.clearDependencies = function() { var parent = document.getElementById('rightside'); var depLine; var vMaxId = vDepId; for ( i=1; i<vMaxId; i++ ) { depLine = document.getElementById("line"+i); if (depLine) { parent.removeChild(depLine); } } vDepId = 1; } // sLine: Draw a straight line (colored one-pixel wide DIV), need to parameterize doc item this.sLine = function(x1,y1,x2,y2) { vLeft = Math.min(x1,x2); vTop = Math.min(y1,y2); vWid = Math.abs(x2-x1) + 1; vHgt = Math.abs(y2-y1) + 1; vDoc = document.getElementById('rightside'); // retrieve DIV var oDiv = document.createElement('div'); oDiv.id = "line"+vDepId++; oDiv.style.position = "absolute"; oDiv.style.margin = "0px"; oDiv.style.padding = "0px"; oDiv.style.overflow = "hidden"; oDiv.style.border = "0px"; // set attributes oDiv.style.zIndex = 0; oDiv.style.backgroundColor = "red"; oDiv.style.left = vLeft + "px"; oDiv.style.top = vTop + "px"; oDiv.style.width = vWid + "px"; oDiv.style.height = vHgt + "px"; oDiv.style.visibility = "visible"; vDoc.appendChild(oDiv); } // dLine: Draw a diaganol line (calc line x,y paisrs and draw multiple one-by-one sLines) this.dLine = function(x1,y1,x2,y2) { var dx = x2 - x1; var dy = y2 - y1; var x = x1; var y = y1; var n = Math.max(Math.abs(dx),Math.abs(dy)); dx = dx / n; dy = dy / n; for ( i = 0; i <= n; i++ ) { vx = Math.round(x); vy = Math.round(y); this.sLine(vx,vy,vx,vy); x += dx; y += dy; } } this.drawDependency =function(x1,y1,x2,y2) { if(x1 + 10 < x2) { this.sLine(x1,y1,x1+4,y1); this.sLine(x1+4,y1,x1+4,y2); this.sLine(x1+4,y2,x2,y2); this.dLine(x2,y2,x2-3,y2-3); this.dLine(x2,y2,x2-3,y2+3); this.dLine(x2-1,y2,x2-3,y2-2); this.dLine(x2-1,y2,x2-3,y2+2); } else { this.sLine(x1,y1,x1+4,y1); this.sLine(x1+4,y1,x1+4,y2-10); this.sLine(x1+4,y2-10,x2-8,y2-10); this.sLine(x2-8,y2-10,x2-8,y2); this.sLine(x2-8,y2,x2,y2); this.dLine(x2,y2,x2-3,y2-3); this.dLine(x2,y2,x2-3,y2+3); this.dLine(x2-1,y2,x2-3,y2-2); this.dLine(x2-1,y2,x2-3,y2+2); } } this.DrawDependencies = function () { //First recalculate the x,y this.CalcTaskXY(); this.clearDependencies(); var vList = this.getList(); for(var i = 0; i < vList.length; i++) { vDepend = vList[i].getDepend(); if(vDepend) { var vDependStr = vDepend + ''; var vDepList = vDependStr.split(','); var n = vDepList.length; for(var k=0;k<n;k++) { var vTask = this.getArrayLocationByID(vDepList[k]); if(vList[vTask].getVisible()==1) this.drawDependency(vList[vTask].getEndX(),vList[vTask].getEndY(),vList[i].getStartX()-1,vList[i].getStartY()) } } } } this.getArrayLocationByID = function(pId) { var vList = this.getList(); for(var i = 0; i < vList.length; i++) { if(vList[i].getID()==pId) return i; } } this.Draw = function() { var vMaxDate = new Date(); var vMinDate = new Date(); var vTmpDate = new Date(); var vNxtDate = new Date(); var vCurrDate = new Date(); var vTaskLeft = 0; var vTaskRight = 0; var vNumCols = 0; var vID = 0; var vMainTable = ""; var vLeftTable = ""; var vRightTable = ""; var vDateRowStr = ""; var vItemRowStr = ""; var vColWidth = 0; var vColUnit = 0; var vChartWidth = 0; var vNumDays = 0; var vDayWidth = 0; var vStr = ""; var vNameWidth = 100; var vStatusWidth = 70; var vLeftWidth = 15 + 120 + 70 + 50 + 50 + 50 + 50; if(vTaskList.length > 0) { // Process all tasks preset parent date and completion % JSGantt.processRows(vTaskList, 0, -1, 1, 1); // get overall min/max dates plus padding vMinDate = JSGantt.getMinDate(vTaskList, vFormat); vMaxDate = JSGantt.getMaxDate(vTaskList, vFormat); // Calculate chart width variables. vColWidth can be altered manually to change each column width // May be smart to make this a parameter of GanttChart or set it based on existing pWidth parameter if(vFormat == 'day') { vColWidth = 18; vColUnit = 1; } else if(vFormat == 'week') { vColWidth = 60; vColUnit = 7; } else if(vFormat == 'month') { vColWidth = 237; vColUnit = 30; } else if(vFormat == 'quarter') { vColWidth = 260; vColUnit = 90; } else if(vFormat=='hour') { vColWidth = 18; vColUnit = 1; } else if(vFormat=='minute') { vColWidth = 18; vColUnit = 1; } vNumDays = (Date.parse(vMaxDate) - Date.parse(vMinDate)) / ( 24 * 60 * 60 * 1000); vNumUnits = vNumDays / vColUnit; vChartWidth = vNumUnits * vColWidth + 1; vDayWidth = (vColWidth / vColUnit) + (1/vColUnit); vMainTable = '<TABLE id=theTable cellSpacing=0 cellPadding=0 border=0><TBODY><TR>' + '<TD vAlign=top bgColor=#ffffff>'; if(vShowRes !=1) vNameWidth+=vStatusWidth; if(vShowDur !=1) vNameWidth+=vStatusWidth; if(vShowComp!=1) vNameWidth+=vStatusWidth; if(vShowStartDate!=1) vNameWidth+=vStatusWidth; if(vShowEndDate!=1) vNameWidth+=vStatusWidth; // DRAW the Left-side of the chart (names, resources, comp%) vLeftTable = '<DIV class="scroll" id=leftside style="width:' + vLeftWidth + 'px"><TABLE cellSpacing=0 cellPadding=0 border=0><TBODY>' + '<TR style="HEIGHT: 17px">' + ' <TD style="WIDTH: 15px; HEIGHT: 17px"></TD>' + ' <TD style="WIDTH: ' + vNameWidth + 'px; HEIGHT: 17px"><NOBR></NOBR></TD>'; if(vShowRes ==1) vLeftTable += ' <TD style="WIDTH: ' + vStatusWidth + 'px; HEIGHT: 17px"></TD>' ; if(vShowDur ==1) vLeftTable += ' <TD style="WIDTH: ' + vStatusWidth + 'px; HEIGHT: 17px"></TD>' ; if(vShowComp==1) vLeftTable += ' <TD style="WIDTH: ' + vStatusWidth + 'px; HEIGHT: 17px"></TD>' ; if(vShowStartDate==1) vLeftTable += ' <TD style="WIDTH: ' + vStatusWidth + 'px; HEIGHT: 17px"></TD>' ; if(vShowEndDate==1) vLeftTable += ' <TD style="WIDTH: ' + vStatusWidth + 'px; HEIGHT: 17px"></TD>' ; vLeftTable += '<TR style="HEIGHT: 20px">' + ' <TD style="BORDER-TOP: #efefef 1px solid; WIDTH: 15px; HEIGHT: 20px"></TD>' + ' <TD style="BORDER-TOP: #efefef 1px solid; WIDTH: ' + vNameWidth + 'px; HEIGHT: 20px"><NOBR></NOBR></TD>' ; if(vShowRes ==1) vLeftTable += ' <TD style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; WIDTH: 60px; HEIGHT: 20px" align=center nowrap>'+(lan=='en'?'Resource':'資源')+'</TD>'; if(vShowDur ==1) vLeftTable += ' <TD style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; WIDTH: 60px; HEIGHT: 20px" align=center nowrap>'+(lan=='en'?'Duration':'天數')+'</TD>'; if(vShowComp==1) vLeftTable += ' <TD style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; WIDTH: 60px; HEIGHT: 20px" align=center nowrap>'+(lan=='en'?'% Comp.':'完成度')+'</TD>'; if(vShowStartDate==1) vLeftTable += ' <TD style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; WIDTH: 60px; HEIGHT: 20px" align=center nowrap>'+(lan=='en'?'Start Date':'開始日期')+'</TD>'; if(vShowEndDate==1) vLeftTable += ' <TD style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; WIDTH: 60px; HEIGHT: 20px" align=center nowrap>'+(lan=='en'?'End Date':'結束日期')+'</TD>'; vLeftTable += '</TR>'; for(i = 0; i < vTaskList.length; i++) { if( vTaskList[i].getGroup()) { vBGColor = "f3f3f3"; vRowType = "group"; } else { vBGColor = "ffffff"; vRowType = "row"; } vID = vTaskList[i].getID(); if(vTaskList[i].getVisible() == 0) vLeftTable += '<TR id=child_' + vID + ' bgcolor=#' + vBGColor + ' style="display:none" onMouseover=g.mouseOver(this,' + vID + ',"left","' + vRowType + '") onMouseout=g.mouseOut(this,' + vID + ',"left","' + vRowType + '")>' ; else vLeftTable += '<TR id=child_' + vID + ' bgcolor=#' + vBGColor + ' onMouseover=g.mouseOver(this,' + vID + ',"left","' + vRowType + '") onMouseout=g.mouseOut(this,' + vID + ',"left","' + vRowType + '")>' ; vLeftTable += ' <TD class="gdatehead" style="WIDTH: 15px; HEIGHT: 20px; BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;"> </TD>' + ' <TD class="gname" style="WIDTH: ' + vNameWidth + 'px; HEIGHT: 20px; BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px;" nowrap><NOBR><span style="color: #aaaaaa">'; for(j=1; j<vTaskList[i].getLevel(); j++) { vLeftTable += '    '; } vLeftTable += '</span>'; if( vTaskList[i].getGroup()) { if( vTaskList[i].getOpen() == 1) vLeftTable += '<SPAN id="group_' + vID + '" style="color:#000000; cursor:pointer; font-weight:bold; FONT-SIZE: 12px;" onclick="JSGantt.folder(' + vID + ','+vGanttVar+');'+vGanttVar+'.DrawDependencies();">–</span><span style="color:#000000"> </SPAN>' ; else vLeftTable += '<SPAN id="group_' + vID + '" style="color:#000000; cursor:pointer; font-weight:bold; FONT-SIZE: 12px;" onclick="JSGantt.folder(' + vID + ','+vGanttVar+');'+vGanttVar+'.DrawDependencies();">+</span><span style="color:#000000"> </SPAN>' ; } else { vLeftTable += '<span style="color: #000000; font-weight:bold; FONT-SIZE: 12px;">   </span>'; } vLeftTable += '<span onclick="' + vTaskList[i].getLink() + '" style="cursor:pointer"> ' + vTaskList[i].getName() + '</span></NOBR></TD>' ; if(vShowRes ==1) vLeftTable += ' <TD class="gname" style="WIDTH: 60px; HEIGHT: 20px; TEXT-ALIGN: center; BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" align=center><NOBR>' + vTaskList[i].getResource() + '</NOBR></TD>' ; if(vShowDur ==1) vLeftTable += ' <TD class="gname" style="WIDTH: 60px; HEIGHT: 20px; TEXT-ALIGN: center; BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" align=center><NOBR>' + vTaskList[i].getDuration(vFormat) + '</NOBR></TD>' ; if(vShowComp==1) vLeftTable += ' <TD class="gname" style="WIDTH: 60px; HEIGHT: 20px; TEXT-ALIGN: center; BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" align=center><NOBR>' + vTaskList[i].getCompStr() + '</NOBR></TD>' ; if(vShowStartDate==1) vLeftTable += ' <TD class="gname" style="WIDTH: 60px; HEIGHT: 20px; TEXT-ALIGN: center; BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" align=center><NOBR>' + JSGantt.formatDateStr( vTaskList[i].getStart(), vDateDisplayFormat) + '</NOBR></TD>' ; if(vShowEndDate==1) vLeftTable += ' <TD class="gname" style="WIDTH: 60px; HEIGHT: 20px; TEXT-ALIGN: center; BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" align=center><NOBR>' + JSGantt.formatDateStr( vTaskList[i].getEnd(), vDateDisplayFormat) + '</NOBR></TD>' ; vLeftTable += '</TR>'; } // DRAW the date format selector at bottom left. Another potential GanttChart parameter to hide/show this selector vLeftTable += '</TD></TR>' + '<TR><TD border=1 colspan=5 align=left style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 11px; BORDER-LEFT: #efefef 1px solid; height=18px"> '; if (vFormatArr.join().indexOf("minute")!=-1) { if (vFormat=='minute') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="minute" checked>Minute'; else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("minute",'+vGanttVar+'); VALUE="minute">Minute'; } if (vFormatArr.join().indexOf("hour")!=-1) { if (vFormat=='hour') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="hour" checked>Hour'; else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("hour",'+vGanttVar+'); VALUE="hour">Hour'; } if (vFormatArr.join().indexOf("day")!=-1) { if (vFormat=='day') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="day" checked>' + (lan=='en'?'Days':'日'); else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("day",'+vGanttVar+'); VALUE="day">' + (lan=='en'?'Days':'日'); } if (vFormatArr.join().indexOf("week")!=-1) { if (vFormat=='week') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="week" checked>' + (lan=='en'?'Week':'周'); else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("week",'+vGanttVar+') VALUE="week">' + (lan=='en'?'Week':'周'); } if (vFormatArr.join().indexOf("month")!=-1) { if (vFormat=='month') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="month" checked>' + (lan=='en'?'Month':'月'); else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("month",'+vGanttVar+') VALUE="month">' + (lan=='en'?'Month':'月'); } if (vFormatArr.join().indexOf("quarter")!=-1) { if (vFormat=='quarter') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="quarter" checked>' + (lan=='en'?'Quarter':'季'); else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("quarter",'+vGanttVar+') VALUE="quarter">' + (lan=='en'?'Quarter':'季'); } // vLeftTable += '<INPUT TYPE=RADIO NAME="other" VALUE="other" style="display:none"> .'; vLeftTable += '</TD></TR></TBODY></TABLE></TD>'; vMainTable += vLeftTable; // Draw the Chart Rows vRightTable = '<TD style="width: ' + vChartWidth + 'px;" vAlign=top bgColor=#ffffff>' + '<DIV class="scroll2" id=rightside>' + '<TABLE style="width: ' + vChartWidth + 'px;" cellSpacing=0 cellPadding=0 border=0>' + '<TBODY><TR style="HEIGHT: 18px">'; vTmpDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate()); vTmpDate.setHours(0); vTmpDate.setMinutes(0); // Major Date Header while(Date.parse(vTmpDate) <= Date.parse(vMaxDate)) { vStr = vTmpDate.getFullYear() + ''; vStr = vStr.substring(2,4); if(vFormat == 'minute') { vRightTable += '<td class="gdatehead" style="FONT-SIZE: 12px; HEIGHT: 19px;" align=center colspan=60>' ; vRightTable += JSGantt.formatDateStr(vTmpDate, vDateDisplayFormat) + ' ' + vTmpDate.getHours() + ':00 -' + vTmpDate.getHours() + ':59 </td>'; vTmpDate.setHours(vTmpDate.getHours()+1); } if(vFormat == 'hour') { vRightTable += '<td class="gdatehead" style="FONT-SIZE: 12px; HEIGHT: 19px;" align=center colspan=24>' ; vRightTable += JSGantt.formatDateStr(vTmpDate, vDateDisplayFormat) + '</td>'; vTmpDate.setDate(vTmpDate.getDate()+1); } if(vFormat == 'day') { vRightTable += '<td class="gdatehead" style="FONT-SIZE: 12px; HEIGHT: 19px;" align=center colspan=7>' + JSGantt.formatDateStr(vTmpDate,vDateDisplayFormat) + ' - '; vTmpDate.setDate(vTmpDate.getDate()+6); vRightTable += JSGantt.formatDateStr(vTmpDate, vDateDisplayFormat) + '</td>'; vTmpDate.setDate(vTmpDate.getDate()+1); } else if(vFormat == 'week') { vRightTable += '<td class="gdatehead" align=center style="FONT-SIZE: 12px; HEIGHT: 19px;" width='+vColWidth+'px>`'+ vStr + '</td>'; vTmpDate.setDate(vTmpDate.getDate()+7); } else if(vFormat == 'month') { vRightTable += '<td class="gdatehead" align=center style="FONT-SIZE: 12px; HEIGHT: 19px;" width='+vColWidth+'px>`'+ vStr + '</td>'; vTmpDate.setDate(vTmpDate.getDate() + 1); while(vTmpDate.getDate() > 1) { vTmpDate.setDate(vTmpDate.getDate() + 1); } } else if(vFormat == 'quarter') { vRightTable += '<td class="gdatehead" align=center style="FONT-SIZE: 12px; HEIGHT: 19px;" width='+vColWidth+'px>`'+ vStr + '</td>'; vTmpDate.setDate(vTmpDate.getDate() + 81); while(vTmpDate.getDate() > 1) { vTmpDate.setDate(vTmpDate.getDate() + 1); } } } vRightTable += '</TR><TR>'; // Minor Date header and Cell Rows vTmpDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate()); vNxtDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate()); vNumCols = 0; while(Date.parse(vTmpDate) <= Date.parse(vMaxDate)) { if (vFormat == 'minute') { if( vTmpDate.getMinutes() ==0 ) vWeekdayColor = "ccccff"; else vWeekdayColor = "ffffff"; vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">' + vTmpDate.getMinutes() + '</div></td>'; vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; cursor: default;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">  </div></td>'; vTmpDate.setMinutes(vTmpDate.getMinutes() + 1); } else if (vFormat == 'hour') { if( vTmpDate.getHours() ==0 ) vWeekdayColor = "ccccff"; else vWeekdayColor = "ffffff"; vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">' + vTmpDate.getHours() + '</div></td>'; vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; cursor: default;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">  </div></td>'; vTmpDate.setHours(vTmpDate.getHours() + 1); } else if(vFormat == 'day' ) { if( JSGantt.formatDateStr(vCurrDate,'mm/dd/yyyy') == JSGantt.formatDateStr(vTmpDate,'mm/dd/yyyy')) { vWeekdayColor = "ccccff"; vWeekendColor = "9999ff"; vWeekdayGColor = "bbbbff"; vWeekendGColor = "8888ff"; } else { vWeekdayColor = "ffffff"; vWeekendColor = "cfcfcf"; vWeekdayGColor = "f3f3f3"; vWeekendGColor = "c3c3c3"; } if(vTmpDate.getDay() % 6 == 0) { vDateRowStr += '<td class="gheadwkend" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" bgcolor=#' + vWeekendColor + ' align=center><div style="width: '+vColWidth+'px">' + vTmpDate.getDate() + '</div></td>'; vItemRowStr += '<td class="gheadwkend" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; cursor: default;" bgcolor=#' + vWeekendColor + ' align=center><div style="width: '+vColWidth+'px"> </div></td>'; } else { vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">' + vTmpDate.getDate() + '</div></td>'; if( JSGantt.formatDateStr(vCurrDate,'mm/dd/yyyy') == JSGantt.formatDateStr(vTmpDate,'mm/dd/yyyy')) vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; cursor: default;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">  </div></td>'; else vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; cursor: default;" align=center><div style="width: '+vColWidth+'px">  </div></td>'; } vTmpDate.setDate(vTmpDate.getDate() + 1); } else if(vFormat == 'week') { vNxtDate.setDate(vNxtDate.getDate() + 7); if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vWeekdayColor = "ccccff"; else vWeekdayColor = "ffffff"; if(vNxtDate <= vMaxDate) { vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center width:'+vColWidth+'px><div style="width: '+vColWidth+'px">' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '</div></td>'; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">  </div></td>'; else vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" align=center><div style="width: '+vColWidth+'px">  </div></td>'; } else { vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid; bgcolor=#' + vWeekdayColor + ' BORDER-RIGHT: #efefef 1px solid;" align=center width:'+vColWidth+'px><div style="width: '+vColWidth+'px">' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '</div></td>'; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">  </div></td>'; else vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=center><div style="width: '+vColWidth+'px">  </div></td>'; } vTmpDate.setDate(vTmpDate.getDate() + 7); } else if(vFormat == 'month') { vNxtDate.setFullYear(vTmpDate.getFullYear(), vTmpDate.getMonth(), vMonthDaysArr[vTmpDate.getMonth()]); if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vWeekdayColor = "ccccff"; else vWeekdayColor = "ffffff"; if(vNxtDate <= vMaxDate) { vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center width:'+vColWidth+'px><div style="width: '+vColWidth+'px">' + (lan=='en'?vMonthArr[vTmpDate.getMonth()].substr(0,3):vTmpDate.getMonth()+1) + '</div></td>'; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">  </div></td>'; else vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" align=center><div style="width: '+vColWidth+'px">  </div></td>'; } else { vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center width:'+vColWidth+'px><div style="width: '+vColWidth+'px">' + (lan=='en'?vMonthArr[vTmpDate.getMonth()].substr(0,3):vTmpDate.getMonth()+1) + '</div></td>'; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">  </div></td>'; else vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=center><div style="width: '+vColWidth+'px">  </div></td>'; } vTmpDate.setDate(vTmpDate.getDate() + 1); while(vTmpDate.getDate() > 1) { vTmpDate.setDate(vTmpDate.getDate() + 1); } } else if(vFormat == 'quarter') { vNxtDate.setDate(vNxtDate.getDate() + 122); if( vTmpDate.getMonth()==0 || vTmpDate.getMonth()==1 || vTmpDate.getMonth()==2 ) vNxtDate.setFullYear(vTmpDate.getFullYear(), 2, 31); else if( vTmpDate.getMonth()==3 || vTmpDate.getMonth()==4 || vTmpDate.getMonth()==5 ) vNxtDate.setFullYear(vTmpDate.getFullYear(), 5, 30); else if( vTmpDate.getMonth()==6 || vTmpDate.getMonth()==7 || vTmpDate.getMonth()==8 ) vNxtDate.setFullYear(vTmpDate.getFullYear(), 8, 30); else if( vTmpDate.getMonth()==9 || vTmpDate.getMonth()==10 || vTmpDate.getMonth()==11 ) vNxtDate.setFullYear(vTmpDate.getFullYear(), 11, 31); if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vWeekdayColor = "ccccff"; else vWeekdayColor = "ffffff"; if(vNxtDate <= vMaxDate) { vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center width:'+vColWidth+'px><div style="width: '+vColWidth+'px">' + vQuarterArr[vTmpDate.getMonth()]+(lan=='en'?'Qtr.':'季') + '</div></td>'; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">  </div></td>'; else vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;" align=center><div style="width: '+vColWidth+'px">  </div></td>'; } else { vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center width:'+vColWidth+'px><div style="width: '+vColWidth+'px">' + vQuarterArr[vTmpDate.getMonth()]+(lan=='en'?'Qtr.':'季') + '</div></td>'; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" bgcolor=#' + vWeekdayColor + ' align=center><div style="width: '+vColWidth+'px">  </div></td>'; else vItemRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid; BORDER-RIGHT: #efefef 1px solid;" align=center><div style="width: '+vColWidth+'px">  </div></td>'; } vTmpDate.setDate(vTmpDate.getDate() + 81); while(vTmpDate.getDate() > 1) { vTmpDate.setDate(vTmpDate.getDate() + 1); } } } vRightTable += vDateRowStr + '</TR>'; vRightTable += '</TBODY></TABLE>'; // Draw each row for(i = 0; i < vTaskList.length; i++) { vTmpDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate()); vTaskStart = vTaskList[i].getStart(); vTaskEnd = vTaskList[i].getEnd(); vNumCols = 0; vID = vTaskList[i].getID(); // vNumUnits = Math.ceil((vTaskList[i].getEnd() - vTaskList[i].getStart()) / (24 * 60 * 60 * 1000)) + 1; vNumUnits = (vTaskList[i].getEnd() - vTaskList[i].getStart()) / (24 * 60 * 60 * 1000) + 1; if (vFormat=='hour') { vNumUnits = (vTaskList[i].getEnd() - vTaskList[i].getStart()) / ( 60 * 1000) + 1; } else if (vFormat=='minute') { vNumUnits = (vTaskList[i].getEnd() - vTaskList[i].getStart()) / ( 60 * 1000) + 1; } if(vTaskList[i].getVisible() == 0) vRightTable += '<DIV id=childgrid_' + vID + ' style="position:relative; display:none;">'; else vRightTable += '<DIV id=childgrid_' + vID + ' style="position:relative">'; if( vTaskList[i].getMile()) { vRightTable += '<DIV><TABLE style="position:relative; top:0px; width: ' + vChartWidth + 'px;" cellSpacing=0 cellPadding=0 border=0>' + '<TR id=childrow_' + vID + ' class="yesdisplay" style="HEIGHT: 20px" onMouseover=g.mouseOver(this,' + vID + ',"right","mile") onMouseout=g.mouseOut(this,' + vID + ',"right","mile")>' + vItemRowStr + '</TR></TABLE></DIV>'; // Build date string for Title vDateRowStr = JSGantt.formatDateStr(vTaskStart,vDateDisplayFormat); vTaskLeft = (Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / (24 * 60 * 60 * 1000); vTaskRight = 1 vRightTable += '<div id=bardiv_' + vID + ' style="position:absolute; top:0px; left:' + Math.ceil((vTaskLeft * (vDayWidth) + 1)) + 'px; height: 18px; width:160px; overflow:hidden;">' + ' <div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr + '" style="height: 16px; width:12px; overflow:hidden; cursor: pointer;" onclick="' + vTaskList[i].getLink() + '">'; if(vTaskList[i].getCompVal() < 100) vRightTable += '◊</div>' ; else vRightTable += '♦</div>' ; if( g.getCaptionType() ) { vCaptionStr = ''; switch( g.getCaptionType() ) { case 'Caption': vCaptionStr = vTaskList[i].getCaption(); break; case 'Resource': vCaptionStr = vTaskList[i].getResource(); break; case 'Duration': vCaptionStr = vTaskList[i].getDuration(vFormat); break; case 'Complete': vCaptionStr = vTaskList[i].getCompStr(); break; } //vRightTable += '<div style="FONT-SIZE:12px; position:absolute; left: 6px; top:1px;">' + vCaptionStr + '</div>'; vRightTable += '<div style="FONT-SIZE:12px; position:absolute; top:2px;white-space:nowrap; left:12px">' + vCaptionStr + '</div>'; } vRightTable += '</div>'; } else { // Build date string for Title vDateRowStr = JSGantt.formatDateStr(vTaskStart,vDateDisplayFormat) + ' - ' + JSGantt.formatDateStr(vTaskEnd,vDateDisplayFormat) if (vFormat=='minute') { vTaskRight = (Date.parse(vTaskList[i].getEnd()) - Date.parse(vTaskList[i].getStart())) / ( 60 * 1000) + 1/vColUnit; vTaskLeft = Math.ceil((Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / ( 60 * 1000)); } else if (vFormat=='hour') { vTaskRight = (Date.parse(vTaskList[i].getEnd()) - Date.parse(vTaskList[i].getStart())) / ( 60 * 60 * 1000) + 1/vColUnit; vTaskLeft = (Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / ( 60 * 60 * 1000); } else { vTaskRight = (Date.parse(vTaskList[i].getEnd()) - Date.parse(vTaskList[i].getStart())) / (24 * 60 * 60 * 1000) + 1/vColUnit; vTaskLeft = Math.ceil((Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / (24 * 60 * 60 * 1000)); if (vFormat='day') { var tTime=new Date(); tTime.setTime(Date.parse(vTaskList[i].getStart())); if (tTime.getMinutes() > 29) vTaskLeft+=.5 } } // Draw Group Bar which has outer div with inner group div and several small divs to left and right to create angled-end indicators if( vTaskList[i].getGroup()) { vRightTable += '<DIV><TABLE style="position:relative; top:0px; width: ' + vChartWidth + 'px;" cellSpacing=0 cellPadding=0 border=0>' + '<TR id=childrow_' + vID + ' class="yesdisplay" style="HEIGHT: 20px" bgColor=#f3f3f3 onMouseover=g.mouseOver(this,' + vID + ',"right","group") onMouseout=g.mouseOut(this,' + vID + ',"right","group")>' + vItemRowStr + '</TR></TABLE></DIV>'; vRightTable += '<div id=bardiv_' + vID + ' style="position:absolute; top:5px; left:' + Math.ceil(vTaskLeft * (vDayWidth) + 1) + 'px; height: 7px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px">' + '<div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr + '" class="gtask" style="background-color:#000000; height: 7px; width:' + Math.ceil((vTaskRight) * (vDayWidth) -1) + 'px; cursor: pointer;opacity:0.9;">' + '<div style="Z-INDEX: -4; float:left; background-color:#666666; height:3px; overflow: hidden; margin-top:1px; ' + 'margin-left:1px; margin-right:1px; filter: alpha(opacity=80); opacity:0.8; width:' + vTaskList[i].getCompStr() + '; ' + 'cursor: pointer;" onclick="' + vTaskList[i].getLink() + '">' + '</div>' + '</div>' + '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:4px; overflow: hidden; width:1px;"></div>' + '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:4px; overflow: hidden; width:1px;"></div>' + '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:3px; overflow: hidden; width:1px;"></div>' + '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:3px; overflow: hidden; width:1px;"></div>' + '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:2px; overflow: hidden; width:1px;"></div>' + '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:2px; overflow: hidden; width:1px;"></div>' + '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:1px; overflow: hidden; width:1px;"></div>' + '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:1px; overflow: hidden; width:1px;"></div>' ; if( g.getCaptionType() ) { vCaptionStr = ''; switch( g.getCaptionType() ) { case 'Caption': vCaptionStr = vTaskList[i].getCaption(); break; case 'Resource': vCaptionStr = vTaskList[i].getResource(); break; case 'Duration': vCaptionStr = vTaskList[i].getDuration(vFormat); break; case 'Complete': vCaptionStr = vTaskList[i].getCompStr(); break; } //vRightTable += '<div style="FONT-SIZE:12px; position:absolute; left: 6px; top:1px;">' + vCaptionStr + '</div>'; vRightTable += '<div style="FONT-SIZE:12px; position:absolute; top:-3px;white-space:nowrap; left:' + (Math.ceil((vTaskRight) * (vDayWidth) - 1) + 6) + 'px">' + vCaptionStr + '</div>'; } vRightTable += '</div>' ; } else { vDivStr = '<DIV><TABLE style="position:relative; top:0px; width: ' + vChartWidth + 'px;" cellSpacing=0 cellPadding=0 border=0>' + '<TR id=childrow_' + vID + ' class="yesdisplay" style="HEIGHT: 20px" bgColor=#ffffff onMouseover=g.mouseOver(this,' + vID + ',"right","row") onMouseout=g.mouseOut(this,' + vID + ',"right","row")>' + vItemRowStr + '</TR></TABLE></DIV>'; vRightTable += vDivStr; // Draw Task Bar which has outer DIV with enclosed colored bar div, and opaque completion div vRightTable += '<div id=bardiv_' + vID + ' style="position:absolute; top:4px; left:' + Math.ceil(vTaskLeft * (vDayWidth) + 1) + 'px; height:18px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px">' + '<div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr + '" class="gtask" style="background-color:#' + vTaskList[i].getColor() +'; height: 13px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px; cursor: pointer;opacity:0.9;" ' + 'onclick="' + vTaskList[i].getLink() + '">' + '<div class="gcomplete" style="Z-INDEX: -4; float:left; background-color:#41ef0e; height:5px; overflow: auto; margin-top:4px; filter: alpha(opacity=40); opacity:0.4; width:' + vTaskList[i].getCompStr() + '; overflow:hidden">' + '</div>' + '</div>'; if( g.getCaptionType() ) { vCaptionStr = ''; switch( g.getCaptionType() ) { case 'Caption': vCaptionStr = vTaskList[i].getCaption(); break; case 'Resource': vCaptionStr = vTaskList[i].getResource(); break; case 'Duration': vCaptionStr = vTaskList[i].getDuration(vFormat); break; case 'Complete': vCaptionStr = vTaskList[i].getCompStr(); break; } //vRightTable += '<div style="FONT-SIZE:12px; position:absolute; left: 6px; top:-3px;">' + vCaptionStr + '</div>'; vRightTable += '<div style="FONT-SIZE:12px; position:absolute; top:-3px;white-space:nowrap; left:' + (Math.ceil((vTaskRight) * (vDayWidth) - 1) + 6) + 'px">' + vCaptionStr + '</div>'; } vRightTable += '</div>' ; } } vRightTable += '</DIV>'; } vMainTable += vRightTable + '</DIV></TD></TR></TBODY></TABLE></BODY></HTML>'; vDiv.innerHTML = vMainTable; } } //this.draw this.mouseOver = function( pObj, pID, pPos, pType ) { if( pPos == 'right' ) vID = 'child_' + pID; else vID = 'childrow_' + pID; pObj.bgColor = "#ffffaa"; vRowObj = JSGantt.findObj(vID); if (vRowObj) vRowObj.bgColor = "#ffffaa"; } this.mouseOut = function( pObj, pID, pPos, pType ) { if( pPos == 'right' ) vID = 'child_' + pID; else vID = 'childrow_' + pID; pObj.bgColor = "#ffffff"; vRowObj = JSGantt.findObj(vID); if (vRowObj) { if( pType == "group") { pObj.bgColor = "#f3f3f3"; vRowObj.bgColor = "#f3f3f3"; } else { pObj.bgColor = "#ffffff"; vRowObj.bgColor = "#ffffff"; } } } } //GanttChart // Recursively process task tree ... set min, max dates of parent tasks and identfy task level. JSGantt.processRows = function(pList, pID, pRow, pLevel, pOpen) { var vMinDate = new Date(); var vMaxDate = new Date(); var vMinSet = 0; var vMaxSet = 0; var vList = pList; var vLevel = pLevel; var i = 0; var vNumKid = 0; var vCompSum = 0; var vVisible = pOpen; for(i = 0; i < pList.length; i++) { if(pList[i].getParent() == pID) { vVisible = pOpen; pList[i].setVisible(vVisible); if(vVisible==1 && pList[i].getOpen() == 0) vVisible = 0; pList[i].setLevel(vLevel); vNumKid++; if(pList[i].getGroup() == 1) { JSGantt.processRows(vList, pList[i].getID(), i, vLevel+1, vVisible); } if( vMinSet==0 || pList[i].getStart() < vMinDate) { vMinDate = pList[i].getStart(); vMinSet = 1; } if( vMaxSet==0 || pList[i].getEnd() > vMaxDate) { vMaxDate = pList[i].getEnd(); vMaxSet = 1; } vCompSum += pList[i].getCompVal(); } } if(pRow >= 0) { pList[pRow].setStart(vMinDate); pList[pRow].setEnd(vMaxDate); pList[pRow].setNumKid(vNumKid); pList[pRow].setCompVal(Math.ceil(vCompSum/vNumKid)); } } // Used to determine the minimum date of all tasks and set lower bound based on format JSGantt.getMinDate = function getMinDate(pList, pFormat) { var vDate = new Date(); vDate.setFullYear(pList[0].getStart().getFullYear(), pList[0].getStart().getMonth(), pList[0].getStart().getDate()); // Parse all Task End dates to find min for(i = 0; i < pList.length; i++) { if(Date.parse(pList[i].getStart()) < Date.parse(vDate)) vDate.setFullYear(pList[i].getStart().getFullYear(), pList[i].getStart().getMonth(), pList[i].getStart().getDate()); } if ( pFormat== 'minute') { vDate.setHours(0); vDate.setMinutes(0); } else if (pFormat == 'hour' ) { vDate.setHours(0); vDate.setMinutes(0); } // Adjust min date to specific format boundaries (first of week or first of month) else if (pFormat=='day') { vDate.setDate(vDate.getDate() - 1); while(vDate.getDay() % 7 > 0) { vDate.setDate(vDate.getDate() - 1); } } else if (pFormat=='week') { vDate.setDate(vDate.getDate() - 7); while(vDate.getDay() % 7 > 0) { vDate.setDate(vDate.getDate() - 1); } } else if (pFormat=='month') { while(vDate.getDate() > 1) { vDate.setDate(vDate.getDate() - 1); } } else if (pFormat=='quarter') { if( vDate.getMonth()==0 || vDate.getMonth()==1 || vDate.getMonth()==2 ) vDate.setFullYear(vDate.getFullYear(), 0, 1); else if( vDate.getMonth()==3 || vDate.getMonth()==4 || vDate.getMonth()==5 ) vDate.setFullYear(vDate.getFullYear(), 3, 1); else if( vDate.getMonth()==6 || vDate.getMonth()==7 || vDate.getMonth()==8 ) vDate.setFullYear(vDate.getFullYear(), 6, 1); else if( vDate.getMonth()==9 || vDate.getMonth()==10 || vDate.getMonth()==11 ) vDate.setFullYear(vDate.getFullYear(), 9, 1); } return(vDate); } // Used to determine the minimum date of all tasks and set lower bound based on format JSGantt.getMaxDate = function (pList, pFormat) { var vDate = new Date(); vDate.setFullYear(pList[0].getEnd().getFullYear(), pList[0].getEnd().getMonth(), pList[0].getEnd().getDate()); // Parse all Task End dates to find max for(i = 0; i < pList.length; i++) { if(Date.parse(pList[i].getEnd()) > Date.parse(vDate)) { //vDate.setFullYear(pList[0].getEnd().getFullYear(), pList[0].getEnd().getMonth(), pList[0].getEnd().getDate()); vDate.setTime(Date.parse(pList[i].getEnd())); } } if (pFormat == 'minute') { vDate.setHours(vDate.getHours() + 1); vDate.setMinutes(59); } if (pFormat == 'hour') { vDate.setHours(vDate.getHours() + 2); } // Adjust max date to specific format boundaries (end of week or end of month) if (pFormat=='day') { vDate.setDate(vDate.getDate() + 1); while(vDate.getDay() % 6 > 0) { vDate.setDate(vDate.getDate() + 1); } } if (pFormat=='week') { //For weeks, what is the last logical boundary? vDate.setDate(vDate.getDate() + 11); while(vDate.getDay() % 6 > 0) { vDate.setDate(vDate.getDate() + 1); } } // Set to last day of current Month if (pFormat=='month') { while(vDate.getDay() > 1) { vDate.setDate(vDate.getDate() + 1); } vDate.setDate(vDate.getDate() - 1); } // Set to last day of current Quarter if (pFormat=='quarter') { if( vDate.getMonth()==0 || vDate.getMonth()==1 || vDate.getMonth()==2 ) vDate.setFullYear(vDate.getFullYear(), 2, 31); else if( vDate.getMonth()==3 || vDate.getMonth()==4 || vDate.getMonth()==5 ) vDate.setFullYear(vDate.getFullYear(), 5, 30); else if( vDate.getMonth()==6 || vDate.getMonth()==7 || vDate.getMonth()==8 ) vDate.setFullYear(vDate.getFullYear(), 8, 30); else if( vDate.getMonth()==9 || vDate.getMonth()==10 || vDate.getMonth()==11 ) vDate.setFullYear(vDate.getFullYear(), 11, 31); } return(vDate); } // This function finds the document id of the specified object JSGantt.findObj = function (theObj, theDoc) { var p, i, foundObj; if(!theDoc) theDoc = document; if( (p = theObj.indexOf("?")) > 0 && parent.frames.length){ theDoc = parent.frames[theObj.substring(p+1)].document; theObj = theObj.substring(0,p); } if(!(foundObj = theDoc[theObj]) && theDoc.all) foundObj = theDoc.all[theObj]; for (i=0; !foundObj && i < theDoc.forms.length; i++) foundObj = theDoc.forms[i][theObj]; for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++) foundObj = JSGantt.findObj(theObj,theDoc.layers[i].document); if(!foundObj && document.getElementById) foundObj = document.getElementById(theObj); return foundObj; } JSGantt.changeFormat = function(pFormat,ganttObj) { if(ganttObj) { ganttObj.setFormat(pFormat); ganttObj.DrawDependencies(); } else alert('Chart undefined'); } // Function to open/close and hide/show children of specified task JSGantt.folder= function (pID,ganttObj) { var vList = ganttObj.getList(); for(i = 0; i < vList.length; i++) { if(vList[i].getID() == pID) { if( vList[i].getOpen() == 1 ) { vList[i].setOpen(0); JSGantt.hide(pID,ganttObj); if (JSGantt.isIE()) JSGantt.findObj('group_'+pID).innerText = '+'; else JSGantt.findObj('group_'+pID).textContent = '+'; } else { vList[i].setOpen(1); JSGantt.show(pID, 1, ganttObj); if (JSGantt.isIE()) JSGantt.findObj('group_'+pID).innerText = '–'; else JSGantt.findObj('group_'+pID).textContent = '–'; } } } } JSGantt.hide= function (pID,ganttObj) { var vList = ganttObj.getList(); var vID = 0; for(var i = 0; i < vList.length; i++) { if(vList[i].getParent() == pID) { vID = vList[i].getID(); JSGantt.findObj('child_' + vID).style.display = "none"; JSGantt.findObj('childgrid_' + vID).style.display = "none"; vList[i].setVisible(0); if(vList[i].getGroup() == 1) JSGantt.hide(vID,ganttObj); } } } // Function to show children of specified task JSGantt.show = function (pID, pTop, ganttObj) { var vList = ganttObj.getList(); var vID = 0; for(var i = 0; i < vList.length; i++) { if(vList[i].getParent() == pID) { vID = vList[i].getID(); if(pTop == 1) { if (JSGantt.isIE()) { // IE; if( JSGantt.findObj('group_'+pID).innerText == '+') { JSGantt.findObj('child_'+vID).style.display = ""; JSGantt.findObj('childgrid_'+vID).style.display = ""; vList[i].setVisible(1); } } else { if( JSGantt.findObj('group_'+pID).textContent == '+') { JSGantt.findObj('child_'+vID).style.display = ""; JSGantt.findObj('childgrid_'+vID).style.display = ""; vList[i].setVisible(1); } } } else { if (JSGantt.isIE()) { // IE; if( JSGantt.findObj('group_'+pID).innerText == '�') { JSGantt.findObj('child_'+vID).style.display = ""; JSGantt.findObj('childgrid_'+vID).style.display = ""; vList[i].setVisible(1); } } else { if( JSGantt.findObj('group_'+pID).textContent == '�') { JSGantt.findObj('child_'+vID).style.display = ""; JSGantt.findObj('childgrid_'+vID).style.display = ""; vList[i].setVisible(1); } } } if(vList[i].getGroup() == 1) JSGantt.show(vID, 0,ganttObj); } } } // function to open window to display task link JSGantt.taskLink = function(pRef,pWidth,pHeight) { if(pWidth) vWidth =pWidth; else vWidth =400; if(pHeight) vHeight=pHeight; else vHeight=400; var OpenWindow=window.open(pRef, "newwin", "height="+vHeight+",width="+vWidth); } JSGantt.parseDateStr = function(pDateStr,pFormatStr) { var vDate =new Date(); vDate.setTime( Date.parse(pDateStr)); switch(pFormatStr) { case 'mm/dd/yyyy': var vDateParts = pDateStr.split('/'); vDate.setFullYear(parseInt(vDateParts[2], 10), parseInt(vDateParts[0], 10) - 1, parseInt(vDateParts[1], 10)); break; case 'dd/mm/yyyy': var vDateParts = pDateStr.split('/'); vDate.setFullYear(parseInt(vDateParts[2], 10), parseInt(vDateParts[1], 10) - 1, parseInt(vDateParts[0], 10)); break; case 'yyyy-mm-dd': var vDateParts = pDateStr.split('-'); vDate.setFullYear(parseInt(vDateParts[0], 10), parseInt(vDateParts[1], 10) - 1, parseInt(vDateParts[1], 10)); break; } return(vDate); } JSGantt.formatDateStr = function(pDate,pFormatStr) { vYear4Str = pDate.getFullYear() + ''; vYear2Str = vYear4Str.substring(2,4); vMonthStr = (pDate.getMonth()+1) + ''; vDayStr = pDate.getDate() + ''; var vDateStr = ""; switch(pFormatStr) { case 'mm/dd/yyyy': return( vMonthStr + '/' + vDayStr + '/' + vYear4Str ); case 'dd/mm/yyyy': return( vDayStr + '/' + vMonthStr + '/' + vYear4Str ); case 'yyyy-mm-dd': return( vYear4Str + '-' + vMonthStr + '-' + vDayStr ); case 'mm/dd/yy': return( vMonthStr + '/' + vDayStr + '/' + vYear2Str ); case 'dd/mm/yy': return( vDayStr + '/' + vMonthStr + '/' + vYear2Str ); case 'yy-mm-dd': return( vYear2Str + '-' + vMonthStr + '-' + vDayStr ); case 'mm/dd': return( vMonthStr + '/' + vDayStr ); case 'dd/mm': return( vDayStr + '/' + vMonthStr ); case 'yy/mm/dd': return( vYear2Str + '/' + vMonthStr + '/' + vDayStr ); } } JSGantt.parseXML = function(ThisFile,pGanttVar){ var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1; // Is this Chrome try { //Internet Explorer xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); } catch(e) { try { //Firefox, Mozilla, Opera, Chrome etc. if (is_chrome==false) { xmlDoc=document.implementation.createDocument("","",null); } } catch(e) { alert(e.message); return; } } if (is_chrome==false) { // can't use xmlDoc.load in chrome at the moment xmlDoc.async=false; xmlDoc.load(ThisFile); // we can use loadxml JSGantt.AddXMLTask(pGanttVar) xmlDoc=null; // a little tidying Task = null; } else { JSGantt.ChromeLoadXML(ThisFile,pGanttVar); ta=null; // a little tidying } } JSGantt.AddXMLTask = function(pGanttVar){ Task=xmlDoc.getElementsByTagName("task"); var n = xmlDoc.documentElement.childNodes.length; // the number of tasks. IE gets this right, but mozilla add extra ones (Whitespace) for(var i=0;i<n;i++) { // optional parameters may not have an entry (Whitespace from mozilla also returns an error ) // Task ID must NOT be zero other wise it will be skipped try { pID = Task[i].getElementsByTagName("pID")[0].childNodes[0].nodeValue; } catch (error) {pID =0;} pID *= 1; // make sure that these are numbers rather than strings in order to make jsgantt.js behave as expected. if(pID!=0){ try { pName = Task[i].getElementsByTagName("pName")[0].childNodes[0].nodeValue; } catch (error) {pName ="No Task Name";} // If there is no corresponding entry in the XML file the set a default. try { pColor = Task[i].getElementsByTagName("pColor")[0].childNodes[0].nodeValue; } catch (error) {pColor ="0000ff";} try { pParent = Task[i].getElementsByTagName("pParent")[0].childNodes[0].nodeValue; } catch (error) {pParent =0;} pParent *= 1; try { pStart = Task[i].getElementsByTagName("pStart")[0].childNodes[0].nodeValue; } catch (error) {pStart ="";} try { pEnd = Task[i].getElementsByTagName("pEnd")[0].childNodes[0].nodeValue; } catch (error) { pEnd ="";} try { pLink = Task[i].getElementsByTagName("pLink")[0].childNodes[0].nodeValue; } catch (error) { pLink ="";} try { pMile = Task[i].getElementsByTagName("pMile")[0].childNodes[0].nodeValue; } catch (error) { pMile=0;} pMile *= 1; try { pRes = Task[i].getElementsByTagName("pRes")[0].childNodes[0].nodeValue; } catch (error) { pRes ="";} try { pComp = Task[i].getElementsByTagName("pComp")[0].childNodes[0].nodeValue; } catch (error) {pComp =0;} pComp *= 1; try { pGroup = Task[i].getElementsByTagName("pGroup")[0].childNodes[0].nodeValue; } catch (error) {pGroup =0;} pGroup *= 1; try { pOpen = Task[i].getElementsByTagName("pOpen")[0].childNodes[0].nodeValue; } catch (error) { pOpen =1;} pOpen *= 1; try { pDepend = Task[i].getElementsByTagName("pDepend")[0].childNodes[0].nodeValue; } catch (error) { pDepend =0;} //pDepend *= 1; if (pDepend.length==0){pDepend=''} // need this to draw the dependency lines try { pCaption = Task[i].getElementsByTagName("pCaption")[0].childNodes[0].nodeValue; } catch (error) { pCaption ="";} // Finally add the task pGanttVar.AddTaskItem(new JSGantt.TaskItem(pID , pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend,pCaption)); } } } JSGantt.ChromeLoadXML = function(ThisFile,pGanttVar){ // Thanks to vodobas at mindlence,com for the initial pointers here. XMLLoader = new XMLHttpRequest(); XMLLoader.onreadystatechange= function(){ JSGantt.ChromeXMLParse(pGanttVar); }; XMLLoader.open("GET", ThisFile, false); XMLLoader.send(null); } JSGantt.ChromeXMLParse = function (pGanttVar){ // Manually parse the file as it is loads quicker if (XMLLoader.readyState == 4) { var ta=XMLLoader.responseText.split(/<task>/gi); var n = ta.length; // the number of tasks. for(var i=1;i<n;i++) { Task = ta[i].replace(/<[/]p/g, '<p'); var te = Task.split(/<pid>/i) if(te.length> 2){var pID=te[1];} else {var pID = 0;} pID *= 1; var te = Task.split(/<pName>/i) if(te.length> 2){var pName=te[1];} else {var pName = "No Task Name";} var te = Task.split(/<pstart>/i) if(te.length> 2){var pStart=te[1];} else {var pStart = "";} var te = Task.split(/<pEnd>/i) if(te.length> 2){var pEnd=te[1];} else {var pEnd = "";} var te = Task.split(/<pColor>/i) if(te.length> 2){var pColor=te[1];} else {var pColor = '0000ff';} var te = Task.split(/<pLink>/i) if(te.length> 2){var pLink=te[1];} else {var pLink = "";} var te = Task.split(/<pMile>/i) if(te.length> 2){var pMile=te[1];} else {var pMile = 0;} pMile *= 1; var te = Task.split(/<pRes>/i) if(te.length> 2){var pRes=te[1];} else {var pRes = "";} var te = Task.split(/<pComp>/i) if(te.length> 2){var pComp=te[1];} else {var pComp = 0;} pComp *= 1; var te = Task.split(/<pGroup>/i) if(te.length> 2){var pGroup=te[1];} else {var pGroup = 0;} pGroup *= 1; var te = Task.split(/<pParent>/i) if(te.length> 2){var pParent=te[1];} else {var pParent = 0;} pParent *= 1; var te = Task.split(/<pOpen>/i) if(te.length> 2){var pOpen=te[1];} else {var pOpen = 1;} pOpen *= 1; var te = Task.split(/<pDepend>/i) if(te.length> 2){var pDepend=te[1];} else {var pDepend = "";} //pDepend *= 1; if (pDepend.length==0){pDepend=''} // need this to draw the dependency lines var te = Task.split(/<pCaption>/i) if(te.length> 2){var pCaption=te[1];} else {var pCaption = "";} // Finally add the task pGanttVar.AddTaskItem(new JSGantt.TaskItem(pID , pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend,pCaption )); } } } JSGantt.benchMark = function(pItem){ var vEndTime=new Date().getTime(); alert(pItem + ': Elapsed time: '+((vEndTime-vBenchTime)/1000)+' seconds.'); vBenchTime=new Date().getTime(); }
JAVA BEANnode
package com.ata.model.atq; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Transient; import org.hibernate.annotations.GenericGenerator; import com.ata.model.sys.SysDept; import com.ata.pageModel.base.PageData; /** * AtqProject entity. @author MyEclipse Persistence Tools */ @Entity @Table(name = "atq_project") public class AtqProject extends PageData implements java.io.Serializable { // Fields private Integer projectId; private AtqProjectGroup atqProjectGroup; private String projectName; private String projectType; private String projectDesc; private String developer; private String tester; private String pm; private String leader; private String developPersons; private Integer developerNum; private String testleader; private String testPersons; private Integer testerNum; private String status; private Integer userId; private Date createTime; private Set<AtqProjectCaseNum> atqProjectCaseNums = new HashSet<AtqProjectCaseNum>(0); private Set<AtqProjectBugNum> atqProjectBugNums = new HashSet<AtqProjectBugNum>(0); private Set<AtqProjectPlanProgress> atqProjectPlanProgresses = new HashSet<AtqProjectPlanProgress>(0); private Set<AtqUserProject> atqUserProjects = new HashSet<AtqUserProject>(0); private Set<AtqProjectScript> atqProjectScripts = new HashSet<AtqProjectScript>(0); // Constructors /** default constructor */ public AtqProject() { } /** full constructor */ public AtqProject(AtqProjectGroup atqProjectGroup, String projectName, String projectType, String projectDesc, String developer, String tester, String developPersons,String testPersons, String status, Integer userId, Date createTime, Set<AtqProjectCaseNum> atqProjectCaseNums, Set<AtqProjectBugNum> atqProjectBugNums, Set<AtqProjectPlanProgress> atqProjectPlanProgresses, Set<AtqUserProject> atqUserProjects, Set<AtqProjectScript> atqProjectScripts) { this.atqProjectGroup = atqProjectGroup; this.projectName = projectName; this.projectType = projectType; this.projectDesc = projectDesc; this.developer=developer; this.tester=tester; this.developPersons = developPersons; this.testPersons=testPersons; this.status = status; this.userId = userId; this.createTime = createTime; this.atqProjectCaseNums = atqProjectCaseNums; this.atqProjectBugNums = atqProjectBugNums; this.atqProjectPlanProgresses = atqProjectPlanProgresses; this.atqUserProjects = atqUserProjects; this.atqProjectScripts = atqProjectScripts; } // Property accessors @GenericGenerator(name = "generator", strategy = "increment") @Id @GeneratedValue(generator = "generator") @Column(name = "project_id", unique = true, nullable = false) public Integer getProjectId() { return this.projectId; } public void setProjectId(Integer projectId) { this.projectId = projectId; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "group_id") public AtqProjectGroup getAtqProjectGroup() { return this.atqProjectGroup; } public void setAtqProjectGroup(AtqProjectGroup atqProjectGroup) { this.atqProjectGroup = atqProjectGroup; } @Column(name = "project_name") public String getProjectName() { return this.projectName; } public void setProjectName(String projectName) { this.projectName = projectName; } @Column(name = "project_type") public String getProjectType() { return this.projectType; } public void setProjectType(String projectType) { this.projectType = projectType; } @Column(name = "project_desc", length = 1000) public String getProjectDesc() { return this.projectDesc; } public void setProjectDesc(String projectDesc) { this.projectDesc = projectDesc; } @Column(name = "leader") public String getLeader() { return leader; } public void setLeader(String leader) { this.leader = leader; } @Column(name = "testleader") public String getTestleader() { return testleader; } public void setTestleader(String testleader) { this.testleader = testleader; } @Column(name = "developer") public String getDeveloper() { return developer; } public void setDeveloper(String developer) { this.developer = developer; } @Column(name = "tester") public String getTester() { return tester; } public void setTester(String tester) { this.tester = tester; } @Column(name = "pm") public String getPm() { return pm; } public void setPm(String pm) { this.pm = pm; } @Column(name = "develop_persons") public String getDevelopPersons() { return developPersons; } public void setDevelopPersons(String developPersons) { this.developPersons = developPersons; } @Column(name = "test_persons") public String getTestPersons() { return testPersons; } public void setTestPersons(String testPersons) { this.testPersons = testPersons; } @Column(name = "status") public String getStatus() { return this.status; } public void setStatus(String status) { this.status = status; } @Column(name = "user_id") public Integer getUserId() { return this.userId; } public void setUserId(Integer userId) { this.userId = userId; } @Column(name = "create_time", length = 23) public Date getCreateTime() { return this.createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "atqProject") public Set<AtqProjectCaseNum> getAtqProjectCaseNums() { return this.atqProjectCaseNums; } public void setAtqProjectCaseNums(Set<AtqProjectCaseNum> atqProjectCaseNums) { this.atqProjectCaseNums = atqProjectCaseNums; } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "atqProject") public Set<AtqProjectBugNum> getAtqProjectBugNums() { return this.atqProjectBugNums; } public void setAtqProjectBugNums(Set<AtqProjectBugNum> atqProjectBugNums) { this.atqProjectBugNums = atqProjectBugNums; } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "atqProject") public Set<AtqProjectPlanProgress> getAtqProjectPlanProgresses() { return this.atqProjectPlanProgresses; } public void setAtqProjectPlanProgresses(Set<AtqProjectPlanProgress> atqProjectPlanProgresses) { this.atqProjectPlanProgresses = atqProjectPlanProgresses; } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "atqProject") public Set<AtqUserProject> getAtqUserProjects() { return this.atqUserProjects; } public void setAtqUserProjects(Set<AtqUserProject> atqUserProjects) { this.atqUserProjects = atqUserProjects; } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "atqProject") public Set<AtqProjectScript> getAtqProjectScripts() { return this.atqProjectScripts; } public void setAtqProjectScripts(Set<AtqProjectScript> atqProjectScripts) { this.atqProjectScripts = atqProjectScripts; } @Column(name = "tester_num") public Integer getTesterNum() { return testerNum; } public void setTesterNum(Integer testerNum) { this.testerNum = testerNum; } @Column(name = "developer_num") public Integer getDeveloperNum() { return developerNum; } public void setDeveloperNum(Integer developerNum) { this.developerNum = developerNum; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private String ids; private String proejctIds; private Integer groupId; private String groupName; private String developerDeptName; private String testDeptName; private String pmName; private String leaderName; private String testleaderName; private String developPersonsName; private String testPersonsName; // 用於產生項目報告JSP頁面 private int caseNumTotal; private int bugNumTotal; private int scriptNumTotal; private String projectBeginDateShow; private int realDaysTotalShow; private int maxBugDaysShow ; private int minBugDaysShow ; private int avgBugDaysShow ; private int closedBugNumTotal; private int closedBugFatalNumTotal; private int closedBugHighNumTotal; private int closedBugLowNumTotal; private int closedBugMiddleNumTotal; private int unclosedBugNumTotal ; private int unclosedBugFatalNumTotal ; private int unclosedBugHighNumTotal ; private int unclosedBugLowNumTotal ; private int unclosedBugMiddleNumTotal ; @Transient public int getUnclosedBugNumTotal() { return unclosedBugNumTotal; } public void setUnclosedBugNumTotal(int unclosedBugNumTotal) { this.unclosedBugNumTotal = unclosedBugNumTotal; } @Transient public int getClosedBugNumTotal() { return closedBugNumTotal; } public void setClosedBugNumTotal(int closedBugNumTotal) { this.closedBugNumTotal = closedBugNumTotal; } @Transient public int getClosedBugHighNumTotal() { return closedBugHighNumTotal; } public void setClosedBugHighNumTotal(int closedBugHighNumTotal) { this.closedBugHighNumTotal = closedBugHighNumTotal; } @Transient public int getClosedBugLowNumTotal() { return closedBugLowNumTotal; } public void setClosedBugLowNumTotal(int closedBugLowNumTotal) { this.closedBugLowNumTotal = closedBugLowNumTotal; } @Transient public int getClosedBugMiddleNumTotal() { return closedBugMiddleNumTotal; } public void setClosedBugMiddleNumTotal(int closedBugMiddleNumTotal) { this.closedBugMiddleNumTotal = closedBugMiddleNumTotal; } @Transient public int getUnclosedBugHighNumTotal() { return unclosedBugHighNumTotal; } public void setUnclosedBugHighNumTotal(int unclosedBugHighNumTotal) { this.unclosedBugHighNumTotal = unclosedBugHighNumTotal; } @Transient public int getUnclosedBugLowNumTotal() { return unclosedBugLowNumTotal; } public void setUnclosedBugLowNumTotal(int unclosedBugLowNumTotal) { this.unclosedBugLowNumTotal = unclosedBugLowNumTotal; } @Transient public int getUnclosedBugMiddleNumTotal() { return unclosedBugMiddleNumTotal; } public void setUnclosedBugMiddleNumTotal(int unclosedBugMiddleNumTotal) { this.unclosedBugMiddleNumTotal = unclosedBugMiddleNumTotal; } @Transient public int getClosedBugFatalNumTotal() { return closedBugFatalNumTotal; } public void setClosedBugFatalNumTotal(int closedBugFatalNumTotal) { this.closedBugFatalNumTotal = closedBugFatalNumTotal; } @Transient public int getUnclosedBugFatalNumTotal() { return unclosedBugFatalNumTotal; } public void setUnclosedBugFatalNumTotal(int unclosedBugFatalNumTotal) { this.unclosedBugFatalNumTotal = unclosedBugFatalNumTotal; } @Transient public int getMaxBugDaysShow() { return maxBugDaysShow; } public void setMaxBugDaysShow(int maxBugDaysShow) { this.maxBugDaysShow = maxBugDaysShow; } @Transient public int getMinBugDaysShow() { return minBugDaysShow; } public void setMinBugDaysShow(int minBugDaysShow) { this.minBugDaysShow = minBugDaysShow; } @Transient public int getAvgBugDaysShow() { return avgBugDaysShow; } public void setAvgBugDaysShow(int avgBugDaysShow) { this.avgBugDaysShow = avgBugDaysShow; } @Transient public int getRealDaysTotalShow() { return realDaysTotalShow; } public void setRealDaysTotalShow(int realDaysTotalShow) { this.realDaysTotalShow = realDaysTotalShow; } @Transient public String getProjectBeginDateShow() { return projectBeginDateShow; } public void setProjectBeginDateShow(String projectBeginDateShow) { this.projectBeginDateShow = projectBeginDateShow; } @Transient public int getCaseNumTotal() { return caseNumTotal; } public void setCaseNumTotal(int caseNumTotal) { this.caseNumTotal = caseNumTotal; } @Transient public int getBugNumTotal() { return bugNumTotal; } public void setBugNumTotal(int bugNumTotal) { this.bugNumTotal = bugNumTotal; } @Transient public int getScriptNumTotal() { return scriptNumTotal; } public void setScriptNumTotal(int scriptNumTotal) { this.scriptNumTotal = scriptNumTotal; } @Transient public String getIds() { return ids; } public void setIds(String ids) { this.ids = ids; } @Transient public Integer getGroupId() { return groupId; } public void setGroupId(Integer groupId) { this.groupId = groupId; } @Transient public String getGroupName() { return groupName; } public void setGroupName(String groupName) { this.groupName = groupName; } @Transient public String getLeaderName() { return leaderName; } public void setLeaderName(String leaderName) { this.leaderName = leaderName; } @Transient public String getPmName() { return pmName; } public void setPmName(String pmName) { this.pmName = pmName; } @Transient public String getDevelopPersonsName() { return developPersonsName; } public void setDevelopPersonsName(String developPersonsName) { this.developPersonsName = developPersonsName; } @Transient public String getTestPersonsName() { return testPersonsName; } public void setTestPersonsName(String testPersonsName) { this.testPersonsName = testPersonsName; } @Transient public String getDeveloperDeptName() { return developerDeptName; } public void setDeveloperDeptName(String developerDeptName) { this.developerDeptName = developerDeptName; } @Transient public String getTestDeptName() { return testDeptName; } public void setTestDeptName(String testDeptName) { this.testDeptName = testDeptName; } @Transient public String getTestleaderName() { return testleaderName; } public void setTestleaderName(String testleaderName) { this.testleaderName = testleaderName; } @Transient public String getProejctIds() { return proejctIds; } public void setProejctIds(String proejctIds) { this.proejctIds = proejctIds; } }