From df843d2966359706b3dac0bd0373565a8d143bf1 Mon Sep 17 00:00:00 2001 From: jsGanttImproved Date: Tue, 25 Aug 2015 16:49:18 +0100 Subject: [PATCH] Updates related to GitHub Migration * Moved ProjectHome.md from wiki branch to README.md in master branch. * Reformatted files to use Unix line feeds. * Point files at GitHub rather than Google Code --- LICENSE | 2 +- README.md | 23 + index.html | 1487 +++++------ jsgantt.css | 484 ++-- jsgantt.js | 5094 ++++++++++++++++++------------------ jsgantt_exExternalXML.html | 1383 +++++----- project.xml | 134 +- 7 files changed, 4316 insertions(+), 4291 deletions(-) create mode 100644 README.md diff --git a/LICENSE b/LICENSE index 68d95c1f..7b49c76d 100644 --- a/LICENSE +++ b/LICENSE @@ -48,4 +48,4 @@ This project is based on jsGantt 1.2, the original project license follows: * 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. \ No newline at end of file +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 00000000..d9a9afa1 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +A fully featured gantt chart component built entirely in Javascript, CSS and AJAX. No images required. + +You can view a live example at http://jsganttimproved.x10host.com/ + +Features include: + * Tasks & Collapsible Task Groups + * Dependencies + * Task Completion + * Task Styling + * Milestones + * Resources + * Dynamic Loading of Tasks + * Dynamic change of format (hour/day/week/month/quarter) + * Load Gantt from XML + * From external files (including experimental support for MS Project XML files) + * From JavaScript Strings + * Support for Internationalisation (all hard coded strings can be overridden) + +Project forked as I was unable to contact the original maintainers. This work was done to support a personal project that didn't warrant a more heavyweight system (e.g. the dojo toolkit gantt chart features). + +See the [Documentation](https://github.com/jsGanttImproved/jsgantt-improved/wiki/Documentation) wiki page or the included ``index.html`` file for instructions on use. + +Latest Release: v1.7.5 - Migration to GitHub diff --git a/index.html b/index.html index 6373b692..17997e13 100644 --- a/index.html +++ b/index.html @@ -1,743 +1,744 @@ - - - - -FREE javascript gantt - jsGantt Improved HTML and CSS only - - - - - - -
-
jsGanttImproved - 1.7.4
- -
-

  100% Free Javascript / CSS/ HTML Gantt chart control. Completely buzzword compliant including AJAX !

- - -
- - -

Basic Features

- - -

Advanced Features

- -

Bugs/Issues

- -
-

Current Issues:

-
    -
  1. If the browser is viewing the page at anything other than 100% zoom then bars may not be sized or positioned correctly.
  2. - -

-

Changes/fixes in jsGanttImproved:

-

v1.7.4:

- -

v1.7:

- -

v1.6:

- -

v1.5:

- -

v1.4:

- -

v1.3:

- -

-Please see the differences for the CSS file in code revision r21 for details of CSS structural changes. -

-

v1.2:

- -

Both these updates required changes to existing element IDs and style classes. Custom stylesheets will most likely need to be updated. -

-All chart element ids are now prefixed with the id of the master DIV containing the chart. As a result the default stylesheet has been updated to no longer use any element ids to apply styles. -

-Please see the notes for code revision r18 for details of CSS structural changes. -

-

v1.1:

- -

v1.0:

- -

Download

-Click here to download the current version of jsGantt Improved
-You can download the latest bleeding edge version, request features and report issues at https://code.google.com/p/jsgantt-improved/ - -

License

-JSGanttImproved is released under BSD license.
-If you plan to use it in a commercial product please consider donating the first sale to charity. -

- - -

Usage

-

Creating a basic Gantt Chart

-
    -
  1. Include JSGantt CSS and Javascript -
    -<link rel="stylesheet" type="text/css" href="jsgantt.css" />
    -<script language="javascript" src="jsgantt.js"></script>
    -
    -
  2. -
  3. Create a div element to hold the gantt chart -
    <div style="position:relative" class="gantt" id="GanttChartDIV"></div>
    -
  4. -
  5. Start a <script> block -
    <script type="text/javascript">
    -
  6. -
  7. Instantiate JSGantt using GanttChart() -
    var g = new JSGantt.GanttChart(document.getElementById('GanttChartDIV'), 'day');
    -
    -

    Method definition: - GanttChart(pDiv, pFormat)

    -
    -
    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
    -
    -
  8. -
  9. Customize the look and feel using configuration methods (see Configuration Options)

  10. -
  11. Add Tasks -
    1. using AddTaskItem() -
      -g.AddTaskItem(new JSGantt.TaskItem(1, 'Define Chart API','',          '',          'ggroupblack','', 0, 'Brian', 0,  1,0,1,'','','Some Notes text',g));
      -g.AddTaskItem(new JSGantt.TaskItem(11,'Chart Object',    '2014-02-20','2014-02-20','gmilestone', '', 1, 'Shlomy',100,0,1,1,'','','',g));
      -
      -

      Method definition: -TaskItem(pID, pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption, pNotes, pGantt)

      -
      -
      pID
      (required) a unique numeric ID used to identify each row
      -
      pName
      (required) the task Label
      -
      pStart
      (required) the task start date, can enter empty date ('') for groups. You can also enter specific time (2014-02-20 12:00) for additional precision.
      -
      pEnd
      (required) the task end date, can enter empty date ('') for groups
      -
      pClass
      (required) the css class for this task
      -
      pLink
      (optional) any http link to be displayed in tool tip as the "More information" link.
      -
      pMile
      (optional) indicates whether this is a milestone task - Numeric; 1 = milestone, 0 = not milestone
      -
      pRes
      (optional) resource name
      -
      pComp
      (required) completion percent, numeric
      -
      pGroup
      (optional) indicates whether this is a group task (parent) - Numeric; 0 = normal task, 1 = standard group task, 2 = combined group task*
      -
      pParent
      (required) identifies a parent pID, this causes this task to be a child of identified task. Numeric, top level tasks should have pParent set to 0
      -
      pOpen
      (required) indicates whether a standard group task is open when chart is first drawn. Value must be set for all items but is only used by standard group tasks. Numeric, 1 = open, 0 = closed
      -
      pDepend
      (optional) comma separated list of id's this task is dependent on. A line will be drawn from each listed task to this item
      Each id can optionally be followed by a dependency type suffix. Valid values are:
      'FS' - Finish to Start (default if suffix is omitted)
      'SF' - Start to Finish
      'SS' - Start to Start
      'FF' - Finish to Finish
      If present the suffix must be added directly to the id e.g. '123SS'
      -
      pCaption
      (optional) caption that will be added after task bar if CaptionType set to "Caption"
      -
      pNotes
      (optional) Detailed task information that will be displayed in tool tip for this task
      -
      pGantt
      (required) javascript JSGantt.GanttChart object from which to take settings. Defaults to "g" for backwards compatibility
      -
      -

      * Combined group tasks show all sub-tasks on one row. The information displayed in the task list and row caption are taken from the parent task. Tool tips are generated individually for each sub-task from its own information. Milestones are not valid as sub-tasks of a combined group task and will not be displayed. No bounds checking of start and end dates of sub-tasks is performed therefore it is possible for these task bars to overlap. Dependencies can be set to and from sub-tasks only.

      -
    2. -
    3. using parseXML() with an external XML file -
      -JSGantt.parseXML("project.xml",g);
      -
      -

      Method definition: - JSGantt.parseXML(pFile, pGanttObj)

      -
      -
      pFile
      (required) this is the filename of the XML
      -
      pGanttObj
      (required) a GanttChart object returned by a call to JSGantt.GanttChart()
      -
      -

      The structure of the native XML file:

      -
      - -
      -

      Field definitions are as described for the parameters to TaskItem above. The pClass element is optional in XML files and will default to "ggroupblack" for group tasks, "gtaskblue" for normal tasks and "gmilestone" for milestones. The pGantt element is not required for XML import.

      -

      JSGannt Improved will also test the provided XML file to see if it appears to be in Microsoft Project XML format. If so an attempt will be made to load up the project. This feature is experimental, the import is best effort and not guaranteed. Once loaded the project as interpreted by JSGantt Improved can be extracted using the XML Export methods provided.

      -
    4. -
    5. using parseXMLString() with XML held in a javascript string object -
      -JSGantt.parseXMLString("<project><task>...</task></project>",g);
      -
      -

      Method definition: - JSGantt.parseXMLString(pStr, pGanttObj)

      -
      -
      pStr
      (required) this is a javascript String containing XML
      -
      pGanttObj
      (required) a GanttChart object returned by a call to JSGantt.GanttChart()
      -
      -

      The XML provided will be parsed in exactly the same way as the contents of an external XML file and hence must match the format as described for JSGantt.parseXML() above

      -
  12. -
  13. Call Draw()

    g.Draw();
    -
  14. -
  15. Close the <script> block

    </script>
    -
  16. -
- -

It is possible to add items to the chart in realtime via javascript using either direct method calls or additional XML files. -It is also possible to delete tasks using RemoveTaskItem() method.

-
g.RemoveTaskItem(11);
-

Method definition: -RemoveTaskItem(pID)

-
-
pID
(required) the unique numeric ID of the item to be removed
-
-

If the task removed is a group item, all child tasks will also be removed.

-

After adding or removing tasks a call to "g.Draw()" must be made to redraw the chart.

- -

Configuration Options

-

Switches

-

Many of the features of jsGanttImproved can be customised through the use of setter methods available on the GanttChart object returned by a call to JSGantt.GanttChart()

-

The following options take a single numeric parameter; a value of 1 will enable the describe functionality, 0 will disable it

-
-
setUseToolTip()
Controls the display of tool tip boxes, defaults to 1 (enabled)
-
setUseFade()
Controls use of the fade effect when showing/hiding tool tips, defaults to 1 (enabled)
-
setUseMove()
Controls use of the sliding effect when changing between different task tool tips, defaults to 1 (enabled)
-
setUseRowHlt()
Controls the use of row mouseover highlighting, defaults to 1 (enabled)
-
setUseSort()
Controls whether the task list is sorted into parent task / start time order or is simply displayed in the order created, defaults to 1 (sort enabled)
-
setShowRes()
Controls whether the Resource column is displayed in the task list, defaults to 1 (show column)
-
setShowDur()
Controls whether the Task Duration column is displayed in the task list, defaults to 1 (show column)
-
setShowComp()
Controls whether the Percentage Complete column is displayed in the task list, defaults to 1 (show column)
-
setShowStartDate()
Controls whether the Task Start Date column is displayed in the task list, defaults to 1 (show column)
-
setShowEndDate()
Controls whether the Task End Date column is displayed in the task list, defaults to 1 (show column)
-
setShowTaskInfoRes()
Controls whether the Resource information is displayed in the task tool tip, defaults to 1 (show information)
-
setShowTaskInfoDur()
Controls whether the Task Duration information is displayed in the task tool tip, defaults to 1 (show information)
-
setShowTaskInfoComp()
Controls whether the Percentage Complete information is displayed in the task tool tip, defaults to 1 (show information)
-
setShowTaskInfoStartDate()
Controls whether the Task Start Date information is displayed in the task tool tip, defaults to 1 (show information)
-
setShowTaskInfoEndDate()
Controls whether the Task End Date information is displayed in the task tool tip, defaults to 1 (show information)
-
Controls whether the More Information link is displayed in the task tool tip, defaults to 0 (do NOT show link)
-
setShowTaskInfoNotes()
Controls whether the Additional Notes data is displayed in the task tool tip, defaults to 1 (show notes)
-
setShowEndWeekDate()
Controls whether the major heading in "Day" view displays the week end-date in the appropriate format (see below), defaults to 1 (show date)
-
setShowDeps()
Controls display of dependancy lines, defaults to 1 (show dependencies)
-
-

Key Values

-

The following options enable functionality using a set of specific key values

-
-
setShowSelector()
Controls where the format selector is displayed, accepts multiple parameters.
Valid parameter values are "Top", "Bottom".
Defaults to "Top".
-
setFormatArr()
Controls which format options are shown in the format selector, accepts multiple parameters.
Valid parameter values are "Hour", "Day", "Week", "Month", "Quarter".
Defaults to all valid values.
-
setCaptionType()
Controls which task field to use as a caption on the Gantt Chart task bar, accepts a single parameter.
Valid parameter values are "None", "Caption", "Resource", "Duration", "Complete".
Defaults to "None"
-
setDateInputFormat()
Defines the input format used for dates in task creation, accepts a single parameter.
Valid parameter values are "yyyy-mm-dd", "dd/mm/yyyy", "mm/dd/yyyy".
Defaults to "yyyy-mm-dd"
-
setScrollTo()
Sets the date the Gantt Chart will be scrolled to, specified in the date input format set by setDateInputFormat() above. Also accepts the special value "today"
Defaults to minimum display date
-
setUseSingleCell()
Sets the threshold total number of cells at which the task list will use a single table cell for each row rather than one cell per period. Useful to improve performance on large charts. A value of 0 disables this functionality (always use multiple cells), defaults to 25000
-
setLang()
Sets translation to use when drawing the chart. Defaults to "en" as this is the only language provided in the base installation (see Internationalisation below for details on how to add more translations.)
-
-

Layout

-

Most of the look and feel of the Gantt Chart can be controlled using CSS however, as the length of a task bar is determined by column width, the following methods take a single numeric parameter that defines the appropriate column width in pixels.

-

Note that the task bar sizing code assumes the use of collapsed table borders 1px wide.

-
-
setHourColWidth()
Width of Gantt Chart columns in pixels when drawn in "Hour" format. Defaults to 18.
-
setDayColWidth()
Width of Gantt Chart columns in pixels when drawn in "Day" format. Defaults to 18.
-
setWeekColWidth()
Width of Gantt Chart columns in pixels when drawn in "Week" format. Defaults to 36.
-
setMonthColWidth()
Width of Gantt Chart columns in pixels when drawn in "Month" format. Defaults to 36.
-
setQuarterColWidth()
Width of Gantt Chart columns in pixels when drawn in "Quarter" format, although not mandatory it is recommended that this be set to a value divisible by 3. Defaults to 18.
-
setRowHeight()
Height of Gantt Chart rows in pixels. Used to route dependency lines near end points. Defaults to 20.
-
setMinGpLen()
Group tasks have their task bars embellished with end points, this value specifies the width of one of these end points in pixels. A short task bar's length will be rounded up to display either a single or both endpoints correctly. Defaults to 8.
-
-

Display Date Formats

-

Date display formats can be individually controlled. The methods used to set these display formats each take a single format string parameter. The format string can be made up of the following components (case sensitive)

-
-
-
h
Hour (1-12)
-
hh
Hour (01-12)
-
pm
am/pm indicator
-
PM
AM/PM indicator
-
H
Hour (0-23)
-
HH
Hour (01-23)
-
mi
Minutes (1-59)
-
MI
Minutes (01-59)
-
d
Day (1-31)
-
dd
Day (01-31)
-
day
Abbriviated day of week
-
DAY
Day of week
-
m
Month (1-12)
-
mm
Month (01-12)
-
mon
Abbriviated month text
-
month
Full month text
-
yy
Year, excluding century
-
yyyy
Year
-
q
Quarter (1-4)
-
qq
Quarter (Q1-Q4)
-
w
ISO Week number (1-53)
-
ww
ISO Week number (01-53)
-
week
Full ISO Week date format
-
-

separated by one of the following characters: "/\-.,'<space>:

-

Any text between separators that does not match one of the components above will be checked using a case insensitive match for a valid internationalised string (see Internationalisation below). If the value is still not found the text will be output unchanged.

-
-

-

