/* _ ___ _ _ _ ____ (_)___ / _ \__ _ _ __ | |_| |_ / | |___ \ | / __| / /_\/ _` | '_ \| __| __| | | __) | | \__ \/ /_\\ (_| | | | | |_| |_ | |_ / __/ _/ |___/\____/\__,_|_| |_|\__|\__| |_(_)_____| |__/ 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: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Shlomy Gantz or BlueBrick Inc. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY SHLOMY GANTZ/BLUEBRICK INC. ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL SHLOMY GANTZ/BLUEBRICK INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ var JSGantt; if (!JSGantt) JSGantt = {}; 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) { 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 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'; } //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 = "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"); 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 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 = '' + ''; vMainTable += vLeftTable; // Draw the Chart Rows vRightTable = '
'; 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 = '
' + '' + ' ' + ' '; if(vShowRes ==1) vLeftTable += ' ' ; if(vShowDur ==1) vLeftTable += ' ' ; if(vShowComp==1) vLeftTable += ' ' ; if(vShowStartDate==1) vLeftTable += ' ' ; if(vShowEndDate==1) vLeftTable += ' ' ; vLeftTable += '' + ' ' + ' ' ; if(vShowRes ==1) vLeftTable += ' ' ; if(vShowDur ==1) vLeftTable += ' ' ; if(vShowComp==1) vLeftTable += ' ' ; if(vShowStartDate==1) vLeftTable += ' ' ; if(vShowEndDate==1) vLeftTable += ' ' ; vLeftTable += ''; 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 += '' ; else vLeftTable += '' ; vLeftTable += ' ' + ' ' ; if(vShowRes ==1) vLeftTable += ' ' ; if(vShowDur ==1) vLeftTable += ' ' ; if(vShowComp==1) vLeftTable += ' ' ; if(vShowStartDate==1) vLeftTable += ' ' ; if(vShowEndDate==1) vLeftTable += ' ' ; vLeftTable += ''; } // DRAW the date format selector at bottom left. Another potential GanttChart parameter to hide/show this selector vLeftTable += '' + '
ResourceDuration% Comp.Start DateEnd Date
 '; for(j=1; j ' ; else vLeftTable += '+ ' ; } else { vLeftTable += '   '; } vLeftTable += ' ' + vTaskList[i].getName() + '' + vTaskList[i].getResource() + '' + vTaskList[i].getDuration(vFormat) + '' + vTaskList[i].getCompStr() + '' + JSGantt.formatDateStr( vTaskList[i].getStart(), vDateDisplayFormat) + '' + JSGantt.formatDateStr( vTaskList[i].getEnd(), vDateDisplayFormat) + '
  Powered by jsGantt      Format:'; if (vFormatArr.join().indexOf("minute")!=-1) { if (vFormat=='minute') vLeftTable += 'Minute'; else vLeftTable += 'Minute'; } if (vFormatArr.join().indexOf("hour")!=-1) { if (vFormat=='hour') vLeftTable += 'Hour'; else vLeftTable += 'Hour'; } if (vFormatArr.join().indexOf("day")!=-1) { if (vFormat=='day') vLeftTable += 'Day'; else vLeftTable += 'Day'; } if (vFormatArr.join().indexOf("week")!=-1) { if (vFormat=='week') vLeftTable += 'Week'; else vLeftTable += 'Week'; } if (vFormatArr.join().indexOf("month")!=-1) { if (vFormat=='month') vLeftTable += 'Month'; else vLeftTable += 'Month'; } if (vFormatArr.join().indexOf("quarter")!=-1) { if (vFormat=='quarter') vLeftTable += 'Quarter'; else vLeftTable += 'Quarter'; } // vLeftTable += ' .'; vLeftTable += '
' + '
' + '' + ''; 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 += ''; vTmpDate.setHours(vTmpDate.getHours()+1); } if(vFormat == 'hour') { vRightTable += ''; vTmpDate.setDate(vTmpDate.getDate()+1); } if(vFormat == 'day') { vRightTable += ''; vTmpDate.setDate(vTmpDate.getDate()+1); } else if(vFormat == 'week') { vRightTable += ''; vTmpDate.setDate(vTmpDate.getDate()+7); } else if(vFormat == 'month') { vRightTable += ''; vTmpDate.setDate(vTmpDate.getDate() + 1); while(vTmpDate.getDate() > 1) { vTmpDate.setDate(vTmpDate.getDate() + 1); } } else if(vFormat == 'quarter') { vRightTable += ''; vTmpDate.setDate(vTmpDate.getDate() + 81); while(vTmpDate.getDate() > 1) { vTmpDate.setDate(vTmpDate.getDate() + 1); } } } vRightTable += ''; // 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 += ''; vItemRowStr += ''; vTmpDate.setMinutes(vTmpDate.getMinutes() + 1); } else if (vFormat == 'hour') { if( vTmpDate.getHours() ==0 ) vWeekdayColor = "ccccff"; else vWeekdayColor = "ffffff"; vDateRowStr += ''; vItemRowStr += ''; 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 += ''; vItemRowStr += ''; } else { vDateRowStr += ''; if( JSGantt.formatDateStr(vCurrDate,'mm/dd/yyyy') == JSGantt.formatDateStr(vTmpDate,'mm/dd/yyyy')) vItemRowStr += ''; else vItemRowStr += ''; } 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 += ''; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += ''; else vItemRowStr += ''; } else { vDateRowStr += ''; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += ''; else vItemRowStr += ''; } 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 += ''; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += ''; else vItemRowStr += ''; } else { vDateRowStr += ''; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += ''; else vItemRowStr += ''; } 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 += ''; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += ''; else vItemRowStr += ''; } else { vDateRowStr += ''; if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate ) vItemRowStr += ''; else vItemRowStr += ''; } vTmpDate.setDate(vTmpDate.getDate() + 81); while(vTmpDate.getDate() > 1) { vTmpDate.setDate(vTmpDate.getDate() + 1); } } } vRightTable += vDateRowStr + ''; vRightTable += '
' ; vRightTable += JSGantt.formatDateStr(vTmpDate, vDateDisplayFormat) + ' ' + vTmpDate.getHours() + ':00 -' + vTmpDate.getHours() + ':59 ' ; vRightTable += JSGantt.formatDateStr(vTmpDate, vDateDisplayFormat) + '' + JSGantt.formatDateStr(vTmpDate,vDateDisplayFormat.substring(0,5)) + ' - '; vTmpDate.setDate(vTmpDate.getDate()+6); vRightTable += JSGantt.formatDateStr(vTmpDate, vDateDisplayFormat) + '`'+ vStr + '`'+ vStr + '`'+ vStr + '
' + vTmpDate.getMinutes() + '
  
' + vTmpDate.getHours() + '
  
' + vTmpDate.getDate() + '
 
' + vTmpDate.getDate() + '
  
  
' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '
  
  
' + (vTmpDate.getMonth()+1) + '/' + vTmpDate.getDate() + '
  
  
' + vMonthArr[vTmpDate.getMonth()].substr(0,3) + '
  
  
' + vMonthArr[vTmpDate.getMonth()].substr(0,3) + '
  
  
Qtr. ' + vQuarterArr[vTmpDate.getMonth()] + '
  
  
Qtr. ' + vQuarterArr[vTmpDate.getMonth()] + '
  
  
'; // 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 += ''; } vMainTable += vRightTable + '
'; 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 ); } } 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/gi); var n = ta.length; // the number of tasks. for(var i=1;i/i) if(te.length> 2){var pID=te[1];} else {var pID = 0;} pID *= 1; var te = Task.split(//i) if(te.length> 2){var pName=te[1];} else {var pName = "No Task Name";} var te = Task.split(//i) if(te.length> 2){var pStart=te[1];} else {var pStart = "";} var te = Task.split(//i) if(te.length> 2){var pEnd=te[1];} else {var pEnd = "";} var te = Task.split(//i) if(te.length> 2){var pColor=te[1];} else {var pColor = '0000ff';} var te = Task.split(//i) if(te.length> 2){var pLink=te[1];} else {var pLink = "";} var te = Task.split(//i) if(te.length> 2){var pMile=te[1];} else {var pMile = 0;} pMile *= 1; var te = Task.split(//i) if(te.length> 2){var pRes=te[1];} else {var pRes = "";} var te = Task.split(//i) if(te.length> 2){var pComp=te[1];} else {var pComp = 0;} pComp *= 1; var te = Task.split(//i) if(te.length> 2){var pGroup=te[1];} else {var pGroup = 0;} pGroup *= 1; var te = Task.split(//i) if(te.length> 2){var pParent=te[1];} else {var pParent = 0;} pParent *= 1; var te = Task.split(//i) if(te.length> 2){var pOpen=te[1];} else {var pOpen = 1;} pOpen *= 1; var te = Task.split(//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(//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(); }