|
@@ -1,2315 +1,2575 @@
|
|
|
/*
|
|
|
-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.
|
|
|
-*
|
|
|
-*
|
|
|
-* LDR Modified to replace hard coded values by i18[key]
|
|
|
-*/
|
|
|
-
|
|
|
-/**
|
|
|
-* JSGantt component is a UI control that displays gantt charts based by using CSS and HTML
|
|
|
-* @module jsgantt
|
|
|
-* @title JSGantt
|
|
|
-*/
|
|
|
-
|
|
|
-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)
|
|
|
+ _ ___ _____ _ _____ ____ ____
|
|
|
+ (_) / _ \ \_ \ / ||___ | ___| |___ \
|
|
|
+ | |/ /_\/ / /\/ | | / /|___ \ __) |
|
|
|
+ | / /_\\/\/ /_ | |_ / /_ ___) | / __/
|
|
|
+ _/ \____/\____/ |_(_)_/(_)____(_)_____|
|
|
|
+ |__/
|
|
|
+ jsGanttImproved 1.7.5.2
|
|
|
+ Copyright (c) 2013-2016, Paul Geldart All rights reserved.
|
|
|
+
|
|
|
+ The current version of this code can be found at https://code.google.com/p/jsgantt-improved/
|
|
|
+
|
|
|
+ * Copyright (c) 2013-2016, Paul Geldart.
|
|
|
+ * 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 Paul Geldart 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 PAUL GELDART. ''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 PAUL GELDART 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.
|
|
|
+
|
|
|
+ This project is based on jsGantt 1.2, (which can be obtained from
|
|
|
+ https://code.google.com/p/jsgantt/) and remains under the original BSD license.
|
|
|
+ The original project license follows:
|
|
|
+
|
|
|
+ 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 vBenchTime=new Date().getTime();
|
|
|
+
|
|
|
+JSGantt.isIE=function ()
|
|
|
{
|
|
|
-
|
|
|
-/**
|
|
|
-* 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;
|
|
|
-
|
|
|
-
|
|
|
- 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 '+i18n["sHour"];
|
|
|
- else
|
|
|
- vDuration = tmpPer + ' '+i18n["sHours"];
|
|
|
- }
|
|
|
-
|
|
|
- else if (vFormat=='minute')
|
|
|
- {
|
|
|
- tmpPer = Math.ceil((this.getEnd() - this.getStart()) / ( 60 * 1000) );
|
|
|
- if(tmpPer == 1)
|
|
|
- vDuration = '1 '+i18n["sMinute"];
|
|
|
- else
|
|
|
- vDuration = tmpPer + ' '+i18n["sMinutes"];
|
|
|
- }
|
|
|
-
|
|
|
- else { //if(vFormat == 'day') {
|
|
|
- tmpPer = Math.ceil((this.getEnd() - this.getStart()) / (24 * 60 * 60 * 1000) + 1);
|
|
|
- if(tmpPer == 1) vDuration = '1 '+i18n["sDay"];
|
|
|
- else vDuration = tmpPer + ' '+i18n["sDays"];
|
|
|
- }
|
|
|
-
|
|
|
- //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; };
|
|
|
-
|
|
|
+ if(typeof document.all!='undefined')
|
|
|
+ {
|
|
|
+ if ('pageXOffset' in window) return false; // give IE9 and above the benefit of the doubt!
|
|
|
+ else return true;
|
|
|
+ }
|
|
|
+ else return false;
|
|
|
};
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
-* 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
|
|
|
-*/
|
|
|
-
|
|
|
-JSGantt.GanttChart = function(pGanttVar, pDiv, pFormat)
|
|
|
+
|
|
|
+JSGantt.TaskItem=function(pID, pName, pStart, pEnd, pClass, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption, pNotes, pGantt)
|
|
|
{
|
|
|
-/**
|
|
|
-* 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(i18n["January"],i18n["February"],i18n["March"],i18n["April"],i18n["May"],i18n["June"],i18n["July"],i18n["August"],i18n["September"],i18n["October"],i18n["November"],i18n["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;
|
|
|
-
|
|
|
- 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 );
|
|
|
- };
|
|
|
- };
|
|
|
- };
|
|
|
-
|
|
|
-/**
|
|
|
-* 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);
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
-/**
|
|
|
-* 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;
|
|
|
- };
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
-/**
|
|
|
-* 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);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
-/**
|
|
|
-* Draw all task dependencies
|
|
|
-* @method DrawDependencies
|
|
|
-* @return {Void}
|
|
|
-*/ this.DrawDependencies = function () {
|
|
|
-
|
|
|
- //First recalculate the x,y
|
|
|
- this.CalcTaskXY();
|
|
|
-
|
|
|
- this.clearDependencies();
|
|
|
-
|
|
|
- var vList = this.getList();
|
|
|
- for(var i = 0; i < vList.length; i++)
|
|
|
- {
|
|
|
-
|
|
|
- vDepend = vList[i].getDepend();
|
|
|
- if(vDepend) {
|
|
|
-
|
|
|
- var vDependStr = vDepend + '';
|
|
|
- var vDepList = vDependStr.split(',');
|
|
|
- var n = vDepList.length;
|
|
|
-
|
|
|
- for(var k=0;k<n;k++) {
|
|
|
- var vTask = this.getArrayLocationByID(vDepList[k]);
|
|
|
-
|
|
|
- if(vList[vTask].getVisible()==1)
|
|
|
- this.drawDependency(vList[vTask].getEndX(),vList[vTask].getEndY(),vList[i].getStartX()-1,vList[i].getStartY())
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
-/**
|
|
|
-* Find location of TaskItem based on the task ID
|
|
|
-* @method getArrayLocationByID
|
|
|
-* @return {Void}
|
|
|
-*/ this.getArrayLocationByID = function(pId) {
|
|
|
-
|
|
|
- var vList = this.getList();
|
|
|
- for(var i = 0; i < vList.length; i++)
|
|
|
- {
|
|
|
- if(vList[i].getID()==pId)
|
|
|
- return i;
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
-/**
|
|
|
-* 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>'+i18n["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>'+i18n["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>%</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>'+i18n["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>'+i18n["End_Date"]+'</TD>' ;
|
|
|
-
|
|
|
- vLeftTable += '</TR>';
|
|
|
-
|
|
|
- for(i = 0; i < vTaskList.length; i++)
|
|
|
- {
|
|
|
- if( vTaskList[i].getGroup()) {
|
|
|
- vBGColor = "f3f3f3";
|
|
|
- vRowType = "group";
|
|
|
- } else {
|
|
|
- vBGColor = "ffffff";
|
|
|
- vRowType = "row";
|
|
|
- }
|
|
|
-
|
|
|
- vID = vTaskList[i].getID();
|
|
|
-
|
|
|
- if(vTaskList[i].getVisible() == 0)
|
|
|
- vLeftTable += '<TR id=child_' + vID + ' bgcolor=#' + vBGColor + ' style="display:none" onMouseover=g.mouseOver(this,' + vID + ',"left","' + vRowType + '") onMouseout=g.mouseOut(this,' + vID + ',"left","' + vRowType + '")>' ;
|
|
|
- else
|
|
|
- vLeftTable += '<TR id=child_' + vID + ' bgcolor=#' + vBGColor + ' onMouseover=g.mouseOver(this,' + vID + ',"left","' + vRowType + '") onMouseout=g.mouseOut(this,' + vID + ',"left","' + vRowType + '")>' ;
|
|
|
-
|
|
|
- vLeftTable +=
|
|
|
- ' <TD class=gdatehead style="WIDTH: 15px; HEIGHT: 20px; BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px; BORDER-LEFT: #efefef 1px solid;"> </TD>' +
|
|
|
- ' <TD class=gname style="WIDTH: ' + vNameWidth + 'px; HEIGHT: 20px; BORDER-TOP: #efefef 1px solid; FONT-SIZE: 12px;" nowrap><NOBR><span style="color: #aaaaaa">';
|
|
|
-
|
|
|
- for(j=1; j<vTaskList[i].getLevel(); j++) {
|
|
|
- vLeftTable += '    ';
|
|
|
- }
|
|
|
-
|
|
|
- vLeftTable += '</span>';
|
|
|
-
|
|
|
- if( vTaskList[i].getGroup()) {
|
|
|
- if( vTaskList[i].getOpen() == 1)
|
|
|
- vLeftTable += '<SPAN id="group_' + vID + '" style="color:#000000; cursor:pointer; font-weight:bold; FONT-SIZE: 12px;" onclick="JSGantt.folder(' + vID + ','+vGanttVar+');'+vGanttVar+'.DrawDependencies();">–</span><span style="color:#000000"> </SPAN>' ;
|
|
|
- else
|
|
|
- vLeftTable += '<SPAN id="group_' + vID + '" style="color:#000000; cursor:pointer; font-weight:bold; FONT-SIZE: 12px;" onclick="JSGantt.folder(' + vID + ','+vGanttVar+');'+vGanttVar+'.DrawDependencies();">+</span><span style="color:#000000"> </SPAN>' ;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- vLeftTable += '<span style="color: #000000; font-weight:bold; FONT-SIZE: 12px;">   </span>';
|
|
|
- }
|
|
|
-
|
|
|
- vLeftTable +=
|
|
|
- '<span onclick=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].getStart() > 0 ? 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>' + (vTaskList[i].getStart() > 0 ? 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>' + (vTaskList[i].getEnd() > 0 ? JSGantt.formatDateStr( vTaskList[i].getEnd(), vDateDisplayFormat) : '') + '</NOBR></TD>' ;
|
|
|
-
|
|
|
- vLeftTable += '</TR>';
|
|
|
|
|
|
- }
|
|
|
+ var vID=parseInt(document.createTextNode(pID).data);
|
|
|
+ var vName=document.createTextNode(pName).data;
|
|
|
+ var vStart=new Date(0);
|
|
|
+ var vEnd=new Date(0);
|
|
|
+ var vGroupMinStart=null;
|
|
|
+ var vGroupMinEnd=null;
|
|
|
+ var vClass=document.createTextNode(pClass).data;
|
|
|
+ var vLink=document.createTextNode(pLink).data;
|
|
|
+ var vMile=parseInt(document.createTextNode(pMile).data);
|
|
|
+ var vRes=document.createTextNode(pRes).data;
|
|
|
+ var vComp=parseFloat(document.createTextNode(pComp).data);
|
|
|
+ var vGroup=parseInt(document.createTextNode(pGroup).data);
|
|
|
+ var vParent=document.createTextNode(pParent).data;
|
|
|
+ var vOpen=(vGroup==2)?1:parseInt(document.createTextNode(pOpen).data);
|
|
|
+ var vDepend=new Array();
|
|
|
+ var vDependType=new Array();
|
|
|
+ var vCaption=document.createTextNode(pCaption).data;
|
|
|
+ var vDuration='';
|
|
|
+ var vLevel=0;
|
|
|
+ var vNumKid=0;
|
|
|
+ var vVisible=1;
|
|
|
+ var vSortIdx=0;
|
|
|
+ var vToDelete=false;
|
|
|
+ var x1, y1, x2, y2;
|
|
|
+ var vNotes;
|
|
|
+ var vParItem=null;
|
|
|
+ var vCellDiv=null;
|
|
|
+ var vGantt=(pGantt instanceof JSGantt.GanttChart)? pGantt : g; //hack for backwards compatibility
|
|
|
+ var vBarDiv=null;
|
|
|
+ var vTaskDiv=null;
|
|
|
+ var vListChildRow=null;
|
|
|
+ var vChildRow=null;
|
|
|
+ var vGroupSpan=null;
|
|
|
+
|
|
|
+ vNotes=document.createElement('span');
|
|
|
+ vNotes.className='gTaskNotes';
|
|
|
+ if (pNotes!=null)
|
|
|
+ {
|
|
|
+ vNotes.innerHTML=pNotes;
|
|
|
+ JSGantt.stripUnwanted(vNotes);
|
|
|
+ }
|
|
|
|
|
|
- // DRAW the date format selector at bottom left. Another potential GanttChart parameter to hide/show this selector
|
|
|
- vLeftTable += '</TD></TR>' +
|
|
|
- // LDR '<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:';
|
|
|
- '<TR><TD border=1 colspan=5 align=left style="BORDER-TOP: #efefef 1px solid; FONT-SIZE: 11px; BORDER-LEFT: #efefef 1px solid; height=18px"> '+i18n["Period"]+': ';
|
|
|
-
|
|
|
- if (vFormatArr.join().indexOf("minute")!=-1) {
|
|
|
- if (vFormat=='minute') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="minute" checked>'+i18n["sMinute"];
|
|
|
- else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("minute",'+vGanttVar+'); VALUE="minute">'+i18n["sMinute"];
|
|
|
- }
|
|
|
-
|
|
|
- if (vFormatArr.join().indexOf("hour")!=-1) {
|
|
|
- if (vFormat=='hour') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="hour" checked>'+i18n["sHour"];
|
|
|
- else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("hour",'+vGanttVar+'); VALUE="hour">'+i18n["sHour"];
|
|
|
- }
|
|
|
-
|
|
|
- if (vFormatArr.join().indexOf("day")!=-1) {
|
|
|
- if (vFormat=='day') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="day" checked>'+i18n["sDay"];
|
|
|
- else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("day",'+vGanttVar+'); VALUE="day">'+i18n["sDay"];
|
|
|
- }
|
|
|
-
|
|
|
- if (vFormatArr.join().indexOf("week")!=-1) {
|
|
|
- if (vFormat=='week') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="week" checked>'+i18n["sWeek"];
|
|
|
- else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("week",'+vGanttVar+') VALUE="week">'+i18n["sWeek"];
|
|
|
- }
|
|
|
-
|
|
|
- if (vFormatArr.join().indexOf("month")!=-1) {
|
|
|
- if (vFormat=='month') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="month" checked>'+i18n["sMonth"];
|
|
|
- else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("month",'+vGanttVar+') VALUE="month">'+i18n["sMonth"];
|
|
|
- }
|
|
|
-
|
|
|
- if (vFormatArr.join().indexOf("quarter")!=-1) {
|
|
|
- if (vFormat=='quarter') vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" VALUE="quarter" checked>'+i18n["sQuarter"];
|
|
|
- else vLeftTable += '<INPUT TYPE=RADIO NAME="radFormat" onclick=JSGantt.changeFormat("quarter",'+vGanttVar+') VALUE="quarter">'+i18n["sQuarter"];
|
|
|
- }
|
|
|
-
|
|
|
-// vLeftTable += '<INPUT TYPE=RADIO NAME="other" VALUE="other" style="display:none"> .';
|
|
|
-
|
|
|
- vLeftTable += '</TD></TR></TBODY></TABLE></TD>';
|
|
|
-
|
|
|
- vMainTable += vLeftTable;
|
|
|
+ if (pStart!=null && pStart!='')
|
|
|
+ {
|
|
|
+ vStart=(pStart instanceof Date)?pStart:JSGantt.parseDateStr(document.createTextNode(pStart).data,vGantt.getDateInputFormat());
|
|
|
+ vGroupMinStart=vStart;
|
|
|
+ }
|
|
|
|
|
|
- // 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">';
|
|
|
+ if (pEnd!=null && pEnd!='')
|
|
|
+ {
|
|
|
+ vEnd =(pEnd instanceof Date)?pEnd:JSGantt.parseDateStr(document.createTextNode(pEnd).data,vGantt.getDateInputFormat());
|
|
|
+ vGroupMinEnd=vEnd;
|
|
|
+ }
|
|
|
|
|
|
- vTmpDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate());
|
|
|
- vTmpDate.setHours(0);
|
|
|
- vTmpDate.setMinutes(0);
|
|
|
+ if (pDepend!=null)
|
|
|
+ {
|
|
|
+ var vDependStr=pDepend+'';
|
|
|
+ var vDepList=vDependStr.split(',');
|
|
|
+ var n=vDepList.length;
|
|
|
|
|
|
- // Major Date Header
|
|
|
- while(Date.parse(vTmpDate) <= Date.parse(vMaxDate))
|
|
|
- {
|
|
|
- vStr = vTmpDate.getFullYear() + '';
|
|
|
- vStr = vStr.substring(2,4);
|
|
|
-
|
|
|
-
|
|
|
- if(vFormat == 'minute')
|
|
|
+ for(var k=0;k<n;k++)
|
|
|
+ {
|
|
|
+ if(vDepList[k].toUpperCase().indexOf('SS')!=-1)
|
|
|
{
|
|
|
- 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);
|
|
|
+ vDepend[k]=vDepList[k].substring(0,vDepList[k].toUpperCase().indexOf('SS'));
|
|
|
+ vDependType[k]='SS';
|
|
|
}
|
|
|
-
|
|
|
- if(vFormat == 'hour')
|
|
|
+ else if(vDepList[k].toUpperCase().indexOf('FF')!=-1)
|
|
|
{
|
|
|
- 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);
|
|
|
+ vDepend[k]=vDepList[k].substring(0,vDepList[k].toUpperCase().indexOf('FF'));
|
|
|
+ vDependType[k]='FF';
|
|
|
}
|
|
|
-
|
|
|
- if(vFormat == 'day')
|
|
|
+ else if(vDepList[k].toUpperCase().indexOf('SF')!=-1)
|
|
|
{
|
|
|
- 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);
|
|
|
+ vDepend[k]=vDepList[k].substring(0,vDepList[k].toUpperCase().indexOf('SF'));
|
|
|
+ vDependType[k]='SF';
|
|
|
}
|
|
|
- else if(vFormat == 'week')
|
|
|
+ else if(vDepList[k].toUpperCase().indexOf('FS')!=-1)
|
|
|
{
|
|
|
- vRightTable += '<td class=gdatehead align=center style="FONT-SIZE: 12px; HEIGHT: 19px;" width='+vColWidth+'px>`'+ vStr + '</td>';
|
|
|
- vTmpDate.setDate(vTmpDate.getDate()+7);
|
|
|
+ vDepend[k]=vDepList[k].substring(0,vDepList[k].toUpperCase().indexOf('FS'));
|
|
|
+ vDependType[k]='FS';
|
|
|
}
|
|
|
- else if(vFormat == 'month')
|
|
|
+ else
|
|
|
{
|
|
|
- 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);
|
|
|
- }
|
|
|
+ vDepend[k]=vDepList[k];
|
|
|
+ vDependType[k]='FS';
|
|
|
}
|
|
|
- else if(vFormat == 'quarter')
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.getID=function(){return vID;};
|
|
|
+ this.getName=function(){return vName;};
|
|
|
+ this.getStart=function(){return vStart;};
|
|
|
+ this.getEnd=function(){return vEnd;};
|
|
|
+ this.getGroupMinStart=function(){return vGroupMinStart;};
|
|
|
+ this.getGroupMinEnd=function(){return vGroupMinEnd;};
|
|
|
+ this.getClass=function(){return vClass;};
|
|
|
+ this.getLink=function(){return vLink;};
|
|
|
+ this.getMile=function(){return vMile;};
|
|
|
+ this.getDepend=function(){if(vDepend) return vDepend; else return null;};
|
|
|
+ this.getDepType=function(){if(vDependType) return vDependType; else return null;};
|
|
|
+ this.getCaption=function(){if(vCaption) return vCaption; else return '';};
|
|
|
+ this.getResource=function(){if(vRes) return vRes; else return '\u00A0';};
|
|
|
+ this.getCompVal=function(){if(vComp) return vComp; else return 0;};
|
|
|
+ this.getCompStr=function(){if(vComp) return vComp+'%'; else return '';};
|
|
|
+ this.getNotes=function(){return vNotes;};
|
|
|
+ this.getSortIdx=function(){return vSortIdx;};
|
|
|
+ this.getToDelete=function(){return vToDelete;};
|
|
|
+
|
|
|
+ this.getDuration=function(pFormat, pLang)
|
|
|
+ {
|
|
|
+ if (vMile)
|
|
|
+ {
|
|
|
+ vDuration='-';
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var vTaskEnd=new Date(this.getEnd().getTime());
|
|
|
+ var vUnits=null;
|
|
|
+ switch(pFormat)
|
|
|
{
|
|
|
- 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);
|
|
|
- }
|
|
|
+ case 'week': vUnits='day'; break;
|
|
|
+ case 'month': vUnits='week'; break;
|
|
|
+ case 'quarter': vUnits='month'; break;
|
|
|
+ default: vUnits=pFormat; break;
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- 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 ((vTaskEnd.getTime()-(vTaskEnd.getTimezoneOffset()*60000))%(86400000)==0)
|
|
|
{
|
|
|
-
|
|
|
- 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);
|
|
|
+ vTaskEnd=new Date(vTaskEnd.getFullYear(), vTaskEnd.getMonth(), vTaskEnd.getDate()+1, vTaskEnd.getHours(), vTaskEnd.getMinutes(), vTaskEnd.getSeconds());
|
|
|
}
|
|
|
-
|
|
|
- else if (vFormat == 'hour')
|
|
|
+ var tmpPer=(JSGantt.getOffset(this.getStart(), vTaskEnd, 999, vUnits))/1000;
|
|
|
+ if(Math.floor(tmpPer)!=tmpPer) tmpPer=Math.round(tmpPer*10)/10;
|
|
|
+ switch(vUnits)
|
|
|
{
|
|
|
-
|
|
|
- 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);
|
|
|
+ case 'hour': vDuration=tmpPer+' '+((tmpPer!=1)?pLang['hrs']:pLang['hr']); break;
|
|
|
+ case 'day': vDuration=tmpPer+' '+((tmpPer!=1)?pLang['dys']:pLang['dy']); break;
|
|
|
+ case 'week': vDuration=tmpPer+' '+((tmpPer!=1)?pLang['wks']:pLang['wk']); break;
|
|
|
+ case 'month': vDuration=tmpPer+' '+((tmpPer!=1)?pLang['mths']:pLang['mth']); break;
|
|
|
+ case 'quarter': vDuration=tmpPer+' '+((tmpPer!=1)?pLang['qtrs']:pLang['qtr']); break;
|
|
|
}
|
|
|
+ }
|
|
|
+ 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.getParItem=function(){return vParItem;};
|
|
|
+ this.getCellDiv=function(){return vCellDiv;};
|
|
|
+ this.getBarDiv=function(){return vBarDiv;};
|
|
|
+ this.getTaskDiv=function(){return vTaskDiv;};
|
|
|
+ this.getChildRow=function(){return vChildRow;};
|
|
|
+ this.getListChildRow=function(){return vListChildRow;};
|
|
|
+ this.getGroupSpan=function(){return vGroupSpan;};
|
|
|
+ this.setStart=function(pStart){if(pStart instanceof Date)vStart=pStart;};
|
|
|
+ this.setEnd=function(pEnd){if(pEnd instanceof Date)vEnd=pEnd;};
|
|
|
+ this.setGroupMinStart=function(pStart){if(pStart instanceof Date)vGroupMinStart=pStart;};
|
|
|
+ this.setGroupMinEnd=function(pEnd){if(pEnd instanceof Date)vGroupMinEnd=pEnd;};
|
|
|
+ this.setLevel=function(pLevel){vLevel=parseInt(document.createTextNode(pLevel).data);};
|
|
|
+ this.setNumKid=function(pNumKid){vNumKid=parseInt(document.createTextNode(pNumKid).data);};
|
|
|
+ this.setCompVal=function(pCompVal){vComp=parseFloat(document.createTextNode(pCompVal).data);};
|
|
|
+ this.setStartX=function(pX){x1=parseInt(document.createTextNode(pX).data);};
|
|
|
+ this.setStartY=function(pY){y1=parseInt(document.createTextNode(pY).data);};
|
|
|
+ this.setEndX=function(pX){x2=parseInt(document.createTextNode(pX).data);};
|
|
|
+ this.setEndY=function(pY){y2=parseInt(document.createTextNode(pY).data);};
|
|
|
+ this.setOpen=function(pOpen){vOpen=parseInt(document.createTextNode(pOpen).data);};
|
|
|
+ this.setVisible=function(pVisible){vVisible=parseInt(document.createTextNode(pVisible).data);};
|
|
|
+ this.setSortIdx=function(pSortIdx){vSortIdx=parseInt(document.createTextNode(pSortIdx).data);};
|
|
|
+ this.setToDelete=function(pToDelete){if (pToDelete) vToDelete=true; else vToDelete=false;};
|
|
|
+ this.setParItem=function(pParItem){if(pParItem instanceof JSGantt.TaskItem) vParItem=pParItem;};
|
|
|
+ this.setCellDiv=function(pCellDiv){if(typeof HTMLDivElement !== 'function' || pCellDiv instanceof HTMLDivElement) vCellDiv=pCellDiv;}; //"typeof HTMLDivElement !== 'function'" to play nice with ie6 and 7
|
|
|
+ this.setGroup=function(pGroup){vGroup=parseInt(document.createTextNode(pGroup).data);};
|
|
|
+ this.setBarDiv=function(pDiv){if(typeof HTMLDivElement !== 'function' || pDiv instanceof HTMLDivElement)vBarDiv=pDiv;};
|
|
|
+ this.setTaskDiv=function(pDiv){if(typeof HTMLDivElement !== 'function' || pDiv instanceof HTMLDivElement)vTaskDiv=pDiv;};
|
|
|
+ this.setChildRow=function(pRow){if(typeof HTMLTableRowElement !== 'function' || pRow instanceof HTMLTableRowElement)vChildRow=pRow;};
|
|
|
+ this.setListChildRow=function(pRow){if(typeof HTMLTableRowElement !== 'function' || pRow instanceof HTMLTableRowElement)vListChildRow=pRow;};
|
|
|
+ this.setGroupSpan=function(pSpan){if(typeof HTMLSpanElement !== 'function' || pSpan instanceof HTMLSpanElement)vGroupSpan=pSpan;};
|
|
|
+};
|
|
|
|
|
|
- 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);
|
|
|
+// function that loads the main gantt chart properties and functions
|
|
|
+// pDiv: (required) this is a div object created in HTML
|
|
|
+// pFormat: (required) - used to indicate whether chart should be drawn in "hour", "day", "week", "month", or "quarter" format
|
|
|
+JSGantt.GanttChart=function(pDiv, pFormat)
|
|
|
+{
|
|
|
+ var vDiv=pDiv;
|
|
|
+ var vFormat=pFormat;
|
|
|
+ var vDivId=null;
|
|
|
+ var vUseFade=1;
|
|
|
+ var vUseMove=1;
|
|
|
+ var vUseRowHlt=1;
|
|
|
+ var vUseToolTip=1;
|
|
|
+ var vUseSort=1;
|
|
|
+ var vUseSingleCell=25000;
|
|
|
+ var vShowRes=1;
|
|
|
+ var vShowDur=1;
|
|
|
+ var vShowComp=1;
|
|
|
+ var vShowStartDate=1;
|
|
|
+ var vShowEndDate=1;
|
|
|
+ var vShowEndWeekDate=1;
|
|
|
+ var vShowTaskInfoRes=1;
|
|
|
+ var vShowTaskInfoDur=1;
|
|
|
+ var vShowTaskInfoComp=1;
|
|
|
+ var vShowTaskInfoStartDate=1;
|
|
|
+ var vShowTaskInfoEndDate=1;
|
|
|
+ var vShowTaskInfoNotes=1;
|
|
|
+ var vShowTaskInfoLink=1;
|
|
|
+ var vShowDeps=1;
|
|
|
+ var vShowSelector=new Array('top');
|
|
|
+ var vDateInputFormat='yyyy-mm-dd';
|
|
|
+ var vDateTaskTableDisplayFormat=JSGantt.parseDateFormatStr('dd/mm/yyyy');
|
|
|
+ var vDateTaskDisplayFormat=JSGantt.parseDateFormatStr('dd month yyyy');
|
|
|
+ var vHourMajorDateDisplayFormat=JSGantt.parseDateFormatStr('day dd month yyyy');
|
|
|
+ var vHourMinorDateDisplayFormat=JSGantt.parseDateFormatStr('HH');
|
|
|
+ var vDayMajorDateDisplayFormat=JSGantt.parseDateFormatStr('dd/mm/yyyy');
|
|
|
+ var vDayMinorDateDisplayFormat=JSGantt.parseDateFormatStr('dd');
|
|
|
+ var vWeekMajorDateDisplayFormat=JSGantt.parseDateFormatStr('yyyy');
|
|
|
+ var vWeekMinorDateDisplayFormat=JSGantt.parseDateFormatStr('dd/mm');
|
|
|
+ var vMonthMajorDateDisplayFormat=JSGantt.parseDateFormatStr('yyyy');
|
|
|
+ var vMonthMinorDateDisplayFormat=JSGantt.parseDateFormatStr('mon');
|
|
|
+ var vQuarterMajorDateDisplayFormat=JSGantt.parseDateFormatStr('yyyy');
|
|
|
+ var vQuarterMinorDateDisplayFormat=JSGantt.parseDateFormatStr('qq');
|
|
|
+ var vUseFullYear=JSGantt.parseDateFormatStr('dd/mm/yyyy');
|
|
|
+ var vCaptionType;
|
|
|
+ var vDepId=1;
|
|
|
+ var vTaskList=new Array();
|
|
|
+ var vFormatArr=new Array('hour','day','week','month','quarter');
|
|
|
+ var vMonthDaysArr=new Array(31,28,31,30,31,30,31,31,30,31,30,31);
|
|
|
+ var vProcessNeeded=true;
|
|
|
+ var vMinGpLen=8;
|
|
|
+ var vScrollTo='';
|
|
|
+ var vHourColWidth=18;
|
|
|
+ var vDayColWidth=18;
|
|
|
+ var vWeekColWidth=36;
|
|
|
+ var vMonthColWidth=36;
|
|
|
+ var vQuarterColWidth=18;
|
|
|
+ var vRowHeight=20;
|
|
|
+ var vTodayPx=-1;
|
|
|
+ /*var vLangs={'en':
|
|
|
+ {'format':'Format','hour':'Hour','day':'Day','week':'Week','month':'Month','quarter':'Quarter','hours':'Hours','days':'Days',
|
|
|
+ 'weeks':'Weeks','months':'Months','quarters':'Quarters','hr':'Hr','dy':'Day','wk':'Wk','mth':'Mth','qtr':'Qtr','hrs':'Hrs',
|
|
|
+ 'dys':'Days','wks':'Wks','mths':'Mths','qtrs':'Qtrs','resource':'Resource','duration':'Duration','comp':'% Comp.',
|
|
|
+ 'completion':'Completion','startdate':'Start Date','enddate':'End Date','moreinfo':'More Information','notes':'Notes',
|
|
|
+ 'january':'January','february':'February','march':'March','april':'April','maylong':'May','june':'June','july':'July',
|
|
|
+ 'august':'August','september':'September','october':'October','november':'November','december':'December','jan':'Jan',
|
|
|
+ 'feb':'Feb','mar':'Mar','apr':'Apr','may':'May','jun':'Jun','jul':'Jul','aug':'Aug','sep':'Sep','oct':'Oct','nov':'Nov',
|
|
|
+ 'dec':'Dec','sunday':'Sunday','monday':'Monday','tuesday':'Tuesday','wednesday':'Wednesday','thursday':'Thursday',
|
|
|
+ 'friday':'Friday','saturday':'Saturday','sun':'Sun','mon':'Mon','tue':'Tue','wed':'Wed','thu':'Thu','fri':'Fri','sat':'Sat'}
|
|
|
+ };
|
|
|
+ var vLang='en';*/
|
|
|
+ var vChartBody=null;
|
|
|
+ var vChartHead=null;
|
|
|
+ var vListBody=null;
|
|
|
+ var vChartTable=null;
|
|
|
+ var vLines=null;
|
|
|
+ var vTimer=20;
|
|
|
+
|
|
|
+ this.setUseFade=function(pVal){vUseFade=pVal;};
|
|
|
+ this.setUseMove=function(pVal){vUseMove=pVal;};
|
|
|
+ this.setUseRowHlt=function(pVal){vUseRowHlt=pVal;};
|
|
|
+ this.setUseToolTip=function(pVal){vUseToolTip=pVal;};
|
|
|
+ this.setUseSort=function(pVal){vUseSort=pVal;};
|
|
|
+ this.setUseSingleCell=function(pVal){vUseSingleCell=pVal*1;};
|
|
|
+ this.setFormatArr=function()
|
|
|
+ {
|
|
|
+ var vValidFormats='hour day week month quarter';
|
|
|
+ vFormatArr=new Array();
|
|
|
+ for(var i=0, j=0; i<arguments.length; i++)
|
|
|
+ {
|
|
|
+ if (vValidFormats.indexOf(arguments[i].toLowerCase())!=-1 && arguments[i].length>1)
|
|
|
+ {
|
|
|
+ vFormatArr[j++]=arguments[i].toLowerCase();
|
|
|
+ var vRegExp=new RegExp('(?:^|\s)'+arguments[i]+'(?!\S)', 'g');
|
|
|
+ vValidFormats=vValidFormats.replace(vRegExp, '');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ this.setShowRes=function(pVal){vShowRes=pVal;};
|
|
|
+ this.setShowDur=function(pVal){vShowDur=pVal;};
|
|
|
+ this.setShowComp=function(pVal){vShowComp=pVal;};
|
|
|
+ this.setShowStartDate=function(pVal){vShowStartDate=pVal;};
|
|
|
+ this.setShowEndDate=function(pVal){vShowEndDate=pVal;};
|
|
|
+ this.setShowTaskInfoRes=function(pVal){vShowTaskInfoRes=pVal;};
|
|
|
+ this.setShowTaskInfoDur=function(pVal){vShowTaskInfoDur=pVal;};
|
|
|
+ this.setShowTaskInfoComp=function(pVal){vShowTaskInfoComp=pVal;};
|
|
|
+ this.setShowTaskInfoStartDate=function(pVal){vShowTaskInfoStartDate=pVal;};
|
|
|
+ this.setShowTaskInfoEndDate=function(pVal){vShowTaskInfoEndDate=pVal;};
|
|
|
+ this.setShowTaskInfoNotes=function(pVal){vShowTaskInfoNotes=pVal;};
|
|
|
+ this.setShowTaskInfoLink=function(pVal){vShowTaskInfoLink=pVal;};
|
|
|
+ this.setShowEndWeekDate=function(pVal){vShowEndWeekDate=pVal;};
|
|
|
+ this.setShowSelector=function()
|
|
|
+ {
|
|
|
+ var vValidSelectors='top bottom';
|
|
|
+ vShowSelector=new Array();
|
|
|
+ for(var i=0, j=0; i<arguments.length; i++)
|
|
|
+ {
|
|
|
+ if (vValidSelectors.indexOf(arguments[i].toLowerCase())!=-1 && arguments[i].length>1)
|
|
|
+ {
|
|
|
+ vShowSelector[j++]=arguments[i].toLowerCase();
|
|
|
+ var vRegExp=new RegExp('(?:^|\s)'+arguments[i]+'(?!\S)', 'g');
|
|
|
+ vValidSelectors=vValidSelectors.replace(vRegExp, '');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ this.setShowDeps=function(pVal){vShowDeps=pVal;};
|
|
|
+ this.setDateInputFormat=function(pVal){vDateInputFormat=pVal;};
|
|
|
+ this.setDateTaskTableDisplayFormat=function(pVal){vDateTaskTableDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setDateTaskDisplayFormat=function(pVal){vDateTaskDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setHourMajorDateDisplayFormat=function(pVal){vHourMajorDateDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setHourMinorDateDisplayFormat=function(pVal){vHourMinorDateDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setDayMajorDateDisplayFormat=function(pVal){vDayMajorDateDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setDayMinorDateDisplayFormat=function(pVal){vDayMinorDateDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setWeekMajorDateDisplayFormat=function(pVal){vWeekMajorDateDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setWeekMinorDateDisplayFormat=function(pVal){vWeekMinorDateDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setMonthMajorDateDisplayFormat=function(pVal){vMonthMajorDateDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setMonthMinorDateDisplayFormat=function(pVal){vMonthMinorDateDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setQuarterMajorDateDisplayFormat=function(pVal){vQuarterMajorDateDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setQuarterMinorDateDisplayFormat=function(pVal){vQuarterMinorDateDisplayFormat=JSGantt.parseDateFormatStr(pVal);};
|
|
|
+ this.setCaptionType=function(pType){vCaptionType=pType;};
|
|
|
+ this.setFormat=function(pFormat)
|
|
|
+ {
|
|
|
+ vFormat=pFormat;
|
|
|
+ this.Draw();
|
|
|
+ };
|
|
|
+ this.setMinGpLen=function(pMinGpLen){vMinGpLen=pMinGpLen;};
|
|
|
+ this.setScrollTo=function(pDate){vScrollTo=pDate;};
|
|
|
+ this.setHourColWidth=function(pWidth){vHourColWidth=pWidth;};
|
|
|
+ this.setDayColWidth=function(pWidth){vDayColWidth=pWidth;};
|
|
|
+ this.setWeekColWidth=function(pWidth){vWeekColWidth=pWidth;};
|
|
|
+ this.setMonthColWidth=function(pWidth){vMonthColWidth=pWidth;};
|
|
|
+ this.setQuarterColWidth=function(pWidth){vQuarterColWidth=pWidth;};
|
|
|
+ this.setRowHeight=function(pHeight){vRowHeight=pHeight;};
|
|
|
+ this.setLang=function(pLang){if(vLangs[pLang])vLang=pLang;};
|
|
|
+ this.setChartBody=function(pDiv){if(typeof HTMLDivElement !== 'function' || pDiv instanceof HTMLDivElement)vChartBody=pDiv;};
|
|
|
+ this.setChartHead=function(pDiv){if(typeof HTMLDivElement !== 'function' || pDiv instanceof HTMLDivElement)vChartHead=pDiv;};
|
|
|
+ this.setListBody=function(pDiv){if(typeof HTMLDivElement !== 'function' || pDiv instanceof HTMLDivElement)vListBody=pDiv;};
|
|
|
+ this.setChartTable=function(pTable){if(typeof HTMLTableElement !== 'function' || pTable instanceof HTMLTableElement)vChartTable=pTable;};
|
|
|
+ this.setLines=function(pDiv){if(typeof HTMLDivElement !== 'function' || pDiv instanceof HTMLDivElement)vLines=pDiv;};
|
|
|
+ this.setTimer=function(pVal){vTimer=pVal*1;};
|
|
|
+ this.addLang=function(pLang, pVals){
|
|
|
+ if(!vLangs[pLang])
|
|
|
+ {
|
|
|
+ vLangs[pLang]=new Object();
|
|
|
+ for(var vKey in vLangs['en'])vLangs[pLang][vKey]=(pVals[vKey])?document.createTextNode(pVals[vKey]).data:vLangs['en'][vKey];
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ this.getDivId=function(){return vDivId;};
|
|
|
+ this.getUseFade=function(){return vUseFade;};
|
|
|
+ this.getUseMove=function(){return vUseMove;};
|
|
|
+ this.getUseRowHlt=function(){return vUseRowHlt;};
|
|
|
+ this.getUseToolTip=function(){return vUseToolTip;};
|
|
|
+ this.getUseSort=function(){return vUseSort;};
|
|
|
+ this.getUseSingleCell=function(){return vUseSingleCell;};
|
|
|
+ this.getFormatArr=function(){return vFormatArr;};
|
|
|
+ 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.getShowTaskInfoRes=function(){return vShowTaskInfoRes;};
|
|
|
+ this.getShowTaskInfoDur=function(){return vShowTaskInfoDur;};
|
|
|
+ this.getShowTaskInfoComp=function(){return vShowTaskInfoComp;};
|
|
|
+ this.getShowTaskInfoStartDate=function(){return vShowTaskInfoStartDate;};
|
|
|
+ this.getShowTaskInfoEndDate=function(){return vShowTaskInfoEndDate;};
|
|
|
+ this.getShowTaskInfoNotes=function(){return vShowTaskInfoNotes;};
|
|
|
+ this.getShowTaskInfoLink=function(){return vShowTaskInfoLink;};
|
|
|
+ this.getShowEndWeekDate=function(){return vShowEndWeekDate;};
|
|
|
+ this.getShowSelector=function(){return vShowSelector;};
|
|
|
+ this.getShowDeps=function(){return vShowDeps;};
|
|
|
+ this.getDateInputFormat=function(){return vDateInputFormat;};
|
|
|
+ this.getDateTaskTableDisplayFormat=function(){return vDateTaskTableDisplayFormat;};
|
|
|
+ this.getDateTaskDisplayFormat=function(){return vDateTaskDisplayFormat;};
|
|
|
+ this.getHourMajorDateDisplayFormat=function(){return vHourMajorDateDisplayFormat;};
|
|
|
+ this.getHourMinorDateDisplayFormat=function(){return vHourMinorDateDisplayFormat;};
|
|
|
+ this.getDayMajorDateDisplayFormat=function(){return vDayMajorDateDisplayFormat;};
|
|
|
+ this.getDayMinorDateDisplayFormat=function(){return vDayMinorDateDisplayFormat;};
|
|
|
+ this.getWeekMajorDateDisplayFormat=function(){return vWeekMajorDateDisplayFormat;};
|
|
|
+ this.getWeekMinorDateDisplayFormat=function(){return vWeekMinorDateDisplayFormat;};
|
|
|
+ this.getMonthMajorDateDisplayFormat=function(){return vMonthMajorDateDisplayFormat;};
|
|
|
+ this.getMonthMinorDateDisplayFormat=function(){return vMonthMinorDateDisplayFormat;};
|
|
|
+ this.getQuarterMajorDateDisplayFormat=function(){return vQuarterMajorDateDisplayFormat;};
|
|
|
+ this.getQuarterMinorDateDisplayFormat=function(){return vQuarterMinorDateDisplayFormat;};
|
|
|
+ this.getCaptionType=function(){return vCaptionType;};
|
|
|
+ this.getMinGpLen=function(){return vMinGpLen;};
|
|
|
+ this.getScrollTo=function(){return vScrollTo;};
|
|
|
+ this.getHourColWidth=function(){return vHourColWidth;};
|
|
|
+ this.getDayColWidth=function(){return vDayColWidth;};
|
|
|
+ this.getWeekColWidth=function(){return vWeekColWidth;};
|
|
|
+ this.getMonthColWidth=function(){return vMonthColWidth;};
|
|
|
+ this.getQuarterColWidth=function(){return vQuarterColWidth;};
|
|
|
+ this.getRowHeight=function(){return vRowHeight;};
|
|
|
+ this.getChartBody=function(){return vChartBody;};
|
|
|
+ this.getChartHead=function(){return vChartHead;};
|
|
|
+ this.getListBody=function(){return vListBody;};
|
|
|
+ this.getChartTable=function(){return vChartTable;};
|
|
|
+ this.getLines=function(){return vLines;};
|
|
|
+ this.getTimer=function(){return vTimer;};
|
|
|
+
|
|
|
+ this.CalcTaskXY=function()
|
|
|
+ {
|
|
|
+ var vID;
|
|
|
+ var vList=this.getList();
|
|
|
+ var vBarDiv;
|
|
|
+ var vTaskDiv;
|
|
|
+ var vParDiv;
|
|
|
+ var vLeft, vTop, vWidth;
|
|
|
+ var vHeight=Math.floor((this.getRowHeight()/2));
|
|
|
+
|
|
|
+ for(var i=0; i<vList.length; i++)
|
|
|
+ {
|
|
|
+ vID=vList[i].getID();
|
|
|
+ vBarDiv=vList[i].getBarDiv();
|
|
|
+ vTaskDiv=vList[i].getTaskDiv();
|
|
|
+ if((vList[i].getParItem() && vList[i].getParItem().getGroup()==2))
|
|
|
+ {
|
|
|
+ vParDiv=vList[i].getParItem().getChildRow();
|
|
|
+ }
|
|
|
+ else vParDiv=vList[i].getChildRow();
|
|
|
|
|
|
+ if(vBarDiv)
|
|
|
+ {
|
|
|
+ vList[i].setStartX(vBarDiv.offsetLeft+1);
|
|
|
+ vList[i].setStartY(vParDiv.offsetTop+vBarDiv.offsetTop+vHeight-1);
|
|
|
+ vList[i].setEndX(vBarDiv.offsetLeft+vBarDiv.offsetWidth+1);
|
|
|
+ vList[i].setEndY(vParDiv.offsetTop+vBarDiv.offsetTop+vHeight-1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ this.AddTaskItem=function(value)
|
|
|
+ {
|
|
|
+ var vExists=false;
|
|
|
+ for (var i=0; i<vTaskList.length; i++)
|
|
|
+ {
|
|
|
+ if (vTaskList[i].getID()==value.getID())
|
|
|
+ {
|
|
|
+ i=vTaskList.length;
|
|
|
+ vExists=true;
|
|
|
}
|
|
|
+ }
|
|
|
+ if(!vExists)
|
|
|
+ {
|
|
|
+ vTaskList.push(value);
|
|
|
+ vProcessNeeded=true;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ this.RemoveTaskItem=function(pID)
|
|
|
+ {
|
|
|
+ // simply mark the task for removal at this point - actually remove it next time we re-draw the chart
|
|
|
+ for (var i=0; i<vTaskList.length; i++)
|
|
|
+ {
|
|
|
+ if (vTaskList[i].getID()==pID) vTaskList[i].setToDelete(true);
|
|
|
+ else if (vTaskList[i].getParent()==pID) this.RemoveTaskItem(vTaskList[i].getID());
|
|
|
+ }
|
|
|
+ vProcessNeeded=true;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.getList=function(){return vTaskList;};
|
|
|
+
|
|
|
+ this.clearDependencies=function()
|
|
|
+ {
|
|
|
+ var parent=this.getLines();
|
|
|
+ while(parent.hasChildNodes())parent.removeChild(parent.firstChild);
|
|
|
+ vDepId=1;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ // sLine: Draw a straight line (colored one-pixel wide div)
|
|
|
+ this.sLine=function(x1,y1,x2,y2,pClass)
|
|
|
+ {
|
|
|
+ var vLeft=Math.min(x1,x2);
|
|
|
+ var vTop=Math.min(y1,y2);
|
|
|
+ var vWid=Math.abs(x2-x1)+1;
|
|
|
+ var vHgt=Math.abs(y2-y1)+1;
|
|
|
+
|
|
|
+ var vTmpDiv=document.createElement('div');
|
|
|
+ vTmpDiv.id=vDivId+'line'+vDepId++;
|
|
|
+ vTmpDiv.style.position='absolute';
|
|
|
+ vTmpDiv.style.overflow='hidden';
|
|
|
+ vTmpDiv.style.zIndex=0;
|
|
|
+ vTmpDiv.style.left=vLeft+'px';
|
|
|
+ vTmpDiv.style.top=vTop+'px';
|
|
|
+ vTmpDiv.style.width=vWid+'px';
|
|
|
+ vTmpDiv.style.height=vHgt+'px';
|
|
|
+
|
|
|
+ vTmpDiv.style.visibility='visible';
|
|
|
+
|
|
|
+ if (vWid==1) vTmpDiv.className='glinev';
|
|
|
+ else vTmpDiv.className='glineh';
|
|
|
+
|
|
|
+ if (pClass) vTmpDiv.className+=' '+pClass;
|
|
|
+
|
|
|
+ this.getLines().appendChild(vTmpDiv);
|
|
|
+
|
|
|
+ return vTmpDiv;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.drawDependency =function(x1,y1,x2,y2,pType,pClass)
|
|
|
+ {
|
|
|
+ var vDir=1;
|
|
|
+ var vBend=false;
|
|
|
+ var vShort=4;
|
|
|
+ var vRow=Math.floor(this.getRowHeight()/2);
|
|
|
+
|
|
|
+ if(y2<y1) vRow*=-1;
|
|
|
+
|
|
|
+ switch(pType)
|
|
|
+ {
|
|
|
+ case 'SF':
|
|
|
+ vShort*=-1;
|
|
|
+ if(x1-10<=x2 && y1!=y2) vBend=true;
|
|
|
+ vDir=-1;
|
|
|
+ break;
|
|
|
+ case 'SS':
|
|
|
+ if (x1<x2) vShort*=-1;
|
|
|
+ else vShort=x2-x1-(2*vShort);
|
|
|
+ break;
|
|
|
+ case 'FF':
|
|
|
+ if (x1<=x2) vShort=x2-x1+(2*vShort);
|
|
|
+ vDir=-1;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ if(x1+10>=x2 && y1!=y2) vBend=true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (vBend)
|
|
|
+ {
|
|
|
+ this.sLine(x1,y1,x1+vShort,y1,pClass);
|
|
|
+ this.sLine(x1+vShort,y1,x1+vShort,y2-vRow,pClass);
|
|
|
+ this.sLine(x1+vShort,y2-vRow,x2-(vShort*2),y2-vRow,pClass);
|
|
|
+ this.sLine(x2-(vShort*2),y2-vRow,x2-(vShort*2),y2,pClass);
|
|
|
+ this.sLine(x2-(vShort*2),y2,x2-(1*vDir),y2,pClass);
|
|
|
+ }
|
|
|
+ else if (y1!=y2)
|
|
|
+ {
|
|
|
+ this.sLine(x1,y1,x1+vShort,y1,pClass);
|
|
|
+ this.sLine(x1+vShort,y1,x1+vShort,y2,pClass);
|
|
|
+ this.sLine(x1+vShort,y2,x2-(1*vDir),y2,pClass);
|
|
|
+ }
|
|
|
+ else this.sLine(x1,y1,x2-(1*vDir),y2,pClass);
|
|
|
+
|
|
|
+ var vTmpDiv=this.sLine(x2,y2,x2-3-((vDir<0)?1:0),y2-3-((vDir<0)?1:0),pClass+"Arw");
|
|
|
+ vTmpDiv.style.width='0px';
|
|
|
+ vTmpDiv.style.height='0px';
|
|
|
+ };
|
|
|
+
|
|
|
+ this.DrawDependencies=function()
|
|
|
+ {
|
|
|
+ if (this.getShowDeps()==1)
|
|
|
+ {
|
|
|
+ //First recalculate the x,y
|
|
|
+ this.CalcTaskXY();
|
|
|
+ this.clearDependencies();
|
|
|
+
|
|
|
+ var vList=this.getList();
|
|
|
+ for(var i=0; i<vList.length; i++)
|
|
|
+ {
|
|
|
+ var vDepend=vList[i].getDepend();
|
|
|
+ var vDependType=vList[i].getDepType();
|
|
|
+ var n=vDepend.length;
|
|
|
|
|
|
- else if(vFormat == 'week')
|
|
|
+ if(n>0 && vList[i].getVisible()==1)
|
|
|
+ {
|
|
|
+ for(var k=0;k<n;k++)
|
|
|
+ {
|
|
|
+ var vTask=this.getArrayLocationByID(vDepend[k]);
|
|
|
+ if (vTask>=0 && vList[vTask].getGroup()!=2)
|
|
|
+ {
|
|
|
+ if(vList[vTask].getVisible()==1)
|
|
|
+ {
|
|
|
+ if(vDependType[k]=='SS')this.drawDependency(vList[vTask].getStartX()-1,vList[vTask].getStartY(),vList[i].getStartX()-1,vList[i].getStartY(),'SS','gDepSS');
|
|
|
+ else if(vDependType[k]=='FF')this.drawDependency(vList[vTask].getEndX(),vList[vTask].getEndY(),vList[i].getEndX(),vList[i].getEndY(),'FF','gDepFF');
|
|
|
+ else if(vDependType[k]=='SF')this.drawDependency(vList[vTask].getStartX()-1,vList[vTask].getStartY(),vList[i].getEndX(),vList[i].getEndY(),'SF','gDepSF');
|
|
|
+ else if(vDependType[k]=='FS')this.drawDependency(vList[vTask].getEndX(),vList[vTask].getEndY(),vList[i].getStartX()-1,vList[i].getStartY(),'FS','gDepFS');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // draw the current date line
|
|
|
+ if (vTodayPx>=0) this.sLine(vTodayPx, 0, vTodayPx, this.getChartTable().offsetHeight-1, 'gCurDate');
|
|
|
+ };
|
|
|
+
|
|
|
+ this.getArrayLocationByID=function(pId)
|
|
|
+ {
|
|
|
+ var vList=this.getList();
|
|
|
+ for(var i=0; i<vList.length; i++)
|
|
|
+ {
|
|
|
+ if(vList[i].getID()==pId)
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.newNode=function(pParent, pNodeType, pId, pClass, pText, pWidth, pLeft, pDisplay, pColspan, pAttribs)
|
|
|
+ {
|
|
|
+ var vNewNode=pParent.appendChild(document.createElement(pNodeType));
|
|
|
+ if (pAttribs)
|
|
|
+ {
|
|
|
+ for (var i=0; i+1<pAttribs.length; i+=2)
|
|
|
+ {
|
|
|
+ vNewNode.setAttribute(pAttribs[i],pAttribs[i+1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // I wish I could do this with setAttribute but older IEs don't play nice
|
|
|
+ if (pId)vNewNode.id=pId;
|
|
|
+ if (pClass)vNewNode.className=pClass;
|
|
|
+ if (pWidth)vNewNode.style.width=(isNaN(pWidth*1))?pWidth:pWidth+'px';
|
|
|
+ if (pLeft)vNewNode.style.left=(isNaN(pLeft*1))?pLeft:pLeft+'px';
|
|
|
+ if (pText)vNewNode.appendChild(document.createTextNode(pText));
|
|
|
+ if (pDisplay)vNewNode.style.display=pDisplay;
|
|
|
+ if (pColspan)vNewNode.colSpan=pColspan;
|
|
|
+ return vNewNode;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.Draw=function()
|
|
|
+ {
|
|
|
+ var vMaxDate=new Date();
|
|
|
+ var vMinDate=new Date();
|
|
|
+ var vTmpDate=new Date();
|
|
|
+ var vTaskLeftPx=0;
|
|
|
+ var vTaskRightPx=0;
|
|
|
+ var vTaskWidth=1;
|
|
|
+ var vNumCols=0;
|
|
|
+ var vNumRows=0;
|
|
|
+ var vSingleCell=false;
|
|
|
+ var vID=0;
|
|
|
+ var vMainTable='';
|
|
|
+ var vDateRow=null;
|
|
|
+ var vFirstCellItemRowStr='';
|
|
|
+ var vItemRowStr='';
|
|
|
+ var vColWidth=0;
|
|
|
+ var vColUnit=0;
|
|
|
+ var vChild;
|
|
|
+ var vGroup;
|
|
|
+ var vTaskDiv;
|
|
|
+ var vParDiv;
|
|
|
+
|
|
|
+ if(vTaskList.length>0)
|
|
|
+ {
|
|
|
+ // Process all tasks, reset parent date and completion % if task list has altered
|
|
|
+ if (vProcessNeeded) JSGantt.processRows(vTaskList, 0, -1, 1, 1, this.getUseSort());
|
|
|
+ vProcessNeeded=false;
|
|
|
+
|
|
|
+ // get overall min/max dates plus padding
|
|
|
+ vMinDate=JSGantt.getMinDate(vTaskList, vFormat);
|
|
|
+ vMaxDate=JSGantt.getMaxDate(vTaskList, vFormat);
|
|
|
+
|
|
|
+ // Calculate chart width variables.
|
|
|
+ if(vFormat=='day') vColWidth=vDayColWidth;
|
|
|
+ else if(vFormat=='week') vColWidth=vWeekColWidth;
|
|
|
+ else if(vFormat=='month') vColWidth=vMonthColWidth;
|
|
|
+ else if(vFormat=='quarter') vColWidth=vQuarterColWidth;
|
|
|
+ else if(vFormat=='hour') vColWidth=vHourColWidth;
|
|
|
+
|
|
|
+ // DRAW the Left-side of the chart (names, resources, comp%)
|
|
|
+ var vLeftHeader=document.createDocumentFragment();
|
|
|
+
|
|
|
+ var vTmpDiv=this.newNode(vLeftHeader, 'div', vDivId+'glisthead', 'glistlbl gcontainercol');
|
|
|
+ var vTmpTab=this.newNode(vTmpDiv, 'table', null, 'gtasktableh');
|
|
|
+ var vTmpTBody=this.newNode(vTmpTab, 'tbody');
|
|
|
+ var vTmpRow=this.newNode(vTmpTBody, 'tr');
|
|
|
+ this.newNode(vTmpRow, 'td', null, 'gtasklist', '\u00A0');
|
|
|
+ var vTmpCell=this.newNode(vTmpRow, 'td', null, 'gspanning gtaskname');
|
|
|
+ vTmpCell.appendChild(this.drawSelector('top'));
|
|
|
+ if(vShowRes==1)this.newNode(vTmpRow, 'td', null, 'gspanning gresource', '\u00A0');
|
|
|
+ if(vShowDur==1)this.newNode(vTmpRow, 'td', null, 'gspanning gduration', '\u00A0');
|
|
|
+ if(vShowComp==1)this.newNode(vTmpRow, 'td', null, 'gspanning gpccomplete', '\u00A0');
|
|
|
+ if(vShowStartDate==1)this.newNode(vTmpRow, 'td', null, 'gspanning gstartdate', '\u00A0');
|
|
|
+ if(vShowEndDate==1)this.newNode(vTmpRow, 'td', null, 'gspanning genddate', '\u00A0');
|
|
|
+
|
|
|
+ vTmpRow=this.newNode(vTmpTBody, 'tr');
|
|
|
+ this.newNode(vTmpRow, 'td', null, 'gtasklist', '\u00A0');
|
|
|
+ this.newNode(vTmpRow, 'td', null, 'gtaskname', '\u00A0');
|
|
|
+ if(vShowRes==1)this.newNode(vTmpRow, 'td', null, 'gtaskheading gresource', vLangs[vLang]['resource']);
|
|
|
+ if(vShowDur==1)this.newNode(vTmpRow, 'td', null, 'gtaskheading gduration', vLangs[vLang]['duration']);
|
|
|
+ if(vShowComp==1)this.newNode(vTmpRow, 'td', null, 'gtaskheading gpccomplete', vLangs[vLang]['comp']);
|
|
|
+ if(vShowStartDate==1)this.newNode(vTmpRow, 'td', null, 'gtaskheading gstartdate', vLangs[vLang]['startdate']);
|
|
|
+ if(vShowEndDate==1)this.newNode(vTmpRow, 'td', null, 'gtaskheading genddate', vLangs[vLang]['enddate']);
|
|
|
+
|
|
|
+ vTmpDiv=this.newNode(vLeftHeader, 'div', null, 'glabelfooter');
|
|
|
+
|
|
|
+ var vLeftTable=document.createDocumentFragment();
|
|
|
+ var vTmpDiv2=this.newNode(vLeftTable, 'div', vDivId+'glistbody', 'glistgrid gcontainercol');
|
|
|
+ this.setListBody(vTmpDiv2);
|
|
|
+ vTmpTab=this.newNode(vTmpDiv2, 'table', null, 'gtasktable');
|
|
|
+ vTmpTBody=this.newNode(vTmpTab, 'tbody');
|
|
|
+
|
|
|
+ for(i=0; i<vTaskList.length; i++)
|
|
|
{
|
|
|
+ if(vTaskList[i].getGroup()==1) var vBGColor='ggroupitem';
|
|
|
+ else vBGColor='glineitem';
|
|
|
|
|
|
- vNxtDate.setDate(vNxtDate.getDate() + 7);
|
|
|
+ vID=vTaskList[i].getID();
|
|
|
|
|
|
- if( vCurrDate >= vTmpDate && vCurrDate < vNxtDate )
|
|
|
- vWeekdayColor = "ccccff";
|
|
|
- else
|
|
|
- vWeekdayColor = "ffffff";
|
|
|
+ if((!(vTaskList[i].getParItem() && vTaskList[i].getParItem().getGroup()==2)) || vTaskList[i].getGroup()==2)
|
|
|
+ {
|
|
|
+ if(vTaskList[i].getVisible()==0) vTmpRow=this.newNode(vTmpTBody, 'tr', vDivId+'child_'+vID, 'gname '+vBGColor, null, null, null, 'none');
|
|
|
+ else vTmpRow=this.newNode(vTmpTBody, 'tr', vDivId+'child_'+vID, 'gname '+vBGColor);
|
|
|
+ vTaskList[i].setListChildRow(vTmpRow);
|
|
|
+ this.newNode(vTmpRow, 'td', null, 'gtasklist', '\u00A0');
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, 'gtaskname');
|
|
|
+
|
|
|
+ var vCellContents ='';
|
|
|
+ for(j=1; j<vTaskList[i].getLevel(); j++)
|
|
|
+ {
|
|
|
+ vCellContents+='\u00A0\u00A0\u00A0\u00A0';
|
|
|
+ }
|
|
|
|
|
|
- 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>';
|
|
|
+ if(vTaskList[i].getGroup()==1)
|
|
|
+ {
|
|
|
+ vTmpDiv=this.newNode(vTmpCell, 'div', null, null, vCellContents);
|
|
|
+ var vTmpSpan=this.newNode(vTmpDiv, 'span', vDivId+'group_'+vID, 'gfoldercollapse', (vTaskList[i].getOpen()==1)?'-':'+');
|
|
|
+ vTaskList[i].setGroupSpan(vTmpSpan);
|
|
|
+ JSGantt.addFolderListeners(this, vTmpSpan, vID);
|
|
|
+ vTmpDiv.appendChild(document.createTextNode('\u00A0'+vTaskList[i].getName()));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vCellContents+='\u00A0\u00A0\u00A0\u00A0';
|
|
|
+ vTmpDiv=this.newNode(vTmpCell, 'div', null, null, vCellContents+vTaskList[i].getName());
|
|
|
+ }
|
|
|
|
|
|
- } 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>';
|
|
|
+ if(vShowRes==1)
|
|
|
+ {
|
|
|
+ /*vTmpCell=this.newNode(vTmpRow, 'td', null, 'gresource');
|
|
|
+ vTmpDiv=this.newNode(vTmpCell, 'div', null, null, vTaskList[i].getResource());*/
|
|
|
|
|
|
- }
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, 'gresource');
|
|
|
+ var vTmpNode=this.newNode(vTmpCell, 'div', null, '');
|
|
|
+ vTmpNode=this.newNode(vTmpNode, 'a', null, '', vLangs[vLang]['moreinfo']);
|
|
|
+ vTmpNode.setAttribute('href',vTaskList[i].getLink());
|
|
|
+ }
|
|
|
+ if(vShowDur==1)
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, 'gduration');
|
|
|
+ vTmpDiv=this.newNode(vTmpCell, 'div', null, null, vTaskList[i].getDuration(vFormat, vLangs[vLang]));
|
|
|
+ }
|
|
|
+ if(vShowComp==1)
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, 'gpccomplete');
|
|
|
+ vTmpDiv=this.newNode(vTmpCell, 'div', null, null, vTaskList[i].getCompStr());
|
|
|
+ }
|
|
|
+ if(vShowStartDate==1)
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, 'gstartdate');
|
|
|
+ vTmpDiv=this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTaskList[i].getStart(), vDateTaskTableDisplayFormat, vLangs[vLang]));
|
|
|
+ }
|
|
|
+ if(vShowEndDate==1)
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, 'genddate');
|
|
|
+ vTmpDiv=this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTaskList[i].getEnd(), vDateTaskTableDisplayFormat, vLangs[vLang]));
|
|
|
+ }
|
|
|
+ vNumRows++;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- vTmpDate.setDate(vTmpDate.getDate() + 7);
|
|
|
+ // DRAW the date format selector at bottom left.
|
|
|
+ vTmpRow=this.newNode(vTmpTBody, 'tr');
|
|
|
+ this.newNode(vTmpRow, 'td', null, 'gtasklist', '\u00A0');
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, 'gspanning gtaskname');
|
|
|
+ vTmpCell.appendChild(this.drawSelector('bottom'));
|
|
|
+ if(vShowRes==1)this.newNode(vTmpRow, 'td', null, 'gspanning gresource', '\u00A0');
|
|
|
+ if(vShowDur==1)this.newNode(vTmpRow, 'td', null, 'gspanning gduration', '\u00A0');
|
|
|
+ if(vShowComp==1)this.newNode(vTmpRow, 'td', null, 'gspanning gpccomplete', '\u00A0');
|
|
|
+ if(vShowStartDate==1)this.newNode(vTmpRow, 'td', null, 'gspanning gstartdate', '\u00A0');
|
|
|
+ if(vShowEndDate==1)this.newNode(vTmpRow, 'td', null, 'gspanning genddate', '\u00A0');
|
|
|
+ // Add some white space so the vertical scroll distance should always be greater
|
|
|
+ // than for the right pane (keep to a minimum as it is seen in unconstrained height designs)
|
|
|
+ this.newNode(vTmpDiv2, 'br');
|
|
|
+ this.newNode(vTmpDiv2, 'br');
|
|
|
|
|
|
- }
|
|
|
+ // Draw the Chart Rows
|
|
|
+ var vRightHeader=document.createDocumentFragment();
|
|
|
+ vTmpDiv=this.newNode(vRightHeader, 'div', vDivId+'gcharthead', 'gchartlbl gcontainercol');
|
|
|
+ this.setChartHead(vTmpDiv);
|
|
|
+ vTmpTab=this.newNode(vTmpDiv, 'table', vDivId+'chartTableh', 'gcharttableh');
|
|
|
+ vTmpTBody=this.newNode(vTmpTab, 'tbody');
|
|
|
+ vTmpRow=this.newNode(vTmpTBody, 'tr');
|
|
|
+
|
|
|
+ vTmpDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate());
|
|
|
+ if(vFormat=='hour')vTmpDate.setHours(vMinDate.getHours());
|
|
|
+ else vTmpDate.setHours(0);
|
|
|
+ vTmpDate.setMinutes(0);
|
|
|
+ vTmpDate.setSeconds(0);
|
|
|
+ vTmpDate.setMilliseconds(0);
|
|
|
|
|
|
- else if(vFormat == 'month')
|
|
|
+ var vColSpan=1;
|
|
|
+ // Major Date Header
|
|
|
+ while(vTmpDate.getTime()<=vMaxDate.getTime())
|
|
|
{
|
|
|
+ var vHeaderCellClass='gmajorheading';
|
|
|
+ vCellContents='';
|
|
|
|
|
|
- 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>';
|
|
|
- }
|
|
|
-
|
|
|
- vTmpDate.setDate(vTmpDate.getDate() + 1);
|
|
|
-
|
|
|
- while(vTmpDate.getDate() > 1)
|
|
|
- {
|
|
|
- vTmpDate.setDate(vTmpDate.getDate() + 1);
|
|
|
- }
|
|
|
+ if(vFormat=='day')
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, vHeaderCellClass, null, null, null, null, 7);
|
|
|
+ vCellContents+=JSGantt.formatDateStr(vTmpDate,vDayMajorDateDisplayFormat,vLangs[vLang]);
|
|
|
+ vTmpDate.setDate(vTmpDate.getDate()+6);
|
|
|
|
|
|
+ if (vShowEndWeekDate==1) vCellContents+=' - ' +JSGantt.formatDateStr(vTmpDate, vDayMajorDateDisplayFormat,vLangs[vLang]);
|
|
|
+
|
|
|
+ this.newNode(vTmpCell, 'div', null, null, vCellContents, vColWidth*7);
|
|
|
+ vTmpDate.setDate(vTmpDate.getDate()+1);
|
|
|
+ }
|
|
|
+ else if(vFormat=='week')
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, vHeaderCellClass, null, vColWidth);
|
|
|
+ this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTmpDate,vWeekMajorDateDisplayFormat,vLangs[vLang]), vColWidth);
|
|
|
+ vTmpDate.setDate(vTmpDate.getDate()+7);
|
|
|
+ }
|
|
|
+ else if(vFormat=='month')
|
|
|
+ {
|
|
|
+ vColSpan=(12-vTmpDate.getMonth());
|
|
|
+ if (vTmpDate.getFullYear()==vMaxDate.getFullYear()) vColSpan-=(11-vMaxDate.getMonth());
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, vHeaderCellClass, null, null, null, null, vColSpan);
|
|
|
+ this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTmpDate,vMonthMajorDateDisplayFormat,vLangs[vLang]), vColWidth*vColSpan);
|
|
|
+ vTmpDate.setFullYear(vTmpDate.getFullYear()+1,0,1);
|
|
|
+ }
|
|
|
+ else if(vFormat=='quarter')
|
|
|
+ {
|
|
|
+ vColSpan=(4-Math.floor(vTmpDate.getMonth()/3));
|
|
|
+ if (vTmpDate.getFullYear()==vMaxDate.getFullYear()) vColSpan-=(3-Math.floor(vMaxDate.getMonth()/3));
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, vHeaderCellClass, null, null, null, null, vColSpan);
|
|
|
+ this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTmpDate,vQuarterMajorDateDisplayFormat,vLangs[vLang]), vColWidth*vColSpan);
|
|
|
+ vTmpDate.setFullYear(vTmpDate.getFullYear()+1,0,1);
|
|
|
+ }
|
|
|
+ else if(vFormat=='hour')
|
|
|
+ {
|
|
|
+ vColSpan=(24-vTmpDate.getHours());
|
|
|
+ if (vTmpDate.getFullYear()==vMaxDate.getFullYear() &&
|
|
|
+ vTmpDate.getMonth()==vMaxDate.getMonth() &&
|
|
|
+ vTmpDate.getDate()==vMaxDate.getDate()) vColSpan-=(23-vMaxDate.getHours());
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, vHeaderCellClass, null, null, null, null, vColSpan);
|
|
|
+ this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTmpDate,vHourMajorDateDisplayFormat,vLangs[vLang]), vColWidth*vColSpan);
|
|
|
+ vTmpDate.setHours(0);
|
|
|
+ vTmpDate.setDate(vTmpDate.getDate()+1);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- else if(vFormat == 'quarter')
|
|
|
- {
|
|
|
+ vTmpRow=this.newNode(vTmpTBody, 'tr');
|
|
|
|
|
|
- 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>';
|
|
|
- }
|
|
|
-
|
|
|
- vTmpDate.setDate(vTmpDate.getDate() + 81);
|
|
|
-
|
|
|
- while(vTmpDate.getDate() > 1)
|
|
|
- {
|
|
|
- vTmpDate.setDate(vTmpDate.getDate() + 1);
|
|
|
- }
|
|
|
+ // Minor Date header and Cell Rows
|
|
|
+ vTmpDate.setFullYear(vMinDate.getFullYear(), vMinDate.getMonth(), vMinDate.getDate(), vMinDate.getHours());
|
|
|
+ if(vFormat=='hour')vTmpDate.setHours(vMinDate.getHours());
|
|
|
+ vNumCols=0;
|
|
|
|
|
|
- }
|
|
|
- }
|
|
|
+ while(vTmpDate.getTime()<=vMaxDate.getTime())
|
|
|
+ {
|
|
|
+ vHeaderCellClass='gminorheading';
|
|
|
+ var vCellClass='gtaskcell';
|
|
|
|
|
|
- vRightTable += vDateRowStr + '</TR>';
|
|
|
- vRightTable += '</TBODY></TABLE>';
|
|
|
+ if(vFormat=='day')
|
|
|
+ {
|
|
|
+ if(vTmpDate.getDay()%6==0)
|
|
|
+ {
|
|
|
+ vHeaderCellClass+='wkend';
|
|
|
+ vCellClass+='wkend';
|
|
|
+ }
|
|
|
|
|
|
- // Draw each row
|
|
|
+ if(vTmpDate<=vMaxDate)
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, vHeaderCellClass);
|
|
|
+ this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTmpDate,vDayMinorDateDisplayFormat,vLangs[vLang]), vColWidth);
|
|
|
+ vNumCols++;
|
|
|
+ }
|
|
|
|
|
|
- for(i = 0; i < vTaskList.length; i++)
|
|
|
+ vTmpDate.setDate(vTmpDate.getDate()+1);
|
|
|
+ }
|
|
|
+ else if(vFormat=='week')
|
|
|
+ {
|
|
|
+ if(vTmpDate<=vMaxDate)
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, vHeaderCellClass);
|
|
|
+ this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTmpDate,vWeekMinorDateDisplayFormat,vLangs[vLang]), vColWidth);
|
|
|
+ vNumCols++;
|
|
|
+ }
|
|
|
|
|
|
- {
|
|
|
+ vTmpDate.setDate(vTmpDate.getDate()+7);
|
|
|
+ }
|
|
|
+ else if(vFormat=='month')
|
|
|
+ {
|
|
|
+ if(vTmpDate<=vMaxDate)
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, vHeaderCellClass);
|
|
|
+ this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTmpDate,vMonthMinorDateDisplayFormat,vLangs[vLang]), vColWidth);
|
|
|
+ vNumCols++;
|
|
|
+ }
|
|
|
|
|
|
- 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()) {
|
|
|
+ vTmpDate.setDate(vTmpDate.getDate()+1);
|
|
|
|
|
|
- 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>';
|
|
|
+ while(vTmpDate.getDate()>1)
|
|
|
+ {
|
|
|
+ vTmpDate.setDate(vTmpDate.getDate()+1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(vFormat=='quarter')
|
|
|
+ {
|
|
|
+ if(vTmpDate<=vMaxDate)
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, vHeaderCellClass);
|
|
|
+ this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTmpDate,vQuarterMinorDateDisplayFormat,vLangs[vLang]), vColWidth);
|
|
|
+ vNumCols++;
|
|
|
+ }
|
|
|
+
|
|
|
+ vTmpDate.setDate(vTmpDate.getDate()+81);
|
|
|
|
|
|
- // Build date string for Title
|
|
|
- vDateRowStr = JSGantt.formatDateStr(vTaskStart,vDateDisplayFormat);
|
|
|
+ while(vTmpDate.getDate()>1) vTmpDate.setDate(vTmpDate.getDate()+1);
|
|
|
+ }
|
|
|
+ else if(vFormat=='hour')
|
|
|
+ {
|
|
|
+ for(i=vTmpDate.getHours();i<24;i++)
|
|
|
+ {
|
|
|
+ vTmpDate.setHours(i);//works around daylight savings but may look a little odd on days where the clock goes forward
|
|
|
+ if(vTmpDate<=vMaxDate)
|
|
|
+ {
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, vHeaderCellClass);
|
|
|
+ this.newNode(vTmpCell, 'div', null, null, JSGantt.formatDateStr(vTmpDate,vHourMinorDateDisplayFormat,vLangs[vLang]), vColWidth);
|
|
|
+ vNumCols++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ vTmpDate.setHours(0);
|
|
|
+ vTmpDate.setDate(vTmpDate.getDate()+1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ vDateRow=vTmpRow;
|
|
|
|
|
|
- vTaskLeft = (Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / (24 * 60 * 60 * 1000);
|
|
|
- vTaskRight = 1;
|
|
|
+ vTaskLeftPx=(vNumCols *(vColWidth+1))+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(vUseSingleCell!=0 && vUseSingleCell<(vNumCols*vNumRows))vSingleCell=true;
|
|
|
|
|
|
- if(vTaskList[i].getCompVal() < 100)
|
|
|
- {vRightTable += '◊</div>' ;}
|
|
|
- else
|
|
|
- { vRightTable += '♦</div>' ;}
|
|
|
+ this.newNode(vTmpDiv, 'div', null, 'rhscrpad', null, null, vTaskLeftPx+1);
|
|
|
|
|
|
- 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>';
|
|
|
- };
|
|
|
+ var vRightTable=document.createDocumentFragment();
|
|
|
+ vTmpDiv=this.newNode(vRightTable, 'div', vDivId+'gchartbody', 'gchartgrid gcontainercol');
|
|
|
+ this.setChartBody(vTmpDiv);
|
|
|
+ vTmpTab=this.newNode(vTmpDiv, 'table', vDivId+'chartTable', 'gcharttable', null, vTaskLeftPx);
|
|
|
+ this.setChartTable(vTmpTab);
|
|
|
+ this.newNode(vTmpDiv, 'div', null, 'rhscrpad', null, null, vTaskLeftPx+1);
|
|
|
+ vTmpTBody=this.newNode(vTmpTab, 'tbody');
|
|
|
|
|
|
- vRightTable += '</div>';
|
|
|
+ // Draw each row
|
|
|
|
|
|
+ var i=0;
|
|
|
+ var j=0;
|
|
|
+ for(i=0; i<vTaskList.length; i++)
|
|
|
+ {
|
|
|
+ var curTaskStart=vTaskList[i].getStart();
|
|
|
+ var curTaskEnd=vTaskList[i].getEnd();
|
|
|
+ if ((curTaskEnd.getTime()-(curTaskEnd.getTimezoneOffset()*60000))%(86400000)==0) curTaskEnd=new Date(curTaskEnd.getFullYear(), curTaskEnd.getMonth(), curTaskEnd.getDate()+1, curTaskEnd.getHours(), curTaskEnd.getMinutes(), curTaskEnd.getSeconds()); // add 1 day here to simplify calculations below
|
|
|
|
|
|
- } else {
|
|
|
+ vTaskLeftPx=JSGantt.getOffset(vMinDate, curTaskStart, vColWidth, vFormat);
|
|
|
+ vTaskRightPx=JSGantt.getOffset(curTaskStart, curTaskEnd, vColWidth, vFormat);
|
|
|
|
|
|
- // Build date string for Title
|
|
|
- vDateRowStr = JSGantt.formatDateStr(vTaskStart,vDateDisplayFormat) + ' - ' + JSGantt.formatDateStr(vTaskEnd,vDateDisplayFormat);
|
|
|
+ vID=vTaskList[i].getID();
|
|
|
+ var vComb=(vTaskList[i].getParItem() && vTaskList[i].getParItem().getGroup()==2);
|
|
|
+ var vCellFormat='';
|
|
|
|
|
|
- if (vFormat=='minute')
|
|
|
+ var vTmpItem=vTaskList[i];
|
|
|
+ var vCaptionStr='';
|
|
|
+ var vCaptClass=null;
|
|
|
+ if(vTaskList[i].getMile() && !vComb)
|
|
|
{
|
|
|
- vTaskRight = (Date.parse(vTaskList[i].getEnd()) - Date.parse(vTaskList[i].getStart())) / ( 60 * 1000) + 1/vColUnit;
|
|
|
- vTaskLeft = Math.ceil((Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / ( 60 * 1000));
|
|
|
+ vTmpRow=this.newNode(vTmpTBody, 'tr', vDivId+'childrow_'+vID, 'gmileitem gmile'+vFormat, null, null, null, ((vTaskList[i].getVisible()==0)? 'none' : null));
|
|
|
+ vTaskList[i].setChildRow(vTmpRow);
|
|
|
+ JSGantt.addThisRowListeners(this, vTaskList[i].getListChildRow(), vTmpRow);
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, 'gtaskcell');
|
|
|
+ vTmpDiv=this.newNode(vTmpCell, 'div', null, 'gtaskcelldiv', '\u00A0\u00A0');
|
|
|
+ vTmpDiv=this.newNode(vTmpDiv, 'div', vDivId+'bardiv_'+vID, 'gtaskbarcontainer', null, 12, vTaskLeftPx-6);
|
|
|
+ vTaskList[i].setBarDiv(vTmpDiv);
|
|
|
+ vTmpDiv2=this.newNode(vTmpDiv, 'div', vDivId+'taskbar_'+vID, vTaskList[i].getClass(), null, 12);
|
|
|
+ vTaskList[i].setTaskDiv(vTmpDiv2);
|
|
|
+
|
|
|
+ if(vTaskList[i].getCompVal()<100)
|
|
|
+ vTmpDiv2.appendChild(document.createTextNode('\u25CA'));
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vTmpDiv2=this.newNode(vTmpDiv2, 'div', null, 'gmilediamond');
|
|
|
+ this.newNode(vTmpDiv2, 'div', null, 'gmdtop');
|
|
|
+ this.newNode(vTmpDiv2, 'div', null, 'gmdbottom');
|
|
|
+ }
|
|
|
+
|
|
|
+ vCaptClass='gmilecaption';
|
|
|
+
|
|
|
+ if(!vSingleCell && !vComb)
|
|
|
+ {
|
|
|
+ vCellFormat='';
|
|
|
+ for(j=0; j<vNumCols-1; j++)
|
|
|
+ {
|
|
|
+ if(vFormat=='day'&&((j%7==4)||(j%7==5))) vCellFormat='gtaskcellwkend';
|
|
|
+ else vCellFormat='gtaskcell';
|
|
|
+ this.newNode(vTmpRow, 'td', null, vCellFormat, '\u00A0\u00A0');
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- else if (vFormat=='hour')
|
|
|
+ else
|
|
|
{
|
|
|
- vTaskRight = (Date.parse(vTaskList[i].getEnd()) - Date.parse(vTaskList[i].getStart())) / ( 60 * 60 * 1000) + 1/vColUnit;
|
|
|
- vTaskLeft = (Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / ( 60 * 60 * 1000);
|
|
|
+ vTaskWidth=vTaskRightPx-1;
|
|
|
+
|
|
|
+ // Draw Group Bar which has outer div with inner group div and several small divs to left and right to create angled-end indicators
|
|
|
+ if(vTaskList[i].getGroup())
|
|
|
+ {
|
|
|
+ vTaskWidth=(vTaskWidth>vMinGpLen && vTaskWidth<vMinGpLen*2)? vMinGpLen*2 : vTaskWidth; // Expand to show two end points
|
|
|
+ vTaskWidth=(vTaskWidth<vMinGpLen)? vMinGpLen : vTaskWidth; // expand to show one end point
|
|
|
+
|
|
|
+ vTmpRow=this.newNode(vTmpTBody, 'tr', vDivId+'childrow_'+vID, ((vTaskList[i].getGroup()==2)?'glineitem gitem':'ggroupitem ggroup')+vFormat, null, null, null, ((vTaskList[i].getVisible()==0)? 'none' : null));
|
|
|
+ vTaskList[i].setChildRow(vTmpRow);
|
|
|
+ JSGantt.addThisRowListeners(this, vTaskList[i].getListChildRow(), vTmpRow);
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, 'gtaskcell');
|
|
|
+ vTmpDiv=this.newNode(vTmpCell, 'div', null, 'gtaskcelldiv', '\u00A0\u00A0');
|
|
|
+ vTaskList[i].setCellDiv(vTmpDiv);
|
|
|
+ if(vTaskList[i].getGroup()==1)
|
|
|
+ {
|
|
|
+ vTmpDiv=this.newNode(vTmpDiv, 'div', vDivId+'bardiv_'+vID, 'gtaskbarcontainer', null, vTaskWidth, vTaskLeftPx);
|
|
|
+ vTaskList[i].setBarDiv(vTmpDiv);
|
|
|
+ vTmpDiv2=this.newNode(vTmpDiv, 'div', vDivId+'taskbar_'+vID, vTaskList[i].getClass(), null, vTaskWidth);
|
|
|
+ vTaskList[i].setTaskDiv(vTmpDiv2);
|
|
|
+
|
|
|
+ this.newNode(vTmpDiv2, 'div', vDivId+'complete_'+vID, vTaskList[i].getClass() +'complete', null, vTaskList[i].getCompStr());
|
|
|
+
|
|
|
+ this.newNode(vTmpDiv, 'div', null, vTaskList[i].getClass() +'endpointleft');
|
|
|
+ if (vTaskWidth>=vMinGpLen*2) this.newNode(vTmpDiv, 'div', null, vTaskList[i].getClass() +'endpointright');
|
|
|
+
|
|
|
+ vCaptClass='ggroupcaption';
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!vSingleCell && !vComb)
|
|
|
+ {
|
|
|
+ vCellFormat='';
|
|
|
+ for(j=0; j<vNumCols-1; j++)
|
|
|
+ {
|
|
|
+ if(vFormat=='day'&&((j%7==4)||(j%7==5))) vCellFormat='gtaskcellwkend';
|
|
|
+ else vCellFormat='gtaskcell';
|
|
|
+ this.newNode(vTmpRow, 'td', null, vCellFormat, '\u00A0\u00A0');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vTaskWidth=(vTaskWidth<=0)? 1 : vTaskWidth;
|
|
|
+
|
|
|
+ if(vComb)
|
|
|
+ {
|
|
|
+ vTmpDiv=vTaskList[i].getParItem().getCellDiv();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vTmpRow=this.newNode(vTmpTBody, 'tr', vDivId+'childrow_'+vID, 'glineitem gitem'+vFormat, null, null, null, ((vTaskList[i].getVisible()==0)? 'none' : null));
|
|
|
+ vTaskList[i].setChildRow(vTmpRow);
|
|
|
+ JSGantt.addThisRowListeners(this, vTaskList[i].getListChildRow(), vTmpRow);
|
|
|
+ vTmpCell=this.newNode(vTmpRow, 'td', null, 'gtaskcell');
|
|
|
+ vTmpDiv=this.newNode(vTmpCell, 'div', null, 'gtaskcelldiv', '\u00A0\u00A0');
|
|
|
+ }
|
|
|
+ // Draw Task Bar which has colored bar div, and opaque completion div
|
|
|
+ vTmpDiv=this.newNode(vTmpDiv, 'div', vDivId+'bardiv_'+vID, 'gtaskbarcontainer', null, vTaskWidth, vTaskLeftPx);
|
|
|
+ vTaskList[i].setBarDiv(vTmpDiv);
|
|
|
+ vTmpDiv2=this.newNode(vTmpDiv, 'div', vDivId+'taskbar_'+vID, vTaskList[i].getClass(), null, vTaskWidth);
|
|
|
+ vTaskList[i].setTaskDiv(vTmpDiv2);
|
|
|
+ this.newNode(vTmpDiv2, 'div', vDivId+'complete_'+vID, vTaskList[i].getClass() +'complete', null, vTaskList[i].getCompStr());
|
|
|
+
|
|
|
+ if(vComb)vTmpItem=vTaskList[i].getParItem();
|
|
|
+ if(!vComb || (vComb && vTaskList[i].getParItem().getEnd()==vTaskList[i].getEnd())) vCaptClass='gcaption';
|
|
|
+
|
|
|
+ if(!vSingleCell && !vComb)
|
|
|
+ {
|
|
|
+ vCellFormat='';
|
|
|
+ for(j=0; j<vNumCols-1; j++)
|
|
|
+ {
|
|
|
+ if(vFormat=='day'&&((j%7==4)||(j%7==5))) vCellFormat='gtaskcellwkend';
|
|
|
+ else vCellFormat='gtaskcell';
|
|
|
+ this.newNode(vTmpRow, 'td', null, vCellFormat, '\u00A0\u00A0');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- else
|
|
|
+
|
|
|
+ if(this.getCaptionType() && vCaptClass!==null)
|
|
|
{
|
|
|
- vTaskRight = (Date.parse(vTaskList[i].getEnd()) - Date.parse(vTaskList[i].getStart())) / (24 * 60 * 60 * 1000) + 1/vColUnit;
|
|
|
- vTaskLeft = Math.ceil((Date.parse(vTaskList[i].getStart()) - Date.parse(vMinDate)) / (24 * 60 * 60 * 1000));
|
|
|
- if (vFormat='day')
|
|
|
+ switch(this.getCaptionType())
|
|
|
{
|
|
|
- var tTime=new Date();
|
|
|
- tTime.setTime(Date.parse(vTaskList[i].getStart()));
|
|
|
- if (tTime.getMinutes() > 29)
|
|
|
- vTaskLeft+=.5;
|
|
|
+ case 'Caption': var vCaptionStr=vTmpItem.getCaption(); break;
|
|
|
+ case 'Resource': vCaptionStr=vTmpItem.getResource(); break;
|
|
|
+ case 'Duration': vCaptionStr=vTmpItem.getDuration(vFormat, vLangs[vLang]); break;
|
|
|
+ case 'Complete': vCaptionStr=vTmpItem.getCompStr(); break;
|
|
|
}
|
|
|
+ this.newNode(vTmpDiv, 'div', null, vCaptClass, vCaptionStr, 120, (vCaptClass=='gmilecaption')?12:0);
|
|
|
}
|
|
|
|
|
|
- // Draw Group Bar which has outer div with inner group div and several small divs to left and right to create angled-end indicators
|
|
|
- if( vTaskList[i].getGroup()) {
|
|
|
- vRightTable += '<DIV><TABLE style="position:relative; top:0px; width: ' + vChartWidth + 'px;" cellSpacing=0 cellPadding=0 border=0>' +
|
|
|
- '<TR id=childrow_' + vID + ' class=yesdisplay style="HEIGHT: 20px" bgColor=#f3f3f3 onMouseover=g.mouseOver(this,' + vID + ',"right","group") onMouseout=g.mouseOut(this,' + vID + ',"right","group")>' + vItemRowStr + '</TR></TABLE></DIV>';
|
|
|
- vRightTable +=
|
|
|
- '<div id=bardiv_' + vID + ' style="position:absolute; top:5px; left:' + Math.ceil(vTaskLeft * (vDayWidth) + 1) + 'px; height: 7px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px">' +
|
|
|
- '<div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr + '" class=gtask style="background-color:#000000; height: 7px; width:' + Math.ceil((vTaskRight) * (vDayWidth) -1) + 'px; cursor: pointer;opacity:0.9;">' +
|
|
|
- '<div style="Z-INDEX: -4; float:left; background-color:#666666; height:3px; overflow: hidden; margin-top:1px; ' +
|
|
|
- 'margin-left:1px; margin-right:1px; filter: alpha(opacity=80); opacity:0.8; width:' + vTaskList[i].getCompStr() + '; ' +
|
|
|
- 'cursor: pointer;" onclick=JSGantt.taskLink("' + vTaskList[i].getLink() + '",300,200);>' +
|
|
|
- '</div>' +
|
|
|
- '</div>' +
|
|
|
- '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:4px; overflow: hidden; width:1px;"></div>' +
|
|
|
- '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:4px; overflow: hidden; width:1px;"></div>' +
|
|
|
- '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:3px; overflow: hidden; width:1px;"></div>' +
|
|
|
- '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:3px; overflow: hidden; width:1px;"></div>' +
|
|
|
- '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:2px; overflow: hidden; width:1px;"></div>' +
|
|
|
- '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:2px; overflow: hidden; width:1px;"></div>' +
|
|
|
- '<div style="Z-INDEX: -4; float:left; background-color:#000000; height:1px; overflow: hidden; width:1px;"></div>' +
|
|
|
- '<div style="Z-INDEX: -4; float:right; background-color:#000000; height:1px; overflow: hidden; width:1px;"></div>' ;
|
|
|
-
|
|
|
- if( g.getCaptionType() ) {
|
|
|
- vCaptionStr = '';
|
|
|
- switch( g.getCaptionType() ) {
|
|
|
- case 'Caption': vCaptionStr = vTaskList[i].getCaption(); break;
|
|
|
- case 'Resource': vCaptionStr = vTaskList[i].getResource(); break;
|
|
|
- case 'Duration': vCaptionStr = vTaskList[i].getDuration(vFormat); break;
|
|
|
- case 'Complete': vCaptionStr = vTaskList[i].getCompStr(); break;
|
|
|
- }
|
|
|
- //vRightTable += '<div style="FONT-SIZE:12px; position:absolute; left: 6px; top:1px;">' + vCaptionStr + '</div>';
|
|
|
- vRightTable += '<div style="FONT-SIZE:12px; position:absolute; top:-3px; width:120px; left:' + (Math.ceil((vTaskRight) * (vDayWidth) - 1) + 6) + 'px">' + vCaptionStr + '</div>';
|
|
|
- };
|
|
|
-
|
|
|
- vRightTable += '</div>' ;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- vDivStr = '<DIV><TABLE style="position:relative; top:0px; width: ' + vChartWidth + 'px;" cellSpacing=0 cellPadding=0 border=0>' +
|
|
|
- '<TR id=childrow_' + vID + ' class=yesdisplay style="HEIGHT: 20px" bgColor=#ffffff onMouseover=g.mouseOver(this,' + vID + ',"right","row") onMouseout=g.mouseOut(this,' + vID + ',"right","row")>' + vItemRowStr + '</TR></TABLE></DIV>';
|
|
|
- vRightTable += vDivStr;
|
|
|
-
|
|
|
- // Draw Task Bar which has outer DIV with enclosed colored bar div, and opaque completion div
|
|
|
- vRightTable +=
|
|
|
- '<div id=bardiv_' + vID + ' style="position:absolute; top:4px; left:' + Math.ceil(vTaskLeft * (vDayWidth) + 1) + 'px; height:18px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px">' +
|
|
|
- '<div id=taskbar_' + vID + ' title="' + vTaskList[i].getName() + ': ' + vDateRowStr + '" class=gtask style="background-color:#' + vTaskList[i].getColor() +'; height: 13px; width:' + Math.ceil((vTaskRight) * (vDayWidth) - 1) + 'px; cursor: pointer;opacity:0.9;" ' +
|
|
|
- 'onclick=JSGantt.taskLink("' + vTaskList[i].getLink() + '",300,200); >' +
|
|
|
- '<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>';
|
|
|
-
|
|
|
- if( g.getCaptionType() ) {
|
|
|
- vCaptionStr = '';
|
|
|
- switch( g.getCaptionType() ) {
|
|
|
- case 'Caption': vCaptionStr = vTaskList[i].getCaption(); break;
|
|
|
- case 'Resource': vCaptionStr = vTaskList[i].getResource(); break;
|
|
|
- case 'Duration': vCaptionStr = vTaskList[i].getDuration(vFormat); break;
|
|
|
- case 'Complete': vCaptionStr = vTaskList[i].getCompStr(); break;
|
|
|
- }
|
|
|
- //vRightTable += '<div style="FONT-SIZE:12px; position:absolute; left: 6px; top:-3px;">' + vCaptionStr + '</div>';
|
|
|
- vRightTable += '<div style="FONT-SIZE:12px; position:absolute; top:-3px; width:120px; left:' + (Math.ceil((vTaskRight) * (vDayWidth) - 1) + 6) + 'px">' + vCaptionStr + '</div>';
|
|
|
- }
|
|
|
- vRightTable += '</div>' ;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
+ if (vTaskList[i].getTaskDiv() && vTmpDiv)
|
|
|
+ {
|
|
|
+ // Add Task Info div for tooltip
|
|
|
+ vTmpDiv2=this.newNode(vTmpDiv, 'div', vDivId+'tt'+vID, null, null, null, null, 'none');
|
|
|
+ vTmpDiv2.appendChild(this.createTaskInfo(vTaskList[i]));
|
|
|
+ JSGantt.addTooltipListeners(this, vTaskList[i].getTaskDiv(), vTmpDiv2);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- vRightTable += '</DIV>';
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- vMainTable += vRightTable + '</DIV></TD></TR></TBODY></TABLE></BODY></HTML>';
|
|
|
-
|
|
|
- vDiv.innerHTML = vMainTable;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }; //this.draw
|
|
|
-
|
|
|
-/**
|
|
|
-* Mouseover behaviour for gantt row
|
|
|
-* @method mouseOver
|
|
|
-* @return {Void}
|
|
|
-*/ 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";
|
|
|
- };
|
|
|
-
|
|
|
-/**
|
|
|
-* Mouseout behaviour for gantt row
|
|
|
-* @method mouseOut
|
|
|
-* @return {Void}
|
|
|
-*/ 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";
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
+ if(!vSingleCell) vTmpTBody.appendChild(vDateRow.cloneNode(true));
|
|
|
+
|
|
|
+ while(vDiv.hasChildNodes())vDiv.removeChild(vDiv.firstChild);
|
|
|
+ vTmpDiv=this.newNode(vDiv, 'div', null, 'gchartcontainer');
|
|
|
+ vTmpDiv.appendChild(vRightHeader);
|
|
|
+ vTmpDiv.appendChild(vLeftHeader);
|
|
|
+ vTmpDiv.appendChild(vRightTable);
|
|
|
+ vTmpDiv.appendChild(vLeftTable);
|
|
|
+ this.newNode(vTmpDiv, 'div', null, 'ggridfooter');
|
|
|
+ vTmpDiv2=this.newNode(this.getChartBody(), 'div', vDivId+'Lines', 'glinediv');
|
|
|
+ vTmpDiv2.style.visibility='hidden';
|
|
|
+ this.setLines(vTmpDiv2);
|
|
|
+
|
|
|
+ /* Quick hack to show the generated HTML on older browsers - add a '/' to the begining of this line to activate
|
|
|
+ var tmpGenSrc=document.createElement('textarea');
|
|
|
+ tmpGenSrc.appendChild(document.createTextNode(vTmpDiv.innerHTML));
|
|
|
+ vDiv.appendChild(tmpGenSrc);
|
|
|
+ //*/
|
|
|
+ // Now all the content exists, register scroll listeners
|
|
|
+ JSGantt.addScrollListeners(this);
|
|
|
+
|
|
|
+ // now check if we are actually scrolling the pane
|
|
|
+ if (vScrollTo!='')
|
|
|
+ {
|
|
|
+ var vScrollDate=new Date(vMinDate.getTime());
|
|
|
+ var vScrollPx=0;
|
|
|
|
|
|
-}; //GanttChart
|
|
|
+ if(vScrollTo.substr(0,2)=='px')
|
|
|
+ {
|
|
|
+ vScrollPx=parseInt(vScrollTo.substr(2));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vScrollDate=JSGantt.parseDateStr(vScrollTo, this.getDateInputFormat());
|
|
|
+ if(vFormat=='hour')vScrollDate.setMinutes(0,0,0);
|
|
|
+ else vScrollDate.setHours(0,0,0,0);
|
|
|
+ vScrollPx=JSGantt.getOffset(vMinDate, vScrollDate, vColWidth, vFormat);
|
|
|
+ }
|
|
|
+ this.getChartBody().scrollLeft=vScrollPx;
|
|
|
+ }
|
|
|
|
|
|
+ if (vMinDate.getTime()<=(new Date()).getTime() && vMaxDate.getTime()>=(new Date()).getTime()) vTodayPx=JSGantt.getOffset(vMinDate, new Date(), vColWidth, vFormat);
|
|
|
+ else vTodayPx=-1;
|
|
|
+ this.DrawDependencies();
|
|
|
+ }
|
|
|
+ }; //this.draw
|
|
|
+
|
|
|
+ this.mouseOver=function(pObj1, pObj2)
|
|
|
+ {
|
|
|
+ if (this.getUseRowHlt())
|
|
|
+ {
|
|
|
+ pObj1.className+=' gitemhighlight';
|
|
|
+ pObj2.className+=' gitemhighlight';
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ this.mouseOut=function(pObj1, pObj2)
|
|
|
+ {
|
|
|
+ if (this.getUseRowHlt())
|
|
|
+ {
|
|
|
+ pObj1.className=pObj1.className.replace(/(?:^|\s)gitemhighlight(?!\S)/g, '');
|
|
|
+ pObj2.className=pObj2.className.replace(/(?:^|\s)gitemhighlight(?!\S)/g, '');
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ this.drawSelector=function(pPos)
|
|
|
+ {
|
|
|
+ var vOutput=document.createDocumentFragment();
|
|
|
+ var vDisplay=false;
|
|
|
+
|
|
|
+ for (var i=0; i<vShowSelector.length && !vDisplay; i++)
|
|
|
+ {
|
|
|
+ if (vShowSelector[i].toLowerCase()==pPos.toLowerCase()) vDisplay=true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (vDisplay)
|
|
|
+ {
|
|
|
+ var vTmpDiv=this.newNode(vOutput, 'div', null, 'gselector', vLangs[vLang]['format']+':');
|
|
|
+
|
|
|
+ if (vFormatArr.join().toLowerCase().indexOf('hour')!=-1)
|
|
|
+ JSGantt.addFormatListeners(this, 'hour', this.newNode(vTmpDiv, 'span', vDivId+'formathour'+pPos, 'gformlabel'+((vFormat=='hour')?' gselected':''), vLangs[vLang]['hour']));
|
|
|
+
|
|
|
+ if (vFormatArr.join().toLowerCase().indexOf('day')!=-1)
|
|
|
+ JSGantt.addFormatListeners(this, 'day', this.newNode(vTmpDiv, 'span', vDivId+'formatday'+pPos, 'gformlabel'+((vFormat=='day')?' gselected':''), vLangs[vLang]['day']));
|
|
|
+
|
|
|
+ if (vFormatArr.join().toLowerCase().indexOf('week')!=-1)
|
|
|
+ JSGantt.addFormatListeners(this, 'week', this.newNode(vTmpDiv, 'span', vDivId+'formatweek'+pPos, 'gformlabel'+((vFormat=='week')?' gselected':''), vLangs[vLang]['week']));
|
|
|
+
|
|
|
+ if (vFormatArr.join().toLowerCase().indexOf('month')!=-1)
|
|
|
+ JSGantt.addFormatListeners(this, 'month', this.newNode(vTmpDiv, 'span', vDivId+'formatmonth'+pPos, 'gformlabel'+((vFormat=='month')?' gselected':''), vLangs[vLang]['month']));
|
|
|
+
|
|
|
+ if (vFormatArr.join().toLowerCase().indexOf('quarter')!=-1)
|
|
|
+ JSGantt.addFormatListeners(this, 'quarter', this.newNode(vTmpDiv, 'span', vDivId+'formatquarter'+pPos, 'gformlabel'+((vFormat=='quarter')?' gselected':''), vLangs[vLang]['quarter']));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ this.newNode(vOutput, 'div', null, 'gselector');
|
|
|
+ }
|
|
|
+ return vOutput;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.createTaskInfo=function(pTask)
|
|
|
+ {
|
|
|
+ var vTmpDiv;
|
|
|
+ var vTaskInfoBox=document.createDocumentFragment();
|
|
|
+ var vTaskInfo=this.newNode(vTaskInfoBox, 'div', null, 'gTaskInfo');
|
|
|
+ this.newNode(vTaskInfo, 'span', null, 'gTtTitle', pTask.getName());
|
|
|
+ if(vShowTaskInfoStartDate==1){
|
|
|
+ vTmpDiv=this.newNode(vTaskInfo, 'div', null, 'gTILine gTIsd');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskLabel', vLangs[vLang]['startdate']+': ');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskText', JSGantt.formatDateStr(pTask.getStart(), vDateTaskDisplayFormat,vLangs[vLang]));
|
|
|
+ }
|
|
|
+ if(vShowTaskInfoEndDate==1){
|
|
|
+ vTmpDiv=this.newNode(vTaskInfo, 'div', null, 'gTILine gTIed');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskLabel', vLangs[vLang]['enddate']+': ');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskText', JSGantt.formatDateStr(pTask.getEnd(), vDateTaskDisplayFormat,vLangs[vLang]));
|
|
|
+ }
|
|
|
+ if(vShowTaskInfoDur==1 && !pTask.getMile()){
|
|
|
+ vTmpDiv=this.newNode(vTaskInfo, 'div', null, 'gTILine gTId');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskLabel', vLangs[vLang]['duration']+': ');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskText', pTask.getDuration(vFormat, vLangs[vLang]));
|
|
|
+ }
|
|
|
+ if(vShowTaskInfoComp==1){
|
|
|
+ vTmpDiv=this.newNode(vTaskInfo, 'div', null, 'gTILine gTIc');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskLabel', vLangs[vLang]['completion']+': ');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskText', pTask.getCompStr());
|
|
|
+ }
|
|
|
+ if(vShowTaskInfoRes==1){
|
|
|
+ vTmpDiv=this.newNode(vTaskInfo, 'div', null, 'gTILine gTIr');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskLabel', vLangs[vLang]['resource']+': ');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskText', pTask.getResource());
|
|
|
+ }
|
|
|
+ if(vShowTaskInfoLink==1 && pTask.getLink()!=''){
|
|
|
+ vTmpDiv=this.newNode(vTaskInfo, 'div', null, 'gTILine gTIl');
|
|
|
+ var vTmpNode=this.newNode(vTmpDiv, 'span', null, 'gTaskLabel');
|
|
|
+ vTmpNode=this.newNode(vTmpNode, 'a', null, 'gTaskText', vLangs[vLang]['moreinfo']);
|
|
|
+ vTmpNode.setAttribute('href',pTask.getLink());
|
|
|
+ }
|
|
|
+ if(vShowTaskInfoNotes==1){
|
|
|
+ vTmpDiv=this.newNode(vTaskInfo, 'div', null, 'gTILine gTIn');
|
|
|
+ this.newNode(vTmpDiv, 'span', null, 'gTaskLabel', vLangs[vLang]['notes']+': ');
|
|
|
+ if(pTask.getNotes())vTmpDiv.appendChild(pTask.getNotes());
|
|
|
+ }
|
|
|
+ return vTaskInfoBox;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.getXMLProject=function()
|
|
|
+ {
|
|
|
+ var vProject='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
|
|
|
+ for (var i=0; i<vTaskList.length; i++)
|
|
|
+ {
|
|
|
+ vProject+=this.getXMLTask(i,true);
|
|
|
+ }
|
|
|
+ vProject+='</project>';
|
|
|
+ return vProject;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.getXMLTask=function(pID,pIdx)
|
|
|
+ {
|
|
|
+ var i=0;
|
|
|
+ var vIdx=-1;
|
|
|
+ var vTask='';
|
|
|
+ var vOutFrmt=JSGantt.parseDateFormatStr(this.getDateInputFormat()+' HH:MI');
|
|
|
+ if (pIdx===true)vIdx=pID;
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for (i=0; i<vTaskList.length; i++)
|
|
|
+ {
|
|
|
+ if (vTaskList[i].getID()==pID) {vIdx=i; break;}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (vIdx>=0 && vIdx<vTaskList.length)
|
|
|
+ {
|
|
|
+ /* Simplest way to return case sensitive node names is to just build a string */
|
|
|
+ vTask='<task>';
|
|
|
+ vTask+='<pID>'+vTaskList[vIdx].getID()+'</pID>';
|
|
|
+ vTask+='<pName>'+vTaskList[vIdx].getName()+'</pName>';
|
|
|
+ vTask+='<pStart>'+JSGantt.formatDateStr(vTaskList[vIdx].getStart(),vOutFrmt,vLangs[vLang])+'</pStart>';
|
|
|
+ vTask+='<pEnd>'+JSGantt.formatDateStr(vTaskList[vIdx].getEnd(),vOutFrmt,vLangs[vLang])+'</pEnd>';
|
|
|
+ vTask+='<pClass>'+vTaskList[vIdx].getClass()+'</pClass>';
|
|
|
+ vTask+='<pLink>'+vTaskList[vIdx].getLink()+'</pLink>';
|
|
|
+ vTask+='<pMile>'+vTaskList[vIdx].getMile()+'</pMile>';
|
|
|
+ if(vTaskList[vIdx].getResource()!='\u00A0') vTask+='<pRes>'+vTaskList[vIdx].getResource()+'</pRes>';
|
|
|
+ vTask+='<pComp>'+vTaskList[vIdx].getCompVal()+'</pComp>';
|
|
|
+ vTask+='<pGroup>'+vTaskList[vIdx].getGroup()+'</pGroup>';
|
|
|
+ vTask+='<pParent>'+vTaskList[vIdx].getParent()+'</pParent>';
|
|
|
+ vTask+='<pOpen>'+vTaskList[vIdx].getOpen()+'</pOpen>';
|
|
|
+ vTask+='<pDepend>';
|
|
|
+ var vDepList=vTaskList[vIdx].getDepend();
|
|
|
+ for (i=0;i<vDepList.length;i++)
|
|
|
+ {
|
|
|
+ if(i>0)vTask+=',';
|
|
|
+ if(vDepList[i]>0)vTask+=vDepList[i]+vTaskList[vIdx].getDepType()[i];
|
|
|
+ }
|
|
|
+ vTask+='</pDepend>';
|
|
|
+ vTask+='<pCaption>'+vTaskList[vIdx].getCaption()+'</pCaption>';
|
|
|
+
|
|
|
+ var vTmpFrag=document.createDocumentFragment();
|
|
|
+ var vTmpDiv=this.newNode(vTmpFrag, 'div', null, null,vTaskList[vIdx].getNotes().innerHTML);
|
|
|
+ vTask+='<pNotes>'+vTmpDiv.innerHTML+'</pNotes>';
|
|
|
+ vTask+='</task>';
|
|
|
+ }
|
|
|
+ return vTask;
|
|
|
+ };
|
|
|
+ if (vDiv && vDiv.nodeName.toLowerCase()=='div') vDivId=vDiv.id;
|
|
|
+}; //GanttChart
|
|
|
|
|
|
-/**
|
|
|
-*
|
|
|
-@class
|
|
|
-*/
|
|
|
-
|
|
|
-/**
|
|
|
-* Checks whether browser is IE
|
|
|
-*
|
|
|
-* @method isIE
|
|
|
-*/
|
|
|
-JSGantt.isIE = function () {
|
|
|
-
|
|
|
- if(typeof document.all != 'undefined')
|
|
|
- {return true;}
|
|
|
- else
|
|
|
- {return false;}
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
-* Recursively process task tree ... set min, max dates of parent tasks and identfy task level.
|
|
|
-*
|
|
|
-* @method processRows
|
|
|
-* @param pList {Array} - Array of TaskItem Objects
|
|
|
-* @param pID {Number} - task ID
|
|
|
-* @param pRow {Number} - Row in chart
|
|
|
-* @param pLevel {Number} - Current tree level
|
|
|
-* @param pOpen {Boolean}
|
|
|
-* @return void
|
|
|
-*/
|
|
|
-JSGantt.processRows = function(pList, pID, pRow, pLevel, pOpen)
|
|
|
-{
|
|
|
+JSGantt.updateFlyingObj=function (e, pGanttChartObj, pTimer) {
|
|
|
+ var vCurTopBuf=3;
|
|
|
+ var vCurLeftBuf=5;
|
|
|
+ var vCurBotBuf=3;
|
|
|
+ var vCurRightBuf=15;
|
|
|
+ var vMouseX=(e)?e.clientX:window.event.clientX;
|
|
|
+ var vMouseY=(e)?e.clientY:window.event.clientY;
|
|
|
+ var vViewportX=document.documentElement.clientWidth||document.getElementsByTagName('body')[0].clientWidth;
|
|
|
+ var vViewportY=document.documentElement.clientHeight||document.getElementsByTagName('body')[0].clientHeight;
|
|
|
+ var vNewX=vMouseX;
|
|
|
+ var vNewY=vMouseY;
|
|
|
+
|
|
|
+ if (navigator.appName.toLowerCase ()=='microsoft internet explorer') {
|
|
|
+ // the clientX and clientY properties include the left and top borders of the client area
|
|
|
+ vMouseX-=document.documentElement.clientLeft;
|
|
|
+ vMouseY-=document.documentElement.clientTop;
|
|
|
+
|
|
|
+ var vZoomFactor=JSGantt.getZoomFactor ();
|
|
|
+ if (vZoomFactor!=1) {// IE 7 at non-default zoom level
|
|
|
+ vMouseX=Math.round (vMouseX / vZoomFactor);
|
|
|
+ vMouseY=Math.round (vMouseY / vZoomFactor);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- 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));
|
|
|
- }
|
|
|
+ var vScrollPos=JSGantt.getScrollPositions();
|
|
|
+
|
|
|
+ /* Code for positioned right of the mouse by default*/
|
|
|
+ /*
|
|
|
+ if (vMouseX+vCurRightBuf+pGanttChartObj.vTool.offsetWidth>vViewportX)
|
|
|
+ {
|
|
|
+ if (vMouseX-vCurLeftBuf-pGanttChartObj.vTool.offsetWidth<0) vNewX=vScrollPos.x;
|
|
|
+ else vNewX=vMouseX+vScrollPos.x-vCurLeftBuf-pGanttChartObj.vTool.offsetWidth;
|
|
|
+ }
|
|
|
+ else vNewX=vMouseX+vScrollPos.x+vCurRightBuf;
|
|
|
+ */
|
|
|
+
|
|
|
+ /* Code for positioned left of the mouse by default */
|
|
|
+ if (vMouseX-vCurLeftBuf-pGanttChartObj.vTool.offsetWidth<0)
|
|
|
+ {
|
|
|
+ if (vMouseX+vCurRightBuf+pGanttChartObj.vTool.offsetWidth>vViewportX) vNewX=vScrollPos.x;
|
|
|
+ else vNewX=vMouseX+vScrollPos.x+vCurRightBuf;
|
|
|
+ }
|
|
|
+ else vNewX=vMouseX+vScrollPos.x-vCurLeftBuf-pGanttChartObj.vTool.offsetWidth;
|
|
|
|
|
|
+ /* Code for positioned below the mouse by default */
|
|
|
+ if (vMouseY+vCurBotBuf+pGanttChartObj.vTool.offsetHeight>vViewportY)
|
|
|
+ {
|
|
|
+ if (vMouseY-vCurTopBuf-pGanttChartObj.vTool.offsetHeight<0) vNewY=vScrollPos.y;
|
|
|
+ else vNewY=vMouseY+vScrollPos.y-vCurTopBuf-pGanttChartObj.vTool.offsetHeight;
|
|
|
+ }
|
|
|
+ else vNewY=vMouseY+vScrollPos.y+vCurBotBuf;
|
|
|
+
|
|
|
+ /* Code for positioned above the mouse by default */
|
|
|
+ /*
|
|
|
+ if (vMouseY-vCurTopBuf-pGanttChartObj.vTool.offsetHeight<0)
|
|
|
+ {
|
|
|
+ if (vMouseY+vCurBotBuf+pGanttChartObj.vTool.offsetHeight>vViewportY) vNewY=vScrollPos.y;
|
|
|
+ else vNewY=vMouseY+vScrollPos.y+vCurBotBuf;
|
|
|
+ }
|
|
|
+ else vNewY=vMouseY+vScrollPos.y-vCurTopBuf-pGanttChartObj.vTool.offsetHeight;
|
|
|
+ */
|
|
|
+
|
|
|
+ if (pGanttChartObj.getUseMove())
|
|
|
+ {
|
|
|
+ clearInterval(pGanttChartObj.vTool.moveInterval);
|
|
|
+ pGanttChartObj.vTool.moveInterval=setInterval(function(){JSGantt.moveToolTip(vNewX, vNewY, pGanttChartObj.vTool, pTimer);},pTimer);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pGanttChartObj.vTool.style.left=vNewX +'px';
|
|
|
+ pGanttChartObj.vTool.style.top=vNewY +'px';
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
-* Determine the minimum date of all tasks and set lower bound based on format
|
|
|
-*
|
|
|
-* @method getMinDate
|
|
|
-* @param pList {Array} - Array of TaskItem Objects
|
|
|
-* @param pFormat {String} - current format (minute,hour,day...)
|
|
|
-* @return {Datetime}
|
|
|
-*/
|
|
|
-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)
|
|
|
+JSGantt.showToolTip=function(pGanttChartObj, e, pContents, pWidth, pTimer){
|
|
|
+ var vTtDivId=pGanttChartObj.getDivId()+'JSGanttToolTip';
|
|
|
+ var vMaxW=500;
|
|
|
+ var vMaxAlpha=100;
|
|
|
+ var vShowing=pContents.id;
|
|
|
+
|
|
|
+ if(pGanttChartObj.getUseToolTip())
|
|
|
+ {
|
|
|
+ if(pGanttChartObj.vTool==null){
|
|
|
+ pGanttChartObj.vTool=document.createElement('div');
|
|
|
+ pGanttChartObj.vTool.id=vTtDivId;
|
|
|
+ pGanttChartObj.vTool.className='JSGanttToolTip';
|
|
|
+ pGanttChartObj.vTool.vToolCont=document.createElement('div');
|
|
|
+ pGanttChartObj.vTool.vToolCont.id=vTtDivId+'cont';
|
|
|
+ pGanttChartObj.vTool.vToolCont.className='JSGanttToolTipcont';
|
|
|
+ pGanttChartObj.vTool.vToolCont.setAttribute('showing','');
|
|
|
+ pGanttChartObj.vTool.appendChild(pGanttChartObj.vTool.vToolCont);
|
|
|
+ document.body.appendChild(pGanttChartObj.vTool);
|
|
|
+ pGanttChartObj.vTool.style.opacity=0;
|
|
|
+ pGanttChartObj.vTool.setAttribute('currentOpacity',0);
|
|
|
+ pGanttChartObj.vTool.setAttribute('fadeIncrement',10);
|
|
|
+ pGanttChartObj.vTool.setAttribute('moveSpeed',10);
|
|
|
+ pGanttChartObj.vTool.style.filter='alpha(opacity=0)';
|
|
|
+ pGanttChartObj.vTool.style.visibility='hidden';
|
|
|
+ pGanttChartObj.vTool.style.left=Math.floor(((e)?e.clientX:window.event.clientX)/2)+'px';
|
|
|
+ pGanttChartObj.vTool.style.top=Math.floor(((e)?e.clientY:window.event.clientY)/2)+'px';
|
|
|
+ JSGantt.addListener('mouseover', function () {clearTimeout(pGanttChartObj.vTool.delayTimeout);}, pGanttChartObj.vTool);
|
|
|
+ JSGantt.addListener('mouseout', function () {JSGantt.delayedHide(pGanttChartObj, pGanttChartObj.vTool, pTimer);}, pGanttChartObj.vTool);
|
|
|
+ }
|
|
|
+ clearTimeout(pGanttChartObj.vTool.delayTimeout);
|
|
|
+ if(pGanttChartObj.vTool.vToolCont.getAttribute('showing')!=vShowing || pGanttChartObj.vTool.style.visibility!='visible')
|
|
|
+ {
|
|
|
+ if (pGanttChartObj.vTool.vToolCont.getAttribute('showing')!=vShowing)
|
|
|
{
|
|
|
- vDate.setDate(vDate.getDate() - 1);
|
|
|
- }
|
|
|
+ pGanttChartObj.vTool.vToolCont.setAttribute('showing',vShowing);
|
|
|
|
|
|
- }
|
|
|
+ pGanttChartObj.vTool.vToolCont.innerHTML=pContents.innerHTML;
|
|
|
+ // as we are allowing arbitrary HTML we should remove any tag ids to prevent duplication
|
|
|
+ JSGantt.stripIds(pGanttChartObj.vTool.vToolCont);
|
|
|
+ }
|
|
|
|
|
|
- else if (pFormat=='week')
|
|
|
- {
|
|
|
- vDate.setDate(vDate.getDate() - 7);
|
|
|
- while(vDate.getDay() % 7 > 0)
|
|
|
- {
|
|
|
- vDate.setDate(vDate.getDate() - 1);
|
|
|
+ pGanttChartObj.vTool.style.visibility='visible';
|
|
|
+ // Rather than follow the mouse just have it stay put
|
|
|
+ JSGantt.updateFlyingObj(e, pGanttChartObj, pTimer);
|
|
|
+ pGanttChartObj.vTool.style.width=(pWidth)? pWidth+'px' : 'auto';
|
|
|
+ if(!pWidth && JSGantt.isIE()){
|
|
|
+ pGanttChartObj.vTool.style.width=pGanttChartObj.vTool.offsetWidth;
|
|
|
}
|
|
|
+ if(pGanttChartObj.vTool.offsetWidth>vMaxW){pGanttChartObj.vTool.style.width=vMaxW+'px';}
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pGanttChartObj.getUseFade())
|
|
|
+ {
|
|
|
+ clearInterval(pGanttChartObj.vTool.fadeInterval);
|
|
|
+ pGanttChartObj.vTool.fadeInterval=setInterval(function(){JSGantt.fadeToolTip(1, pGanttChartObj.vTool, vMaxAlpha);},pTimer);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pGanttChartObj.vTool.style.opacity=vMaxAlpha * 0.01;
|
|
|
+ pGanttChartObj.vTool.style.filter='alpha(opacity='+vMaxAlpha+')';
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+JSGantt.stripIds=function(pNode){
|
|
|
+ for(var i=0; i<pNode.childNodes.length; i++)
|
|
|
+ {
|
|
|
+ if ('removeAttribute' in pNode.childNodes[i]) pNode.childNodes[i].removeAttribute('id');
|
|
|
+ if (pNode.childNodes[i].hasChildNodes()) JSGantt.stripIds(pNode.childNodes[i]);
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- }
|
|
|
+JSGantt.stripUnwanted=function(pNode){
|
|
|
+ var vAllowedTags=new Array('#text','p','br','ul','ol','li','div','span','img');
|
|
|
+ for(var i=0; i<pNode.childNodes.length; i++)
|
|
|
+ {
|
|
|
+ /* versions of IE<9 don't support indexOf on arrays so add trailing comma to the joined array and lookup value to stop substring matches */
|
|
|
+ if ((vAllowedTags.join().toLowerCase()+',').indexOf(pNode.childNodes[i].nodeName.toLowerCase()+',')==-1)
|
|
|
+ {
|
|
|
+ pNode.replaceChild(document.createTextNode(pNode.childNodes[i].outerHTML), pNode.childNodes[i]);
|
|
|
+ }
|
|
|
+ if (pNode.childNodes[i].hasChildNodes()) JSGantt.stripUnwanted(pNode.childNodes[i]);
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- else if (pFormat=='month')
|
|
|
- {
|
|
|
- while(vDate.getDate() > 1)
|
|
|
- {
|
|
|
- vDate.setDate(vDate.getDate() - 1);
|
|
|
- }
|
|
|
- }
|
|
|
+JSGantt.delayedHide=function(pGanttChartObj, pTool, pTimer){
|
|
|
+ var vDelay=1500;
|
|
|
+ if(pTool) pTool.delayTimeout=setTimeout(function(){JSGantt.hideToolTip(pGanttChartObj, pTool, pTimer);}, vDelay);
|
|
|
+};
|
|
|
|
|
|
- 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);}
|
|
|
+JSGantt.hideToolTip=function(pGanttChartObj, pTool, pTimer){
|
|
|
+ if (pGanttChartObj.getUseFade())
|
|
|
+ {
|
|
|
+ clearInterval(pTool.fadeInterval);
|
|
|
+ pTool.fadeInterval=setInterval(function(){JSGantt.fadeToolTip(-1, pTool, 0);}, pTimer);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pTool.style.opacity=0;
|
|
|
+ pTool.style.filter='alpha(opacity=0)';
|
|
|
+ pTool.style.visibility='hidden';
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- };
|
|
|
+JSGantt.fadeToolTip=function(pDirection, pTool, pMaxAlpha){
|
|
|
+ var vIncrement=parseInt(pTool.getAttribute('fadeIncrement'));
|
|
|
+ var vAlpha=pTool.getAttribute('currentOpacity');
|
|
|
+ var vCurAlpha=parseInt(vAlpha);
|
|
|
+ if((vCurAlpha!=pMaxAlpha && pDirection==1) || (vCurAlpha!=0 && pDirection==-1)){
|
|
|
+ var i=vIncrement;
|
|
|
+ if(pMaxAlpha-vCurAlpha<vIncrement && pDirection==1){
|
|
|
+ i=pMaxAlpha-vCurAlpha;
|
|
|
+ }else if(vAlpha<vIncrement && pDirection==-1){
|
|
|
+ i=vCurAlpha;
|
|
|
+ }
|
|
|
+ vAlpha=vCurAlpha+(i * pDirection);
|
|
|
+ pTool.style.opacity=vAlpha * 0.01;
|
|
|
+ pTool.style.filter='alpha(opacity='+vAlpha+')';
|
|
|
+ pTool.setAttribute('currentOpacity', vAlpha);
|
|
|
+ }else{
|
|
|
+ clearInterval(pTool.fadeInterval);
|
|
|
+ if(pDirection==-1){
|
|
|
+ pTool.style.opacity=0;
|
|
|
+ pTool.style.filter='alpha(opacity=0)';
|
|
|
+ pTool.style.visibility='hidden';
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- return(vDate);
|
|
|
+JSGantt.moveToolTip=function(pNewX, pNewY, pTool){
|
|
|
+ var vSpeed=parseInt(pTool.getAttribute('moveSpeed'));
|
|
|
+ var vOldX=parseInt(pTool.style.left);
|
|
|
+ var vOldY=parseInt(pTool.style.top);
|
|
|
|
|
|
- };
|
|
|
+ if (pTool.style.visibility!='visible')
|
|
|
+ {
|
|
|
+ pTool.style.left=pNewX +'px';
|
|
|
+ pTool.style.top=pNewY +'px';
|
|
|
+ clearInterval(pTool.moveInterval);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(pNewX!=vOldX && pNewY!=vOldY)
|
|
|
+ {
|
|
|
+ vOldX+=Math.ceil((pNewX-vOldX)/vSpeed);
|
|
|
+ vOldY+=Math.ceil((pNewY-vOldY)/vSpeed);
|
|
|
+ pTool.style.left=vOldX +'px';
|
|
|
+ pTool.style.top=vOldY +'px';
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ clearInterval(pTool.moveInterval);
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
+JSGantt.getZoomFactor=function() {
|
|
|
+ var vFactor=1;
|
|
|
+ if (document.body.getBoundingClientRect)
|
|
|
+ {
|
|
|
+ // rect is only in physical pixel size in IE before version 8
|
|
|
+ var vRect=document.body.getBoundingClientRect ();
|
|
|
+ var vPhysicalW=vRect.right-vRect.left;
|
|
|
+ var vLogicalW=document.body.offsetWidth;
|
|
|
+
|
|
|
+ // the zoom level is always an integer percent value
|
|
|
+ vFactor=Math.round ((vPhysicalW / vLogicalW) * 100) / 100;
|
|
|
+ }
|
|
|
+ return vFactor;
|
|
|
+};
|
|
|
|
|
|
+JSGantt.getScrollPositions=function() {
|
|
|
+ var vScrollLeft=window.pageXOffset;
|
|
|
+ var vScrollTop=window.pageYOffset;
|
|
|
+ if (!('pageXOffset' in window)) // Internet Explorer before version 9
|
|
|
+ {
|
|
|
+ var vZoomFactor=JSGantt.getZoomFactor ();
|
|
|
+ vScrollLeft=Math.round (document.documentElement.scrollLeft / vZoomFactor);
|
|
|
+ vScrollTop=Math.round (document.documentElement.scrollTop / vZoomFactor);
|
|
|
+ }
|
|
|
+ return {x : vScrollLeft, y : vScrollTop};
|
|
|
+};
|
|
|
|
|
|
+JSGantt.getOffset=function(pStartDate, pEndDate, pColWidth, pFormat)
|
|
|
+{
|
|
|
+ var vMonthDaysArr=new Array(31,28,31,30,31,30,31,31,30,31,30,31);
|
|
|
+ var curTaskStart=new Date(pStartDate.getTime());
|
|
|
+ var curTaskEnd=new Date(pEndDate.getTime());
|
|
|
+ var vTaskRightPx=0;
|
|
|
+ var tmpTaskStart=Date.UTC(curTaskStart.getFullYear(), curTaskStart.getMonth(), curTaskStart.getDate(), curTaskStart.getHours(), 0, 0);
|
|
|
+ var tmpTaskEnd=Date.UTC(curTaskEnd.getFullYear(), curTaskEnd.getMonth(), curTaskEnd.getDate(), curTaskEnd.getHours(), 0, 0);
|
|
|
+
|
|
|
+ var vTaskRight=(tmpTaskEnd-tmpTaskStart)/3600000; // Length of task in hours
|
|
|
+
|
|
|
+ if(pFormat=='day')
|
|
|
+ {
|
|
|
+ vTaskRightPx=Math.ceil((vTaskRight/24) * (pColWidth+1));
|
|
|
+ }
|
|
|
+ else if(pFormat=='week')
|
|
|
+ {
|
|
|
+ vTaskRightPx=Math.ceil(((vTaskRight/24) * (pColWidth+1))/7);
|
|
|
+ }
|
|
|
+ else if(pFormat=='month')
|
|
|
+ {
|
|
|
+ var vMonthsDiff=(12 * (curTaskEnd.getFullYear()-curTaskStart.getFullYear()))+(curTaskEnd.getMonth()-curTaskStart.getMonth());
|
|
|
+ var vPosTmpDate=new Date(curTaskEnd.getTime());
|
|
|
+ vPosTmpDate.setDate(curTaskStart.getDate());
|
|
|
+ var vDaysCrctn=(curTaskEnd.getTime()-vPosTmpDate.getTime())/ (86400000);
|
|
|
+
|
|
|
+ vTaskRightPx=Math.ceil((vMonthsDiff * (pColWidth+1))+(vDaysCrctn * (pColWidth/vMonthDaysArr[curTaskEnd.getMonth()])));
|
|
|
+ }
|
|
|
+ else if(pFormat=='quarter')
|
|
|
+ {
|
|
|
+ vMonthsDiff=(12 * (curTaskEnd.getFullYear()-curTaskStart.getFullYear()))+(curTaskEnd.getMonth()-curTaskStart.getMonth());
|
|
|
+ vPosTmpDate=new Date(curTaskEnd.getTime());
|
|
|
+ vPosTmpDate.setDate(curTaskStart.getDate());
|
|
|
+ vDaysCrctn=(curTaskEnd.getTime()-vPosTmpDate.getTime())/ (86400000);
|
|
|
+
|
|
|
+ vTaskRightPx=Math.ceil((vMonthsDiff * ((pColWidth+1)/3))+(vDaysCrctn * (pColWidth/90)));
|
|
|
+ }
|
|
|
+ else if(pFormat=='hour')
|
|
|
+ {
|
|
|
+ // can't just calculate sum because of daylight savings changes
|
|
|
+ vPosTmpDate=new Date(curTaskEnd.getTime());
|
|
|
+ vPosTmpDate.setMinutes(curTaskStart.getMinutes(), 0);
|
|
|
+ var vMinsCrctn=(curTaskEnd.getTime()-vPosTmpDate.getTime())/(3600000);
|
|
|
+
|
|
|
+ vTaskRightPx=Math.ceil((vTaskRight * (pColWidth+1))+(vMinsCrctn * (pColWidth)));
|
|
|
+ }
|
|
|
+ return vTaskRightPx;
|
|
|
+};
|
|
|
|
|
|
-/**
|
|
|
-* Used to determine the minimum date of all tasks and set lower bound based on format
|
|
|
-*
|
|
|
-* @method getMaxDate
|
|
|
-* @param pList {Array} - Array of TaskItem Objects
|
|
|
-* @param pFormat {String} - current format (minute,hour,day...)
|
|
|
-* @return {Datetime}
|
|
|
-*/
|
|
|
-JSGantt.getMaxDate = function (pList, pFormat)
|
|
|
+// Recursively process task tree ... set min, max dates of parent tasks and identfy task level.
|
|
|
+JSGantt.processRows=function(pList, pID, pRow, pLevel, pOpen, pUseSort)
|
|
|
{
|
|
|
- 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))
|
|
|
+ var vMinDate=new Date();
|
|
|
+ var vMaxDate=new Date();
|
|
|
+ var vVisible=pOpen;
|
|
|
+ var vCurItem=null;
|
|
|
+ var vCompSum=0;
|
|
|
+ var vMinSet=0;
|
|
|
+ var vMaxSet=0;
|
|
|
+ var vNumKid=0;
|
|
|
+ var vLevel=pLevel;
|
|
|
+ var vList=pList;
|
|
|
+ var vComb=false;
|
|
|
+ var i=0;
|
|
|
+
|
|
|
+ for(i=0; i<pList.length; i++)
|
|
|
+ {
|
|
|
+ if (pList[i].getToDelete())
|
|
|
+ {
|
|
|
+ pList.splice(i,1);
|
|
|
+ i--;
|
|
|
+ }
|
|
|
+ if (i>=0 && pList[i].getID()==pID)vCurItem=pList[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ for(i=0; i<pList.length; i++)
|
|
|
+ {
|
|
|
+ if(pList[i].getParent()==pID)
|
|
|
+ {
|
|
|
+ vVisible=pOpen;
|
|
|
+ pList[i].setParItem(vCurItem);
|
|
|
+ pList[i].setVisible(vVisible);
|
|
|
+ if(vVisible==1 && pList[i].getOpen()==0) vVisible=0;
|
|
|
+
|
|
|
+ if(pList[i].getMile() && pList[i].getParItem() && pList[i].getParItem().getGroup()==2)
|
|
|
+ {//remove milestones owned by combined groups
|
|
|
+ pList.splice(i,1);
|
|
|
+ i--;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ pList[i].setLevel(vLevel);
|
|
|
+ vNumKid++;
|
|
|
+
|
|
|
+ if(pList[i].getGroup())
|
|
|
{
|
|
|
- //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)
|
|
|
+ if(pList[i].getParItem() && pList[i].getParItem().getGroup()==2)pList[i].setGroup(2);
|
|
|
+ JSGantt.processRows(vList, pList[i].getID(), i, vLevel+1, vVisible, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(vMinSet==0 || pList[i].getStart()<vMinDate)
|
|
|
+ {
|
|
|
+ vMinDate=pList[i].getStart();
|
|
|
+ vMinSet=1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(vMaxSet==0 || pList[i].getEnd()>vMaxDate)
|
|
|
{
|
|
|
- vDate.setDate(vDate.getDate() + 1);
|
|
|
+ vMaxDate=pList[i].getEnd();
|
|
|
+ vMaxSet=1;
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ vCompSum+=pList[i].getCompVal();
|
|
|
+ pList[i].setSortIdx(i*pList.length);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if (pFormat=='week')
|
|
|
- {
|
|
|
- //For weeks, what is the last logical boundary?
|
|
|
- vDate.setDate(vDate.getDate() + 11);
|
|
|
+ if(pRow>=0)
|
|
|
+ {
|
|
|
+ if(pList[pRow].getGroupMinStart()!=null && pList[pRow].getGroupMinStart()<vMinDate)
|
|
|
+ {
|
|
|
+ vMinDate=pList[pRow].getGroupMinStart();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(pList[pRow].getGroupMinEnd()!=null && pList[pRow].getGroupMinEnd()>vMaxDate)
|
|
|
+ {
|
|
|
+ vMaxDate=pList[pRow].getGroupMinEnd();
|
|
|
+ }
|
|
|
+ pList[pRow].setStart(vMinDate);
|
|
|
+ pList[pRow].setEnd(vMaxDate);
|
|
|
+ pList[pRow].setNumKid(vNumKid);
|
|
|
+ pList[pRow].setCompVal(Math.ceil(vCompSum/vNumKid));
|
|
|
+ }
|
|
|
|
|
|
- while(vDate.getDay() % 6 > 0)
|
|
|
+ if (pID==0 && pUseSort==1)
|
|
|
+ {
|
|
|
+ JSGantt.sortTasks(pList, 0, 0);
|
|
|
+ pList.sort(function(a,b){return a.getSortIdx()-b.getSortIdx();});
|
|
|
+ }
|
|
|
+ if (pID==0 && pUseSort!=1) // Need to sort combined tasks regardless
|
|
|
+ {
|
|
|
+ for(i=0; i<pList.length; i++)
|
|
|
+ {
|
|
|
+ if (pList[i].getGroup()==2)
|
|
|
{
|
|
|
- vDate.setDate(vDate.getDate() + 1);
|
|
|
+ vComb=true;
|
|
|
+ JSGantt.sortTasks(pList, pList[i].getID(), pList[i].getSortIdx()+1);
|
|
|
}
|
|
|
+ }
|
|
|
+ if(vComb==true) pList.sort(function(a,b){return a.getSortIdx()-b.getSortIdx();});
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- }
|
|
|
+JSGantt.sortTasks=function (pList, pID, pIdx)
|
|
|
+{
|
|
|
+ var sortIdx=pIdx;
|
|
|
+ var sortArr=new Array();
|
|
|
+
|
|
|
+ for(var i=0; i<pList.length; i++)
|
|
|
+ {
|
|
|
+ if(pList[i].getParent()==pID)sortArr.push(pList[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sortArr.length>0)
|
|
|
+ {
|
|
|
+ sortArr.sort(function(a,b){ var i=a.getStart().getTime()-b.getStart().getTime();
|
|
|
+ if (i==0) i=a.getEnd().getTime()-b.getEnd().getTime();
|
|
|
+ if (i==0) return a.getID()-b.getID();
|
|
|
+ else return i; });
|
|
|
+ }
|
|
|
|
|
|
- // Set to last day of current Month
|
|
|
- if (pFormat=='month')
|
|
|
- {
|
|
|
- while(vDate.getDay() > 1)
|
|
|
+ for (var j=0; j<sortArr.length; j++)
|
|
|
+ {
|
|
|
+ for(i=0; i<pList.length; i++)
|
|
|
+ {
|
|
|
+ if(pList[i].getID()==sortArr[j].getID())
|
|
|
{
|
|
|
- vDate.setDate(vDate.getDate() + 1);
|
|
|
+ pList[i].setSortIdx(sortIdx++);
|
|
|
+ sortIdx=JSGantt.sortTasks(pList, pList[i].getID(), sortIdx);
|
|
|
}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return sortIdx;
|
|
|
+};
|
|
|
|
|
|
- vDate.setDate(vDate.getDate() - 1);
|
|
|
- }
|
|
|
+// 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.setTime(pList[0].getStart().getTime());
|
|
|
|
|
|
- // 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);
|
|
|
+ // Parse all Task End dates to find min
|
|
|
+ for(var i=0; i<pList.length; i++)
|
|
|
+ {
|
|
|
+ if(pList[i].getStart().getTime()<vDate.getTime()) vDate.setTime(pList[i].getStart().getTime());
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ // Adjust min date to specific format boundaries (first of week or first of month)
|
|
|
+ if (pFormat=='day')
|
|
|
+ {
|
|
|
+ vDate.setDate(vDate.getDate()-1);
|
|
|
+ while(vDate.getDay()%7!=1) vDate.setDate(vDate.getDate()-1);
|
|
|
+ }
|
|
|
+ else if (pFormat=='week')
|
|
|
+ {
|
|
|
+ vDate.setDate(vDate.getDate()-1);
|
|
|
+ while(vDate.getDay()%7!=1) vDate.setDate(vDate.getDate()-1);
|
|
|
+ }
|
|
|
+ else if (pFormat=='month')
|
|
|
+ {
|
|
|
+ vDate.setDate(vDate.getDate()-15);
|
|
|
+ while(vDate.getDate()>1) vDate.setDate(vDate.getDate()-1);
|
|
|
+ }
|
|
|
+ else if (pFormat=='quarter')
|
|
|
+ {
|
|
|
+ vDate.setDate(vDate.getDate()-31);
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ else if (pFormat=='hour')
|
|
|
+ {
|
|
|
+ vDate.setHours(vDate.getHours()-1);
|
|
|
+ while(vDate.getHours()%6!=0) vDate.setHours(vDate.getHours()-1);
|
|
|
+ }
|
|
|
|
|
|
- return(vDate);
|
|
|
+ if(pFormat=='hour')vDate.setMinutes(0,0);
|
|
|
+ else vDate.setHours(0,0,0);
|
|
|
+ return(vDate);
|
|
|
+};
|
|
|
|
|
|
- };
|
|
|
+// Used to determine the maximum date of all tasks and set upper bound based on format
|
|
|
+JSGantt.getMaxDate=function (pList, pFormat)
|
|
|
+{
|
|
|
+ var vDate=new Date();
|
|
|
|
|
|
+ vDate.setTime(pList[0].getEnd().getTime());
|
|
|
|
|
|
-/**
|
|
|
-* Returns an object from the current DOM
|
|
|
-*
|
|
|
-* @method findObj
|
|
|
-* @param theObj {String} - Object name
|
|
|
-* @param theDoc {Document} - current document (DOM)
|
|
|
-* @return {Object}
|
|
|
-*/
|
|
|
-JSGantt.findObj = function (theObj, theDoc)
|
|
|
+ // Parse all Task End dates to find max
|
|
|
+ for(var i=0; i<pList.length; i++)
|
|
|
+ {
|
|
|
+ if(pList[i].getEnd().getTime()>vDate.getTime()) vDate.setTime(pList[i].getEnd().getTime());
|
|
|
+ }
|
|
|
|
|
|
- {
|
|
|
+ // Adjust max date to specific format boundaries (end of week or end of month)
|
|
|
+ if (pFormat=='day')
|
|
|
+ {
|
|
|
+ vDate.setDate(vDate.getDate()+1);
|
|
|
|
|
|
- var p, i, foundObj;
|
|
|
+ while(vDate.getDay()%7!=0) vDate.setDate(vDate.getDate()+1);
|
|
|
+ }
|
|
|
+ else if (pFormat=='week')
|
|
|
+ {
|
|
|
+ //For weeks, what is the last logical boundary?
|
|
|
+ vDate.setDate(vDate.getDate()+1);
|
|
|
|
|
|
- if(!theDoc) {theDoc = document;}
|
|
|
+ while(vDate.getDay()%7!=0) vDate.setDate(vDate.getDate()+1);
|
|
|
+ }
|
|
|
+ else if (pFormat=='month')
|
|
|
+ {
|
|
|
+ // Set to last day of current Month
|
|
|
+ while(vDate.getDate()>1) vDate.setDate(vDate.getDate()+1);
|
|
|
+ vDate.setDate(vDate.getDate()-1);
|
|
|
+ }
|
|
|
+ else if (pFormat=='quarter')
|
|
|
+ {
|
|
|
+ // Set to last day of current 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);
|
|
|
+ }
|
|
|
+ else if (pFormat=='hour')
|
|
|
+ {
|
|
|
+ if(vDate.getHours()==0)vDate.setDate(vDate.getDate()+1);
|
|
|
+ vDate.setHours(vDate.getHours()+1);
|
|
|
|
|
|
- if( (p = theObj.indexOf("?")) > 0 && parent.frames.length){
|
|
|
+ while(vDate.getHours()%6!=5) vDate.setHours(vDate.getHours()+1);
|
|
|
+ }
|
|
|
+ return(vDate);
|
|
|
+};
|
|
|
|
|
|
- theDoc = parent.frames[theObj.substring(p+1)].document;
|
|
|
+// This function finds the document id of the specified object
|
|
|
+JSGantt.findObj=function (theObj, theDoc)
|
|
|
+{
|
|
|
+ var p, i, foundObj;
|
|
|
+ if(!theDoc) theDoc=document;
|
|
|
+ if(document.getElementById) foundObj=document.getElementById(theObj);
|
|
|
+ return foundObj;
|
|
|
+};
|
|
|
|
|
|
- theObj = theObj.substring(0,p);
|
|
|
+JSGantt.changeFormat=function(pFormat,ganttObj)
|
|
|
+{
|
|
|
+ if(ganttObj) ganttObj.setFormat(pFormat);
|
|
|
+ else alert('Chart undefined');
|
|
|
+};
|
|
|
|
|
|
- }
|
|
|
+// Function to open/close and hide/show children of specified task
|
|
|
+JSGantt.folder=function (pID,ganttObj)
|
|
|
+{
|
|
|
+ var vList=ganttObj.getList();
|
|
|
+ var vDivId=ganttObj.getDivId();
|
|
|
|
|
|
- if(!(foundObj = theDoc[theObj]) && theDoc.all)
|
|
|
+ ganttObj.clearDependencies(); // clear these first so slow rendering doesn't look odd
|
|
|
|
|
|
- {foundObj = theDoc.all[theObj];}
|
|
|
+ for(var 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())
|
|
|
+ vList[i].getGroupSpan().innerText='+';
|
|
|
+ else
|
|
|
+ vList[i].getGroupSpan().textContent='+';
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vList[i].setOpen(1);
|
|
|
+ JSGantt.show(pID, 1, ganttObj);
|
|
|
|
|
|
+ if (JSGantt.isIE())
|
|
|
+ vList[i].getGroupSpan().innerText='-';
|
|
|
+ else
|
|
|
+ vList[i].getGroupSpan().textContent='-';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ganttObj.DrawDependencies();
|
|
|
+};
|
|
|
|
|
|
- for (i=0; !foundObj && i < theDoc.forms.length; i++)
|
|
|
+JSGantt.hide=function (pID,ganttObj)
|
|
|
+{
|
|
|
+ var vList=ganttObj.getList();
|
|
|
+ var vID=0;
|
|
|
+ var vDivId=ganttObj.getDivId();
|
|
|
+
|
|
|
+ for(var i=0; i<vList.length; i++)
|
|
|
+ {
|
|
|
+ if(vList[i].getParent()==pID)
|
|
|
+ {
|
|
|
+ vID=vList[i].getID();
|
|
|
+ // it's unlikely but if the task list has been updated since
|
|
|
+ // the chart was drawn some of the rows may not exist
|
|
|
+ if (vList[i].getListChildRow()) vList[i].getListChildRow().style.display='none';
|
|
|
+ if (vList[i].getChildRow()) vList[i].getChildRow().style.display='none';
|
|
|
+ vList[i].setVisible(0);
|
|
|
+ if(vList[i].getGroup()) JSGantt.hide(vID,ganttObj);
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- {foundObj = theDoc.forms[i][theObj];}
|
|
|
+// Function to show children of specified task
|
|
|
+JSGantt.show=function (pID, pTop, ganttObj)
|
|
|
+{
|
|
|
+ var vList=ganttObj.getList();
|
|
|
+ var vID=0;
|
|
|
+ var vDivId=ganttObj.getDivId();
|
|
|
+ var vState='';
|
|
|
+
|
|
|
+ for(var i=0; i<vList.length; i++)
|
|
|
+ {
|
|
|
+ if(vList[i].getParent()==pID)
|
|
|
+ {
|
|
|
+ if (vList[i].getParItem().getGroupSpan())
|
|
|
+ {
|
|
|
+ if (JSGantt.isIE()) vState=vList[i].getParItem().getGroupSpan().innerText;
|
|
|
+ else vState=vList[i].getParItem().getGroupSpan().textContent;
|
|
|
+ }
|
|
|
+ i=vList.length;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ for(i=0; i<vList.length; i++)
|
|
|
+ {
|
|
|
+ if(vList[i].getParent()==pID)
|
|
|
+ {
|
|
|
+ var vChgState=false;
|
|
|
+ vID=vList[i].getID();
|
|
|
|
|
|
+ if(pTop==1 && vState=='+')vChgState=true;
|
|
|
+ else if(vState=='-')vChgState=true;
|
|
|
+ else if(vList[i].getParItem() && vList[i].getParItem().getGroup()==2)vList[i].setVisible(1);
|
|
|
|
|
|
- for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++)
|
|
|
+ if(vChgState)
|
|
|
+ {
|
|
|
+ if (vList[i].getListChildRow()) vList[i].getListChildRow().style.display='';
|
|
|
+ if (vList[i].getChildRow()) vList[i].getChildRow().style.display='';
|
|
|
+ vList[i].setVisible(1);
|
|
|
+ }
|
|
|
+ if(vList[i].getGroup()) JSGantt.show(vID, 0,ganttObj);
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- {foundObj = JSGantt.findObj(theObj,theDoc.layers[i].document);}
|
|
|
+// function to open window to display task link
|
|
|
+JSGantt.taskLink=function(pRef,pWidth,pHeight)
|
|
|
+{
|
|
|
|
|
|
+ if(pWidth) var vWidth =pWidth; else vWidth =400;
|
|
|
+ if(pHeight) var vHeight=pHeight; else vHeight=400;
|
|
|
|
|
|
+ var OpenWindow=window.open(pRef, 'newwin', 'height='+vHeight+',width='+vWidth);
|
|
|
+};
|
|
|
|
|
|
- if(!foundObj && document.getElementById)
|
|
|
+JSGantt.parseDateStr=function(pDateStr,pFormatStr)
|
|
|
+{
|
|
|
+ var vDate=new Date();
|
|
|
+ var vDateParts=pDateStr.split(/[^0-9]/);
|
|
|
+ if (pDateStr.length>=10 && vDateParts.length>=3)
|
|
|
+ {
|
|
|
+ while(vDateParts.length<5)vDateParts.push(0);
|
|
|
+
|
|
|
+ switch(pFormatStr)
|
|
|
+ {
|
|
|
+ case 'mm/dd/yyyy':
|
|
|
+ vDate=new Date(vDateParts[2], vDateParts[0]-1, vDateParts[1], vDateParts[3], vDateParts[4]);
|
|
|
+ break;
|
|
|
+ case 'dd/mm/yyyy':
|
|
|
+ vDate=new Date(vDateParts[2], vDateParts[1]-1, vDateParts[0], vDateParts[3], vDateParts[4]);
|
|
|
+ break;
|
|
|
+ case 'yyyy-mm-dd':
|
|
|
+ vDate=new Date(vDateParts[0], vDateParts[1]-1, vDateParts[2], vDateParts[3], vDateParts[4]);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return(vDate);
|
|
|
+};
|
|
|
|
|
|
- {foundObj = document.getElementById(theObj);}
|
|
|
+JSGantt.formatDateStr=function(pDate, pDateFormatArr, pL)
|
|
|
+{
|
|
|
+ var vDateStr='';
|
|
|
+
|
|
|
+ var vYear2Str=pDate.getFullYear().toString().substring(2,4);
|
|
|
+ var vMonthStr=(pDate.getMonth()+1)+'';
|
|
|
+ var vMonthArr=new Array(pL['january'],pL['february'],pL['march'],pL['april'],pL['maylong'],pL['june'],pL['july'],pL['august'],pL['september'],pL['october'],pL['november'],pL['december']);
|
|
|
+ var vDayArr=new Array(pL['sunday'],pL['monday'],pL['tuesday'],pL['wednesday'],pL['thursday'],pL['friday'],pL['saturday']);
|
|
|
+ var vMthArr=new Array(pL['jan'],pL['feb'],pL['mar'],pL['apr'],pL['may'],pL['jun'],pL['jul'],pL['aug'],pL['sep'],pL['oct'],pL['nov'],pL['dec']);
|
|
|
+ var vDyArr=new Array(pL['sun'],pL['mon'],pL['tue'],pL['wed'],pL['thu'],pL['fri'],pL['sat']);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ for (var i=0; i<pDateFormatArr.length; i++)
|
|
|
+ {
|
|
|
+ switch(pDateFormatArr[i])
|
|
|
+ {
|
|
|
+ case 'dd':
|
|
|
+ if (pDate.getDate()<10) vDateStr+='0'; // now fall through
|
|
|
+ case 'd':
|
|
|
+ vDateStr+=pDate.getDate();
|
|
|
+ break;
|
|
|
+ case 'day':
|
|
|
+ vDateStr+=vDyArr[pDate.getDay()];
|
|
|
+ break;
|
|
|
+ case 'DAY':
|
|
|
+ vDateStr+=vDayArr[pDate.getDay()];
|
|
|
+ break;
|
|
|
+ case 'mm':
|
|
|
+ if (vMonthStr<10) vDateStr+='0'; // now fall through
|
|
|
+ case 'm':
|
|
|
+ vDateStr+=vMonthStr;
|
|
|
+ break;
|
|
|
+ case 'mon':
|
|
|
+ vDateStr+=vMthArr[pDate.getMonth()];
|
|
|
+ break;
|
|
|
+ case 'month':
|
|
|
+ vDateStr+=vMonthArr[pDate.getMonth()];
|
|
|
+ break;
|
|
|
+ case 'yyyy':
|
|
|
+ vDateStr+=pDate.getFullYear();
|
|
|
+ break;
|
|
|
+ case 'yy':
|
|
|
+ vDateStr+=vYear2Str;
|
|
|
+ break;
|
|
|
+ case 'qq':
|
|
|
+ vDateStr+='Q'; // now fall through
|
|
|
+ case 'q':
|
|
|
+ vDateStr+=Math.floor(pDate.getMonth()/3)+1;
|
|
|
+ break;
|
|
|
+ case 'hh':
|
|
|
+ if ((((pDate.getHours()%12)==0)?12:pDate.getHours()%12)<10) vDateStr+='0'; // now fall through
|
|
|
+ case 'h':
|
|
|
+ vDateStr+=((pDate.getHours()%12)==0)?12:pDate.getHours()%12;
|
|
|
+ break;
|
|
|
+ case 'HH':
|
|
|
+ if ((pDate.getHours())<10) vDateStr+='0'; // now fall through
|
|
|
+ case 'H':
|
|
|
+ vDateStr+=(pDate.getHours());
|
|
|
+ break;
|
|
|
+ case 'MI':
|
|
|
+ if (pDate.getMinutes()<10) vDateStr+='0'; // now fall through
|
|
|
+ case 'mi':
|
|
|
+ vDateStr+=pDate.getMinutes();
|
|
|
+ break;
|
|
|
+ case 'pm':
|
|
|
+ vDateStr+=((pDate.getHours())<12)?'am':'pm';
|
|
|
+ break;
|
|
|
+ case 'PM':
|
|
|
+ vDateStr+=((pDate.getHours())<12)?'AM':'PM';
|
|
|
+ break;
|
|
|
+ case 'ww':
|
|
|
+ if (JSGantt.getIsoWeek(pDate)<10) vDateStr+='0'; // now fall through
|
|
|
+ case 'w':
|
|
|
+ vDateStr+=JSGantt.getIsoWeek(pDate);
|
|
|
+ break;
|
|
|
+ case 'week':
|
|
|
+ var vWeekNum=JSGantt.getIsoWeek(pDate);
|
|
|
+ var vYear=pDate.getFullYear();
|
|
|
+ var vDayOfWeek=(pDate.getDay()==0)? 7 : pDate.getDay();
|
|
|
+ if (vWeekNum>=52 && vMonthStr==1) vYear--;
|
|
|
+ if (vWeekNum==1 && vMonthStr==12) vYear++;
|
|
|
+ if (vWeekNum<10) vWeekNum='0'+vWeekNum;
|
|
|
+
|
|
|
+ vDateStr+=vYear+'-W'+vWeekNum+'-'+vDayOfWeek;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ if (pL[pDateFormatArr[i].toLowerCase()]) vDateStr+=pL[pDateFormatArr[i].toLowerCase()];
|
|
|
+ else vDateStr+=pDateFormatArr[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return vDateStr;
|
|
|
+};
|
|
|
|
|
|
+JSGantt.parseDateFormatStr=function(pFormatStr)
|
|
|
+{
|
|
|
+ var vDateStr='';
|
|
|
+ var vComponantStr='';
|
|
|
+ var vCurrChar='';
|
|
|
+ var vSeparators=new RegExp('[\/\\ -.,\'":]');
|
|
|
+ var vDateFormatArray=new Array();
|
|
|
+
|
|
|
+ for (var i=0; i<pFormatStr.length; i++)
|
|
|
+ {
|
|
|
+ vCurrChar=pFormatStr.charAt(i);
|
|
|
+ if ((vCurrChar.match(vSeparators)) || (i+1==pFormatStr.length)) // separator or end of string
|
|
|
+ {
|
|
|
+ if ((i+1==pFormatStr.length) && (!(vCurrChar.match(vSeparators)))) // at end of string add any non-separator chars to the current component
|
|
|
+ {
|
|
|
+ vComponantStr+=vCurrChar;
|
|
|
+ }
|
|
|
+ vDateFormatArray.push(vComponantStr);
|
|
|
+ if (vCurrChar.match(vSeparators)) vDateFormatArray.push(vCurrChar);
|
|
|
+ vComponantStr='';
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ vComponantStr+=vCurrChar;
|
|
|
+ }
|
|
|
|
|
|
+ }
|
|
|
+ return vDateFormatArray;
|
|
|
+};
|
|
|
|
|
|
- return foundObj;
|
|
|
+JSGantt.parseXML=function(pFile,pGanttVar)
|
|
|
+{
|
|
|
+ if (window.XMLHttpRequest) {
|
|
|
+ var xhttp=new XMLHttpRequest();
|
|
|
+ } else { // IE 5/6
|
|
|
+ xhttp=new ActiveXObject('Microsoft.XMLHTTP');
|
|
|
+ }
|
|
|
|
|
|
- };
|
|
|
+ xhttp.open('GET', pFile, false);
|
|
|
+ xhttp.send(null);
|
|
|
+ var xmlDoc=xhttp.responseXML;
|
|
|
|
|
|
+ JSGantt.AddXMLTask(pGanttVar, xmlDoc);
|
|
|
+};
|
|
|
|
|
|
-/**
|
|
|
-* Change display format of current gantt chart
|
|
|
-*
|
|
|
-* @method changeFormat
|
|
|
-* @param pFormat {String} - Current format (minute,hour,day...)
|
|
|
-* @param ganttObj {GanttChart} - The gantt object
|
|
|
-* @return {void}
|
|
|
-*/
|
|
|
-JSGantt.changeFormat = function(pFormat,ganttObj) {
|
|
|
+JSGantt.parseXMLString=function(pStr,pGanttVar)
|
|
|
+{
|
|
|
+ if (typeof window.DOMParser!='undefined') {
|
|
|
+ var xmlDoc =(new window.DOMParser()).parseFromString(pStr, 'text/xml');
|
|
|
+ } else if (typeof window.ActiveXObject!='undefined' &&
|
|
|
+ new window.ActiveXObject('Microsoft.XMLDOM')) {
|
|
|
+ xmlDoc=new window.ActiveXObject('Microsoft.XMLDOM');
|
|
|
+ xmlDoc.async='false';
|
|
|
+ xmlDoc.loadXML(pStr);
|
|
|
+ }
|
|
|
|
|
|
- if(ganttObj)
|
|
|
- {
|
|
|
- ganttObj.setFormat(pFormat);
|
|
|
- ganttObj.DrawDependencies();
|
|
|
- }
|
|
|
- else
|
|
|
- {alert('Chart undefined');};
|
|
|
- };
|
|
|
+ JSGantt.AddXMLTask(pGanttVar, xmlDoc);
|
|
|
+};
|
|
|
|
|
|
|
|
|
-/**
|
|
|
-* Open/Close and hide/show children of specified task
|
|
|
-*
|
|
|
-* @method folder
|
|
|
-* @param pID {Number} - Task ID
|
|
|
-* @param ganttObj {GanttChart} - The gantt object
|
|
|
-* @return {void}
|
|
|
-*/
|
|
|
-JSGantt.folder= function (pID,ganttObj) {
|
|
|
+JSGantt.findXMLNode=function(pRoot,pNodeName)
|
|
|
+{
|
|
|
+ var vRetValue;
|
|
|
|
|
|
- var vList = ganttObj.getList();
|
|
|
+ try {vRetValue=pRoot.getElementsByTagName(pNodeName);
|
|
|
+ } catch (error) { ; } // do nothing, we'll return undefined
|
|
|
|
|
|
- for(i = 0; i < vList.length; i++)
|
|
|
- {
|
|
|
- if(vList[i].getID() == pID) {
|
|
|
+ return vRetValue;
|
|
|
+};
|
|
|
|
|
|
- if( vList[i].getOpen() == 1 ) {
|
|
|
- vList[i].setOpen(0);
|
|
|
- JSGantt.hide(pID,ganttObj);
|
|
|
+// pType can be 1=numeric, 2=String, all other values just return raw data
|
|
|
+JSGantt.getXMLNodeValue=function(pRoot,pNodeName,pType,pDefault)
|
|
|
+{
|
|
|
+ var vRetValue;
|
|
|
|
|
|
- if (JSGantt.isIE())
|
|
|
- {JSGantt.findObj('group_'+pID).innerText = '+';}
|
|
|
- else
|
|
|
- {JSGantt.findObj('group_'+pID).textContent = '+';}
|
|
|
-
|
|
|
- } else {
|
|
|
+ try {vRetValue=pRoot.getElementsByTagName(pNodeName)[0].childNodes[0].nodeValue;
|
|
|
+ } catch (error)
|
|
|
+ {
|
|
|
+ if (typeof pDefault!='undefined')vRetValue=pDefault;
|
|
|
+ }
|
|
|
|
|
|
- vList[i].setOpen(1);
|
|
|
+ if (typeof vRetValue!='undefined' && vRetValue!=null)
|
|
|
+ {
|
|
|
+ if (pType==1)vRetValue*=1;
|
|
|
+ else if (pType==2)vRetValue=vRetValue.toString();
|
|
|
+ }
|
|
|
+ return vRetValue;
|
|
|
+};
|
|
|
|
|
|
- JSGantt.show(pID, 1, ganttObj);
|
|
|
+JSGantt.AddXMLTask=function(pGanttVar, pXmlDoc)
|
|
|
+{
|
|
|
+ var project='';
|
|
|
+ var vMSP=false;
|
|
|
+ var Task;
|
|
|
+ var n=0;
|
|
|
+ var m=0;
|
|
|
+ var i=0;
|
|
|
+ var j=0;
|
|
|
+ var k=0;
|
|
|
+ var maxPID=0;
|
|
|
+ var ass=new Array();
|
|
|
+ var assRes=new Array();
|
|
|
+ var res=new Array();
|
|
|
+ var pars=new Array();
|
|
|
+
|
|
|
+ var projNode=JSGantt.findXMLNode(pXmlDoc,'Project');
|
|
|
+ if (typeof projNode!='undefined' && projNode.length>0) project=projNode[0].getAttribute('xmlns');
|
|
|
+
|
|
|
+ if(project=='http://schemas.microsoft.com/project')
|
|
|
+ {
|
|
|
+ vMSP=true;
|
|
|
+ pGanttVar.setDateInputFormat('yyyy-mm-dd');
|
|
|
+ Task=JSGantt.findXMLNode(pXmlDoc,'Task');
|
|
|
+ if (typeof Task=='undefined')n=0;
|
|
|
+ else n=Task.length;
|
|
|
+
|
|
|
+ var resources=JSGantt.findXMLNode(pXmlDoc,'Resource');
|
|
|
+ if (typeof resources=='undefined'){n=0; m=0;}
|
|
|
+ else m=resources.length;
|
|
|
+
|
|
|
+ for(i=0;i<m;i++)
|
|
|
+ {
|
|
|
+ var resname=JSGantt.getXMLNodeValue(resources[i],'Name',2,'');
|
|
|
+ var uid=JSGantt.getXMLNodeValue(resources[i],'UID',1,-1);
|
|
|
+
|
|
|
+ if (resname.length>0 && uid>0) res[uid]=resname;
|
|
|
+ }
|
|
|
+
|
|
|
+ var assignments=JSGantt.findXMLNode(pXmlDoc,'Assignment');
|
|
|
+ if (typeof assignments=='undefined') j=0;
|
|
|
+ else j=assignments.length;
|
|
|
+
|
|
|
+ for(i=0;i<j;i++)
|
|
|
+ {
|
|
|
+ var resUID=JSGantt.getXMLNodeValue(assignments[i],'ResourceUID',1,-1);
|
|
|
+ uid=JSGantt.getXMLNodeValue(assignments[i],'TaskUID',1,-1);
|
|
|
+
|
|
|
+ if (uid>0)
|
|
|
+ {
|
|
|
+ if (resUID>0) assRes[uid]=res[resUID];
|
|
|
+ ass[uid]=assignments[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if (JSGantt.isIE())
|
|
|
- {JSGantt.findObj('group_'+pID).innerText = '�';}
|
|
|
- else
|
|
|
- {JSGantt.findObj('group_'+pID).textContent = '�';}
|
|
|
+ // Store information about parent UIDs in an easily searchable form
|
|
|
+ for(i=0;i<n;i++)
|
|
|
+ {
|
|
|
+ uid=JSGantt.getXMLNodeValue(Task[i],'UID',1,0);
|
|
|
|
|
|
- }
|
|
|
+ if(uid!=0) var vOutlineNumber=JSGantt.getXMLNodeValue(Task[i],'OutlineNumber',2,'0');
|
|
|
+ if (uid>0) pars[vOutlineNumber]=uid;
|
|
|
+ if (uid>maxPID)maxPID=uid;
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
+ for(i=0;i<n;i++)
|
|
|
+ {
|
|
|
+ // optional parameters may not have an entry
|
|
|
+ // Task ID must NOT be zero otherwise it will be skipped
|
|
|
+ var pID=JSGantt.getXMLNodeValue(Task[i],'UID',1,0);
|
|
|
|
|
|
-/**
|
|
|
-* Hide children of a task
|
|
|
-*
|
|
|
-* @method hide
|
|
|
-* @param pID {Number} - Task ID
|
|
|
-* @param ganttObj {GanttChart} - The gantt object
|
|
|
-* @return {void}
|
|
|
-*/
|
|
|
-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);}
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-};
|
|
|
+ if(pID!=0)
|
|
|
+ {
|
|
|
+ var pName=JSGantt.getXMLNodeValue(Task[i],'Name',2,'No Task Name');
|
|
|
+ var pStart=JSGantt.getXMLNodeValue(Task[i],'Start',2,'');
|
|
|
+ var pEnd=JSGantt.getXMLNodeValue(Task[i],'Finish',2,'');
|
|
|
+ var pLink=JSGantt.getXMLNodeValue(Task[i],'HyperlinkAddress',2,'');
|
|
|
+ var pMile=JSGantt.getXMLNodeValue(Task[i],'Milestone',1,0);
|
|
|
+ var pComp=JSGantt.getXMLNodeValue(Task[i],'PercentWorkComplete',1,0);
|
|
|
+ var pGroup=JSGantt.getXMLNodeValue(Task[i],'Summary',1,0);
|
|
|
+
|
|
|
+ var pParent=0;
|
|
|
+
|
|
|
+ var vOutlineLevel=JSGantt.getXMLNodeValue(Task[i],'OutlineLevel',1,0);
|
|
|
+ if (vOutlineLevel>1)
|
|
|
+ {
|
|
|
+ vOutlineNumber=JSGantt.getXMLNodeValue(Task[i],'OutlineNumber',2,'0');
|
|
|
+ pParent=pars[vOutlineNumber.substr(0, vOutlineNumber.lastIndexOf('.'))];
|
|
|
+ }
|
|
|
|
|
|
-/**
|
|
|
-* Show children of a task
|
|
|
-*
|
|
|
-* @method show
|
|
|
-* @param pID {Number} - Task ID
|
|
|
-* @param ganttObj {GanttChart} - The gantt object
|
|
|
-* @return {void}
|
|
|
-*/
|
|
|
-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);
|
|
|
- }
|
|
|
+ try {var pNotes=Task[i].getElementsByTagName('Notes')[0].childNodes[1].nodeValue; //this should be a CDATA node
|
|
|
+ } catch (error)
|
|
|
+ {pNotes ='';}
|
|
|
|
|
|
- }
|
|
|
+ if(typeof assRes[pID]!='undefined') var pRes=assRes[pID];
|
|
|
+ else pRes='';
|
|
|
+
|
|
|
+ var predecessors=JSGantt.findXMLNode(Task[i],'PredecessorLink');
|
|
|
+ if (typeof predecessors=='undefined') j=0;
|
|
|
+ else j=predecessors.length;
|
|
|
+ var pDepend='';
|
|
|
+
|
|
|
+ for(k=0;k<j;k++)
|
|
|
+ {
|
|
|
+ var depUID=JSGantt.getXMLNodeValue(predecessors[k],'PredecessorUID',1,-1);
|
|
|
+ var depType=JSGantt.getXMLNodeValue(predecessors[k],'Type',1,1);
|
|
|
+
|
|
|
+ if (depUID>0)
|
|
|
+ {
|
|
|
+ if (pDepend.length>0)pDepend+=',';
|
|
|
+ switch(depType)
|
|
|
+ {
|
|
|
+ case 0: pDepend+=depUID+'FF'; break;
|
|
|
+ case 1: pDepend+=depUID+'FS'; break;
|
|
|
+ case 2: pDepend+=depUID+'SF'; break;
|
|
|
+ case 3: pDepend+=depUID+'SS'; break;
|
|
|
+ default: pDepend+=depUID+'FS'; break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
+ var pOpen=1;
|
|
|
+ var pCaption='';
|
|
|
|
|
|
- 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);
|
|
|
- }
|
|
|
+ if(pGroup>0) var pClass ='ggroupblack';
|
|
|
+ else if(pMile>0) pClass ='gmilestone';
|
|
|
+ else pClass ='gtaskblue';
|
|
|
|
|
|
- } else {
|
|
|
+ // check for split tasks
|
|
|
|
|
|
- if( JSGantt.findObj('group_'+pID).textContent == '�') {
|
|
|
- JSGantt.findObj('child_'+vID).style.display = "";
|
|
|
- JSGantt.findObj('childgrid_'+vID).style.display = "";
|
|
|
- vList[i].setVisible(1);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ var splits=JSGantt.findXMLNode(ass[pID],'TimephasedData');
|
|
|
+ if (typeof splits=='undefined') j=0;
|
|
|
+ else j=splits.length;
|
|
|
|
|
|
- if(vList[i].getGroup() == 1)
|
|
|
- {JSGantt.show(vID, 0,ganttObj);}
|
|
|
+ var vSplitStart=pStart;
|
|
|
+ var vSplitEnd=pEnd;
|
|
|
+ var vSubCreated=false;
|
|
|
+ var vDepend=pDepend.replace(/,*[0-9]+[FS]F/g,'');
|
|
|
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-/**
|
|
|
-* Handles click events on task name, currently opens a new window
|
|
|
-*
|
|
|
-* @method taskLink
|
|
|
-* @param pRef {String} - URL for window
|
|
|
-* @param pWidth {Number} - Width of window
|
|
|
-* @param pHeight {Number} - Height of window
|
|
|
-* @return {void}
|
|
|
-*/
|
|
|
-JSGantt.taskLink = function(pRef,pWidth,pHeight)
|
|
|
-
|
|
|
- {
|
|
|
-
|
|
|
- if(pWidth) {vWidth =pWidth;} else {vWidth =400;}
|
|
|
- if(pHeight) {vHeight=pHeight;} else {vHeight=400;}
|
|
|
-
|
|
|
- // LDR To open in same window
|
|
|
- //var OpenWindow=window.open(pRef, "newwin", "height="+vHeight+",width="+vWidth);
|
|
|
- window.location.href=pRef
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
-/**
|
|
|
-* Parse dates based on gantt date format setting as defined in JSGantt.GanttChart.setDateInputFormat()
|
|
|
-*
|
|
|
-* @method parseDateStr
|
|
|
-* @param pDateStr {String} - A string that contains the date (i.e. "01/01/09")
|
|
|
-* @param pFormatStr {String} - The date format (mm/dd/yyyy,dd/mm/yyyy,yyyy-mm-dd)
|
|
|
-* @return {Datetime}
|
|
|
-*/
|
|
|
-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;
|
|
|
+ for(k=0;k<j;k++)
|
|
|
+ {
|
|
|
+ var vDuration=JSGantt.getXMLNodeValue(splits[k],'Value',2,'0');
|
|
|
+ //remove all text
|
|
|
+ vDuration='0'+vDuration.replace(/\D/g,'');
|
|
|
+ vDuration*=1;
|
|
|
+ if ((vDuration==0 && !vSubCreated)|| (k+1==j && pGroup==2))
|
|
|
+ {
|
|
|
+ // No time booked in the given period (or last entry)
|
|
|
+ // Make sure the parent task is set as a combined group
|
|
|
+ pGroup=2;
|
|
|
+ // Handle last loop
|
|
|
+ if (k+1==j)vDepend=pDepend.replace(/,*[0-9]+[FS]S/g,'');
|
|
|
+ // Now create a subtask
|
|
|
+ maxPID++;
|
|
|
+ vSplitEnd=JSGantt.getXMLNodeValue(splits[k],(k+1==j)?'Finish':'Start',2,'');
|
|
|
+ pGanttVar.AddTaskItem(new JSGantt.TaskItem(maxPID, pName, vSplitStart, vSplitEnd, 'gtaskblue', pLink, pMile, pRes, pComp, 0, pID, pOpen, vDepend, pCaption, pNotes, pGanttVar));
|
|
|
+ vSubCreated=true;
|
|
|
+ vDepend='';
|
|
|
+ }
|
|
|
+ else if (vDuration!=0 && vSubCreated)
|
|
|
+ {
|
|
|
+ vSplitStart=JSGantt.getXMLNodeValue(splits[k],'Start',2,'');
|
|
|
+ vSubCreated=false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (vSubCreated)pDepend='';
|
|
|
+
|
|
|
+ // Finally add the task
|
|
|
+ pGanttVar.AddTaskItem(new JSGantt.TaskItem(pID, pName, pStart, pEnd, pClass, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption, pNotes, pGanttVar));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Task=pXmlDoc.getElementsByTagName('task');
|
|
|
+ n=Task.length;
|
|
|
+
|
|
|
+ for(i=0;i<n;i++)
|
|
|
+ {
|
|
|
+ // optional parameters may not have an entry
|
|
|
+ // Task ID must NOT be zero otherwise it will be skipped
|
|
|
+ pID=JSGantt.getXMLNodeValue(Task[i],'pID',1,0);
|
|
|
+
|
|
|
+ if(pID!=0)
|
|
|
+ {
|
|
|
+ pName=JSGantt.getXMLNodeValue(Task[i],'pName',2,'No Task Name');
|
|
|
+ pStart=JSGantt.getXMLNodeValue(Task[i],'pStart',2,'');
|
|
|
+ pEnd=JSGantt.getXMLNodeValue(Task[i],'pEnd',2,'');
|
|
|
+ pLink=JSGantt.getXMLNodeValue(Task[i],'pLink',2,'');
|
|
|
+ pMile=JSGantt.getXMLNodeValue(Task[i],'pMile',1,0);
|
|
|
+ pComp=JSGantt.getXMLNodeValue(Task[i],'pComp',1,0);
|
|
|
+ pGroup=JSGantt.getXMLNodeValue(Task[i],'pGroup',1,0);
|
|
|
+ pParent=JSGantt.getXMLNodeValue(Task[i],'pParent',1,0);
|
|
|
+ pRes=JSGantt.getXMLNodeValue(Task[i],'pRes',2,'');
|
|
|
+ pOpen=JSGantt.getXMLNodeValue(Task[i],'pOpen',1,1);
|
|
|
+ pDepend=JSGantt.getXMLNodeValue(Task[i],'pDepend',2,'');
|
|
|
+ pCaption=JSGantt.getXMLNodeValue(Task[i],'pCaption',2,'');
|
|
|
+ pNotes=JSGantt.getXMLNodeValue(Task[i],'pNotes',2,'');
|
|
|
+ pClass=JSGantt.getXMLNodeValue(Task[i],'pClass',2);
|
|
|
+ if (typeof pClass=='undefined')
|
|
|
+ {
|
|
|
+ if(pGroup>0) pClass ='ggroupblack';
|
|
|
+ else if(pMile>0) pClass ='gmilestone';
|
|
|
+ else pClass ='gtaskblue';
|
|
|
+ }
|
|
|
+
|
|
|
+ // Finally add the task
|
|
|
+ pGanttVar.AddTaskItem(new JSGantt.TaskItem(pID, pName, pStart, pEnd, pClass, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption, pNotes, pGanttVar));
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+};
|
|
|
|
|
|
- return(vDate);
|
|
|
-
|
|
|
+
|
|
|
+JSGantt.benchMark=function(pItem)
|
|
|
+{
|
|
|
+ var vEndTime=new Date().getTime();
|
|
|
+ alert(pItem+': Elapsed time: '+((vEndTime-vBenchTime)/1000)+' seconds.');
|
|
|
+ vBenchTime=new Date().getTime();
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
-* Display a formatted date based on gantt date format setting as defined in JSGantt.GanttChart.setDateDisplayFormat()
|
|
|
-*
|
|
|
-* @method formatDateStr
|
|
|
-* @param pDate {Date} - A javascript date object
|
|
|
-* @param pFormatStr {String} - The date format (mm/dd/yyyy,dd/mm/yyyy,yyyy-mm-dd...)
|
|
|
-* @return {String}
|
|
|
-*/
|
|
|
-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.getIsoWeek=function(pDate){
|
|
|
+ // We have to compare against the monday of the first week of the year containing 04 jan *not* 01/01
|
|
|
+ // 60*60*24*1000=86400000
|
|
|
+ var dayMiliseconds=86400000;
|
|
|
+ var keyDay=new Date(pDate.getFullYear(),0,4,0,0,0);
|
|
|
+ var keyDayOfWeek=(keyDay.getDay()==0) ? 6 : keyDay.getDay()-1; // define monday as 0
|
|
|
+ var firstMondayYearTime=keyDay.getTime()-(keyDayOfWeek * dayMiliseconds);
|
|
|
+ var thisDate=new Date(pDate.getFullYear(), pDate.getMonth(),pDate.getDate(),0,0,0); // This at 00:00:00
|
|
|
+ var thisTime=thisDate.getTime();
|
|
|
+ var daysFromFirstMonday=Math.round(((thisTime-firstMondayYearTime) / dayMiliseconds));
|
|
|
+ var lastWeek=99;
|
|
|
+ var thisWeek=99;
|
|
|
+
|
|
|
+ var firstMondayYear=new Date(firstMondayYearTime);
|
|
|
+
|
|
|
+ thisWeek=Math.ceil((daysFromFirstMonday+1)/7);
|
|
|
+
|
|
|
+ if (thisWeek<=0) thisWeek=JSGantt.getIsoWeek(new Date(pDate.getFullYear()-1,11,31,0,0,0));
|
|
|
+ else if (thisWeek==53 && (new Date(pDate.getFullYear(),0,1,0,0,0)).getDay()!=4 && (new Date(pDate.getFullYear(),11,31,0,0,0)).getDay()!=4) thisWeek=1;
|
|
|
+ return thisWeek;
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
-* Parse an external XML file containing task items.
|
|
|
-*
|
|
|
-* @method parseXML
|
|
|
-* @param ThisFile {String} - URL to XML file
|
|
|
-* @param pGanttVar {Gantt} - Gantt object
|
|
|
-* @return {void}
|
|
|
-*/
|
|
|
-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.addListener=function (eventName, handler, control)
|
|
|
+{
|
|
|
+ // Check if control is a string
|
|
|
+ if (control===String(control)) control=JSGantt.findObj(control);
|
|
|
+
|
|
|
+ if(control.addEventListener) //Standard W3C
|
|
|
+ {
|
|
|
+ return control.addEventListener(eventName, handler, false);
|
|
|
+ }
|
|
|
+ else if (control.attachEvent) //IExplore
|
|
|
+ {
|
|
|
+ return control.attachEvent('on'+eventName, handler);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
-* Add a task based on parsed XML doc
|
|
|
-*
|
|
|
-* @method AddXMLTask
|
|
|
-* @param pGanttVar {Gantt} - Gantt object
|
|
|
-* @return {void}
|
|
|
-*/
|
|
|
-JSGantt.AddXMLTask = function(pGanttVar){
|
|
|
-
|
|
|
- Task=xmlDoc.getElementsByTagName("task");
|
|
|
-
|
|
|
- var n = xmlDoc.documentElement.childNodes.length; // the number of tasks. IE gets this right, but mozilla add extra ones (Whitespace)
|
|
|
-
|
|
|
- for(var i=0;i<n;i++) {
|
|
|
-
|
|
|
- // optional parameters may not have an entry (Whitespace from mozilla also returns an error )
|
|
|
- // Task ID must NOT be zero other wise it will be skipped
|
|
|
- try { pID = Task[i].getElementsByTagName("pID")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) {pID =0;}
|
|
|
- pID *= 1; // make sure that these are numbers rather than strings in order to make jsgantt.js behave as expected.
|
|
|
-
|
|
|
- if(pID!=0){
|
|
|
- try { pName = Task[i].getElementsByTagName("pName")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) {pName ="No Task Name";} // If there is no corresponding entry in the XML file the set a default.
|
|
|
-
|
|
|
- try { pColor = Task[i].getElementsByTagName("pColor")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) {pColor ="0000ff";}
|
|
|
-
|
|
|
- try { pParent = Task[i].getElementsByTagName("pParent")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) {pParent =0;}
|
|
|
- pParent *= 1;
|
|
|
-
|
|
|
- try { pStart = Task[i].getElementsByTagName("pStart")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) {pStart ="";}
|
|
|
-
|
|
|
- try { pEnd = Task[i].getElementsByTagName("pEnd")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) { pEnd ="";}
|
|
|
-
|
|
|
- try { pLink = Task[i].getElementsByTagName("pLink")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) { pLink ="";}
|
|
|
-
|
|
|
- try { pMile = Task[i].getElementsByTagName("pMile")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) { pMile=0;}
|
|
|
- pMile *= 1;
|
|
|
-
|
|
|
- try { pRes = Task[i].getElementsByTagName("pRes")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) { pRes ="";}
|
|
|
-
|
|
|
- try { pComp = Task[i].getElementsByTagName("pComp")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) {pComp =0;}
|
|
|
- pComp *= 1;
|
|
|
-
|
|
|
- try { pGroup = Task[i].getElementsByTagName("pGroup")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) {pGroup =0;}
|
|
|
- pGroup *= 1;
|
|
|
-
|
|
|
- try { pOpen = Task[i].getElementsByTagName("pOpen")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) { pOpen =1;}
|
|
|
- pOpen *= 1;
|
|
|
-
|
|
|
- try { pDepend = Task[i].getElementsByTagName("pDepend")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) { pDepend =0;}
|
|
|
- //pDepend *= 1;
|
|
|
- if (pDepend.length==0){pDepend=''} // need this to draw the dependency lines
|
|
|
-
|
|
|
- try { pCaption = Task[i].getElementsByTagName("pCaption")[0].childNodes[0].nodeValue;
|
|
|
- } catch (error) { pCaption ="";}
|
|
|
-
|
|
|
-
|
|
|
- // Finally add the task
|
|
|
- pGanttVar.AddTaskItem(new JSGantt.TaskItem(pID , pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend,pCaption));
|
|
|
- }
|
|
|
- }
|
|
|
+JSGantt.addTooltipListeners=function(pGanttChart, pObj1, pObj2)
|
|
|
+{
|
|
|
+ JSGantt.addListener('mouseover', function (e) {JSGantt.showToolTip(pGanttChart, e, pObj2, null, pGanttChart.getTimer());}, pObj1);
|
|
|
+ JSGantt.addListener('mouseout', function (e) {JSGantt.delayedHide(pGanttChart, pGanttChart.vTool, pGanttChart.getTimer());}, pObj1);
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
-* Load an XML document in Chrome
|
|
|
-*
|
|
|
-* @method ChromeLoadXML
|
|
|
-* @param ThisFile {String} - URL to XML file
|
|
|
-* @param pGanttVar {Gantt} - Gantt object
|
|
|
-* @return {void}
|
|
|
-*/
|
|
|
-JSGantt.ChromeLoadXML = function(ThisFile,pGanttVar){
|
|
|
-// Thanks to vodobas at mindlence,com for the initial pointers here.
|
|
|
- XMLLoader = new XMLHttpRequest();
|
|
|
- XMLLoader.onreadystatechange= function(){
|
|
|
- JSGantt.ChromeXMLParse(pGanttVar);
|
|
|
- };
|
|
|
- XMLLoader.open("GET", ThisFile, false);
|
|
|
- XMLLoader.send(null);
|
|
|
+JSGantt.addThisRowListeners=function(pGanttChart, pObj1, pObj2)
|
|
|
+{
|
|
|
+ JSGantt.addListener('mouseover', function () {pGanttChart.mouseOver(pObj1, pObj2);}, pObj1);
|
|
|
+ JSGantt.addListener('mouseover', function () {pGanttChart.mouseOver(pObj1, pObj2);}, pObj2);
|
|
|
+ JSGantt.addListener('mouseout', function () {pGanttChart.mouseOut(pObj1, pObj2);}, pObj1);
|
|
|
+ JSGantt.addListener('mouseout', function () {pGanttChart.mouseOut(pObj1, pObj2);}, pObj2);
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
-* Parse XML document in Chrome
|
|
|
-*
|
|
|
-* @method ChromeXMLParse
|
|
|
-* @param pGanttVar {Gantt} - Gantt object
|
|
|
-* @return {void}
|
|
|
-*/
|
|
|
-
|
|
|
-JSGantt.ChromeXMLParse = function (pGanttVar){
|
|
|
-// Manually parse the file as it is loads quicker
|
|
|
- if (XMLLoader.readyState == 4) {
|
|
|
- var ta=XMLLoader.responseText.split(/<task>/gi);
|
|
|
-
|
|
|
- var n = ta.length; // the number of tasks.
|
|
|
- for(var i=1;i<n;i++) {
|
|
|
- Task = ta[i].replace(/<[/]p/g, '<p');
|
|
|
- var te = Task.split(/<pid>/i);
|
|
|
-
|
|
|
- if(te.length> 2){var pID=te[1];} else {var pID = 0;}
|
|
|
- pID *= 1;
|
|
|
-
|
|
|
- var te = Task.split(/<pName>/i);
|
|
|
- if(te.length> 2){var pName=te[1];} else {var pName = "No Task Name";}
|
|
|
-
|
|
|
- var te = Task.split(/<pstart>/i);
|
|
|
- if(te.length> 2){var pStart=te[1];} else {var pStart = "";}
|
|
|
-
|
|
|
- var te = Task.split(/<pEnd>/i);
|
|
|
- if(te.length> 2){var pEnd=te[1];} else {var pEnd = "";}
|
|
|
-
|
|
|
- var te = Task.split(/<pColor>/i);
|
|
|
- if(te.length> 2){var pColor=te[1];} else {var pColor = '0000ff';}
|
|
|
-
|
|
|
- var te = Task.split(/<pLink>/i);
|
|
|
- if(te.length> 2){var pLink=te[1];} else {var pLink = "";}
|
|
|
-
|
|
|
- var te = Task.split(/<pMile>/i);
|
|
|
- if(te.length> 2){var pMile=te[1];} else {var pMile = 0;}
|
|
|
- pMile *= 1;
|
|
|
-
|
|
|
- var te = Task.split(/<pRes>/i);
|
|
|
- if(te.length> 2){var pRes=te[1];} else {var pRes = "";}
|
|
|
-
|
|
|
- var te = Task.split(/<pComp>/i);
|
|
|
- if(te.length> 2){var pComp=te[1];} else {var pComp = 0;}
|
|
|
- pComp *= 1;
|
|
|
-
|
|
|
- var te = Task.split(/<pGroup>/i);
|
|
|
- if(te.length> 2){var pGroup=te[1];} else {var pGroup = 0;}
|
|
|
- pGroup *= 1;
|
|
|
-
|
|
|
- var te = Task.split(/<pParent>/i);
|
|
|
- if(te.length> 2){var pParent=te[1];} else {var pParent = 0;}
|
|
|
- pParent *= 1;
|
|
|
-
|
|
|
- var te = Task.split(/<pOpen>/i);
|
|
|
- if(te.length> 2){var pOpen=te[1];} else {var pOpen = 1;}
|
|
|
- pOpen *= 1;
|
|
|
-
|
|
|
- var te = Task.split(/<pDepend>/i);
|
|
|
- if(te.length> 2){var pDepend=te[1];} else {var pDepend = "";}
|
|
|
- //pDepend *= 1;
|
|
|
- if (pDepend.length==0){pDepend=''} // need this to draw the dependency lines
|
|
|
-
|
|
|
- var te = Task.split(/<pCaption>/i);
|
|
|
- if(te.length> 2){var pCaption=te[1];} else {var pCaption = "";}
|
|
|
-
|
|
|
- // Finally add the task
|
|
|
- pGanttVar.AddTaskItem(new JSGantt.TaskItem(pID , pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend,pCaption ));
|
|
|
- };
|
|
|
- };
|
|
|
+JSGantt.addFolderListeners=function(pGanttChart, pObj, pID)
|
|
|
+{
|
|
|
+ JSGantt.addListener('click', function () {JSGantt.folder(pID, pGanttChart);}, pObj);
|
|
|
};
|
|
|
-/**
|
|
|
-* Used for benchmarking performace
|
|
|
-*
|
|
|
-* @method benchMark
|
|
|
-* @param pItem {TaskItem} - TaskItem object
|
|
|
-* @return {void}
|
|
|
-*/
|
|
|
-JSGantt.benchMark = function(pItem){
|
|
|
- var vEndTime=new Date().getTime();
|
|
|
- alert(pItem + ': Elapsed time: '+((vEndTime-vBenchTime)/1000)+' seconds.');
|
|
|
- vBenchTime=new Date().getTime();
|
|
|
+
|
|
|
+JSGantt.addFormatListeners=function(pGanttChart, pFormat, pObj)
|
|
|
+{
|
|
|
+ JSGantt.addListener('click', function () {JSGantt.changeFormat(pFormat, pGanttChart);}, pObj);
|
|
|
};
|
|
|
|
|
|
+JSGantt.addScrollListeners=function(pGanttChart)
|
|
|
+{
|
|
|
+ JSGantt.addListener('scroll', function () {pGanttChart.getChartBody().scrollTop=pGanttChart.getListBody().scrollTop;}, pGanttChart.getListBody());
|
|
|
+ JSGantt.addListener('scroll', function () {pGanttChart.getListBody().scrollTop=pGanttChart.getChartBody().scrollTop;}, pGanttChart.getChartBody());
|
|
|
+ JSGantt.addListener('scroll', function () {pGanttChart.getChartHead().scrollLeft=pGanttChart.getChartBody().scrollLeft;}, pGanttChart.getChartBody());
|
|
|
+ JSGantt.addListener('scroll', function () {pGanttChart.getChartBody().scrollLeft=pGanttChart.getChartHead().scrollLeft;}, pGanttChart.getChartHead());
|
|
|
+ JSGantt.addListener('resize', function () {pGanttChart.getChartHead().scrollLeft=pGanttChart.getChartBody().scrollLeft;}, window);
|
|
|
+ JSGantt.addListener('resize', function () {pGanttChart.getListBody().scrollTop=pGanttChart.getChartBody().scrollTop;}, window);
|
|
|
+};
|