-
setDateTaskTableDisplayFormat()
Date format used for start and end dates in the main task list. Defaults to 'dd/mm/yyyy'.
-
setDateTaskDisplayFormat()
Date format used for start and end dates in task tool tips. Defaults to 'dd month yyyy'.
-
setHourMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Hour" format. Defaults to 'day dd month yyyy'.
-
setDayMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Day" format. Defaults to 'dd/mm/yyyy'.
-
setWeekMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Week" format. Defaults to 'yyyy'.
-
setMonthMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Month" format. Defaults to 'yyyy'.
-
setQuarterMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Year" format. Defaults to 'yyyy'.
-
setHourMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Hour" format. Defaults to 'HH'.
-
setDayMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Day" format. Defaults to 'dd'.
-
setWeekMinjorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Week" format. Defaults to 'dd/mm'.
-
setMonthMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Month" format. Defaults to 'mon'.
-
setQuarterMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Year" format. Defaults to 'qq'.
-
- -

Internationalisation

-

jsGanttImproved only provides English text however all hard coded strings can be replaced by calling the addLang() method available on the GanttChart object returned by a call to JSGantt.GanttChart()

-

The addLang() method takes two parameters. The first is a string identifier for the language, the second is a javascript object containing all the replacement text pairs, the default English settings are:

-
- - - - - - - -
-
-
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
-
resource
Resource
-
duration
Duration
-
comp
% Comp.
-
completion
Completion
-
startdate
Start Date
-
enddate
End Date
-
moreinfo
More Information
-
notes
Notes
-
-
-
-
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
-
-
-
-

When adding a language any translations that are not provided will use the default English language value. This provides a simple way to override default strings e.g.

-
-g.addLang('en2', {'format':'Select', 'comp':'Complete'});
-
-

would create a language called 'en2' where the text in the format selector was "Select" rather than "Format" and the header for the Percentage Complete column in the task list is "Complete" rather than "% Comp."

-

Once a translation has been added a call must be made to setLang() with the appropriate langage identifier before calling Draw().

- - -

Example Options

-

The configuration options used in the example chart above are:

- -
-g.setCaptionType('Complete');  // Set to Show Caption (None,Caption,Resource,Duration,Complete)
-g.setQuarterColWidth(36);
-g.setDateTaskDisplayFormat('day dd month yyyy'); // Shown in tool tip box
-g.setDayMajorDateDisplayFormat('mon yyyy - Week ww'); // Set format to display dates in the "Major" header of the "Day" view
-g.setWeekMinorDateDisplayFormat('dd mon'); // Set format to display dates in the "Minor" header of the "Week" view
-g.setShowTaskInfoLink(1); //Show link in tool tip (0/1)
-g.setShowEndWeekDate(0); // Show/Hide the date for the last day of the week in header for daily view (1/0)
-g.setUseSingleCell(10000); // Set the threshold at which we will only use one cell per table row (0 disables).  Helps with rendering performance for large charts.
-g.setFormatArr('Day', 'Week', 'Month', 'Quarter'); // Even with setUseSingleCell using Hour format on such a large chart can cause issues in some browsers
-
- -

Putting all this information together the final code to produce the chart above is as follows:

- - -

XML Export

-

The following methods can be used to extract details of tasks in the project in XML format

- -

Method definition: getXMLProject()

-

Returns a string containing the entire project in JSGantt Improved XML format. Dates will be exported in the currently defined input format as set by setDateInputFormat()

- -

Method definition: getXMLTask(pID, pIdx)

-
-
pID
(required) the numeric ID that identifies the task to extract
-
pIdx
(optional) Boolean - if present and set to "true" the number passed in the pID parameter is treated as an array index for the task list rather than an ID
-
-

Returns a string containing the specified task item in JSGantt Improved XML format. Dates will be exported in the currently defined input format as set by setDateInputFormat()

- -

Additional Demos

- - - - -

Credits

- -

Developed by Paul Geldart

-

Based on jsGantt 1.2 developed by Shlomy Gantz and Brian Twidt
-Contributed: Paul Labuschagne, Kevin Badgett, Ilan Admon
-

- - - - \ No newline at end of file + + + + +FREE javascript gantt - jsGantt Improved HTML and CSS only + + + + + + +
+
jsGanttImproved - 1.7.5
+ +
+

  100% Free Javascript / CSS/ HTML Gantt chart control. Completely buzzword compliant including AJAX !

+ + +
+ + +

Basic Features

+ + +

Advanced Features

+ +

Bugs/Issues

+ +
+

Current Issues:

+
    +
  1. If the browser is viewing the page at anything other than 100% zoom then bars may not be sized or positioned correctly.
  2. + +

+

Changes/fixes in jsGanttImproved:

+

v1.7.5:

+ +

v1.7:

+ +

v1.6:

+ +

v1.5:

+ +

v1.4:

+ +

v1.3:

+ +

+Please see the differences for the CSS file in commit ea9890e for details of CSS structural changes. +

+

v1.2:

+ +

Both these updates required changes to existing element IDs and style classes. Custom stylesheets will most likely need to be updated. +

+All chart element ids are now prefixed with the id of the master DIV containing the chart. As a result the default stylesheet has been updated to no longer use any element ids to apply styles. +

+Please see the notes for commit b4bf8ea for details of CSS structural changes. +

+

v1.1:

+ +

v1.0:

+ +

Download

+Click here to download the current version of jsGantt Improved
+You can download the latest bleeding edge version, request features and report issues at https://github.com/jsGanttImproved/jsgantt-improved/ + +

License

+JSGanttImproved is released under BSD license.
+If you plan to use it in a commercial product please consider donating the first sale to charity. +

+ + +

Usage

+

Creating a basic Gantt Chart

+
    +
  1. Include JSGantt CSS and Javascript +
    +<link rel="stylesheet" type="text/css" href="jsgantt.css" />
    +<script language="javascript" src="jsgantt.js"></script>
    +
    +
  2. +
  3. Create a div element to hold the gantt chart +
    <div style="position:relative" class="gantt" id="GanttChartDIV"></div>
    +
  4. +
  5. Start a <script> block +
    <script type="text/javascript">
    +
  6. +
  7. Instantiate JSGantt using GanttChart() +
    var g = new JSGantt.GanttChart(document.getElementById('GanttChartDIV'), 'day');
    +
    +

    Method definition: + GanttChart(pDiv, pFormat)

    +
    +
    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
    +
    +
  8. +
  9. Customize the look and feel using configuration methods (see Configuration Options)

  10. +
  11. Add Tasks +
    1. using AddTaskItem() +
      +g.AddTaskItem(new JSGantt.TaskItem(1, 'Define Chart API','',          '',          'ggroupblack','', 0, 'Brian', 0,  1,0,1,'','','Some Notes text',g));
      +g.AddTaskItem(new JSGantt.TaskItem(11,'Chart Object',    '2014-02-20','2014-02-20','gmilestone', '', 1, 'Shlomy',100,0,1,1,'','','',g));
      +
      +

      Method definition: +TaskItem(pID, pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption, pNotes, pGantt)

      +
      +
      pID
      (required) a unique numeric ID used to identify each row
      +
      pName
      (required) the task Label
      +
      pStart
      (required) the task start date, can enter empty date ('') for groups. You can also enter specific time (2014-02-20 12:00) for additional precision.
      +
      pEnd
      (required) the task end date, can enter empty date ('') for groups
      +
      pClass
      (required) the css class for this task
      +
      pLink
      (optional) any http link to be displayed in tool tip as the "More information" link.
      +
      pMile
      (optional) indicates whether this is a milestone task - Numeric; 1 = milestone, 0 = not milestone
      +
      pRes
      (optional) resource name
      +
      pComp
      (required) completion percent, numeric
      +
      pGroup
      (optional) indicates whether this is a group task (parent) - Numeric; 0 = normal task, 1 = standard group task, 2 = combined group task*
      +
      pParent
      (required) identifies a parent pID, this causes this task to be a child of identified task. Numeric, top level tasks should have pParent set to 0
      +
      pOpen
      (required) indicates whether a standard group task is open when chart is first drawn. Value must be set for all items but is only used by standard group tasks. Numeric, 1 = open, 0 = closed
      +
      pDepend
      (optional) comma separated list of id's this task is dependent on. A line will be drawn from each listed task to this item
      Each id can optionally be followed by a dependency type suffix. Valid values are:
      'FS' - Finish to Start (default if suffix is omitted)
      'SF' - Start to Finish
      'SS' - Start to Start
      'FF' - Finish to Finish
      If present the suffix must be added directly to the id e.g. '123SS'
      +
      pCaption
      (optional) caption that will be added after task bar if CaptionType set to "Caption"
      +
      pNotes
      (optional) Detailed task information that will be displayed in tool tip for this task
      +
      pGantt
      (required) javascript JSGantt.GanttChart object from which to take settings. Defaults to "g" for backwards compatibility
      +
      +

      * Combined group tasks show all sub-tasks on one row. The information displayed in the task list and row caption are taken from the parent task. Tool tips are generated individually for each sub-task from its own information. Milestones are not valid as sub-tasks of a combined group task and will not be displayed. No bounds checking of start and end dates of sub-tasks is performed therefore it is possible for these task bars to overlap. Dependencies can be set to and from sub-tasks only.

      +
    2. +
    3. using parseXML() with an external XML file +
      +JSGantt.parseXML("project.xml",g);
      +
      +

      Method definition: + JSGantt.parseXML(pFile, pGanttObj)

      +
      +
      pFile
      (required) this is the filename of the XML
      +
      pGanttObj
      (required) a GanttChart object returned by a call to JSGantt.GanttChart()
      +
      +

      The structure of the native XML file:

      +
      + +
      +

      Field definitions are as described for the parameters to TaskItem above. The pClass element is optional in XML files and will default to "ggroupblack" for group tasks, "gtaskblue" for normal tasks and "gmilestone" for milestones. The pGantt element is not required for XML import.

      +

      JSGannt Improved will also test the provided XML file to see if it appears to be in Microsoft Project XML format. If so an attempt will be made to load up the project. This feature is experimental, the import is best effort and not guaranteed. Once loaded the project as interpreted by JSGantt Improved can be extracted using the XML Export methods provided.

      +
    4. +
    5. using parseXMLString() with XML held in a javascript string object +
      +JSGantt.parseXMLString("<project><task>...</task></project>",g);
      +
      +

      Method definition: + JSGantt.parseXMLString(pStr, pGanttObj)

      +
      +
      pStr
      (required) this is a javascript String containing XML
      +
      pGanttObj
      (required) a GanttChart object returned by a call to JSGantt.GanttChart()
      +
      +

      The XML provided will be parsed in exactly the same way as the contents of an external XML file and hence must match the format as described for JSGantt.parseXML() above

      +
  12. +
  13. Call Draw()

    g.Draw();
    +
  14. +
  15. Close the <script> block

    </script>
    +
  16. +
+ +

It is possible to add items to the chart in realtime via javascript using either direct method calls or additional XML files. +It is also possible to delete tasks using RemoveTaskItem() method.

+
g.RemoveTaskItem(11);
+

Method definition: +RemoveTaskItem(pID)

+
+
pID
(required) the unique numeric ID of the item to be removed
+
+

If the task removed is a group item, all child tasks will also be removed.

+

After adding or removing tasks a call to "g.Draw()" must be made to redraw the chart.

+ +

Configuration Options

+

Switches

+

Many of the features of jsGanttImproved can be customised through the use of setter methods available on the GanttChart object returned by a call to JSGantt.GanttChart()

+

The following options take a single numeric parameter; a value of 1 will enable the describe functionality, 0 will disable it

+
+
setUseToolTip()
Controls the display of tool tip boxes, defaults to 1 (enabled)
+
setUseFade()
Controls use of the fade effect when showing/hiding tool tips, defaults to 1 (enabled)
+
setUseMove()
Controls use of the sliding effect when changing between different task tool tips, defaults to 1 (enabled)
+
setUseRowHlt()
Controls the use of row mouseover highlighting, defaults to 1 (enabled)
+
setUseSort()
Controls whether the task list is sorted into parent task / start time order or is simply displayed in the order created, defaults to 1 (sort enabled)
+
setShowRes()
Controls whether the Resource column is displayed in the task list, defaults to 1 (show column)
+
setShowDur()
Controls whether the Task Duration column is displayed in the task list, defaults to 1 (show column)
+
setShowComp()
Controls whether the Percentage Complete column is displayed in the task list, defaults to 1 (show column)
+
setShowStartDate()
Controls whether the Task Start Date column is displayed in the task list, defaults to 1 (show column)
+
setShowEndDate()
Controls whether the Task End Date column is displayed in the task list, defaults to 1 (show column)
+
setShowTaskInfoRes()
Controls whether the Resource information is displayed in the task tool tip, defaults to 1 (show information)
+
setShowTaskInfoDur()
Controls whether the Task Duration information is displayed in the task tool tip, defaults to 1 (show information)
+
setShowTaskInfoComp()
Controls whether the Percentage Complete information is displayed in the task tool tip, defaults to 1 (show information)
+
setShowTaskInfoStartDate()
Controls whether the Task Start Date information is displayed in the task tool tip, defaults to 1 (show information)
+
setShowTaskInfoEndDate()
Controls whether the Task End Date information is displayed in the task tool tip, defaults to 1 (show information)
+
Controls whether the More Information link is displayed in the task tool tip, defaults to 0 (do NOT show link)
+
setShowTaskInfoNotes()
Controls whether the Additional Notes data is displayed in the task tool tip, defaults to 1 (show notes)
+
setShowEndWeekDate()
Controls whether the major heading in "Day" view displays the week end-date in the appropriate format (see below), defaults to 1 (show date)
+
setShowDeps()
Controls display of dependancy lines, defaults to 1 (show dependencies)
+
+

Key Values

+

The following options enable functionality using a set of specific key values

+
+
setShowSelector()
Controls where the format selector is displayed, accepts multiple parameters.
Valid parameter values are "Top", "Bottom".
Defaults to "Top".
+
setFormatArr()
Controls which format options are shown in the format selector, accepts multiple parameters.
Valid parameter values are "Hour", "Day", "Week", "Month", "Quarter".
Defaults to all valid values.
+
setCaptionType()
Controls which task field to use as a caption on the Gantt Chart task bar, accepts a single parameter.
Valid parameter values are "None", "Caption", "Resource", "Duration", "Complete".
Defaults to "None"
+
setDateInputFormat()
Defines the input format used for dates in task creation, accepts a single parameter.
Valid parameter values are "yyyy-mm-dd", "dd/mm/yyyy", "mm/dd/yyyy".
Defaults to "yyyy-mm-dd"
+
setScrollTo()
Sets the date the Gantt Chart will be scrolled to, specified in the date input format set by setDateInputFormat() above. Also accepts the special value "today"
Defaults to minimum display date
+
setUseSingleCell()
Sets the threshold total number of cells at which the task list will use a single table cell for each row rather than one cell per period. Useful to improve performance on large charts. A value of 0 disables this functionality (always use multiple cells), defaults to 25000
+
setLang()
Sets translation to use when drawing the chart. Defaults to "en" as this is the only language provided in the base installation (see Internationalisation below for details on how to add more translations.)
+
+

Layout

+

Most of the look and feel of the Gantt Chart can be controlled using CSS however, as the length of a task bar is determined by column width, the following methods take a single numeric parameter that defines the appropriate column width in pixels.

+

Note that the task bar sizing code assumes the use of collapsed table borders 1px wide.

+
+
setHourColWidth()
Width of Gantt Chart columns in pixels when drawn in "Hour" format. Defaults to 18.
+
setDayColWidth()
Width of Gantt Chart columns in pixels when drawn in "Day" format. Defaults to 18.
+
setWeekColWidth()
Width of Gantt Chart columns in pixels when drawn in "Week" format. Defaults to 36.
+
setMonthColWidth()
Width of Gantt Chart columns in pixels when drawn in "Month" format. Defaults to 36.
+
setQuarterColWidth()
Width of Gantt Chart columns in pixels when drawn in "Quarter" format, although not mandatory it is recommended that this be set to a value divisible by 3. Defaults to 18.
+
setRowHeight()
Height of Gantt Chart rows in pixels. Used to route dependency lines near end points. Defaults to 20.
+
setMinGpLen()
Group tasks have their task bars embellished with end points, this value specifies the width of one of these end points in pixels. A short task bar's length will be rounded up to display either a single or both endpoints correctly. Defaults to 8.
+
+

