Modified: ofbiz/trunk/framework/images/webapp/images/jsgantt.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/jsgantt.js?rev=918340&r1=918339&r2=918340&view=diff ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/jsgantt.js (original) +++ ofbiz/trunk/framework/images/webapp/images/jsgantt.js Wed Mar 3 07:03:59 2010 @@ -1,5 +1,5 @@ -/* Copyright (c) 2008, Shlomy Gantz/BlueBrick Inc. -* All rights reserved. +/* +Copyright (c) 2009, Shlomy Gantz BlueBrick Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -23,1722 +23,1798 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - // function that loads each Task Item and fills TaskList array with each task attributes. - // You should be able to add items to the chart in realtime via javascript and issuing "g.Draw()" command. - - // Parameters: - - // pID: (required) is a unique ID used to identify each row for parent functions and for setting dom id for hiding/showing - - // pName: (required) is the task Label - - // pStart: (required) the task start date, can enter empty date ('') for groups - - // pEnd: (required) the task end date, can enter empty date ('') for groups - - // pColor: (required) the html color for this task; e.g. '00ff00' - - // pLink: (optional) any http link navigated to when task bar is clicked. - - // pMile: UNUSED - in future will represent a milestone - - // pRes: (optional) resource name - - // pComp: (required) completion percent - - // pGroup: (optional) indicates whether this is a group(parent) - 0=NOT Parent; 1=IS Parent - - // pParent: (required) identifies a parent pID, this causes this task to be a child of identified task - - // pOpen: UNUSED - in future can be initially set to close folder when chart is first drawn - - - // ******* 1024,768 replaced by 1024,768 by JLR ******* - - -var JSGantt; if (!JSGantt) JSGantt = {}; - -var vTimeout = 0; - -//function JSGantt() {} - -JSGantt.isIE = function () { - - if(typeof document.all != 'undefined') - return true; - else - return false; - } - -function Graphics(canvas) - -{ - - this.canvas = canvas; - - this.cache = new Array; - - this.shapes = new Object; - - this.nObject = 0; - - - - // defaults - - this.penColor = "black"; - - this.zIndex = 0; - -} - - -Graphics.prototype.createPlotElement = function(x,y,w,h) { - // detect canvas - if ( (this.canvas == undefined) || (this.canvas == "") ) - this.oCanvas = document.body; - else - this.oCanvas = document.getElementById(this.canvas); - - // retrieve DIV - var oDiv; - oDiv = document.createElement('div'); - this.oCanvas.appendChild(oDiv); - - 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 = this.zIndex; - oDiv.style.backgroundColor = this.penColor; - - oDiv.style.left = x + "px"; - oDiv.style.top = y + "px"; - oDiv.style.width = w + "px"; - oDiv.style.height = h + "px"; - - oDiv.style.visibility = "visible"; - - return oDiv; -} - - -Graphics.prototype.releasePlotElement = function(oDiv) - -{ - - oDiv.style.visibility = "hidden"; - - this.cache.push(oDiv); - -} - - - -Graphics.prototype.addShape = function(shape) - -{ - - shape.oGraphics = this; - - shape.graphicsID = this.nObject; - - this.shapes[this.nObject] = shape; - - this.nObject++; - - shape.draw(); - - return shape; - -} - - - -Graphics.prototype.removeShape = function(shape) - -{ - - if ( (shape instanceof Object) && - - (shape.oGraphics == this) && - - (this.shapes[shape.graphicsID] == shape) ) - - { - - shape.undraw(); - - this.shapes[shape.graphicsID] = undefined; - - shape.oGraphics = undefined; - - } - -} - -Graphics.prototype.clear = function() - -{ - - for ( var i in this.shapes ) - - this.removeShape(this.shapes[i]); - -} - - - - - -//============================================================================= - -// Point - -Graphics.prototype.drawPoint = function(x,y) - -{ - - return this.addShape(new Point(x,y)) - -} - - - -function Point(x,y) - -{ - - this.x = x; - - this.y = y; - -} - -Point.prototype.draw = function() - -{ - - this.oDiv = this.oGraphics.createPlotElement(this.x,this.y,1,1); - -} - -Point.prototype.undraw = function() - -{ - - this.oGraphics.releasePlotElement(this.oDiv); - - this.oDiv = undefined; - -} - - - -//============================================================================= - -// Line - -Graphics.prototype.drawLine = function(x1,y1,x2,y2) - -{ - - return this.addShape(new Line(x1,y1,x2,y2)) - -} - - - -function Line(x1,y1,x2,y2) - -{ - - this.x1 = x1; - - this.y1 = y1; - - this.x2 = x2; - - this.y2 = y2; - -} - - - -Line.prototype.draw = function() - -{ - - this.plots = new Array; - - - - var dx = this.x2 - this.x1; - - var dy = this.y2 - this.y1; - - var x = this.x1; - - var y = this.y1; - - - - var n = Math.max(Math.abs(dx),Math.abs(dy)); - - dx = dx / n; - - dy = dy / n; - - for ( i = 0; i <= n; i++ ) - - { - - this.plots.push(this.oGraphics.createPlotElement(Math.round(x),Math.round(y),1,1)); - - - - x += dx; - - y += dy; - - } - -} - -Line.prototype.undraw = function() - -{ - - while ( this.plots.length ) - - this.oGraphics.releasePlotElement(this.plots.pop()); - - this.plots = undefined; - -} - - - - - -JSGantt.TaskItem = function(pID, pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend) - - { - - - - 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 vLevel = 0; - - var vNumKid = 0; - - var vVisible = 1; - - var x1, y1, x2, y2; - - - - - - if (vGroup != 1) - - { - - var vDateParts = pStart.split('/'); - - vStart.setFullYear(parseInt(vDateParts[2], 10), parseInt(vDateParts[0], 10) - 1, parseInt(vDateParts[1], 10)); - - vDateParts = pEnd.split('/'); - - vEnd.setFullYear(parseInt(vDateParts[2], 10), parseInt(vDateParts[0], 10) - 1, parseInt(vDateParts[1], 10)); - - } - - - - 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(){ return vDepend }; - - 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) return '-'; - - - - if(vFormat == 'day') { - - tmpDays = Math.ceil((this.getEnd() - this.getStart()) / (24 * 60 * 60 * 1000) + 1); - - if(tmpDays == 1) return (tmpDays + ' Day'); else return(tmpDays + ' Days'); - - } - - if(vFormat == 'week') { - - tmpWeeks = ((this.getEnd() - this.getStart()) / (24 * 60 * 60 * 1000) + 1)/7; - - if(tmpWeeks == 1) return ('1 Week'); else return(tmpWeeks.toFixed(1) + ' Weeks'); - - } - - if(vFormat == 'month') { - - tmpMonths = ((this.getEnd() - this.getStart()) / (24 * 60 * 60 * 1000) + 1)/30; - - if(tmpMonths == 1) return ('1 Month'); else return(tmpMonths.toFixed(1) + ' Months'); - - } - - }; - - 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", or "month" format - -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 vNumUnits = 0; - - var pWidth = 1024; // added by JLR - - var pHeight = 768; // added by JLR - - - - var gr = new Graphics('rightside'); - - var vTaskList = new Array(); - - - var month=new Array(12); - - month[0]="January"; - - month[1]="February"; - - month[2]="March"; - - month[3]="April"; - - month[4]="May"; - - month[5]="June"; - - month[6]="July"; - - month[7]="August"; - - month[8]="September"; - - month[9]="October"; - - month[10]="November"; - - month[11]="December"; - - - this.setShowRes = function(pShow) { vShowRes = pShow; }; - - this.setShowDur = function(pShow) { vShowDur = pShow; }; - - this.setShowComp = function(pShow) { vShowComp = pShow; }; - - this.setFormat = function(pFormat){ - vFormat = pFormat; - - this.Draw(); - }; - - - - this.getShowRes = function(){ return vShowRes }; - - this.getShowDur = function(){ return vShowDur }; - - this.getShowComp = function(){ return vShowComp }; - - - 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.getGraphics = function() {return gr;}; - - - - this.drawDependency =function(x1,y1,x2,y2) - - { - - var gr = this.getGraphics(); - - gr.penColor = "red"; - - if(x1 < x2) - - { - - gr.drawLine(x1,y1,x1+5,y1); - - gr.drawLine(x1+5,y1,x1+5,y2); - - gr.drawLine(x1+5,y2,x2,y2); - - } - - else - - { - - var Xpoints = new Array(x1,x1+5, x1+5, x2-5, x2-5,x2); - - var Ypoints = new Array(y1,y1, y2-5, y2-5, y2,y2); - - gr.drawLine(x1,y1,x1+5,y1); - - gr.drawLine(x1+5,y1,x1+5,y2-10); - - gr.drawLine(x1+5,y2-10,x2-5,y2-10); - - gr.drawLine(x2-5,y2-10,x2-5,y2); - - gr.drawLine(x2-5,y2,x2,y2); - - } - - } - - - - - - this.DrawDependencies = function () - { - - //First recalculate the x,y - - this.CalcTaskXY(); - - - - var gr = this.getGraphics(); - - gr.clear(); - - - - var vList = this.getList(); - - - - for(var i = 0; i < vList.length; i++) - - { - - //if(!isNaN(vList[i].getDepend()) && document.getElementById("childgrid_"+vList[i].getID()).style.display=='') - if(!isNaN(vList[i].getDepend()) && vList[i].getVisible()==1) - - { - - var ii = this.getArrayLocationByID(vList[i].getDepend()); - - //if(document.getElementById("childgrid_"+vList[ii].getID()).style.display=='') - if(vList[ii].getVisible()==1) - - { - - this.drawDependency(vList[ii].getEndX(),vList[ii].getEndY(),vList[i].getStartX(),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 vCurrDate = new Date(); - - var vMaxDate = new Date(); - - var vMinDate = new Date(); - - var vTmpDate = new Date(); - - var vNxtDate = 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 vSpanSet = 0; - - var vColWidth = 0; - - var vColUnit = 0; - - var vChartWidth = 0; - - var vNumDays = 0; - - var vDayWidth = 0; - - var vStr = ""; - - var vNameWidth = 220; - - var vStatusWidth = 70; - - var vLeftWidth = 15 + 220 + 70 + 70 + 70; - - if(vTaskList.length > 0) - - { - - - vCurrDate.setFullYear(vCurrDate.getFullYear(), vCurrDate.getMonth(), vCurrDate.getDate()); - - - - // Process all tasks preset parent date and completion % - - JSGantt.processRows(vTaskList, 0, -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; - - } - - if(vFormat == 'week') { - - vColWidth = 37; - - vColUnit = 7; - - } - - if(vFormat == 'month') { - - vColWidth = 37; - - vColUnit = 30; - - } - - - - - - vNumDays = Math.ceil((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; - - // 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>' ; - - 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>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>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>% Comp.</TD>' ; - - vLeftTable += '</TR>'; - - - for(i = 0; i < vTaskList.length; i++) - - { - - vID = vTaskList[i].getID(); - - if(vTaskList[i].getVisible() == 0) - - vLeftTable += '<TR id=child_' + vID + ' style="display:none">' ; - - else - - vLeftTable += '<TR id=child_' + vID + '>' ; - - - 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: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:bold; FONT-SIZE: 12px;" onclick="JSGantt.folder(' + vID + ','+vGanttVar+');'+vGanttVar+'.DrawDependencies();">+</span><span style="color:#000000"> </SPAN>' ; - - } else { - - vLeftTable += '<span style="color: #000000; font:bold; FONT-SIZE: 12px;">   </span>'; - } - - - - vLeftTable += - - '<span onclick=JSGantt.taskLink("' + vTaskList[i].getLink() + '",1024,768); 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>' ; - - 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"> Powered by <a href=http://www.jsgantt.com>jsGantt</a> Format:'; - - - - if (vFormat=='day') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="day" checked>Day'; - - else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("day",'+vGanttVar+'); VALUE="day">Day'; - - - - if (vFormat=='week') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="week" checked>Week'; - - else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("week",'+vGanttVar+') VALUE="week">Week'; - - - - if (vFormat=='month') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" checked>Month'; - - else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("month",'+vGanttVar+') VALUE="month">Month'; - - - - 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()); - - - - // Major Date Header - - while(Date.parse(vTmpDate) <= Date.parse(vMaxDate)) - - { - - - - vStr = vTmpDate.getFullYear() + ''; - - vStr = vStr.substring(2,4); - - - - if(vFormat == 'day') - - { - - vRightTable += '<td class=gdatehead style="FONT-SIZE: 12px; HEIGHT: 19px;" align=center colspan=7>' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + ' - '; - - vTmpDate.setDate(vTmpDate.getDate()+6); - - vRightTable += (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '/' + vStr + '</td>'; - - vTmpDate.setDate(vTmpDate.getDate()+1); - - - - } - - 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); - - } - - 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); - - } - - } - - - - } - - - - - - 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 == 'day') - - { - - - - 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=#cfcfcf 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=#cfcfcf 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;" align=center><div style="width: '+vColWidth+'px">' + vTmpDate.getDate() + '</div></td>'; - - 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); - - - - } - - - - if(vFormat == 'week') - - { - - - - vNxtDate.setDate(vNxtDate.getDate() + 7); - - if(vNxtDate <= vMaxDate) { - - vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" align=center width:'+vColWidth+'px><div style="width: '+vColWidth+'px">' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '</div></td>'; - - 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;" align=center width:'+vColWidth+'px><div style="width: '+vColWidth+'px">' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '</div></td>'; - - 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); - - - - } - - - - if(vFormat == 'month') - - { - - - - vNxtDate.setDate(vNxtDate.getDate() + 31); - - if(vNxtDate <= vMaxDate) { - - vDateRowStr += '<td class="ghead" style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; HEIGHT: 19px; BORDER-LEFT: #efefef 1px solid;" align=center width:'+vColWidth+'px><div style="width: '+vColWidth+'px">' + month[vTmpDate.getMonth()].substr(0,3) + '</div></td>'; - - 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;" align=center width:'+vColWidth+'px><div style="width: '+vColWidth+'px">' + month[vTmpDate.getMonth()].substr(0,3) + '</div></td>'; - - 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); - - } - - - - } - - - - } - - - - - - - - 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; - - - - vSpanSet = 0; - - - - if(vTaskList[i].getVisible() == 0) - - vRightTable += '<DIV id=childgrid_' + vID + ' style="position:relative; display:none;">'; - - else - - vRightTable += '<DIV id=childgrid_' + vID + ' style="position:relative">'; - - - - vRightTable += '<DIV><TABLE style="position:relative; top:0px; width: ' + vChartWidth + 'px;" cellSpacing=0 cellPadding=0 border=0><TR class=yesdisplay style="HEIGHT: 20px">' + vItemRowStr + '</TR></TABLE></DIV>'; - - - - if( vTaskList[i].getMile()) { - - - - // Build date string for Title - - vStr = vTaskStart.getFullYear() + ''; - - vStr = vStr.substring(2,4); - - vDateRowStr = vTaskStart.getMonth() + '/' + vTaskStart.getDate() + '/' + vStr; - - - - 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: 16px; width:12px; overflow:hidden;">' + +/** +* JSGantt component is a UI control that displays gantt charts based by using CSS and HTML +* @module jsgantt +* @title JSGantt +*/ - '<div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr + '" style="height: 16px; width:12px; overflow:hidden; cursor: pointer;" onclick=JSGantt.taskLink("' + vTaskList[i].getLink() + '",1024,768);>'; +var JSGantt; if (!JSGantt) JSGantt = {}; +var vTimeout = 0; +var vBenchTime = new Date().getTime(); +/** +* Creates a task (one row) in gantt object +* @class TaskItem +* @namespace JSGantt +* @constructor +* @for JSGantt + +* @param pID {Number} Task unique numeric ID +* @param pName {String} Task Name +* @param pStart {Date} Task start date/time (not required for pGroup=1 ) +* @param pEnd {Date} Task end date/time, you can set the end time to 12:00 to indicate half-day (not required for pGroup=1 ) +* @param pColor {String} Task bar RGB value +* @param pLink {String} Task URL, clicking on the task will redirect to this url. Leave empty if you do not with the Task also serve as a link +* @param pMile {Boolean} Determines whether task is a milestone (1=Yes,0=No) +* @param pRes {String} Resource to perform the task +* @param pComp {Number} Percent complete (Number between 0 and 100) +* @param pGroup {Boolean} +* @param pParent {Number} ID of the parent task +* @param pOpen {Boolean} +* @param pDepend {String} Comma seperated list of IDs this task depends on +* @param pCaption {String} Caption to be used instead of default caption (Resource). +* note : you should use setCaption("Caption") in order to display the caption +* @return void +*/ +JSGantt.TaskItem = function(pID, pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption) +{ - if(vTaskList[i].getCompVal() < 100) +/** +* The name of the attribute. +* @property vID +* @type String +* @default pID +* @private +*/ +var vID = pID; + +/** +* @property vName +* @type String +* @default pName +* @private +*/ +var vName = pName; + +/** +* @property vStart +* @type Datetime +* @default new Date() +* @private +*/ +var vStart = new Date(); + +/** +* @property vEnd +* @type Datetime +* @default new Date() +* @private +*/ +var vEnd = new Date(); + +/** +* @property vColor +* @type String +* @default pColor +* @private +*/ +var vColor = pColor; + +/** +* @property vLink +* @type String +* @default pLink +* @private +*/ +var vLink = pLink; + +/** +* @property vMile +* @type Boolean +* @default pMile +* @private +*/ +var vMile = pMile; + +/** +* @property vRes +* @type String +* @default pRes +* @private +*/ +var vRes = pRes; + +/** +* @property vComp +* @type Number +* @default pComp +* @private +*/ +var vComp = pComp; + +/** +* @property vGroup +* @type Boolean +* @default pGroup +* @private +*/ +var vGroup = pGroup; + +/** +* @property vParent +* @type Number +* @default pParent +* @private +*/ +var vParent = pParent; + +/** +* @property vOpen +* @type Boolean +* @default pOpen +* @private +*/ +var vOpen = pOpen; + +/** +* @property vDepend +* @type String +* @default pDepend +* @private +*/ +var vDepend = pDepend; + +/** +* @property vCaption +* @type String +* @default pCaption +* @private +*/ +var vCaption = pCaption; + +/** +* @property vDuration +* @type Number +* @default '' +* @private +*/ +var vDuration = ''; + +/** +* @property vLevel +* @type Number +* @default 0 +* @private +*/ +var vLevel = 0; + +/** +* @property vNumKid +* @type Number +* @default 0 +* @private +*/ +var vNumKid = 0; + +/** +* @property vVisible +* @type Boolean +* @default 0 +* @private +*/ +var vVisible = 1; + var x1, y1, x2, y2; - vRightTable += '◊</div></div>' ; + if (vGroup != 1) + { + vStart = JSGantt.parseDateStr(pStart,g.getDateInputFormat()); + vEnd = JSGantt.parseDateStr(pEnd,g.getDateInputFormat()); + } +/** +* Returns task ID +* @method getID +* @return {Number} +*/ + this.getID = function(){ return vID }; +/** +* Returns task name +* @method getName +* @return {String} +*/ + this.getName = function(){ return vName }; +/** +* Returns task start date +* @method getStart +* @return {Datetime} +*/ + this.getStart = function(){ return vStart}; +/** +* Returns task end date +* @method getEnd +* @return {Datetime} +*/ this.getEnd = function(){ return vEnd }; + +/** +* Returns task bar color (i.e. 00FF00) +* @method getColor +* @return {String} +*/ this.getColor = function(){ return vColor}; + +/** +* Returns task URL (i.e. http://www.jsgantt.com) +* @method getLink +* @return {String} +*/ this.getLink = function(){ return vLink }; + +/** +* Returns whether task is a milestone (1=Yes,0=No) +* @method getMile +* @return {Boolean} +*/ this.getMile = function(){ return vMile }; + +/** +* Returns task dependencies as list of values (i.e. 123,122) +* @method getDepend +* @return {String} +*/ this.getDepend = function(){ if(vDepend) return vDepend; else return null }; + +/** +* Returns task caption (if it exists) +* @method getCaption +* @return {String} +*/ this.getCaption = function(){ if(vCaption) return vCaption; else return ''; }; + +/** +* Returns task resource name as string +* @method getResource +* @return {String} +*/ this.getResource = function(){ if(vRes) return vRes; else return ' '; }; + +/** +* Returns task completion percent as numeric value +* @method getCompVal +* @return {Boolean} +*/ this.getCompVal = function(){ if(vComp) return vComp; else return 0; }; + +/** +* Returns task completion percent as formatted string (##%) +* @method getCompStr +* @return {String} +*/ this.getCompStr = function(){ if(vComp) return vComp+'%'; else return ''; }; + +/** +* Returns task duration as a fortmatted string based on the current selected format +* @method getDuration +* @param vFormat {String} selected format (minute,hour,day,week,month) +* @return {String} +*/ 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'; + } - vRightTable += '♦</div></div>' ; - - - - } else { - - - - // Build date string for Title - - vStr = vTaskStart.getFullYear() + ''; - - vStr = vStr.substring(2,4); - - vDateRowStr = vTaskStart.getMonth() + '/' + vTaskStart.getDate() + '/' + vStr; - - vStr = vTaskEnd.getFullYear() + ''; - - vStr = vStr.substring(2,4); - - - vDateRowStr += ' - ' + vTaskEnd.getMonth() + '/' + vTaskEnd.getDate() + '/' + vStr; - - - - vTaskLeft = (Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / (24 * 60 * 60 * 1000); - - vTaskRight = (Date.parse(vTaskList[i].getEnd()) - Date.parse(vTaskList[i].getStart())) / (24 * 60 * 60 * 1000) + 1/vColUnit; + //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 ) + }; +/** +* Returns task parent ID +* @method getParent +* @return {Number} +*/ this.getParent = function(){ return vParent }; + +/** +* Returns whether task is a group (1=Yes,0=No) +* @method getGroup +* @return {Number} +*/ this.getGroup = function(){ return vGroup }; + +/** +* Returns whether task is open (1=Yes,0=No) +* @method getOpen +* @return {Boolean} +*/ this.getOpen = function(){ return vOpen }; + +/** +* Returns task tree level (0,1,2,3...) +* @method getLevel +* @return {Boolean} +*/ this.getLevel = function(){ return vLevel }; + +/** +* Returns the number of child tasks +* @method getNumKids +* @return {Number} +*/ this.getNumKids = function(){ return vNumKid }; + /** +* Returns the X position of the left side of the task bar on the graph (right side) +* @method getStartX +* @return {Number} +*/ this.getStartX = function(){ return x1 }; + +/** +* Returns the Y position of the top of the task bar on the graph (right side) +* @method getStartY +* @return {Number} +*/ this.getStartY = function(){ return y1 }; + +/** +* Returns the X position of the right of the task bar on the graph (right side) +* @method getEndX +* @return {Int} +*/ this.getEndX = function(){ return x2 }; + +/** +* Returns the Y position of the bottom of the task bar on the graph (right side) +* @method getEndY +* @return {Number} +*/ this.getEndY = function(){ return y2 }; + +/** +* Returns whether task is visible (1=Yes,0=No) +* @method getVisible +* @return {Boolean} +*/ this.getVisible = function(){ return vVisible }; + +/** +* Set task dependencies +* @method setDepend +* @param pDepend {String} A comma delimited list of task IDs the current task depends on. +* @return {void} +*/ this.setDepend = function(pDepend){ vDepend = pDepend;}; + +/** +* Set task start date/time +* @method setStart +* @param pStart {Datetime} +* @return {void} +*/ this.setStart = function(pStart){ vStart = pStart;}; + +/** +* Set task end date/time +* @method setEnd +* @param pEnd {Datetime} +* @return {void} +*/ this.setEnd = function(pEnd) { vEnd = pEnd; }; + +/** +* Set task tree level (0,1,2,3...) +* @method setLevel +* @param pLevel {Number} +* @return {void} +*/ this.setLevel = function(pLevel){ vLevel = pLevel;}; + +/** +* Set Number of children for the task +* @method setNumKid +* @param pNumKid {Number} +* @return {void} +*/ this.setNumKid = function(pNumKid){ vNumKid = pNumKid;}; + +/** +* Set task completion percentage +* @method setCompVal +* @param pCompVal {Number} +* @return {void} +*/ this.setCompVal = function(pCompVal){ vComp = pCompVal;}; + +/** +* Set a task bar starting position (left) +* @method setStartX +* @param pX {Number} +* @return {void} +*/ this.setStartX = function(pX) {x1 = pX; }; + +/** +* Set a task bar starting position (top) +* @method setStartY +* @param pY {Number} +* @return {String} +*/ this.setStartY = function(pY) {y1 = pY; }; + +/** +* Set a task bar starting position (right) +* @method setEndX +* @param pX {Number} +* @return {String} +*/ this.setEndX = function(pX) {x2 = pX; }; + +/** +* Set a task bar starting position (bottom) +* @method setEndY +* @param pY {Number} +* @return {String} +*/ this.setEndY = function(pY) {y2 = pY; }; + +/** +* Set task open/closed +* @method setOpen +* @param pOpen {Boolean} +* @return {void} +*/ this.setOpen = function(pOpen) {vOpen = pOpen; }; + +/** +* Set task visibility +* @method setVisible +* @param pVisible {Boolean} +* @return {void} +*/ this.setVisible = function(pVisible) {vVisible = pVisible; }; + + }; + + +/** +* Creates the gant chart. for example: + +<p>var g = new JSGantt.GanttChart('g',document.getElementById('GanttChartDIV'), 'day');</p> + +var g = new JSGantt.GanttChart( - assign the gantt chart to a javascript variable called 'g' +'g' - the name of the variable that was just assigned (will be used later so that gantt object can reference itself) +document.getElementById('GanttChartDIV') - reference to the DIV that will hold the gantt chart +'day' - default format will be by day +* +* @class GanttChart +* @param pGanttVar {String} the name of the gantt chart variable +* @param pDiv {String} reference to the DIV that will hold the gantt chart +* @param pFormat {String} default format (minute,hour,day,week,month,quarter) +* @return void +*/ - // Draw Group Bar which has outer div with inner group div and several small divs to left and right to create angled-end indicators +JSGantt.GanttChart = function(pGanttVar, pDiv, pFormat) +{ +/** +* The name of the gantt chart variable +* @property vGanttVar +* @type String +* @default pGanttVar +* @private +*/ var vGanttVar = pGanttVar; +/** +* The name of the gantt chart DIV +* @property vDiv +* @type String +* @default pDiv +* @private +*/ var vDiv = pDiv; +/** +* Selected format (minute,hour,day,week,month) +* @property vFormat +* @type String +* @default pFormat +* @private +*/ var vFormat = pFormat; +/** +* Show resource column +* @property vShowRes +* @type Number +* @default 1 +* @private +*/ var vShowRes = 1; +/** +* Show duration column +* @property vShowDur +* @type Number +* @default 1 +* @private +*/ var vShowDur = 1; +/** +* Show percent complete column +* @property vShowComp +* @type Number +* @default 1 +* @private +*/ var vShowComp = 1; +/** +* Show start date column +* @property vShowStartDate +* @type Number +* @default 1 +* @private +*/ var vShowStartDate = 1; +/** +* Show end date column +* @property vShowEndDate +* @type Number +* @default 1 +* @private +*/ var vShowEndDate = 1; +/** +* Date input format +* @property vDateInputFormat +* @type String +* @default "mm/dd/yyyy" +* @private +*/var vDateInputFormat = "mm/dd/yyyy"; +/** +* Date display format +* @property vDateDisplayFormat +* @type String +* @default "mm/dd/yy" +* @private +*/var vDateDisplayFormat = "mm/dd/yy"; + + 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"); +/** +* Set current display format (minute/hour/day/week/month/quarter) +* Only the first 4 arguments are used, for example: +* <code> +* g.setFormatArr("day","week","month"); +* </code> +* will show 3 formatting options (day/week/month) at the bottom right of the gantt chart +* @method setFormatArr +* @return {void} +*/ 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;} + }; +/** +* Show/Hide resource column +* @param pShow {Number} 1=Show,0=Hide +* @method setShowRes +* @return {void} +*/ this.setShowRes = function(pShow) { vShowRes = pShow; }; +/** +* Show/Hide duration column +* @param pShow {Number} 1=Show,0=Hide +* @method setShowDur +* @return {void} +*/ this.setShowDur = function(pShow) { vShowDur = pShow; }; +/** +* Show/Hide completed column +* @param pShow {Number} 1=Show,0=Hide +* @method setShowComp +* @return {void} +*/ this.setShowComp = function(pShow) { vShowComp = pShow; }; +/** +* Show/Hide start date column +* @param pShow {Number} 1=Show,0=Hide +* @method setShowStartDate +* @return {void} +*/ this.setShowStartDate = function(pShow) { vShowStartDate = pShow; }; +/** +* Show/Hide end date column +* @param pShow {Number} 1=Show,0=Hide +* @method setShowEndDate +* @return {void} +*/ this.setShowEndDate = function(pShow) { vShowEndDate = pShow; }; +/** +* Overall date input format +* @param pShow {String} (mm/dd/yyyy,dd/mm/yyyy,yyyy-mm-dd) +* @method setDateInputFormat +* @return {void} +*/ this.setDateInputFormat = function(pShow) { vDateInputFormat = pShow; }; +/** +* Overall date display format +* @param pShow {String} (mm/dd/yyyy,dd/mm/yyyy,yyyy-mm-dd) +* @method setDateDisplayFormat +* @return {void} +*/ this.setDateDisplayFormat = function(pShow) { vDateDisplayFormat = pShow; }; +/** +* Set gantt caption +* @param pType {String} +<p>Caption-Displays a custom caption set in TaskItem<br> +Resource-Displays task resource<br> +Duration-Displays task duration<br> +Complete-Displays task percent complete</p> +* @method setCaptionType +* @return {void} +*/ this.setCaptionType = function(pType) { vCaptionType = pType }; +/** +* Set current display format and redraw gantt chart (minute/hour/day/week/month/quarter) +* @param pFormat {String} (mm/dd/yyyy,dd/mm/yyyy,yyyy-mm-dd) +* @method setFormat +* @return {void} +*/ this.setFormat = function(pFormat){ + vFormat = pFormat; + this.Draw(); + }; +/** +* Returns whether resource column is shown +* @method getShowRes +* @return {Number} +*/ this.getShowRes = function(){ return vShowRes }; +/** +* Returns whether duration column is shown +* @method getShowDur +* @return {Number} +*/ this.getShowDur = function(){ return vShowDur }; +/** +* Returns whether percent complete column is shown +* @method getShowComp +* @return {Number} +*/ this.getShowComp = function(){ return vShowComp }; +/** +* Returns whether start date column is shown +* @method getShowStartDate +* @return {Number} +*/ this.getShowStartDate = function(){ return vShowStartDate }; +/** +* Returns whether end date column is shown +* @method getShowEndDate +* @return {Number} +*/ this.getShowEndDate = function(){ return vShowEndDate }; +/** +* Returns date input format +* @method getDateInputFormat +* @return {String} +*/ this.getDateInputFormat = function() { return vDateInputFormat }; +/** +* Returns current display format +* @method getDateDisplayFormat +* @return {String} +*/ this.getDateDisplayFormat = function() { return vDateDisplayFormat }; +/** +* Returns current gantt caption type +* @method getCaptionType +* @return {String} +*/ this.getCaptionType = function() { return vCaptionType }; +/** +* Calculates X/Y coordinates of a task and sets the Start and End properties of the TaskItem +* @method CalcTaskXY +* @return {Void} +*/ this.CalcTaskXY = function () + { + var vList = this.getList(); + var vTaskDiv; + var vParDiv; + var vLeft, vTop, vHeight, vWidth; - if( vTaskList[i].getGroup()) { + 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 ); + }; + }; + }; - vRightTable += +/** +* Adds a TaskItem to the Gantt object task list array +* @method AddTaskItem +* @return {Void} +*/ this.AddTaskItem = function(value) + { + vTaskList.push(value); + }; +/** +* Returns task list Array +* @method getList +* @return {Array} +*/ this.getList = function() { return vTaskList }; + +/** +* Clears dependency lines between tasks +* @method clearDependencies +* @return {Void} +*/ 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; + }; +/** +* Draw a straight line (colored one-pixel wide DIV), need to parameterize doc item +* @method sLine +* @return {Void} +*/ 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); - '<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;">' + +/** +* Draw a diaganol line (calc line x,y pairs and draw multiple one-by-one sLines) +* @method dLine +* @return {Void} +*/ 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; + }; - '<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() + '; ' + +/** +* Draw dependency line between two points (task 1 end -> task 2 start) +* @method drawDependency +* @return {Void} +*/ 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); + } + }; - 'cursor: pointer;" onclick=JSGantt.taskLink("' + vTaskList[i].getLink() + '",1024,768);></div></div>' + +/** +* Draw all task dependencies +* @method DrawDependencies +* @return {Void} +*/ this.DrawDependencies = function () { - '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:4px; overflow: hidden; width:1px;"></div>' + + //First recalculate the x,y + this.CalcTaskXY(); - '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:4px; overflow: hidden; width:1px;"></div>' + + this.clearDependencies(); - '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:3px; overflow: hidden; width:1px;"></div>' + + var vList = this.getList(); + for(var i = 0; i < vList.length; i++) + { - '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:3px; overflow: hidden; width:1px;"></div>' + + vDepend = vList[i].getDepend(); + if(vDepend) { + + var vDependStr = vDepend + ''; + var vDepList = vDependStr.split(','); + var n = vDepList.length; - '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:2px; overflow: hidden; width:1px;"></div>' + + for(var k=0;k<n;k++) { + var vTask = this.getArrayLocationByID(vDepList[k]); - '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:2px; overflow: hidden; width:1px;"></div>' + + if(vList[vTask].getVisible()==1) + this.drawDependency(vList[vTask].getEndX(),vList[vTask].getEndY(),vList[i].getStartX()-1,vList[i].getStartY()) + } + } + } + }; - '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:1px; overflow: hidden; width:1px;"></div>' + +/** +* Find location of TaskItem based on the task ID +* @method getArrayLocationByID +* @return {Void} +*/ this.getArrayLocationByID = function(pId) { - '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:1px; overflow: hidden; width:1px;"></div>' + + var vList = this.getList(); + for(var i = 0; i < vList.length; i++) + { + if(vList[i].getID()==pId) + return i; + } + }; - '</div>' ; +/** +* Draw gantt chart +* @method Draw +* @return {Void} +*/ 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 = 220; + var vStatusWidth = 70; + var vLeftWidth = 15 + 220 + 70 + 70 + 70 + 70 + 70; + 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 = 37; + vColUnit = 7; + } + else if(vFormat == 'month') { + vColWidth = 37; + vColUnit = 30; + } + else if(vFormat == 'quarter') { + vColWidth = 60; + 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>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>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>% 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>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>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(); - // 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; 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;" ' + + 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 + '")>' ; - 'onclick=JSGantt.taskLink("' + vTaskList[i].getLink() + '",1024,768);>' + + 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">'; - '<div class=gcomplete style="Z-INDEX: -4; float:left; background-color:black; height:5px; overflow: auto; margin-top:4px; filter: alpha(opacity=40); opacity:0.4; width:' + vTaskList[i].getCompStr() + '; overflow:hidden"></div></div></div>' ; + 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=JSGantt.taskLink("' + vTaskList[i].getLink() + '",300,200); 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>'; + } - vRightTable += '</DIV>'; + // 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"> Powered by <a href=http://www.jsgantt.com>jsGantt</a> Format:'; + + 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>Day'; + else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("day",'+vGanttVar+'); VALUE="day">Day'; + } + + if (vFormatArr.join().indexOf("week")!=-1) { + if (vFormat=='week') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="week" checked>Week'; + else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("week",'+vGanttVar+') VALUE="week">Week'; + } + + if (vFormatArr.join().indexOf("month")!=-1) { + if (vFormat=='month') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="month" checked>Month'; + else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("month",'+vGanttVar+') VALUE="month">Month'; + } + + if (vFormatArr.join().indexOf("quarter")!=-1) { + if (vFormat=='quarter') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="quarter" checked>Quarter'; + else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("quarter",'+vGanttVar+') VALUE="quarter">Quarter'; + } + +// vLeftTable += '<INPUT TYPE=RADIO NAME="other" VALUE="other" style="display:none"> .'; - } + vLeftTable += '</TD></TR></TBODY></TABLE></TD>'; - vMainTable += vRightTable + '</DIV></TD></TR></TBODY></TABLE></BODY></HTML>'; + 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); - vDiv.innerHTML = vMainTable; + // 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.substring(0,5)) + ' - '; + 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>'; - // Recursively process task tree ... set min, max dates of parent tasks and identfy task level. + } 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>'; -JSGantt.processRows = function(pList, pID, pRow, pLevel) + } - { + vTmpDate.setDate(vTmpDate.getDate() + 7); + } + else if(vFormat == 'month') + { - var vMinDate = new Date(); + 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">' + vMonthArr[vTmpDate.getMonth()].substr(0,3) + '</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">' + vMonthArr[vTmpDate.getMonth()].substr(0,3) + '</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>'; + } - var vMaxDate = new Date(); + vTmpDate.setDate(vTmpDate.getDate() + 1); - var vMinSet = 0; + while(vTmpDate.getDate() > 1) + { + vTmpDate.setDate(vTmpDate.getDate() + 1); + } - var vMaxSet = 0; + } - var vList = pList; + else if(vFormat == 'quarter') + { - var vLevel = pLevel; + 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">Qtr. ' + vQuarterArr[vTmpDate.getMonth()] + '</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">Qtr. ' + vQuarterArr[vTmpDate.getMonth()] + '</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>'; + } - var i = 0; + vTmpDate.setDate(vTmpDate.getDate() + 81); - var vNumKid = 0; + while(vTmpDate.getDate() > 1) + { + vTmpDate.setDate(vTmpDate.getDate() + 1); + } - var vCompSum = 0; + } + } + vRightTable += vDateRowStr + '</TR>'; + vRightTable += '</TBODY></TABLE>'; + // Draw each row - for(i = 0; i < pList.length; i++) + 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>'; - if(pList[i].getParent() == pID) { - - - - pList[i].setLevel(vLevel); - - vNumKid++; - - - - if(pList[i].getGroup() == 1) { - - JSGantt.processRows(vList, pList[i].getID(), i, vLevel+1); + // 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=JSGantt.taskLink("' + vTaskList[i].getLink() + '",300,200);>'; + + 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; width:120px; left:12px">' + vCaptionStr + '</div>'; + }; [... 1246 lines stripped ...] |
Free forum by Nabble | Edit this page |