SVGGraph Gantt Charts

« Return to SVGGraph page

Skip to:

A Gantt chart is a type of horizontal floating bar graph, used for showing the schedule and progress of a project. Each bar represents a task, and these tasks can be grouped together to show sub-projects. The chart can also show milestones - markers that show imprtant points in the project. The graph type name that you should use to make SVGGraph render these is "GanttChart".

Full example

Before I explain how to use GanttChart, here is an example showing a main project broken down into two sub-projects, with four tasks and a milestone.

28 Mar04 Apr11 Apr18 Apr25 Apr02 May09 May16 May2022Big projectFirst partA simple taskSecond taskSecond partImportant dateThird taskFinal task[36.86%][57.91%][80%][40%][7.66%]Important date[10%][0%]
Gantt chart

The task bars are standard floating bar chart bars, though they do show the percentage completion as a gauge in the filled area. Group bars are displayed with downward points at each end, and these too show the percentage completion inside. Milestones are displayed as diamond-shaped markers.

There are plenty of options for configuring Gantt charts, though the task bars, milestones and group bars are all specified using structured data.

Automatic height

One important change for Gantt charts is the added support for an automatic SVG document height. Supplying the string "auto" as the graph height will make SVGGraph calculate a height for the graph based on the number of entries, font sizes, bar widths and other options.

$graph = new Goat1000\SVGGraph\SVGGraph(670, 'auto', $options);

You can continue to specify your own height for the graph and the bars and milestone markers will be spread out or squashed together to fit the available space.

Task bars

The simplest Gantt chart contains only task bars. For this example I have set the bar_round option to 10, rounding off the ends of the bars.

28 Mar04 Apr11 Apr18 Apr25 Apr02 May09 May16 May2022A simple taskSecond taskThird taskFinal task
Gantt chart, task bars only

Since Gantt charts require more than simple coordinate pairs, you must use structured data for passing the bar values to SVGGraph:

$options = [
  'structure' => [
    'key' => 0, 'value' => 1, 'end' => 2,
  ],
  'bar_round' => 10,
];

$values = [
  ['A simple task', '2022-04-01', '2022-04-13'],
  ['Second task', '2022-04-05', '2022-04-20'],
  ['Third task', '2022-05-02', '2022-05-17'],
  ['Final task', '2022-05-16', '2022-05-20'],
];

The example is using the task names as the key field, with the value field and end field containing the start and end dates of the tasks.

Repeated item names

If you want to repeat the name of a task, group or milestone, you must use a separate unique key field and the axis_text field:

28 Mar04 Apr11 Apr18 Apr25 Apr02 May09 May16 May2022A simple taskTestingSecond taskTestingFinal taskTesting
Gantt chart with repeated tasks

In this example “Testing” appears twice, so I have had to use a key field:

$options = [
  'structure' => [
    'key' => 0, 'axis_text' => 1, 'value' => 2, 'end' => 3,
  ],
  'bar_round' => 10,
];

$values = [
  ['A0', 'A simple task', '2022-04-01', '2022-04-13'],
  ['A2a', 'Testing', '2022-04-13', '2022-04-15'],
  ['A1', 'Second task', '2022-04-05', '2022-04-20'],
  ['A2', 'Testing', '2022-04-20', '2022-04-21'],
  //['A3', 'Third task', '2022-05-02', '2022-05-17'],
  ['A4', 'Final task', '2022-05-16', '2022-05-20'],
  ['A5', 'Testing', '2022-05-20', '2022-05-20'],
];

I have used alphanumeric string keys for this example because it allows me to comment out one of the values. If I had used numeric keys and commented one out there would have been a gap in the chart where the missing item should be. Apart from that, numeric keys should work fine - just make sure that the key values are sequential integers starting at 0.

Completion percentages

To show how far the project has progressed you can give each task a completion percentage.

28 Mar04 Apr11 Apr18 Apr25 Apr02 May09 May16 May2022A simple taskTestingSecond taskTestingThird taskFinal taskTesting[50%][0%][20%][0%][60%][78%][0%]
Gantt chart with completion percentages

To do this I added a complete field to the data structure and set the colour used for the complete part. SVGGraph uses the dataset 0 colour for incomplete bars and the dataset 1 colour for the complete gauge inside the bar:

$options = [
  'structure' => [
    'key' => 0, 'axis_text' => 1, 'value' => 2, 'end' => 3,
    'complete' => 'c',
  ],
  'bar_round' => 10,
  'show_data_labels' => true,
  'pad_right' => 20,
];

$values = [
  ['A0', 'A simple task', '2022-04-01', '2022-04-13', 'c' => 50],
  ['A2a', 'Testing', '2022-04-13', '2022-04-15'],
  ['A1', 'Second task', '2022-04-05', '2022-04-20', 'c' => 20],
  ['A2', 'Testing', '2022-04-20', '2022-04-21'],
  ['A3', 'Third task', '2022-05-02', '2022-05-17', 'c' => 60],
  ['A4', 'Final task', '2022-05-16', '2022-05-20', 'c' => 78],
  ['A5', 'Testing', '2022-05-20', '2022-05-20'],
];