Display Date Formats

+

Date display formats can be individually controlled. The methods used to set these display formats each take a single format string parameter. The format string can be made up of the following components (case sensitive)

+
+
+
h
Hour (1-12)
+
hh
Hour (01-12)
+
pm
am/pm indicator
+
PM
AM/PM indicator
+
H
Hour (0-23)
+
HH
Hour (01-23)
+
mi
Minutes (1-59)
+
MI
Minutes (01-59)
+
d
Day (1-31)
+
dd
Day (01-31)
+
day
Abbriviated day of week
+
DAY
Day of week
+
m
Month (1-12)
+
mm
Month (01-12)
+
mon
Abbriviated month text
+
month
Full month text
+
yy
Year, excluding century
+
yyyy
Year
+
q
Quarter (1-4)
+
qq
Quarter (Q1-Q4)
+
w
ISO Week number (1-53)
+
ww
ISO Week number (01-53)
+
week
Full ISO Week date format
+
+

separated by one of the following characters: "/\-.,'<space>:

+

Any text between separators that does not match one of the components above will be checked using a case insensitive match for a valid internationalised string (see Internationalisation below). If the value is still not found the text will be output unchanged.

+
+

+

+
setDateTaskTableDisplayFormat()
Date format used for start and end dates in the main task list. Defaults to 'dd/mm/yyyy'.
+
setDateTaskDisplayFormat()
Date format used for start and end dates in task tool tips. Defaults to 'dd month yyyy'.
+
setHourMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Hour" format. Defaults to 'day dd month yyyy'.
+
setDayMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Day" format. Defaults to 'dd/mm/yyyy'.
+
setWeekMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Week" format. Defaults to 'yyyy'.
+
setMonthMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Month" format. Defaults to 'yyyy'.
+
setQuarterMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Year" format. Defaults to 'yyyy'.
+
setHourMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Hour" format. Defaults to 'HH'.
+
setDayMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Day" format. Defaults to 'dd'.
+
setWeekMinjorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Week" format. Defaults to 'dd/mm'.
+
setMonthMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Month" format. Defaults to 'mon'.
+
setQuarterMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Year" format. Defaults to 'qq'.
+
+ +

Internationalisation

+

jsGanttImproved only provides English text however all hard coded strings can be replaced by calling the addLang() method available on the GanttChart object returned by a call to JSGantt.GanttChart()

+

The addLang() method takes two parameters. The first is a string identifier for the language, the second is a javascript object containing all the replacement text pairs, the default English settings are:

+
+ + + + + + + +
+
+
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
+
resource
Resource
+
duration
Duration
+
comp
% Comp.
+
completion
Completion
+
startdate
Start Date
+
enddate
End Date
+
moreinfo
More Information
+
notes
Notes
+
+
+
+
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
+
+
+
+

When adding a language any translations that are not provided will use the default English language value. This provides a simple way to override default strings e.g.

+
+g.addLang('en2', {'format':'Select', 'comp':'Complete'});
+
+

would create a language called 'en2' where the text in the format selector was "Select" rather than "Format" and the header for the Percentage Complete column in the task list is "Complete" rather than "% Comp."

+

Once a translation has been added a call must be made to setLang() with the appropriate langage identifier before calling Draw().

+ + +

Example Options

+

The configuration options used in the example chart above are:

+ +
+g.setCaptionType('Complete');  // Set to Show Caption (None,Caption,Resource,Duration,Complete)
+g.setQuarterColWidth(36);
+g.setDateTaskDisplayFormat('day dd month yyyy'); // Shown in tool tip box
+g.setDayMajorDateDisplayFormat('mon yyyy - Week ww'); // Set format to display dates in the "Major" header of the "Day" view
+g.setWeekMinorDateDisplayFormat('dd mon'); // Set format to display dates in the "Minor" header of the "Week" view
+g.setShowTaskInfoLink(1); //Show link in tool tip (0/1)
+g.setShowEndWeekDate(0); // Show/Hide the date for the last day of the week in header for daily view (1/0)
+g.setUseSingleCell(10000); // Set the threshold at which we will only use one cell per table row (0 disables).  Helps with rendering performance for large charts.
+g.setFormatArr('Day', 'Week', 'Month', 'Quarter'); // Even with setUseSingleCell using Hour format on such a large chart can cause issues in some browsers
+
+ +

Putting all this information together the final code to produce the chart above is as follows:

+ + +

XML Export

+

The following methods can be used to extract details of tasks in the project in XML format

+ +

Method definition: getXMLProject()

+

Returns a string containing the entire project in JSGantt Improved XML format. Dates will be exported in the currently defined input format as set by setDateInputFormat()

+ +

Method definition: getXMLTask(pID, pIdx)

+
+
pID
(required) the numeric ID that identifies the task to extract
+
pIdx
(optional) Boolean - if present and set to "true" the number passed in the pID parameter is treated as an array index for the task list rather than an ID
+
+

Returns a string containing the specified task item in JSGantt Improved XML format. Dates will be exported in the currently defined input format as set by setDateInputFormat()

+ +

Additional Demos

+ + + + +

Credits

+ +

Developed by Paul Geldart

+

Based on jsGantt 1.2 developed by Shlomy Gantz and Brian Twidt
+Contributed: Paul Labuschagne, Kevin Badgett, Ilan Admon
+

