Gantt Chart Integration

gantt with phpgrid
Launch Demo

 
We are constantly experimenting with new frameworks in order to better combine content and reporting tools in phpGrid. The most recent is a Gantt chart integration.

Setup

Before you start, download phpGrid and phpGantt.

phpGantt is a wrapper class of excellent javascript library Frappe Gantt (https://frappe.io/gantt). It is also included in phpGrid and phpChart commercial license with more features and full fledged Gantt examples.
X

It’s important to install phpGrid and phpGantt in separate folders. The chart below shows the folder structure we used in our example. This is the RECOMMENDED folder hierarchy.

localhost
+-- phpGrid_Gantt
|   |-- phpGrid
|   |   +-- conf.php
|   |-- phpGantt
|   |   +-- conf.php
|   +-- phpgrid-with-gantt-chart.php

 
Once we have the folder structure, define the database connection settings in phpGantt/conf.php, similar to the followings.

1
2
3
4
5
6
7
<?php
define('PGC_DB_HOSTNAME', 'localhost:3306'); // database host name
define('PGC_DB_USERNAME', 'root'); // database user name
define('PGC_DB_PASSWORD', 'root'); // database password
define('PGC_DB_NAME', 'sampledb'); // database name
define('PGC_DB_TYPE', 'mysql'); // database type
define('PGC_DB_CHARSET','utf8mb4');

Load Tasks

Now, we can move on to the actual integration. First all, let’s add the instruction to include both conf.php files for each product at the start of the script.

1
2
require_once("phpGrid/conf.php");
require_once("phpGantt/conf.php");

The data for the tasks must then be loaded into an array, which will serve as the data source for the Gantt chart. The following is the tasks table definition with some sample task data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE TABLE `tasks` (
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) DEFAULT NULL,
  `estimated_days` INT(11) DEFAULT NULL,
  `start` DATE DEFAULT NULL,
  `end` DATE DEFAULT NULL,
  `progress` INT(11) DEFAULT NULL,
  `note` mediumtext,
  `dependencies` VARCHAR(255) DEFAULT NULL,
  `assignee` VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;


INSERT INTO `tasks` (`id`, `name`, `estimated_days`, `start`, `end`, `progress`, `note`, `dependencies`, `assignee`)
VALUES
  (8, 'task1', 3, '2022-05-11', '2022-05-14', 30, 'working on it', NULL, 'Joe'),
  (9, 'task2', 2, '2022-05-12', '2022-05-14', 50, 'good ', '8', 'Mary'),
  (10, 'task3', 5, '2022-05-15', '2022-05-22', 80, 'WIP still', '9', 'Frank'),
  (11, 'task4', 1, '2022-05-22', '2022-05-23', 10, 'Waiting for testing', '10', 'Joe'),
  (12, 'task5', 3, '2022-05-16', '2022-05-18', 50, 'Agile meeting votes', '8', 'Frank'),
  (13, 'task6', 2, '2022-05-16', '2022-05-18', 75, 'Testing', '10', 'Joe');

The following creates a two-dimensional array from the “tasks” table above.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$sql = 'SELECT * FROM tasks';

$db = new phpCtrl\C_Database(PGC_DB_HOSTNAME, PGC_DB_USERNAME, PGC_DB_PASSWORD, PGC_DB_NAME, PGC_DB_TYPE, PGC_DB_CHARSET);

$results = $db->db_query($sql);
$tasks = [];
$count = 0;

// prepare tasks to display in Gantt
while($row = $db->fetch_array_assoc($results)) {

    for($i = 0; $i < $db->num_fields($results); $i++) {

    $col_name = $db->field_name($results, $i);

        $tasks[$count]['id'] = $row['id'];
        $tasks[$count]['start'] = $row['start'];
        $tasks[$count]['end'] = date('Y-m-d', strtotime('+'.$row['estimated_days'] .' days', strtotime($row['start'])));
        $tasks[$count]['name'] = $row['name'];
        $tasks[$count]['progress'] = (int)$row['progress'];
        $tasks[$count]['_start'] = $row['start'];
        $tasks[$count]['_end'] = $row['end'];
        $tasks[$count]['_index'] = $row['id'];
        $tasks[$count]['dependencies'] = $row['dependencies'];
    }

    $count++;
}

Next, we simply pass the $tasks, a 2-dimensional array to our Gantt constructor.

1
2
$pgc = new phpCtrl\C_Gantt($tasks);
$pgc -> display();

This should give us the Gantt Chart. Since we also want to update the tasks, we can add the phpGrid.

1
2
3
4
$dg = new phpCtrl\C_DataGrid('select * from tasks', 'id', 'tasks');
$dg->enable_autowidth(true);
$dg->enable_edit('INLINE');
$dg->display();

That’s all there is to it! Try a quick search or sort and observe the graph updating in real-time.

Complete Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?php
require_once("phpGantt/conf.php");
require_once("phpGrid/conf.php");
?>
<!DOCTYPE html>
<html>
<head>
<title>phpGantt - Basic Gantt</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

</head>
<body>

<h2 class="text-center">A Gantt Chart with phpGrid </h2>

<?php
$sql = 'SELECT * FROM tasks';

$db = new phpCtrl\C_Database(PGC_DB_HOSTNAME, PGC_DB_USERNAME, PGC_DB_PASSWORD, PGC_DB_NAME, PGC_DB_TYPE, PGC_DB_CHARSET);

$results = $db->db_query($sql);
$tasks = [];
$count = 0;

// prepare tasks to display in Gantt
while($row = $db->fetch_array_assoc($results)) {

    for($i = 0; $i < $db->num_fields($results); $i++) {

    $col_name = $db->field_name($results, $i);

        $tasks[$count]['id'] = $row['id'];
        $tasks[$count]['start'] = $row['start'];
        $tasks[$count]['end'] = date('Y-m-d', strtotime('+'.$row['estimated_days'] .' days', strtotime($row['start'])));
        $tasks[$count]['name'] = $row['name'];
        $tasks[$count]['progress'] = (int)$row['progress'];
        $tasks[$count]['_start'] = $row['start'];
        $tasks[$count]['_end'] = $row['end'];
        $tasks[$count]['_index'] = $row['id'];
        $tasks[$count]['dependencies'] = $row['dependencies'];
    }

    $count++;
}


// display our beautiful Gantt
$pgc = new phpCtrl\C_Gantt($tasks);
$pgc -> display();


// add datagrid for CRUD
$dg = new phpCtrl\C_DataGrid('select * from tasks', 'id', 'tasks');
$dg->set_theme('bootstrap');
$dg->set_col_hidden('note');
$dg->enable_autowidth(true);
$dg->set_dimension('950px');
$dg->enable_edit('INLINE');
$dg->display();
?>

</body>
</html>

What to Improve

The application may be improved by including an event handler that will update the Gantt chart whenever an update or deletion occurs in the datagrid.  On the other hand, the grid may be refreshed when the Gantt Chart changes (by dragging either end of a task with mouse), which can also be reflected in the database via ajax calls.

Give it a try!