// orange-red-purple range for bars, green-blue for complete
$graph->colourRangeHexHSL(0, '#c50', '#c59');
$graph->colourRangeHexHSL(1, '#6a0', '#6a9');

The complete field is set to "c" to use the relevant parts of the data array. I've also enabled data labels, which display the completion percentage. The extra pad_right is there to provide a bit more space for the labels.

Milestones

A Gantt chart with nothing but milestones seems a bit odd, but SVGGraph does support doing that. Here is what it can look like:

02 May09 May16 May23 May30 May2022Start hereMilestone 2Milestone 3AnotherAnotherLast oneStart hereMilestone 2Milestone 3AnotherAnotherLast one
Gantt chart with milestones only

The milestone field is set in the structure to use the "m" values from the data. These are simple booleans to tell SVGGraph that the row of data represents a milestone. Milestones are points in time, so the end value is not used or required.

$options = [
  'structure' => [
    'key' => 0, 'axis_text' => 1, 'value' => 2, 'end' => 3,
    'milestone' => 'm',
  ],
  'show_data_labels' => true,
];

$values = [
  ['M1', 'Start here', '2022-05-02', 'm' => true],
  ['M2', 'Milestone 2', '2022-05-09', 'm' => true],
  ['M3', 'Milestone 3', '2022-05-16', 'm' => true],
  ['M4', 'Another', '2022-05-17', 'm' => true],
  ['M5', 'Another', '2022-05-18', 'm' => true],
  ['M6', 'Last one', '2022-06-02', 'm' => true],
];

The show_data_labels option is used again to label the milestones on the chart. There are options for setting the colour, size and marker type used for the milestones, but I haven't used any here.

Group bars

Group bars are used to group multiple task bars and milestones together. They usually have downward-pointing corners at either end.

28 Mar04 Apr11 Apr18 Apr25 Apr02 May09 May16 May2022A Group barA simple taskTestingSecond taskTestingThird taskFinal taskTesting[28.75%][50%][0%][20%][0%][60%][78%][0%]
Gantt chart with group bar

This example sets the group field in the structure to point at the "g" fields in the data array. There is only one group defined, with a value of 4, and that means the four entries following the group are included in the group.

$options = [
  'structure' => [
    'key' => 0, 'axis_text' => 1, 'value' => 2, 'end' => 3,
    'complete' => 'c',
    'group' => 'g',
  ],
  'bar_round' => 10,
  'show_data_labels' => true,
  'pad_right' => 20,
];

$values = [
  ['G0', 'A Group bar', 'g' => 4],
  ['A0', 'A simple task', '2022-04-01', '2022-04-13', 'c' => 50],
  ['A2a', 'Testing', '2022-04-13', '2022-04-15'],
  ['A1', 'Second task', '2022-04-05', '2022-04-20', 'c' => 20],
  ['A2', 'Testing', '2022-04-20', '2022-04-21'],
  ['A3', 'Third task', '2022-05-02', '2022-05-17', 'c' => 60],
  ['A4', 'Final task', '2022-05-16', '2022-05-20', 'c' => 78],
  ['A5', 'Testing', '2022-05-20', '2022-05-20'],
];

If you want to include all the following entries in the group, you could use a larger number, or instead of a number use the string "*". In fact, any non-numeric string would work, since strings are used for nested group levels.

The completion gauge inside the group bar is automatically calculated from all the bars inside the group, so you don't need to do anything to make it work.

Nested groups

To put groups inside other groups is quite easy - just pick a name for each level and use it as the value of the group field.

28 Mar04 Apr11 Apr18 Apr25 Apr02 May09 May16 May2022Top-level groupSub-group 1A simple taskTestingSecond taskTestingSub-group 2Third taskFinal taskTesting[41.68%][28.75%][50%][0%][20%][0%][61.72%][60%][78%][0%]
Gantt chart with group and sub-groups

This example has one top-level group and two sub-groups. The field structure is the same in this example, but the data values have changed:

$values = [
  ['G0', 'Top-level group', 'g' => 'top'],
  ['G1', 'Sub-group 1', 'g' => 'level 1'],
  ['A0', 'A simple task', '2022-04-01', '2022-04-13', 'c' => 50],
  ['A2a', 'Testing', '2022-04-13', '2022-04-15'],
  ['A1', 'Second task', '2022-04-05', '2022-04-20', 'c' => 20],
  ['A2', 'Testing', '2022-04-20', '2022-04-21'],
  ['G2', 'Sub-group 2', 'g' => 'level 1'],
  ['A3', 'Third task', '2022-05-02', '2022-05-17', 'c' => 60],
  ['A4', 'Final task', '2022-05-16', '2022-05-20', 'c' => 78],
  ['A5', 'Testing', '2022-05-20', '2022-05-20'],
];