+ + + + diff --git a/jsgantt.css b/jsgantt.css index 1dbad927..d93f1b06 100644 --- a/jsgantt.css +++ b/jsgantt.css @@ -1,242 +1,242 @@ -/* Sample CSS for jsGanttImproved v1.7.3 */ -div.gantt { font-family:tahoma, arial, verdana, Sans-serif; font-size:10px; color: #656565; } - -.gantt table { border-collapse: collapse; } -.gantt td { padding: 0px; } - -/* cell defaults */ -.gmajorheading, -.gminorheading, -.gminorheadingwkend, -.gtaskcell, -.gtaskcellwkend { height: 19px; font-size: 12px; border: #efefef 1px solid; text-align: center; cursor: default } -.gtasklist { height: 19px; min-width: 5px; max-width: 5px; width: 5px; border: #efefef 1px solid; border-right: none; } /* all three width values set just to make sure - helps resizing code */ - -/* Additional values for some cell elements */ -.gtaskheading, -.gmajorheading, -.gminorheading { background-color: #ffffff; font-weight: bold; font-size: 9px; white-space: nowrap; } -.gtaskcellwkend, -.gminorheadingwkend { background-color: #f7f7f7; font-weight: bold; font-size: 9px; white-space: nowrap; } -td.gtaskcell { text-align: left } -td.gspanning { border-left: none; border-right: none; } -.gtaskcelldiv { position: relative; } - -/* Task list defaults */ -.gtaskheading, -.gname, -.gtaskname, -.gresource, -.gduration, -.gpccomplete, -.gstartdate, -.genddate { height: 18px; white-space: nowrap; border: #efefef 1px solid; } - -/* Additional values for some task list elements */ -.gresource, -.gduration, -.gpccomplete, -.gstartdate div, /* needed for IE8 */ -.gstartdate { text-align: center; min-width: 70px; max-width: 70px; width: 70px; font-size: 10px; } -.genddate div, /* needed for IE8 */ -.genddate { text-align: center; min-width: 70px; max-width: 70px; width: 70px; font-size: 10px; } -.gtaskheading { text-align: center; } -.gtaskname div, /* needed for IE8 */ -.gtaskname { min-width: 170px; max-width: 170px; width: 170px; font-size: 9px; border-left: none; } - -.gselector { text-align: left; white-space: nowrap; min-width: 170px; max-width: 170px; width: 170px; } - -.gformlabel { position:relative; top:0px; cursor:pointer; border: #ffffff 1px solid; margin-left: 2px; padding-left: 2px; padding-right: 2px; } -span.gformlabel:hover, -span.gselected { background-color: #dbecff; border: #cccccc 1px solid;} - -span.gfoldercollapse { color:#000000; cursor:pointer; font-weight:bold; font-size: 12px; font-family: Courier, "Courier New", monospace; } - -.gtasktableh, -.gtasktable { border-right: #efefef 1px solid; } -.gcharttable { border: #efefef 1px solid; } /* for some reason firefox needs this */ - -/* Differentiate Group, Milestone and Ordinary task items (applied to row) */ -.ggroupitem { background-color: #fbfbfb; font-weight: bold; } -.gmileitem, -.glineitem { background-color: #ffffff; } - -/* highlight row (applied to row) */ -.gitemhighlight td { background-image: none; background-color: #fffde5;} - -/* task bar caption text styles */ -.gmilecaption, -.ggroupcaption, -.gcaption { font-weight: normal; font-size: 9px; text-align: left; white-space: nowrap; top:1px; position: absolute; top:2px; } - -.ggroupcaption, -.gcaption { right: -126px; } - -/* Task complete %age bar shared attributes */ -.gtaskcomplete { float:left; overflow: hidden; } - -/* Task complete %age bar */ -.gtaskcomplete { height:5px; background-color:#000000; margin-top:4px; opacity:0.4; filter: alpha(opacity=40); } - -/* Milestones */ -.gmilestone { font-size: 14px; position: absolute; top: -2px; } -.gmdtop { top: 2px; overflow: hidden; width:0px; height:0px; border-bottom: 5px solid black; border-left: 5px solid transparent; border-top: 5px solid transparent; border-right: 5px solid transparent;} -.gmdbottom { top: 2px; overflow: hidden; width:0px; height:0px; border-top: 5px solid black; border-left: 5px solid transparent; border-bottom: 5px solid transparent; border-right: 5px solid transparent;} - -/* Task bar shared attributes */ -.ggroupblack, -.gtaskblue, -.gtaskred, -.gtaskgreen, -.gtaskyellow, -.gtaskpurple, -.gtaskpink { height: 13px; filter: alpha(opacity=90); opacity:0.9; margin-top: 1px; } - -/* Task bars - ggroupblack is set as the default class on the task if it is undefined */ -.ggroupblack { height: 7px; background: #000000; margin-top: 2px; } -.ggroupblackendpointleft { overflow: hidden; width:0px; height:0px; top: 2px; border-top: 4px solid black; border-left: 4px solid transparent; border-bottom: 4px solid transparent; border-right: 4px solid transparent; float: left; } -.ggroupblackendpointright { overflow: hidden; width:0px; height:0px; top: 2px; border-top: 4px solid black; border-left: 4px solid transparent; border-bottom: 4px solid transparent; border-right: 4px solid transparent; float: right; } -.ggroupblackcomplete { float:left; overflow: hidden; height:3px; filter: alpha(opacity=80); opacity:0.8; background-color:#777777; margin-top:2px; margin-bottom: 2px; } -.gtaskblue { - background: rgb(58,132,195); /* Old browsers */ - background: linear-gradient(to bottom, rgba(58,132,195,1) 0%,rgba(65,154,214,1) 20%,rgba(75,184,240,1) 40%,rgba(58,139,194,1) 70%,rgba(38,85,139,1) 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4bb8f0', endColorstr='#3a84c3',GradientType=0 ); /* IE6-9 */ -} -.gtaskred { - background: rgb(196,58,58); /* Old browsers */ - background: linear-gradient(to bottom, rgba(196,58,58,1) 0%,rgba(211,65,65,1) 20%,rgba(239,76,76,1) 40%,rgba(196,58,58,1) 70%,rgba(135,37,37,1) 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ef4c4c', endColorstr='#c43a3a',GradientType=0 ); /* IE6-9 */ -} -.gtaskgreen { - background: rgb(80,193,58); /* Old browsers */ - background: linear-gradient(to bottom, rgba(80,193,58,1) 0%,rgba(88,209,64,1) 20%,rgba(102,237,75,1) 40%,rgba(80,193,58,1) 70%,rgba(53,132,37,1) 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#66ED4B', endColorstr='#50c13a',GradientType=0 ); /* IE6-9 */ -} -.gtaskyellow { - background: rgb(247,228,56); /* Old browsers */ - background: linear-gradient(to bottom, rgba(247,228,56,1) 0%,rgba(239,239,55,1) 20%,rgba(255,255,58,1) 40%,rgba(242,236,55,1) 70%,rgba(241,218,54,1) 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffff3a', endColorstr='#f7e438',GradientType=0 ); /* IE6-9 */ -} -.gtaskpurple { - background: rgb(193,58,193); /* Old browsers */ - background: linear-gradient(to bottom, rgba(193,58,193,1) 0%,rgba(211,65,211,1) 20%,rgba(239,76,239,1) 40%,rgba(193,58,193,1) 70%,rgba(137,38,137,1) 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ef4cef', endColorstr='#892689',GradientType=0 ); /* IE6-9 */ -} -.gtaskpink { - background: rgb(249,177,245); /* Old browsers */ - background: linear-gradient(to bottom, rgba(249,177,245,1) 0%,rgba(247,192,243,1) 20%,rgba(247,202,244,1) 40%,rgba(249,192,246,1) 70%,rgba(252,174,247,1) 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f7caf4', endColorstr='#fcaef7',GradientType=0 ); /* IE6-9 */ -} -.gtaskbluecomplete, -.gtaskredcomplete, -.gtaskgreencomplete, -.gtaskyellowcomplete, -.gtaskpurplecomplete, -.gtaskpinkcomplete { float:left; overflow: hidden; height:5px; filter: alpha(opacity=40); opacity:0.4; background-color: #000000; margin-top:4px; } - -/* Printer friendly styles - we could use these all the time but they are not as pretty! */ -/* note that "@media print" is not supported in IE6 or 7. Fully patched IE8 should be OK */ -@media print { - .ggroupblack { height:0px; border-top: 7px solid; border-color: #000000; } - .gtaskblue { height:0px; border-top: 13px solid; border-color: rgb(58,132,195); } - .gtaskred { height:0px; border-top: 13px solid; border-color: rgb(196,58,58); } - .gtaskgreen { height:0px; border-top: 13px solid; border-color: rgb(80,193,58); } - .gtaskyellow { height:0px; border-top: 13px solid; border-color: rgb(247,228,56); } - .gtaskpurple { height:0px; border-top: 13px solid; border-color: rgb(193,58,193); } - .gtaskpink { height:0px; border-top: 13px solid; border-color: rgb(249,177,245); } - - .gtaskbluecomplete, - .gtaskredcomplete, - .gtaskgreencomplete, - .gtaskyellowcomplete, - .gtaskpurplecomplete, - .gtaskpinkcomplete { height:0px; filter: alpha(opacity=40); opacity:0.4; margin-top: -9px; border-top: 5px solid; border-color: #000000; } - .ggroupblackcomplete { height: 0px; filter: alpha(opacity=80); opacity:0.8; margin-top:-5px; border-top:3px solid; border-color:#777777; } -} - -/* END Task bar styles */ -.glinev { border-left: 1px solid; width: 0px; } -.glineh { border-top: 1px solid; height: 0px; } - -.gDepFS, -.gDepSS, -.gDepSF, -.gDepFF { border-color: #ff0000; } -.gDepFSArw, -.gDepSSArw { overflow: hidden; width:0px; height:0px; border-bottom: 4px solid transparent; border-left: 4px solid #ff0000; border-top: 4px solid transparent; border-right: 4px solid transparent;} -.gDepFFArw, -.gDepSFArw { overflow: hidden; width:0px; height:0px; border-bottom: 4px solid transparent; border-left: 4px solid transparent; border-top: 4px solid transparent; border-right: 4px solid #ff0000;} -.gCurDate { border-color: #0000ff; } - - -div.gtaskbarcontainer { z-index: 1; position: absolute; top: 0px } - -.JSGanttToolTip {position: absolute; display: block; z-index: 2;} -.JSGanttToolTipcont {font-family: tahoma, arial, verdana; font-size: 10px; display: block; background: #ffffff; color: #656565} -.gTaskInfo {background: #dbecff; width: 400px; border: #656565 1px solid; border-radius: 10px; padding: 4px 6px 4px 6px; float: left;} -.gTtTitle {display: block; font-size: 12px; font-weight: bold; color: #404040; margin-left: 4px; margin-bottom: 1em;} -.gTaskLabel {font-size: 11px; font-weight: bold; color: #656565; margin-left: 4px;} -.gTaskText {position:absolute; left: 90px; padding-top: 1px; font-size: 10px; font-weight: normal; color: #656565;} -.gTaskNotes {font-size: 11px; font-weight: normal; color: #323232; padding: 0 15px; display: block;} -.gTIn {padding-top: 10px;} - -.gantt { min-width: 1064px; /* 2x LC width */ } -.gchartcontainer { padding-left: 532px; /* LC width */ } -.gcontainercol { position: relative; float: left; } /* Add a max-height value here if wanted */ -.glistgrid { width: 532px; /* LC width */ margin-left: -100%; right: 532px; /* LC width */ padding-right: 0px; padding-left: 0px; padding-bottom: 0px; padding-top: 0px; background-color: #ffffff; overflow: hidden; } -.glistlbl { width: 532px; /* LC width */ margin-left: -100%; right: 532px; /* LC width */ padding-right: 0px; padding-left: 0px; padding-bottom: 0px; padding-top: 0px; background-color: #ffffff; overflow: hidden; } -.glabelfooter { clear: both; } -.ggridfooter { clear: both; } - -.rhscrpad { width: 150px; position: absolute; top: 0px; height: 1px; } - -.gchartgrid { width: 100%; padding-right: 0px; padding-left: 0px; padding-bottom: 0px; padding-top: 0px; background-color: #ffffff; position: relative; overflow: auto; min-height: 0%; } -.gchartlbl { width: 100%; padding-right: 0px; padding-left: 0px; padding-bottom: 0px; padding-top: 0px; background-color: #ffffff; position: relative; overflow: hidden; } - -/* Old Internet Explorer version hacks */ -.gantt { _height: 100% } /* otherwise the chart disappears! */ -div .gantt { _width: 1064px; } /* ie6 fixed width */ -div.gchartlbl, -div.gchartgrid { _width: 532px; } /* ie6 fixed width */ -div.glistlbl, -div.glistgrid { - *right: 0px; /* ie7 pulls the content too far left with the negative margin */ - _right: 532px; /* but ie6 fixed width needs this */ - _margin-left: -532px; /* ie6 fixed width */ -} -div.gchartgrid { *padding-bottom: 20px; *overflow-y: hidden; } /* variable height design, no need for vertical scroll */ -td.gmajorheading div { *overflow: hidden; } /* stops resizing fixed width columns if the text is too wide */ -td.gspanning div { *overflow: hidden; } /* stops resizing fixed width columns if the text is too wide */ - -/* border transparency tricks */ -.ggroupblackendpointleft { _border-top: 4px solid black; _border-left: 4px solid pink; _border-bottom: 4px solid pink; _border-right: 4px solid pink; _filter: chroma(color=pink); } -.ggroupblackendpointright { _border-top: 4px solid black; _border-left: 4px solid pink; _border-bottom: 4px solid pink; _border-right: 4px solid pink;_filter: chroma(color=pink); } - -.gmdtop { _border-left: 5px solid pink; _border-top: 5px solid pink; _border-right: 5px solid pink; _filter: chroma(color=pink);} -.gmdbottom { _border-left: 5px solid pink; _border-bottom: 5px solid pink; _border-right: 5px solid pink; _filter: chroma(color=pink);} - -.gDepFSArw, -.gDepSSArw { _border-bottom: 4px solid pink; _border-top: 4px solid pink; _border-right: 4px solid pink; _filter: chroma(color=pink);} -.gDepFFArw, -.gDepSFArw { _border-bottom: 4px solid pink; _border-left: 4px solid pink; _border-top: 4px solid pink; _filter: chroma(color=pink);} - -/* Workaround for odd bug in old versions of Opera - no other browser needs this */ -.glinediv {position: absolute; top: 0px; left: 0px;} - -/* if using setUseSingleCell(1) the following is a suggested set of CSS3 styles to recreate the table grid - won't work on old browsers -.ggrouphour td, -.gmilehour td, -.gitemhour td { background-size: 19px 1px; background-image: linear-gradient(to left, #efefef, transparent 1px, transparent 18px); width: 100%; height: 19px; } -.ggroupday td, -.gmileday td, -.gitemday td { background-size: 19px 1px, 133px 1px; background-image: linear-gradient(to left, #efefef, transparent 1px, transparent 18px), linear-gradient(to left, #f7f7f7 39px, transparent 1px, transparent 92px); width: 100%; height: 19px; } -.ggroupweek td, -.gmileweek td, -.gitemweek td { background-size: 37px 1px; background-image: linear-gradient(to left, #efefef, transparent 1px, transparent 36px); width: 100%; height: 19px; } -.ggroupmonth td, -.gmilemonth td, -.gitemmonth td { background-size: 37px 1px; background-image: linear-gradient(to left, #efefef, transparent 1px, transparent 36px); width: 100%; height: 19px; } -.ggroupquarter td, -.gmilequarter td, -.gitemquarter td { background-size: 19px 1px; background-image: linear-gradient(to left, #efefef, transparent 1px, transparent 18px); width: 100%; height: 19px; } -*/ +/* Sample CSS for jsGanttImproved v1.7.3 */ +div.gantt { font-family:tahoma, arial, verdana, Sans-serif; font-size:10px; color: #656565; } + +.gantt table { border-collapse: collapse; } +.gantt td { padding: 0px; } + +/* cell defaults */ +.gmajorheading, +.gminorheading, +.gminorheadingwkend, +.gtaskcell, +.gtaskcellwkend { height: 19px; font-size: 12px; border: #efefef 1px solid; text-align: center; cursor: default } +.gtasklist { height: 19px; min-width: 5px; max-width: 5px; width: 5px; border: #efefef 1px solid; border-right: none; } /* all three width values set just to make sure - helps resizing code */ + +/* Additional values for some cell elements */ +.gtaskheading, +.gmajorheading, +.gminorheading { background-color: #ffffff; font-weight: bold; font-size: 9px; white-space: nowrap; } +.gtaskcellwkend, +.gminorheadingwkend { background-color: #f7f7f7; font-weight: bold; font-size: 9px; white-space: nowrap; } +td.gtaskcell { text-align: left } +td.gspanning { border-left: none; border-right: none; } +.gtaskcelldiv { position: relative; } + +/* Task list defaults */ +.gtaskheading, +.gname, +.gtaskname, +.gresource, +.gduration, +.gpccomplete, +.gstartdate, +.genddate { height: 18px; white-space: nowrap; border: #efefef 1px solid; } + +/* Additional values for some task list elements */ +.gresource, +.gduration, +.gpccomplete, +.gstartdate div, /* needed for IE8 */ +.gstartdate { text-align: center; min-width: 70px; max-width: 70px; width: 70px; font-size: 10px; } +.genddate div, /* needed for IE8 */ +.genddate { text-align: center; min-width: 70px; max-width: 70px; width: 70px; font-size: 10px; } +.gtaskheading { text-align: center; } +.gtaskname div, /* needed for IE8 */ +.gtaskname { min-width: 170px; max-width: 170px; width: 170px; font-size: 9px; border-left: none; } + +.gselector { text-align: left; white-space: nowrap; min-width: 170px; max-width: 170px; width: 170px; } + +.gformlabel { position:relative; top:0px; cursor:pointer; border: #ffffff 1px solid; margin-left: 2px; padding-left: 2px; padding-right: 2px; } +span.gformlabel:hover, +span.gselected { background-color: #dbecff; border: #cccccc 1px solid;} + +span.gfoldercollapse { color:#000000; cursor:pointer; font-weight:bold; font-size: 12px; font-family: Courier, "Courier New", monospace; } + +.gtasktableh, +.gtasktable { border-right: #efefef 1px solid; } +.gcharttable { border: #efefef 1px solid; } /* for some reason firefox needs this */ + +/* Differentiate Group, Milestone and Ordinary task items (applied to row) */ +.ggroupitem { background-color: #fbfbfb; font-weight: bold; } +.gmileitem, +.glineitem { background-color: #ffffff; } + +/* highlight row (applied to row) */ +.gitemhighlight td { background-image: none; background-color: #fffde5;} + +/* task bar caption text styles */ +.gmilecaption, +.ggroupcaption, +.gcaption { font-weight: normal; font-size: 9px; text-align: left; white-space: nowrap; top:1px; position: absolute; top:2px; } + +.ggroupcaption, +.gcaption { right: -126px; } + +/* Task complete %age bar shared attributes */ +.gtaskcomplete { float:left; overflow: hidden; } + +/* Task complete %age bar */ +.gtaskcomplete { height:5px; background-color:#000000; margin-top:4px; opacity:0.4; filter: alpha(opacity=40); } + +/* Milestones */ +.gmilestone { font-size: 14px; position: absolute; top: -2px; } +.gmdtop { top: 2px; overflow: hidden; width:0px; height:0px; border-bottom: 5px solid black; border-left: 5px solid transparent; border-top: 5px solid transparent; border-right: 5px solid transparent;} +.gmdbottom { top: 2px; overflow: hidden; width:0px; height:0px; border-top: 5px solid black; border-left: 5px solid transparent; border-bottom: 5px solid transparent; border-right: 5px solid transparent;} + +/* Task bar shared attributes */ +.ggroupblack, +.gtaskblue, +.gtaskred, +.gtaskgreen, +.gtaskyellow, +.gtaskpurple, +.gtaskpink { height: 13px; filter: alpha(opacity=90); opacity:0.9; margin-top: 1px; } + +/* Task bars - ggroupblack is set as the default class on the task if it is undefined */ +.ggroupblack { height: 7px; background: #000000; margin-top: 2px; } +.ggroupblackendpointleft { overflow: hidden; width:0px; height:0px; top: 2px; border-top: 4px solid black; border-left: 4px solid transparent; border-bottom: 4px solid transparent; border-right: 4px solid transparent; float: left; } +.ggroupblackendpointright { overflow: hidden; width:0px; height:0px; top: 2px; border-top: 4px solid black; border-left: 4px solid transparent; border-bottom: 4px solid transparent; border-right: 4px solid transparent; float: right; } +.ggroupblackcomplete { float:left; overflow: hidden; height:3px; filter: alpha(opacity=80); opacity:0.8; background-color:#777777; margin-top:2px; margin-bottom: 2px; } +.gtaskblue { + background: rgb(58,132,195); /* Old browsers */ + background: linear-gradient(to bottom, rgba(58,132,195,1) 0%,rgba(65,154,214,1) 20%,rgba(75,184,240,1) 40%,rgba(58,139,194,1) 70%,rgba(38,85,139,1) 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4bb8f0', endColorstr='#3a84c3',GradientType=0 ); /* IE6-9 */ +} +.gtaskred { + background: rgb(196,58,58); /* Old browsers */ + background: linear-gradient(to bottom, rgba(196,58,58,1) 0%,rgba(211,65,65,1) 20%,rgba(239,76,76,1) 40%,rgba(196,58,58,1) 70%,rgba(135,37,37,1) 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ef4c4c', endColorstr='#c43a3a',GradientType=0 ); /* IE6-9 */ +} +.gtaskgreen { + background: rgb(80,193,58); /* Old browsers */ + background: linear-gradient(to bottom, rgba(80,193,58,1) 0%,rgba(88,209,64,1) 20%,rgba(102,237,75,1) 40%,rgba(80,193,58,1) 70%,rgba(53,132,37,1) 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#66ED4B', endColorstr='#50c13a',GradientType=0 ); /* IE6-9 */ +} +.gtaskyellow { + background: rgb(247,228,56); /* Old browsers */ + background: linear-gradient(to bottom, rgba(247,228,56,1) 0%,rgba(239,239,55,1) 20%,rgba(255,255,58,1) 40%,rgba(242,236,55,1) 70%,rgba(241,218,54,1) 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffff3a', endColorstr='#f7e438',GradientType=0 ); /* IE6-9 */ +} +.gtaskpurple { + background: rgb(193,58,193); /* Old browsers */ + background: linear-gradient(to bottom, rgba(193,58,193,1) 0%,rgba(211,65,211,1) 20%,rgba(239,76,239,1) 40%,rgba(193,58,193,1) 70%,rgba(137,38,137,1) 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ef4cef', endColorstr='#892689',GradientType=0 ); /* IE6-9 */ +} +.gtaskpink { + background: rgb(249,177,245); /* Old browsers */ + background: linear-gradient(to bottom, rgba(249,177,245,1) 0%,rgba(247,192,243,1) 20%,rgba(247,202,244,1) 40%,rgba(249,192,246,1) 70%,rgba(252,174,247,1) 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f7caf4', endColorstr='#fcaef7',GradientType=0 ); /* IE6-9 */ +} +.gtaskbluecomplete, +.gtaskredcomplete, +.gtaskgreencomplete, +.gtaskyellowcomplete, +.gtaskpurplecomplete, +.gtaskpinkcomplete { float:left; overflow: hidden; height:5px; filter: alpha(opacity=40); opacity:0.4; background-color: #000000; margin-top:4px; } + +/* Printer friendly styles - we could use these all the time but they are not as pretty! */ +/* note that "@media print" is not supported in IE6 or 7. Fully patched IE8 should be OK */ +@media print { + .ggroupblack { height:0px; border-top: 7px solid; border-color: #000000; } + .gtaskblue { height:0px; border-top: 13px solid; border-color: rgb(58,132,195); } + .gtaskred { height:0px; border-top: 13px solid; border-color: rgb(196,58,58); } + .gtaskgreen { height:0px; border-top: 13px solid; border-color: rgb(80,193,58); } + .gtaskyellow { height:0px; border-top: 13px solid; border-color: rgb(247,228,56); } + .gtaskpurple { height:0px; border-top: 13px solid; border-color: rgb(193,58,193); } + .gtaskpink { height:0px; border-top: 13px solid; border-color: rgb(249,177,245); } + + .gtaskbluecomplete, + .gtaskredcomplete, + .gtaskgreencomplete, + .gtaskyellowcomplete, + .gtaskpurplecomplete, + .gtaskpinkcomplete { height:0px; filter: alpha(opacity=40); opacity:0.4; margin-top: -9px; border-top: 5px solid; border-color: #000000; } + .ggroupblackcomplete { height: 0px; filter: alpha(opacity=80); opacity:0.8; margin-top:-5px; border-top:3px solid; border-color:#777777; } +} + +/* END Task bar styles */ +.glinev { border-left: 1px solid; width: 0px; } +.glineh { border-top: 1px solid; height: 0px; } + +.gDepFS, +.gDepSS, +.gDepSF, +.gDepFF { border-color: #ff0000; } +.gDepFSArw, +.gDepSSArw { overflow: hidden; width:0px; height:0px; border-bottom: 4px solid transparent; border-left: 4px solid #ff0000; border-top: 4px solid transparent; border-right: 4px solid transparent;} +.gDepFFArw, +.gDepSFArw { overflow: hidden; width:0px; height:0px; border-bottom: 4px solid transparent; border-left: 4px solid transparent; border-top: 4px solid transparent; border-right: 4px solid #ff0000;} +.gCurDate { border-color: #0000ff; } + + +div.gtaskbarcontainer { z-index: 1; position: absolute; top: 0px } + +.JSGanttToolTip {position: absolute; display: block; z-index: 2;} +.JSGanttToolTipcont {font-family: tahoma, arial, verdana; font-size: 10px; display: block; background: #ffffff; color: #656565} +.gTaskInfo {background: #dbecff; width: 400px; border: #656565 1px solid; border-radius: 10px; padding: 4px 6px 4px 6px; float: left;} +.gTtTitle {display: block; font-size: 12px; font-weight: bold; color: #404040; margin-left: 4px; margin-bottom: 1em;} +.gTaskLabel {font-size: 11px; font-weight: bold; color: #656565; margin-left: 4px;} +.gTaskText {position:absolute; left: 90px; padding-top: 1px; font-size: 10px; font-weight: normal; color: #656565;} +.gTaskNotes {font-size: 11px; font-weight: normal; color: #323232; padding: 0 15px; display: block;} +.gTIn {padding-top: 10px;} + +.gantt { min-width: 1064px; /* 2x LC width */ } +.gchartcontainer { padding-left: 532px; /* LC width */ } +.gcontainercol { position: relative; float: left; } /* Add a max-height value here if wanted */ +.glistgrid { width: 532px; /* LC width */ margin-left: -100%; right: 532px; /* LC width */ padding-right: 0px; padding-left: 0px; padding-bottom: 0px; padding-top: 0px; background-color: #ffffff; overflow: hidden; } +.glistlbl { width: 532px; /* LC width */ margin-left: -100%; right: 532px; /* LC width */ padding-right: 0px; padding-left: 0px; padding-bottom: 0px; padding-top: 0px; background-color: #ffffff; overflow: hidden; } +.glabelfooter { clear: both; } +.ggridfooter { clear: both; } + +.rhscrpad { width: 150px; position: absolute; top: 0px; height: 1px; } + +.gchartgrid { width: 100%; padding-right: 0px; padding-left: 0px; padding-bottom: 0px; padding-top: 0px; background-color: #ffffff; position: relative; overflow: auto; min-height: 0%; } +.gchartlbl { width: 100%; padding-right: 0px; padding-left: 0px; padding-bottom: 0px; padding-top: 0px; background-color: #ffffff; position: relative; overflow: hidden; } + +/* Old Internet Explorer version hacks */ +.gantt { _height: 100% } /* otherwise the chart disappears! */ +div .gantt { _width: 1064px; } /* ie6 fixed width */ +div.gchartlbl, +div.gchartgrid { _width: 532px; } /* ie6 fixed width */ +div.glistlbl, +div.glistgrid { + *right: 0px; /* ie7 pulls the content too far left with the negative margin */ + _right: 532px; /* but ie6 fixed width needs this */ + _margin-left: -532px; /* ie6 fixed width */ +} +div.gchartgrid { *padding-bottom: 20px; *overflow-y: hidden; } /* variable height design, no need for vertical scroll */ +td.gmajorheading div { *overflow: hidden; } /* stops resizing fixed width columns if the text is too wide */ +td.gspanning div { *overflow: hidden; } /* stops resizing fixed width columns if the text is too wide */ + +/* border transparency tricks */ +.ggroupblackendpointleft { _border-top: 4px solid black; _border-left: 4px solid pink; _border-bottom: 4px solid pink; _border-right: 4px solid pink; _filter: chroma(color=pink); } +.ggroupblackendpointright { _border-top: 4px solid black; _border-left: 4px solid pink; _border-bottom: 4px solid pink; _border-right: 4px solid pink;_filter: chroma(color=pink); } + +.gmdtop { _border-left: 5px solid pink; _border-top: 5px solid pink; _border-right: 5px solid pink; _filter: chroma(color=pink);} +.gmdbottom { _border-left: 5px solid pink; _border-bottom: 5px solid pink; _border-right: 5px solid pink; _filter: chroma(color=pink);} + +.gDepFSArw, +.gDepSSArw { _border-bottom: 4px solid pink; _border-top: 4px solid pink; _border-right: 4px solid pink; _filter: chroma(color=pink);} +.gDepFFArw, +.gDepSFArw { _border-bottom: 4px solid pink; _border-left: 4px solid pink; _border-top: 4px solid pink; _filter: chroma(color=pink);} + +/* Workaround for odd bug in old versions of Opera - no other browser needs this */ +.glinediv {position: absolute; top: 0px; left: 0px;} + +/* if using setUseSingleCell(1) the following is a suggested set of CSS3 styles to recreate the table grid - won't work on old browsers +.ggrouphour td, +.gmilehour td, +.gitemhour td { background-size: 19px 1px; background-image: linear-gradient(to left, #efefef, transparent 1px, transparent 18px); width: 100%; height: 19px; } +.ggroupday td, +.gmileday td, +.gitemday td { background-size: 19px 1px, 133px 1px; background-image: linear-gradient(to left, #efefef, transparent 1px, transparent 18px), linear-gradient(to left, #f7f7f7 39px, transparent 1px, transparent 92px); width: 100%; height: 19px; } +.ggroupweek td, +.gmileweek td, +.gitemweek td { background-size: 37px 1px; background-image: linear-gradient(to left, #efefef, transparent 1px, transparent 36px); width: 100%; height: 19px; } +.ggroupmonth td, +.gmilemonth td, +.gitemmonth td { background-size: 37px 1px; background-image: linear-gradient(to left, #efefef, transparent 1px, transparent 36px); width: 100%; height: 19px; } +.ggroupquarter td, +.gmilequarter td, +.gitemquarter td { background-size: 19px 1px; background-image: linear-gradient(to left, #efefef, transparent 1px, transparent 18px); width: 100%; height: 19px; } +*/ diff --git a/jsgantt.js b/jsgantt.js index d677ab74..ae442805 100644 --- a/jsgantt.js +++ b/jsgantt.js @@ -1,2547 +1,2547 @@ -/* - _ ___ _____ _ _____ _ _ - (_) / _ \ \_ \ / ||___ | || | - | |/ /_\/ / /\/ | | / /| || |_ - | / /_\\/\/ /_ | |_ / /_|__ _| - _/ \____/\____/ |_(_)_/(_) |_| - |__/ - jsGanttImproved 1.7.4 - Copyright (c) 2013-2015, 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-2015, 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 () -{ - 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; -}; - -JSGantt.TaskItem=function(pID, pName, pStart, pEnd, pClass, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption, pNotes, pGantt) -{ - - var vID=parseInt(document.createTextNode(pID).data); - var vName=document.createTextNode(pName).data; - var vStart=new Date(0); - var vEnd=new Date(0); - 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); - } - - if (vGroup!=1) - { - vStart=(pStart instanceof Date)?pStart:JSGantt.parseDateStr(document.createTextNode(pStart).data,vGantt.getDateInputFormat()); - vEnd =(pEnd instanceof Date)?pEnd:JSGantt.parseDateStr(document.createTextNode(pEnd).data,vGantt.getDateInputFormat()); - } - - if (pDepend!=null) - { - var vDependStr=pDepend+''; - var vDepList=vDependStr.split(','); - var n=vDepList.length; - - for(var k=0;k1) - { - 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; i1) - { - 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=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; i0 && vList[i].getVisible()==1) - { - for(var k=0;k=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; i0) - { - // 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; i1) - { - 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); - - 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; - - vTaskLeftPx=(vNumCols *(vColWidth+1))+1; - - if(vUseSingleCell!=0 && vUseSingleCell<(vNumCols*vNumRows))vSingleCell=true; - - this.newNode(vTmpDiv, 'div', null, 'rhscrpad', null, null, vTaskLeftPx+1); - - 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'); - - // Draw each row - - var i=0; - var j=0; - for(i=0; ivMinGpLen && vTaskWidth=vMinGpLen*2) this.newNode(vTmpDiv, 'div', null, vTaskList[i].getClass() +'endpointright'); - - vCaptClass='ggroupcaption'; - } - - if(!vSingleCell && !vComb) - { - vCellFormat=''; - for(j=0; j=(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=0 && vIdx'; - vTask+=''+vTaskList[vIdx].getName()+''; - vTask+=''+JSGantt.formatDateStr(vTaskList[vIdx].getStart(),vOutFrmt,vLangs[vLang])+''; - vTask+=''+JSGantt.formatDateStr(vTaskList[vIdx].getEnd(),vOutFrmt,vLangs[vLang])+''; - vTask+=''+vTaskList[vIdx].getClass()+''; - vTask+=''+vTaskList[vIdx].getLink()+''; - vTask+=''+vTaskList[vIdx].getMile()+''; - if(vTaskList[vIdx].getResource()!='\u00A0') vTask+=''+vTaskList[vIdx].getResource()+''; - vTask+=''+vTaskList[vIdx].getCompVal()+''; - vTask+=''+vTaskList[vIdx].getGroup()+''; - vTask+=''+vTaskList[vIdx].getParent()+''; - vTask+=''+vTaskList[vIdx].getOpen()+''; - vTask+=''; - var vDepList=vTaskList[vIdx].getDepend(); - for (i=0;i0)vTask+=','; - if(vDepList[i]>0)vTask+=vDepList[i]+vTaskList[vIdx].getDepType()[i]; - } - vTask+=''; - vTask+=''+vTaskList[vIdx].getCaption()+''; - - var vTmpFrag=document.createDocumentFragment(); - var vTmpDiv=this.newNode(vTmpFrag, 'div', null, null,vTaskList[vIdx].getNotes().innerHTML); - vTask+=''+vTmpDiv.innerHTML+''; - vTask+=''; - } - return vTask; - }; - if (vDiv && vDiv.nodeName.toLowerCase()=='div') vDivId=vDiv.id; -}; //GanttChart - -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 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'; - } -}; - -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) - { - 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); - } - - 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=0 && pList[i].getID()==pID)vCurItem=pList[i]; - } - - for(i=0; ivMaxDate) - { - vMaxDate=pList[i].getEnd(); - vMaxSet=1; - } - - vCompSum+=pList[i].getCompVal(); - pList[i].setSortIdx(i*pList.length); - } - } - - if(pRow>=0) - { - pList[pRow].setStart(vMinDate); - pList[pRow].setEnd(vMaxDate); - pList[pRow].setNumKid(vNumKid); - pList[pRow].setCompVal(Math.ceil(vCompSum/vNumKid)); - } - - 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; i0) - { - 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; }); - } - - for (var j=0; j1) 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); - } - - 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()); - - // Parse all Task End dates to find max - for(var i=0; ivDate.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); - - 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); - - 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); - - while(vDate.getHours()%6!=5) vDate.setHours(vDate.getHours()+1); - } - return(vDate); -}; - -// This function finds the document id of the specified object -JSGantt.findObj=function (theObj, theDoc) -{ - var p, i, foundObj; - if(!theDoc) theDoc=document; - if(document.getElementById) foundObj=document.getElementById(theObj); - return foundObj; -}; - -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(); - - ganttObj.clearDependencies(); // clear these first so slow rendering doesn't look odd - - for(var i=0; i=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; i0) 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;i0 && uid>0) res[uid]=resname; - } - - var assignments=JSGantt.findXMLNode(pXmlDoc,'Assignment'); - if (typeof assignments=='undefined') j=0; - else j=assignments.length; - - for(i=0;i0) - { - if (resUID>0) assRes[uid]=res[resUID]; - ass[uid]=assignments[i]; - } - } - - // Store information about parent UIDs in an easily searchable form - for(i=0;i0) pars[vOutlineNumber]=uid; - if (uid>maxPID)maxPID=uid; - } - - for(i=0;i1) - { - vOutlineNumber=JSGantt.getXMLNodeValue(Task[i],'OutlineNumber',2,'0'); - pParent=pars[vOutlineNumber.substr(0, vOutlineNumber.lastIndexOf('.'))]; - } - - 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;k0) - { - 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; - } - } - } - - var pOpen=1; - var pCaption=''; - - if(pGroup>0) var pClass ='ggroupblack'; - else if(pMile>0) pClass ='gmilestone'; - else pClass ='gtaskblue'; - - // check for split tasks - - var splits=JSGantt.findXMLNode(ass[pID],'TimephasedData'); - if (typeof splits=='undefined') j=0; - else j=splits.length; - - var vSplitStart=pStart; - var vSplitEnd=pEnd; - var vSubCreated=false; - var vDepend=pDepend.replace(/,*[0-9]+[FS]F/g,''); - - for(k=0;k0) 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)); - } - } - } -}; - - -JSGantt.benchMark=function(pItem) -{ - var vEndTime=new Date().getTime(); - alert(pItem+': Elapsed time: '+((vEndTime-vBenchTime)/1000)+' seconds.'); - vBenchTime=new Date().getTime(); -}; - -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; -}; - -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; - } -}; - -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); -}; - -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); -}; - -JSGantt.addFolderListeners=function(pGanttChart, pObj, pID) -{ - JSGantt.addListener('click', function () {JSGantt.folder(pID, pGanttChart);}, pObj); -}; - -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); -}; +/* + _ ___ _____ _ _____ ____ + (_) / _ \ \_ \ / ||___ | ___| + | |/ /_\/ / /\/ | | / /|___ \ + | / /_\\/\/ /_ | |_ / /_ ___) | + _/ \____/\____/ |_(_)_/(_)____/ + |__/ + jsGanttImproved 1.7.5 + Copyright (c) 2013-2015, 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-2015, 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 () +{ + 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; +}; + +JSGantt.TaskItem=function(pID, pName, pStart, pEnd, pClass, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption, pNotes, pGantt) +{ + + var vID=parseInt(document.createTextNode(pID).data); + var vName=document.createTextNode(pName).data; + var vStart=new Date(0); + var vEnd=new Date(0); + 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); + } + + if (vGroup!=1) + { + vStart=(pStart instanceof Date)?pStart:JSGantt.parseDateStr(document.createTextNode(pStart).data,vGantt.getDateInputFormat()); + vEnd =(pEnd instanceof Date)?pEnd:JSGantt.parseDateStr(document.createTextNode(pEnd).data,vGantt.getDateInputFormat()); + } + + if (pDepend!=null) + { + var vDependStr=pDepend+''; + var vDepList=vDependStr.split(','); + var n=vDepList.length; + + for(var k=0;k1) + { + 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; i1) + { + 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=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; i0 && vList[i].getVisible()==1) + { + for(var k=0;k=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; i0) + { + // 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; i1) + { + 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); + + 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; + + vTaskLeftPx=(vNumCols *(vColWidth+1))+1; + + if(vUseSingleCell!=0 && vUseSingleCell<(vNumCols*vNumRows))vSingleCell=true; + + this.newNode(vTmpDiv, 'div', null, 'rhscrpad', null, null, vTaskLeftPx+1); + + 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'); + + // Draw each row + + var i=0; + var j=0; + for(i=0; ivMinGpLen && vTaskWidth=vMinGpLen*2) this.newNode(vTmpDiv, 'div', null, vTaskList[i].getClass() +'endpointright'); + + vCaptClass='ggroupcaption'; + } + + if(!vSingleCell && !vComb) + { + vCellFormat=''; + for(j=0; j=(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=0 && vIdx'; + vTask+=''+vTaskList[vIdx].getName()+''; + vTask+=''+JSGantt.formatDateStr(vTaskList[vIdx].getStart(),vOutFrmt,vLangs[vLang])+''; + vTask+=''+JSGantt.formatDateStr(vTaskList[vIdx].getEnd(),vOutFrmt,vLangs[vLang])+''; + vTask+=''+vTaskList[vIdx].getClass()+''; + vTask+=''+vTaskList[vIdx].getLink()+''; + vTask+=''+vTaskList[vIdx].getMile()+''; + if(vTaskList[vIdx].getResource()!='\u00A0') vTask+=''+vTaskList[vIdx].getResource()+''; + vTask+=''+vTaskList[vIdx].getCompVal()+''; + vTask+=''+vTaskList[vIdx].getGroup()+''; + vTask+=''+vTaskList[vIdx].getParent()+''; + vTask+=''+vTaskList[vIdx].getOpen()+''; + vTask+=''; + var vDepList=vTaskList[vIdx].getDepend(); + for (i=0;i0)vTask+=','; + if(vDepList[i]>0)vTask+=vDepList[i]+vTaskList[vIdx].getDepType()[i]; + } + vTask+=''; + vTask+=''+vTaskList[vIdx].getCaption()+''; + + var vTmpFrag=document.createDocumentFragment(); + var vTmpDiv=this.newNode(vTmpFrag, 'div', null, null,vTaskList[vIdx].getNotes().innerHTML); + vTask+=''+vTmpDiv.innerHTML+''; + vTask+=''; + } + return vTask; + }; + if (vDiv && vDiv.nodeName.toLowerCase()=='div') vDivId=vDiv.id; +}; //GanttChart + +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 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'; + } +}; + +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) + { + 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); + } + + 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=0 && pList[i].getID()==pID)vCurItem=pList[i]; + } + + for(i=0; ivMaxDate) + { + vMaxDate=pList[i].getEnd(); + vMaxSet=1; + } + + vCompSum+=pList[i].getCompVal(); + pList[i].setSortIdx(i*pList.length); + } + } + + if(pRow>=0) + { + pList[pRow].setStart(vMinDate); + pList[pRow].setEnd(vMaxDate); + pList[pRow].setNumKid(vNumKid); + pList[pRow].setCompVal(Math.ceil(vCompSum/vNumKid)); + } + + 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; i0) + { + 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; }); + } + + for (var j=0; j1) 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); + } + + 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()); + + // Parse all Task End dates to find max + for(var i=0; ivDate.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); + + 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); + + 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); + + while(vDate.getHours()%6!=5) vDate.setHours(vDate.getHours()+1); + } + return(vDate); +}; + +// This function finds the document id of the specified object +JSGantt.findObj=function (theObj, theDoc) +{ + var p, i, foundObj; + if(!theDoc) theDoc=document; + if(document.getElementById) foundObj=document.getElementById(theObj); + return foundObj; +}; + +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(); + + ganttObj.clearDependencies(); // clear these first so slow rendering doesn't look odd + + for(var i=0; i=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; i0) 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;i0 && uid>0) res[uid]=resname; + } + + var assignments=JSGantt.findXMLNode(pXmlDoc,'Assignment'); + if (typeof assignments=='undefined') j=0; + else j=assignments.length; + + for(i=0;i0) + { + if (resUID>0) assRes[uid]=res[resUID]; + ass[uid]=assignments[i]; + } + } + + // Store information about parent UIDs in an easily searchable form + for(i=0;i0) pars[vOutlineNumber]=uid; + if (uid>maxPID)maxPID=uid; + } + + for(i=0;i1) + { + vOutlineNumber=JSGantt.getXMLNodeValue(Task[i],'OutlineNumber',2,'0'); + pParent=pars[vOutlineNumber.substr(0, vOutlineNumber.lastIndexOf('.'))]; + } + + 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;k0) + { + 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; + } + } + } + + var pOpen=1; + var pCaption=''; + + if(pGroup>0) var pClass ='ggroupblack'; + else if(pMile>0) pClass ='gmilestone'; + else pClass ='gtaskblue'; + + // check for split tasks + + var splits=JSGantt.findXMLNode(ass[pID],'TimephasedData'); + if (typeof splits=='undefined') j=0; + else j=splits.length; + + var vSplitStart=pStart; + var vSplitEnd=pEnd; + var vSubCreated=false; + var vDepend=pDepend.replace(/,*[0-9]+[FS]F/g,''); + + for(k=0;k0) 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)); + } + } + } +}; + + +JSGantt.benchMark=function(pItem) +{ + var vEndTime=new Date().getTime(); + alert(pItem+': Elapsed time: '+((vEndTime-vBenchTime)/1000)+' seconds.'); + vBenchTime=new Date().getTime(); +}; + +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; +}; + +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; + } +}; + +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); +}; + +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); +}; + +JSGantt.addFolderListeners=function(pGanttChart, pObj, pID) +{ + JSGantt.addListener('click', function () {JSGantt.folder(pID, pGanttChart);}, pObj); +}; + +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); +}; diff --git a/jsgantt_exExternalXML.html b/jsgantt_exExternalXML.html index 1bb46db5..7dc34f27 100644 --- a/jsgantt_exExternalXML.html +++ b/jsgantt_exExternalXML.html @@ -1,691 +1,692 @@ - - - - -FREE javascript gantt - jsGantt Improved HTML and CSS only - - - - - - -
-
jsGanttImproved - 1.7.4
- -
-

  100% Free Javascript / CSS/ HTML Gantt chart control. Completely buzzword compliant including AJAX !

- - -
- - -

Basic Features

-
    -
  • Tasks & Collapsible Task Groups
  • -
  • Multiple Dependencies
  • -
  • Task Completion
  • -
  • Task Style
  • -
  • Milestones
  • -
  • Resources
  • -
  • No images needed
  • -
- -

Advanced Features

-
    -
  • Dynamic Loading of Tasks
  • -
  • Dynamic change of format -
      -
    • Hour
    • -
    • Day
    • -
    • Week
    • -
    • Month
    • -
    • Quarter
    • -
    -
  • -
  • Load Gantt from XML using -
      -
    • External XML files (including experimental support for Microsoft Project XML files)
    • -
    • JavaScript strings
    • -
    -
  • -
  • Export Gantt as XML string
  • -
  • Support for internationalisation
  • -
-

Bugs/Issues

- -
-

Current Issues:

-
    -
  1. If the browser is viewing the page at anything other than 100% zoom then bars may not be sized or positioned correctly.
  2. - -

-

Changes/fixes in jsGanttImproved:

-

v1.7.4:

-
    -
  • Instantiating a new JSGantt.TaskItem will now also accept Date objects for start and end dates
  • -
  • Fixed old Internet Explorer compatibilty broken by v1.7
  • -
  • Fixed bug in Iso week date format
  • -
  • Changed to solid arrows on dependency lines to be more printer friendly
  • -
  • Code refactoring and clean up
  • -
-

v1.7:

-
    -
  • Fixed nasty long-standing bug where the first Gantt chart created must be stored in a javascript variable named "g" -
      -
    • NOTE: This required a change in the method to instatiate a JSGantt.TaskItem object to pass the related chart.
    • -
    • A temporary fix is included that still assumes the use of "g" for the chart if the chart object is not passed, this will be removed in v1.8
    • -
    -
  • -
  • Altered XML export functionality so that dates are output in the specified input format for the chart
  • -
  • Added method to read XML directly from an input string
  • -
  • Prevented creation of a task with a duplicate "unique" ID
  • -
  • Fixed bug where attempting to remove the first task defined would prevent the chart from redrawing
  • -
  • Some general code clean up
  • -
-

v1.6:

-
    -
  • Allow use of Internationalisation strings in custom date formats
  • -
  • Modified how tooltip is hidden and revealed to make it more compatible with CSS transitions
  • -
  • Added experimental support for importing Microsoft Project XML files
  • -
  • Added methods to generate JGI XML from current task list
  • -
-

v1.5:

-
    -
  • Added support for Internationalisation
  • -
  • Task duration now calculated using the same method as is used to size and position task bars
  • -
  • Milestones owned by combined group items are now ignored completely rather than hidden
  • -
  • Fixed positioning bug in day format where charts spanned a DST clock change (only noticeable if column width set to large value)
  • -
  • Fixed a number of minor bugs -
      -
    • Dependencies on the first task in the list did not display
    • -
    • Combined group task rows are now styled like standard tasks
    • -
    • Disabling the tool tip caused problems with scrolling
    • -
    -
  • -
-

v1.4:

-
    -
  • Reintroduced hour view
  • -
  • Changed definition of "setUseSingleCell" to try and prevent huge charts causing issues
  • -
-

v1.3:

-
    -
  • Code refactored to: -
      -
    • Move the last non-structural style information from javascript to css file
    • -
    • Restructure the Tooltip DIV slightly to allow styling rather than relying on line breaks for layout
    • -
    • Create the chart using createElement() and appendChild() rather than innerHTML to enable...
    • -
  • -
  • New "Combined Group" element created. Combined groups show all child task information on one row
  • -
-

-Please see the differences for the CSS file in code revision r21 for details of CSS structural changes. -

-

v1.2:

-
    -
  • Multiple gantt charts per page are now supported
  • -
  • Charts are now more printer friendly
  • -
-

Both these updates required changes to existing element IDs and style classes. Custom stylesheets will most likely need to be updated. -

-All chart element ids are now prefixed with the id of the master DIV containing the chart. As a result the default stylesheet has been updated to no longer use any element ids to apply styles. -

-Please see the notes for code revision r18 for details of CSS structural changes. -

-

v1.1:

-
    -
  • Added support for additional dependency types
  • -
  • Altered date parsing so specifying time works in all browsers
  • -
  • Fixed bug in calculating end date when time is specified
  • -
  • Updated CSS to prevent growing DIV bug in IE9
  • -
-

v1.0:

-
    -
  • Multiple new display configuration options (see Configuration Options)
  • -
  • Hour/Minute format removed
  • -
  • Width/positioning calculations for Month and Quarter views no longer assume 30/90 day periods
  • -
  • Vast majority of look and feel now controllable via CSS
  • -
  • Tool tips added to gantt chart bars
  • -
  • New "Notes" field added for detailed task information to be displayed in tool tips
  • -
  • Tasks can now be removed from as well as added to chart
  • -
  • Tasks can now be sorted by parent task & start time
  • -
  • Dependencies no longer draw when the parent task is hidden
  • -
  • Min/Max date calculations now correctly identify the date of first and last periods
  • -
  • Current date/time now shown as a vertical blue line rather than period highlight
  • -
  • Optimised chart structure to reduce number of elements required / ensure positioning match
  • -
  • Chart pane width will change dynamically with containing element
  • -
-

Download

-Click here to download the current version of jsGantt Improved
-You can download the latest bleeding edge version, request features and report issues at https://code.google.com/p/jsgantt-improved/ - -

License

-JSGanttImproved is released under BSD license.
-If you plan to use it in a commercial product please consider donating the first sale to charity. -

- - -

Usage

-

Creating a basic Gantt Chart

-
    -
  1. Include JSGantt CSS and Javascript -
    -<link rel="stylesheet" type="text/css" href="jsgantt.css" />
    -<script language="javascript" src="jsgantt.js"></script>
    -
    -
  2. -
  3. Create a div element to hold the gantt chart -
    <div style="position:relative" class="gantt" id="GanttChartDIV"></div>
    -
  4. -
  5. Start a <script> block -
    <script type="text/javascript">
    -
  6. -
  7. Instantiate JSGantt using GanttChart() -
    var g = new JSGantt.GanttChart(document.getElementById('GanttChartDIV'), 'day');
    -
    -

    Method definition: - GanttChart(pDiv, pFormat)

    -
    -
    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
    -
    -
  8. -
  9. Customize the look and feel using configuration methods (see Configuration Options)

  10. -
  11. Add Tasks -
    1. using AddTaskItem() -
      -g.AddTaskItem(new JSGantt.TaskItem(1, 'Define Chart API','',          '',          'ggroupblack','', 0, 'Brian', 0,  1,0,1,'','','Some Notes text',g));
      -g.AddTaskItem(new JSGantt.TaskItem(11,'Chart Object',    '2014-02-20','2014-02-20','gmilestone', '', 1, 'Shlomy',100,0,1,1,'','','',g));
      -
      -

      Method definition: -TaskItem(pID, pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption, pNotes, pGantt)

      -
      -
      pID
      (required) a unique numeric ID used to identify each row
      -
      pName
      (required) the task Label
      -
      pStart
      (required) the task start date, can enter empty date ('') for groups. You can also enter specific time (2014-02-20 12:00) for additional precision.
      -
      pEnd
      (required) the task end date, can enter empty date ('') for groups
      -
      pClass
      (required) the css class for this task
      -
      pLink
      (optional) any http link to be displayed in tool tip as the "More information" link.
      -
      pMile
      (optional) indicates whether this is a milestone task - Numeric; 1 = milestone, 0 = not milestone
      -
      pRes
      (optional) resource name
      -
      pComp
      (required) completion percent, numeric
      -
      pGroup
      (optional) indicates whether this is a group task (parent) - Numeric; 0 = normal task, 1 = standard group task, 2 = combined group task*
      -
      pParent
      (required) identifies a parent pID, this causes this task to be a child of identified task. Numeric, top level tasks should have pParent set to 0
      -
      pOpen
      (required) indicates whether a standard group task is open when chart is first drawn. Value must be set for all items but is only used by standard group tasks. Numeric, 1 = open, 0 = closed
      -
      pDepend
      (optional) comma separated list of id's this task is dependent on. A line will be drawn from each listed task to this item
      Each id can optionally be followed by a dependency type suffix. Valid values are:
      'FS' - Finish to Start (default if suffix is omitted)
      'SF' - Start to Finish
      'SS' - Start to Start
      'FF' - Finish to Finish
      If present the suffix must be added directly to the id e.g. '123SS'
      -
      pCaption
      (optional) caption that will be added after task bar if CaptionType set to "Caption"
      -
      pNotes
      (optional) Detailed task information that will be displayed in tool tip for this task
      -
      pGantt
      (required) javascript JSGantt.GanttChart object from which to take settings. Defaults to "g" for backwards compatibility
      -
      -

      * Combined group tasks show all sub-tasks on one row. The information displayed in the task list and row caption are taken from the parent task. Tool tips are generated individually for each sub-task from its own information. Milestones are not valid as sub-tasks of a combined group task and will not be displayed. No bounds checking of start and end dates of sub-tasks is performed therefore it is possible for these task bars to overlap. Dependencies can be set to and from sub-tasks only.

      -
    2. -
    3. using parseXML() with an external XML file -
      -JSGantt.parseXML("project.xml",g);
      -
      -

      Method definition: - JSGantt.parseXML(pFile, pGanttObj)

      -
      -
      pFile
      (required) this is the filename of the XML
      -
      pGanttObj
      (required) a GanttChart object returned by a call to JSGantt.GanttChart()
      -
      -

      The structure of the native XML file:

      -
      - -
      -

      Field definitions are as described for the parameters to TaskItem above. The pClass element is optional in XML files and will default to "ggroupblack" for group tasks, "gtaskblue" for normal tasks and "gmilestone" for milestones. The pGantt element is not required for XML import.

      -

      JSGannt Improved will also test the provided XML file to see if it appears to be in Microsoft Project XML format. If so an attempt will be made to load up the project. This feature is experimental, the import is best effort and not guaranteed. Once loaded the project as interpreted by JSGantt Improved can be extracted using the XML Export methods provided.

      -
    4. -
    5. using parseXMLString() with XML held in a javascript string object -
      -JSGantt.parseXMLString("<project><task>...</task></project>",g);
      -
      -

      Method definition: - JSGantt.parseXMLString(pStr, pGanttObj)

      -
      -
      pStr
      (required) this is a javascript String containing XML
      -
      pGanttObj
      (required) a GanttChart object returned by a call to JSGantt.GanttChart()
      -
      -

      The XML provided will be parsed in exactly the same way as the contents of an external XML file and hence must match the format as described for JSGantt.parseXML() above

      -
  12. -
  13. Call Draw()

    g.Draw();
    -
  14. -
  15. Close the <script> block

    </script>
    -
  16. -
- -

It is possible to add items to the chart in realtime via javascript using either direct method calls or additional XML files. -It is also possible to delete tasks using RemoveTaskItem() method.

-
g.RemoveTaskItem(11);
-

Method definition: -RemoveTaskItem(pID)

-
-
pID
(required) the unique numeric ID of the item to be removed
-
-

If the task removed is a group item, all child tasks will also be removed.

-

After adding or removing tasks a call to "g.Draw()" must be made to redraw the chart.

- -

Configuration Options

-

Switches

-

Many of the features of jsGanttImproved can be customised through the use of setter methods available on the GanttChart object returned by a call to JSGantt.GanttChart()

-

The following options take a single numeric parameter; a value of 1 will enable the describe functionality, 0 will disable it

-
-
setUseToolTip()
Controls the display of tool tip boxes, defaults to 1 (enabled)
-
setUseFade()
Controls use of the fade effect when showing/hiding tool tips, defaults to 1 (enabled)
-
setUseMove()
Controls use of the sliding effect when changing between different task tool tips, defaults to 1 (enabled)
-
setUseRowHlt()
Controls the use of row mouseover highlighting, defaults to 1 (enabled)
-
setUseSort()
Controls whether the task list is sorted into parent task / start time order or is simply displayed in the order created, defaults to 1 (sort enabled)
-
setShowRes()
Controls whether the Resource column is displayed in the task list, defaults to 1 (show column)
-
setShowDur()
Controls whether the Task Duration column is displayed in the task list, defaults to 1 (show column)
-
setShowComp()
Controls whether the Percentage Complete column is displayed in the task list, defaults to 1 (show column)
-
setShowStartDate()
Controls whether the Task Start Date column is displayed in the task list, defaults to 1 (show column)
-
setShowEndDate()
Controls whether the Task End Date column is displayed in the task list, defaults to 1 (show column)
-
setShowTaskInfoRes()
Controls whether the Resource information is displayed in the task tool tip, defaults to 1 (show information)
-
setShowTaskInfoDur()
Controls whether the Task Duration information is displayed in the task tool tip, defaults to 1 (show information)
-
setShowTaskInfoComp()
Controls whether the Percentage Complete information is displayed in the task tool tip, defaults to 1 (show information)
-
setShowTaskInfoStartDate()
Controls whether the Task Start Date information is displayed in the task tool tip, defaults to 1 (show information)
-
setShowTaskInfoEndDate()
Controls whether the Task End Date information is displayed in the task tool tip, defaults to 1 (show information)
-
Controls whether the More Information link is displayed in the task tool tip, defaults to 0 (do NOT show link)
-
setShowTaskInfoNotes()
Controls whether the Additional Notes data is displayed in the task tool tip, defaults to 1 (show notes)
-
setShowEndWeekDate()
Controls whether the major heading in "Day" view displays the week end-date in the appropriate format (see below), defaults to 1 (show date)
-
setShowDeps()
Controls display of dependancy lines, defaults to 1 (show dependencies)
-
-

Key Values

-

The following options enable functionality using a set of specific key values

-
-
setShowSelector()
Controls where the format selector is displayed, accepts multiple parameters.
Valid parameter values are "Top", "Bottom".
Defaults to "Top".
-
setFormatArr()
Controls which format options are shown in the format selector, accepts multiple parameters.
Valid parameter values are "Hour", "Day", "Week", "Month", "Quarter".
Defaults to all valid values.
-
setCaptionType()
Controls which task field to use as a caption on the Gantt Chart task bar, accepts a single parameter.
Valid parameter values are "None", "Caption", "Resource", "Duration", "Complete".
Defaults to "None"
-
setDateInputFormat()
Defines the input format used for dates in task creation, accepts a single parameter.
Valid parameter values are "yyyy-mm-dd", "dd/mm/yyyy", "mm/dd/yyyy".
Defaults to "yyyy-mm-dd"
-
setScrollTo()
Sets the date the Gantt Chart will be scrolled to, specified in the date input format set by setDateInputFormat() above. Also accepts the special value "today"
Defaults to minimum display date
-
setUseSingleCell()
Sets the threshold total number of cells at which the task list will use a single table cell for each row rather than one cell per period. Useful to improve performance on large charts. A value of 0 disables this functionality (always use multiple cells), defaults to 25000
-
setLang()
Sets translation to use when drawing the chart. Defaults to "en" as this is the only language provided in the base installation (see Internationalisation below for details on how to add more translations.)
-
-

Layout

-

Most of the look and feel of the Gantt Chart can be controlled using CSS however, as the length of a task bar is determined by column width, the following methods take a single numeric parameter that defines the appropriate column width in pixels.

-

Note that the task bar sizing code assumes the use of collapsed table borders 1px wide.

-
-
setHourColWidth()
Width of Gantt Chart columns in pixels when drawn in "Hour" format. Defaults to 18.
-
setDayColWidth()
Width of Gantt Chart columns in pixels when drawn in "Day" format. Defaults to 18.
-
setWeekColWidth()
Width of Gantt Chart columns in pixels when drawn in "Week" format. Defaults to 36.
-
setMonthColWidth()
Width of Gantt Chart columns in pixels when drawn in "Month" format. Defaults to 36.
-
setQuarterColWidth()
Width of Gantt Chart columns in pixels when drawn in "Quarter" format, although not mandatory it is recommended that this be set to a value divisible by 3. Defaults to 18.
-
setRowHeight()
Height of Gantt Chart rows in pixels. Used to route dependency lines near end points. Defaults to 20.
-
setMinGpLen()
Group tasks have their task bars embellished with end points, this value specifies the width of one of these end points in pixels. A short task bar's length will be rounded up to display either a single or both endpoints correctly. Defaults to 8.
-
-

Display Date Formats

-

Date display formats can be individually controlled. The methods used to set these display formats each take a single format string parameter. The format string can be made up of the following components (case sensitive)

-
-
-
h
Hour (1-12)
-
hh
Hour (01-12)
-
pm
am/pm indicator
-
PM
AM/PM indicator
-
H
Hour (0-23)
-
HH
Hour (01-23)
-
mi
Minutes (1-59)
-
MI
Minutes (01-59)
-
d
Day (1-31)
-
dd
Day (01-31)
-
day
Abbriviated day of week
-
DAY
Day of week
-
m
Month (1-12)
-
mm
Month (01-12)
-
mon
Abbriviated month text
-
month
Full month text
-
yy
Year, excluding century
-
yyyy
Year
-
q
Quarter (1-4)
-
qq
Quarter (Q1-Q4)
-
w
ISO Week number (1-53)
-
ww
ISO Week number (01-53)
-
week
Full ISO Week date format
-
-

separated by one of the following characters: "/\-.,'<space>:

-

Any text between separators that does not match one of the components above will be checked using a case insensitive match for a valid internationalised string (see Internationalisation below). If the value is still not found the text will be output unchanged.

-
-

-

-
setDateTaskTableDisplayFormat()
Date format used for start and end dates in the main task list. Defaults to 'dd/mm/yyyy'.
-
setDateTaskDisplayFormat()
Date format used for start and end dates in task tool tips. Defaults to 'dd month yyyy'.
-
setHourMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Hour" format. Defaults to 'day dd month yyyy'.
-
setDayMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Day" format. Defaults to 'dd/mm/yyyy'.
-
setWeekMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Week" format. Defaults to 'yyyy'.
-
setMonthMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Month" format. Defaults to 'yyyy'.
-
setQuarterMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Year" format. Defaults to 'yyyy'.
-
setHourMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Hour" format. Defaults to 'HH'.
-
setDayMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Day" format. Defaults to 'dd'.
-
setWeekMinjorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Week" format. Defaults to 'dd/mm'.
-
setMonthMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Month" format. Defaults to 'mon'.
-
setQuarterMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Year" format. Defaults to 'qq'.
-
- -

Internationalisation

-

jsGanttImproved only provides English text however all hard coded strings can be replaced by calling the addLang() method available on the GanttChart object returned by a call to JSGantt.GanttChart()

-

The addLang() method takes two parameters. The first is a string identifier for the language, the second is a javascript object containing all the replacement text pairs, the default English settings are:

-
- - - - - - - -
-
-
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
-
resource
Resource
-
duration
Duration
-
comp
% Comp.
-
completion
Completion
-
startdate
Start Date
-
enddate
End Date
-
moreinfo
More Information
-
notes
Notes
-
-
-
-
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
-
-
-
-

When adding a language any translations that are not provided will use the default English language value. This provides a simple way to override default strings e.g.

-
-g.addLang('en2', {'format':'Select', 'comp':'Complete'});
-
-

would create a language called 'en2' where the text in the format selector was "Select" rather than "Format" and the header for the Percentage Complete column in the task list is "Complete" rather than "% Comp."

-

Once a translation has been added a call must be made to setLang() with the appropriate langage identifier before calling Draw().

- -

Example Options

-

The configuration options used in the example chart above are:

- -
-g.setCaptionType('Resource');
-g.setShowTaskInfoLink(1);
-g.setDayMajorDateDisplayFormat('dd mon');
-g.setDateTaskDisplayFormat('dd month yyyy HH:MI');
-
- -

Putting all this information together the final code to produce the chart above is as follows:

- - - -

XML Export

-

The following methods can be used to extract details of tasks in the project in XML format

- -

Method definition: getXMLProject()

-

Returns a string containing the entire project in JSGantt Improved XML format. Dates will be exported in the currently defined input format as set by setDateInputFormat()

- -

Method definition: getXMLTask(pID, pIdx)

-
-
pID
(required) the numeric ID that identifies the task to extract
-
pIdx
(optional) Boolean - if present and set to "true" the number passed in the pID parameter is treated as an array index for the task list rather than an ID
-
-

Returns a string containing the specified task item in JSGantt Improved XML format. Dates will be exported in the currently defined input format as set by setDateInputFormat()

- - -

Additional Demos

- - - - -

Credits

- -

Developed by Paul Geldart

-

Based on jsGantt 1.2 developed by Shlomy Gantz and Brian Twidt
-Contributed: Paul Labuschagne, Kevin Badgett, Ilan Admon
-

- - - - \ No newline at end of file + + + + +FREE javascript gantt - jsGantt Improved HTML and CSS only + + + + + + +
+
jsGanttImproved - 1.7.5
+ +
+

  100% Free Javascript / CSS/ HTML Gantt chart control. Completely buzzword compliant including AJAX !

+ + +
+ + +

Basic Features

+
    +
  • Tasks & Collapsible Task Groups
  • +
  • Multiple Dependencies
  • +
  • Task Completion
  • +
  • Task Style
  • +
  • Milestones
  • +
  • Resources
  • +
  • No images needed
  • +
+ +

Advanced Features

+
    +
  • Dynamic Loading of Tasks
  • +
  • Dynamic change of format +
      +
    • Hour
    • +
    • Day
    • +
    • Week
    • +
    • Month
    • +
    • Quarter
    • +
    +
  • +
  • Load Gantt from XML using +
      +
    • External XML files (including experimental support for Microsoft Project XML files)
    • +
    • JavaScript strings
    • +
    +
  • +
  • Export Gantt as XML string
  • +
  • Support for internationalisation
  • +
+

Bugs/Issues

+ +
+

Current Issues:

+
    +
  1. If the browser is viewing the page at anything other than 100% zoom then bars may not be sized or positioned correctly.
  2. + +

+

Changes/fixes in jsGanttImproved:

+

v1.7.5:

+
    +
  • Project Migrated to GitHub
  • +
  • Instantiating a new JSGantt.TaskItem will now also accept Date objects for start and end dates
  • +
  • Fixed old Internet Explorer compatibilty broken by v1.7
  • +
  • Fixed bug in Iso week date format
  • +
  • Changed to solid arrows on dependency lines to be more printer friendly
  • +
  • Code refactoring and clean up
  • +
+

v1.7:

+
    +
  • Fixed nasty long-standing bug where the first Gantt chart created must be stored in a javascript variable named "g" +
      +
    • NOTE: This required a change in the method to instatiate a JSGantt.TaskItem object to pass the related chart.
    • +
    • A temporary fix is included that still assumes the use of "g" for the chart if the chart object is not passed, this will be removed in v1.8
    • +
    +
  • +
  • Altered XML export functionality so that dates are output in the specified input format for the chart
  • +
  • Added method to read XML directly from an input string
  • +
  • Prevented creation of a task with a duplicate "unique" ID
  • +
  • Fixed bug where attempting to remove the first task defined would prevent the chart from redrawing
  • +
  • Some general code clean up
  • +
+

v1.6:

+
    +
  • Allow use of Internationalisation strings in custom date formats
  • +
  • Modified how tooltip is hidden and revealed to make it more compatible with CSS transitions
  • +
  • Added experimental support for importing Microsoft Project XML files
  • +
  • Added methods to generate JGI XML from current task list
  • +
+

v1.5:

+
    +
  • Added support for Internationalisation
  • +
  • Task duration now calculated using the same method as is used to size and position task bars
  • +
  • Milestones owned by combined group items are now ignored completely rather than hidden
  • +
  • Fixed positioning bug in day format where charts spanned a DST clock change (only noticeable if column width set to large value)
  • +
  • Fixed a number of minor bugs +
      +
    • Dependencies on the first task in the list did not display
    • +
    • Combined group task rows are now styled like standard tasks
    • +
    • Disabling the tool tip caused problems with scrolling
    • +
    +
  • +
+

v1.4:

+
    +
  • Reintroduced hour view
  • +
  • Changed definition of "setUseSingleCell" to try and prevent huge charts causing issues
  • +
+

v1.3:

+
    +
  • Code refactored to: +
      +
    • Move the last non-structural style information from javascript to css file
    • +
    • Restructure the Tooltip DIV slightly to allow styling rather than relying on line breaks for layout
    • +
    • Create the chart using createElement() and appendChild() rather than innerHTML to enable...
    • +
  • +
  • New "Combined Group" element created. Combined groups show all child task information on one row
  • +
+

+Please see the differences for the CSS file in commit ea9890e for details of CSS structural changes. +

+

v1.2:

+
    +
  • Multiple gantt charts per page are now supported
  • +
  • Charts are now more printer friendly
  • +
+

Both these updates required changes to existing element IDs and style classes. Custom stylesheets will most likely need to be updated. +

+All chart element ids are now prefixed with the id of the master DIV containing the chart. As a result the default stylesheet has been updated to no longer use any element ids to apply styles. +

+Please see the notes for commit b4bf8ea for details of CSS structural changes. +

+

v1.1:

+
    +
  • Added support for additional dependency types
  • +
  • Altered date parsing so specifying time works in all browsers
  • +
  • Fixed bug in calculating end date when time is specified
  • +
  • Updated CSS to prevent growing DIV bug in IE9
  • +
+

v1.0:

+
    +
  • Multiple new display configuration options (see Configuration Options)
  • +
  • Hour/Minute format removed
  • +
  • Width/positioning calculations for Month and Quarter views no longer assume 30/90 day periods
  • +
  • Vast majority of look and feel now controllable via CSS
  • +
  • Tool tips added to gantt chart bars
  • +
  • New "Notes" field added for detailed task information to be displayed in tool tips
  • +
  • Tasks can now be removed from as well as added to chart
  • +
  • Tasks can now be sorted by parent task & start time
  • +
  • Dependencies no longer draw when the parent task is hidden
  • +
  • Min/Max date calculations now correctly identify the date of first and last periods
  • +
  • Current date/time now shown as a vertical blue line rather than period highlight
  • +
  • Optimised chart structure to reduce number of elements required / ensure positioning match
  • +
  • Chart pane width will change dynamically with containing element
  • +
+

Download

+Click here to download the current version of jsGantt Improved
+You can download the latest bleeding edge version, request features and report issues at https://github.com/jsGanttImproved/jsgantt-improved/ + +

License

+JSGanttImproved is released under BSD license.
+If you plan to use it in a commercial product please consider donating the first sale to charity. +

+ + +

Usage

+

Creating a basic Gantt Chart

+
    +
  1. Include JSGantt CSS and Javascript +
    +<link rel="stylesheet" type="text/css" href="jsgantt.css" />
    +<script language="javascript" src="jsgantt.js"></script>
    +
    +
  2. +
  3. Create a div element to hold the gantt chart +
    <div style="position:relative" class="gantt" id="GanttChartDIV"></div>
    +
  4. +
  5. Start a <script> block +
    <script type="text/javascript">
    +
  6. +
  7. Instantiate JSGantt using GanttChart() +
    var g = new JSGantt.GanttChart(document.getElementById('GanttChartDIV'), 'day');
    +
    +

    Method definition: + GanttChart(pDiv, pFormat)

    +
    +
    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
    +
    +
  8. +
  9. Customize the look and feel using configuration methods (see Configuration Options)

  10. +
  11. Add Tasks +
    1. using AddTaskItem() +
      +g.AddTaskItem(new JSGantt.TaskItem(1, 'Define Chart API','',          '',          'ggroupblack','', 0, 'Brian', 0,  1,0,1,'','','Some Notes text',g));
      +g.AddTaskItem(new JSGantt.TaskItem(11,'Chart Object',    '2014-02-20','2014-02-20','gmilestone', '', 1, 'Shlomy',100,0,1,1,'','','',g));
      +
      +

      Method definition: +TaskItem(pID, pName, pStart, pEnd, pColor, pLink, pMile, pRes, pComp, pGroup, pParent, pOpen, pDepend, pCaption, pNotes, pGantt)

      +
      +
      pID
      (required) a unique numeric ID used to identify each row
      +
      pName
      (required) the task Label
      +
      pStart
      (required) the task start date, can enter empty date ('') for groups. You can also enter specific time (2014-02-20 12:00) for additional precision.
      +
      pEnd
      (required) the task end date, can enter empty date ('') for groups
      +
      pClass
      (required) the css class for this task
      +
      pLink
      (optional) any http link to be displayed in tool tip as the "More information" link.
      +
      pMile
      (optional) indicates whether this is a milestone task - Numeric; 1 = milestone, 0 = not milestone
      +
      pRes
      (optional) resource name
      +
      pComp
      (required) completion percent, numeric
      +
      pGroup
      (optional) indicates whether this is a group task (parent) - Numeric; 0 = normal task, 1 = standard group task, 2 = combined group task*
      +
      pParent
      (required) identifies a parent pID, this causes this task to be a child of identified task. Numeric, top level tasks should have pParent set to 0
      +
      pOpen
      (required) indicates whether a standard group task is open when chart is first drawn. Value must be set for all items but is only used by standard group tasks. Numeric, 1 = open, 0 = closed
      +
      pDepend
      (optional) comma separated list of id's this task is dependent on. A line will be drawn from each listed task to this item
      Each id can optionally be followed by a dependency type suffix. Valid values are:
      'FS' - Finish to Start (default if suffix is omitted)
      'SF' - Start to Finish
      'SS' - Start to Start
      'FF' - Finish to Finish
      If present the suffix must be added directly to the id e.g. '123SS'
      +
      pCaption
      (optional) caption that will be added after task bar if CaptionType set to "Caption"
      +
      pNotes
      (optional) Detailed task information that will be displayed in tool tip for this task
      +
      pGantt
      (required) javascript JSGantt.GanttChart object from which to take settings. Defaults to "g" for backwards compatibility
      +
      +

      * Combined group tasks show all sub-tasks on one row. The information displayed in the task list and row caption are taken from the parent task. Tool tips are generated individually for each sub-task from its own information. Milestones are not valid as sub-tasks of a combined group task and will not be displayed. No bounds checking of start and end dates of sub-tasks is performed therefore it is possible for these task bars to overlap. Dependencies can be set to and from sub-tasks only.

      +
    2. +
    3. using parseXML() with an external XML file +
      +JSGantt.parseXML("project.xml",g);
      +
      +

      Method definition: + JSGantt.parseXML(pFile, pGanttObj)

      +
      +
      pFile
      (required) this is the filename of the XML
      +
      pGanttObj
      (required) a GanttChart object returned by a call to JSGantt.GanttChart()
      +
      +

      The structure of the native XML file:

      +
      + +
      +

      Field definitions are as described for the parameters to TaskItem above. The pClass element is optional in XML files and will default to "ggroupblack" for group tasks, "gtaskblue" for normal tasks and "gmilestone" for milestones. The pGantt element is not required for XML import.

      +

      JSGannt Improved will also test the provided XML file to see if it appears to be in Microsoft Project XML format. If so an attempt will be made to load up the project. This feature is experimental, the import is best effort and not guaranteed. Once loaded the project as interpreted by JSGantt Improved can be extracted using the XML Export methods provided.

      +
    4. +
    5. using parseXMLString() with XML held in a javascript string object +
      +JSGantt.parseXMLString("<project><task>...</task></project>",g);
      +
      +

      Method definition: + JSGantt.parseXMLString(pStr, pGanttObj)

      +
      +
      pStr
      (required) this is a javascript String containing XML
      +
      pGanttObj
      (required) a GanttChart object returned by a call to JSGantt.GanttChart()
      +
      +

      The XML provided will be parsed in exactly the same way as the contents of an external XML file and hence must match the format as described for JSGantt.parseXML() above

      +
  12. +
  13. Call Draw()

    g.Draw();
    +
  14. +
  15. Close the <script> block

    </script>
    +
  16. +
+ +

It is possible to add items to the chart in realtime via javascript using either direct method calls or additional XML files. +It is also possible to delete tasks using RemoveTaskItem() method.

+
g.RemoveTaskItem(11);
+

Method definition: +RemoveTaskItem(pID)

+
+
pID
(required) the unique numeric ID of the item to be removed
+
+

If the task removed is a group item, all child tasks will also be removed.

+

After adding or removing tasks a call to "g.Draw()" must be made to redraw the chart.

+ +

Configuration Options

+

Switches

+

Many of the features of jsGanttImproved can be customised through the use of setter methods available on the GanttChart object returned by a call to JSGantt.GanttChart()

+

The following options take a single numeric parameter; a value of 1 will enable the describe functionality, 0 will disable it

+
+
setUseToolTip()
Controls the display of tool tip boxes, defaults to 1 (enabled)
+
setUseFade()
Controls use of the fade effect when showing/hiding tool tips, defaults to 1 (enabled)
+
setUseMove()
Controls use of the sliding effect when changing between different task tool tips, defaults to 1 (enabled)
+
setUseRowHlt()
Controls the use of row mouseover highlighting, defaults to 1 (enabled)
+
setUseSort()
Controls whether the task list is sorted into parent task / start time order or is simply displayed in the order created, defaults to 1 (sort enabled)
+
setShowRes()
Controls whether the Resource column is displayed in the task list, defaults to 1 (show column)
+
setShowDur()
Controls whether the Task Duration column is displayed in the task list, defaults to 1 (show column)
+
setShowComp()
Controls whether the Percentage Complete column is displayed in the task list, defaults to 1 (show column)
+
setShowStartDate()
Controls whether the Task Start Date column is displayed in the task list, defaults to 1 (show column)
+
setShowEndDate()
Controls whether the Task End Date column is displayed in the task list, defaults to 1 (show column)
+
setShowTaskInfoRes()
Controls whether the Resource information is displayed in the task tool tip, defaults to 1 (show information)
+
setShowTaskInfoDur()
Controls whether the Task Duration information is displayed in the task tool tip, defaults to 1 (show information)
+
setShowTaskInfoComp()
Controls whether the Percentage Complete information is displayed in the task tool tip, defaults to 1 (show information)
+
setShowTaskInfoStartDate()
Controls whether the Task Start Date information is displayed in the task tool tip, defaults to 1 (show information)
+
setShowTaskInfoEndDate()
Controls whether the Task End Date information is displayed in the task tool tip, defaults to 1 (show information)
+
Controls whether the More Information link is displayed in the task tool tip, defaults to 0 (do NOT show link)
+
setShowTaskInfoNotes()
Controls whether the Additional Notes data is displayed in the task tool tip, defaults to 1 (show notes)
+
setShowEndWeekDate()
Controls whether the major heading in "Day" view displays the week end-date in the appropriate format (see below), defaults to 1 (show date)
+
setShowDeps()
Controls display of dependancy lines, defaults to 1 (show dependencies)
+
+

Key Values

+

The following options enable functionality using a set of specific key values

+
+
setShowSelector()
Controls where the format selector is displayed, accepts multiple parameters.
Valid parameter values are "Top", "Bottom".
Defaults to "Top".
+
setFormatArr()
Controls which format options are shown in the format selector, accepts multiple parameters.
Valid parameter values are "Hour", "Day", "Week", "Month", "Quarter".
Defaults to all valid values.
+
setCaptionType()
Controls which task field to use as a caption on the Gantt Chart task bar, accepts a single parameter.
Valid parameter values are "None", "Caption", "Resource", "Duration", "Complete".
Defaults to "None"
+
setDateInputFormat()
Defines the input format used for dates in task creation, accepts a single parameter.
Valid parameter values are "yyyy-mm-dd", "dd/mm/yyyy", "mm/dd/yyyy".
Defaults to "yyyy-mm-dd"
+
setScrollTo()
Sets the date the Gantt Chart will be scrolled to, specified in the date input format set by setDateInputFormat() above. Also accepts the special value "today"
Defaults to minimum display date
+
setUseSingleCell()
Sets the threshold total number of cells at which the task list will use a single table cell for each row rather than one cell per period. Useful to improve performance on large charts. A value of 0 disables this functionality (always use multiple cells), defaults to 25000
+
setLang()
Sets translation to use when drawing the chart. Defaults to "en" as this is the only language provided in the base installation (see Internationalisation below for details on how to add more translations.)
+
+

Layout

+

Most of the look and feel of the Gantt Chart can be controlled using CSS however, as the length of a task bar is determined by column width, the following methods take a single numeric parameter that defines the appropriate column width in pixels.

+

Note that the task bar sizing code assumes the use of collapsed table borders 1px wide.

+
+
setHourColWidth()
Width of Gantt Chart columns in pixels when drawn in "Hour" format. Defaults to 18.
+
setDayColWidth()
Width of Gantt Chart columns in pixels when drawn in "Day" format. Defaults to 18.
+
setWeekColWidth()
Width of Gantt Chart columns in pixels when drawn in "Week" format. Defaults to 36.
+
setMonthColWidth()
Width of Gantt Chart columns in pixels when drawn in "Month" format. Defaults to 36.
+
setQuarterColWidth()
Width of Gantt Chart columns in pixels when drawn in "Quarter" format, although not mandatory it is recommended that this be set to a value divisible by 3. Defaults to 18.
+
setRowHeight()
Height of Gantt Chart rows in pixels. Used to route dependency lines near end points. Defaults to 20.
+
setMinGpLen()
Group tasks have their task bars embellished with end points, this value specifies the width of one of these end points in pixels. A short task bar's length will be rounded up to display either a single or both endpoints correctly. Defaults to 8.
+
+

Display Date Formats

+

Date display formats can be individually controlled. The methods used to set these display formats each take a single format string parameter. The format string can be made up of the following components (case sensitive)

+
+
+
h
Hour (1-12)
+
hh
Hour (01-12)
+
pm
am/pm indicator
+
PM
AM/PM indicator
+
H
Hour (0-23)
+
HH
Hour (01-23)
+
mi
Minutes (1-59)
+
MI
Minutes (01-59)
+
d
Day (1-31)
+
dd
Day (01-31)
+
day
Abbriviated day of week
+
DAY
Day of week
+
m
Month (1-12)
+
mm
Month (01-12)
+
mon
Abbriviated month text
+
month
Full month text
+
yy
Year, excluding century
+
yyyy
Year
+
q
Quarter (1-4)
+
qq
Quarter (Q1-Q4)
+
w
ISO Week number (1-53)
+
ww
ISO Week number (01-53)
+
week
Full ISO Week date format
+
+

separated by one of the following characters: "/\-.,'<space>:

+

Any text between separators that does not match one of the components above will be checked using a case insensitive match for a valid internationalised string (see Internationalisation below). If the value is still not found the text will be output unchanged.

+
+

+

+
setDateTaskTableDisplayFormat()
Date format used for start and end dates in the main task list. Defaults to 'dd/mm/yyyy'.
+
setDateTaskDisplayFormat()
Date format used for start and end dates in task tool tips. Defaults to 'dd month yyyy'.
+
setHourMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Hour" format. Defaults to 'day dd month yyyy'.
+
setDayMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Day" format. Defaults to 'dd/mm/yyyy'.
+
setWeekMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Week" format. Defaults to 'yyyy'.
+
setMonthMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Month" format. Defaults to 'yyyy'.
+
setQuarterMajorDateDisplayFormat()
Date format used for Gantt Chart major date headings displayed in "Year" format. Defaults to 'yyyy'.
+
setHourMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Hour" format. Defaults to 'HH'.
+
setDayMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Day" format. Defaults to 'dd'.
+
setWeekMinjorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Week" format. Defaults to 'dd/mm'.
+
setMonthMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Month" format. Defaults to 'mon'.
+
setQuarterMinorDateDisplayFormat()
Date format used for Gantt Chart minor date headings displayed in "Year" format. Defaults to 'qq'.
+
+ +

Internationalisation

+

jsGanttImproved only provides English text however all hard coded strings can be replaced by calling the addLang() method available on the GanttChart object returned by a call to JSGantt.GanttChart()

+

The addLang() method takes two parameters. The first is a string identifier for the language, the second is a javascript object containing all the replacement text pairs, the default English settings are:

+
+ + + + + + + +
+
+
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
+
resource
Resource
+
duration
Duration
+
comp
% Comp.
+
completion
Completion
+
startdate
Start Date
+
enddate
End Date
+
moreinfo
More Information
+
notes
Notes
+
+
+
+
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
+
+
+
+

When adding a language any translations that are not provided will use the default English language value. This provides a simple way to override default strings e.g.

+
+g.addLang('en2', {'format':'Select', 'comp':'Complete'});
+
+

would create a language called 'en2' where the text in the format selector was "Select" rather than "Format" and the header for the Percentage Complete column in the task list is "Complete" rather than "% Comp."

+

Once a translation has been added a call must be made to setLang() with the appropriate langage identifier before calling Draw().

+ +

Example Options

+

The configuration options used in the example chart above are:

+ +
+g.setCaptionType('Resource');
+g.setShowTaskInfoLink(1);
+g.setDayMajorDateDisplayFormat('dd mon');
+g.setDateTaskDisplayFormat('dd month yyyy HH:MI');
+
+ +

Putting all this information together the final code to produce the chart above is as follows:

+ + + +

XML Export

+

The following methods can be used to extract details of tasks in the project in XML format

+ +

Method definition: getXMLProject()

+

Returns a string containing the entire project in JSGantt Improved XML format. Dates will be exported in the currently defined input format as set by setDateInputFormat()

+ +

Method definition: getXMLTask(pID, pIdx)

+
+
pID
(required) the numeric ID that identifies the task to extract
+
pIdx
(optional) Boolean - if present and set to "true" the number passed in the pID parameter is treated as an array index for the task list rather than an ID
+
+

Returns a string containing the specified task item in JSGantt Improved XML format. Dates will be exported in the currently defined input format as set by setDateInputFormat()

+ + +

Additional Demos

+ + + + +

Credits

+ +

Developed by Paul Geldart

+

Based on jsGantt 1.2 developed by Shlomy Gantz and Brian Twidt
+Contributed: Paul Labuschagne, Kevin Badgett, Ilan Admon
+

+ + + + diff --git a/project.xml b/project.xml index 26e33943..726596b9 100644 --- a/project.xml +++ b/project.xml @@ -1,67 +1,67 @@ - - - - 10 - WCF Changes - - - ggroupblack - - 0 - - 0 - 1 - 0 - 1 - - - - 20 - Move to WCF from remoting - 2014-05-11 09:00 - 2014-05-15 - gtaskblue - - 0 - Rich - 10 - 0 - 10 - 1 - - Brian - This text is only available in tool tips - - - 30 - add Auditing - 2014-05-19 10:30 - 2014-05-21 12:00 - gtaskblue - - 0 - Shlomy - 50 - 0 - 10 - 1 - 20 - Shlomy - - - 40 - Yet another task - 2014-05-23 - 2014-05-24 - gtaskblue - - 0 - Shlomy - 30 - 0 - 0 - 1 - 20,30 - Shlomy - - \ No newline at end of file + + + + 10 + WCF Changes + + + ggroupblack + + 0 + + 0 + 1 + 0 + 1 + + + + 20 + Move to WCF from remoting + 2014-05-11 09:00 + 2014-05-15 + gtaskblue + + 0 + Rich + 10 + 0 + 10 + 1 + + Brian + This text is only available in tool tips + + + 30 + add Auditing + 2014-05-19 10:30 + 2014-05-21 12:00 + gtaskblue + + 0 + Shlomy + 50 + 0 + 10 + 1 + 20 + Shlomy + + + 40 + Yet another task + 2014-05-23 + 2014-05-24 + gtaskblue + + 0 + Shlomy + 30 + 0 + 0 + 1 + 20,30 + Shlomy + +