The “Top-level group” group has a group value of "top", which is just an arbitrary name for that level. The two sub-groups have a group value of "level 1", another arbitrary name.

SVGGraph puts every task bar or milestone below a named group into that group. When it finds a new group name it starts a new sub-group. A group ends when the data contains the same group name again, starting a new group at the same level.

Writing that out makes it sound really complicated - here's another example, this time with a top level, sub-level and sub-sub-level:

28 Mar04 Apr11 Apr18 Apr25 Apr02 May09 May16 May2022Top-level groupSub-group 1A simple taskTestingSub-sub-groupSecond taskTestingSub-group 2Third taskSub-sub-groupFinal taskTesting[41.68%][28.75%][50%][0%][17.92%][20%][0%][61.72%][60%][66.53%][78%][0%]
Gantt chart with three levels of groups

And here is the data for it, with the rows indented to match the chart:

$values = [
  ['G0', 'Top-level group', 'g' => 'top'],
    ['G1', 'Sub-group 1', 'g' => 'level 1'],
      ['A0', 'A simple task', '2022-04-01', '2022-04-13', 'c' => 50],
      ['A2a', 'Testing', '2022-04-13', '2022-04-15'],
      ['G1a', 'Sub-sub-group', 'g' => 'l 2'],
        ['A1', 'Second task', '2022-04-05', '2022-04-20', 'c' => 20],
        ['A2', 'Testing', '2022-04-20', '2022-04-21'],
    ['G2', 'Sub-group 2', 'g' => 'level 1'],
      ['A3', 'Third task', '2022-05-02', '2022-05-17', 'c' => 60],
      ['G2a', 'Sub-sub-group', 'g' => 'l 2'],
        ['A4', 'Final task', '2022-05-16', '2022-05-20', 'c' => 78],
        ['A5', 'Testing', '2022-05-20', '2022-05-20'],
];

There is one top-level group called "top", containing everything else because the group name "top" doesn't come up again.

“Sub-group 1” is called "level 1" and contains everything until the name "level 1" is used again for “Sub-group 2”.

The name "l 2" is used for the sub-sub-group inside "level 1". It is not repeated inside the parent group, so it ends when its parent group ends.

Today line

By default, the Gantt chart will display a dashed, red vertical line on the chart corresponding with the current day. I've turned it off for most of the example charts on this page since it will not be visible after the current day drops off the end of the scale, but here is an example with the line showing:

28 Mar04 Apr11 Apr18 Apr25 Apr02 May09 May16 May2022A simple taskSecond taskThird taskFinal task
Gantt chart with today line

For this chart I've used the gantt_today_date option to fix the position of the line on the 28th of April. I've also made it wider and bright green. There are several options for configuring how the line looks, listed in the options section of this page.

Text classes

You may have noticed that the text to the left of the charts with groups has different styling depending on the type of entry and its grouping level. The options for this come from a file called "text_classes.ini", which contains a section for each entry type and at various levels.

Here is a short section of the file:

[gantt_group:1]
font = 'Arial Black'
font_size = 14

[gantt_group:2]
font = 'Arial Black'
indent = 10

To change the styling used for the axis text you can either edit the "text_classes.ini" file, or use the text_classes_file option to use your own file instead.

Structured data fields

Gantt charts use several structured data fields for the different types of data, plus there are some other fields available for configuring how each individual item looks.

FieldUsed for
key*Item key field.
value*Task start date/time or milestone date/time.
end*Task end date/time.
milestoneWhen true, item is a milestone.
groupStarts a new group or sub-group.
axis_textWhen supplied, used instead of key value.
colourColour of task/group bar or milestone.
colour_completeColour of complete percentage gauge in task/group bar.
sizeSize of milestone marker.
typeType of milestone marker.
corner_widthWidth of group bar bottom corner.
corner_heightHeight of group bar bottom corner.

Fields required in the structure option are marked with an asterisk.

Gantt chart options

When it comes to options a Gantt chart is based on a bar chart, so it supports the usual bar width, spacing and other options. It also has these specific options - follow the links for details.

Where's my task?

And finally, here's a chart showing what happens when you set the date axis minimum and maximum options to values that don't include all your data:

25262728293001020304050607080910111213141516Apr 2022May 2022Project groupA simple taskTestingSecond taskTestingLater partThird taskFinal taskTestingConcurrent projectHush-hush stuffTell no-one
Gantt chart with tasks off the sides

When the task or milestone is not visible on the chart, SVGGraph adds a triangle marker at the left or right pointing towards where it is. In the example, the “Project group” tasks are all earlier, and the “Later part” testing task is after the 16th of May. The end of the “Concurrent project” is also earlier than the 25th of April start date of the chart axis.

« Back to top of page Other graphs »