JavaScript - - By Sergey Laptick

Making your own Gantt chart with Webix

In my previous article, I’ve introduced you the Webix Framework. You’ve discovered its basic features and learned how to create a very good-looking responsive web application with it. Now it’s time to take a little step forward and see what else we can do with this promising framework.

In this article, I’ll show you how to create your own Gantt chart application and to complete this task I’ll use the Webix framework in combination with an open source JavaScript Gantt chart called dhtmlxGantt.

But why the Gantt chart, you might ask. Well, undoubtedly it has many pros. Firstly, these charts are widely used to visualize the working process of a project due to their intuitive way of representation. Secondly, dhtmlxGantt is a Gantt chart tool which has a big list of features such as export, customizable time scale, and so on. Finally, I found a post titled DHTMLX Gantt Chart in Webix Web Apps in the Webix developer’s blog and it turned out that you can add a Gantt chart into a Webix application with just few lines of code. So, I thought that they could fit well together.
If you might need help, a bunch of step-by-step guides are available as well, so feel free to use them if in doubt.

Creating a Basic Gantt Chart

Let’s now create our application. First, we’ll take a look at a basic chart. Then, we’ll add some features to increase its functionality.

Preparing the Files

First of all, we need to download the dhtmlxGantt library package and extract the “codebase” folder to the project directory. Since the ntegration with dhtmlxGantt isn’t a built-in Webix feature, we need to download required files from this GitHub repository. We are interested in is the “gantt” directory that you should place into your project directory.
I’ve used the Webix CDN to include Webix to my project, but you can download the full library if you want. Moreover, we need the api.js file which will allow us to use the export feature.

So, here’s my index.html file at the moment:

<head>
   <title>Webix Gantt Chart</title>
   <!--Webix-->
   <script src="http://cdn.webix.com/edge/webix.js"></script>
   <link rel="stylesheet" href="http://cdn.webix.com/edge/webix.css" />
   <!--dhtmlxGantt-->
   <script src="codebase/dhtmlxgantt.js"></script>
   <link href="codebase/dhtmlxgantt.css" rel="stylesheet" />
   <!--dhtmlxGantt integration-->
   <script type="text/javascript" src="./gantt/gantt.js"></script>
   <!--export-->
   <script src="http://export.dhtmlx.com/gantt/api.js"></script>
</head>

Once done, we can create a basic Gantt chart.

Gantt Chart Initialization

This chart offers the possibility to use a database to store the data (you can check the documentation page to see how it works). However, for our experiment we’ll use inline data as an example to focus on the JavaScript part. n this tutorial I’ll pretend the use of the second one whose content has also been converted into its equivalent JavaScript object:

var tasks = {
   data: [{
         id: 1,
         text: "Project #1",
         start_date: "01-06-2015",
         duration: 11,
         progress: 0.6,
         open: true
      }, {
         id: 2,
         text: "Task #1",
         start_date: "03-06-2015",
         duration: 5,
         progress: 1,
         open: true,
         parent: 1
      },
      /*some more tasks*/
      {
         id: 6,
         text: "Task #2.3",
         start_date: "05-06-2015",
         duration: 4,
         progress: 0.2,
         open: true,
         parent: 3
      }
   ],
   links: [{
         id: 1,
         source: 1,
         target: 2,
         type: "1"
      }, {
         id: 2,
         source: 1,
         target: 3,
         type: "1"
      },
      /*some more links*/
      {
         id: 5,
         source: 5,
         target: 6,
         type: "0"
      }
   ]
};

Let’s discuss the properties. The dataproperty contains the tasks description: the task name, its ID, its starting date, the task duration presented in the units of the current time scale (days by default), and the current progress (a number ranging from 0 to 1). It also includes the open property which defines whether the task branch is open or not, and the parent property, whose aim is to define the parent task. The links parameter defines dependency links and it consists of the following values: the task ID, the source task that depends on the target one and, the dependency type (0 – ‘finish to start’, 1 – ‘start to start’, 2 – ‘finish to finish’).

We can now initialize our chart with this data:

webix.ui({
   rows: [
      //row_1: header
      {
         type: "header",
         template: "Webix Gantt Chart"
      },
      //row_2: gantt chart
      {
         view: "dhx-gantt",
         init: function() {
            gantt.config.order_branch = true;
         },
         ready: function() {
            gantt.parse(tasks);
         }
      }
   ]
});

The view:"dhx-gantt" defines a UI component type, Gantt chart in this case. The init property contains the function which will run before the initialization. I’ve used the order_branch option to enable drag-and-drop tasks reordering. The ready property defines the function which is triggered when the component is fully loaded. In our case, it initializes the chart with previously created data using the gantt.parse() method.

The result is shown below:

basic gantt chart

So, which features do we have? You can redefine the existing task dependencies and create new ones. You can do it by dragging circles at the edges of the tasks. The progress status can be changed with the triangle at the bottom. The start time of a task can be changed by means of dragging a task in the horizontal direction. As for duration, you can set it by resizing the task. We can add new tasks and subtasks using the “+” buttons.

Here’s how a new task creation looks like:

adding new subtask

At this point we can create a chart, but there are no ways to manipulate it. So, let’s add some controls for this purpose.

More Control with Webix

We’ll use some of the Webix UI components to control our chart.

“Export to…” Menu Button

To avoid messy code, I’ve decided to separate the UI components initialization from the layout code.

Firstly, let’s define the menu button, which will allow us to export our chart into different file formats. For this purpose, we’ll use the Webix Menu component.

Here’s the menu description:

var menu = {
   view: "menu",
   openAction: "click",
   data: [{
      value: "Export to...",
      type: "icon",
      icon: "save",
      config: {
         on: {
            onItemClick: function(id) {
               switch (id) {
                  case "pdf":
                     gantt.exportToPDF();
                     break;
                  case "png":
                     gantt.exportToPNG();
                     break;
                  case "excel":
                     gantt.exportToExcel();
                     break;
                  case "ical":
                     gantt.exportToICal();
                     break;
                  default:
                     webix.message("Unknown file format");
               }
            }
         }
      },
      submenu: [{
         id: "pdf",
         value: "PDF",
         type: "icon",
         icon: "file-pdf-o"
      }, {
         id: "png",
         value: "PNG",
         type: "icon",
         icon: "file-image-o"
      }, {
         id: "excel",
         value: "Excel",
         type: "icon",
         icon: "file-excel-o"
      }, {
         id: "ical",
         value: "iCal",
         type: "icon",
         icon: "calendar"
      }]
   }]
};

By default, the menu button is activated when the mouse hovers over it. The openAction: "click" property redefines this behavior, so the menu will open its submenus by the mouse click only. The data parameter defines the menu content. What’s interesting here is the type: "icon" property which allows us to add an icon to the menu button. Webix uses Font Awesome icons collection. If you want to apply the icon you like, you have to use the icon’s name as the value of the icon parameter.
The next step is the event handling. The onItemClick event fires when one of the menu items is clicked. I’ve used the switch statement to handle the selected id value, so you can see what method is used for a certain file format. The submenu parameter contains the menu items definition.

Toolbar

We’ll place our toolbar at the bottom of the page. It’ll contain the control elements including our menu button.

The Toolbar component will help us with that. But before, let’s define which options we should add. If you want to manage a project the duration of which is long enough, you should think about the scale changing feature. dhtmlxGantt provides you with a wide variety of available scale properties. We’ll use Day, Week, and Month scales.

Let’s define the function that will enable the month scale:

var scaleMonths = function() {
   gantt.config.scale_unit = "month";
   gantt.config.date_scale = "%F, %Y";
   gantt.parse(tasks);
};

The scale_unit property defines the scale unit. Its possible values are “minute”, “hour”, “day”, “week”, “quarter”, “month”, and “year”. To set a proper format of the time scale we’ve used the date_scale property. After that we should refresh the chart with gantt.parse(tasks).

Here’s how our chart looks like after we’ve used this function:

scale

Other scale functions work pretty in a similar fashion, so I won’t describe them.

Now we can define the toolbar variable:

var toolbar = {
   view: "toolbar",
   paddingY: 0,
   elements: [
      menu, {
         view: "segmented",
         on: {
            onChange: function(id) {
               switch (id) {
                  case "days":
                     scaleDays();
                     break;
                  case "weeks":
                     scaleWeeks();
                     break;
                  case "months":
                     scaleMonths();
                     break;
                  default:
                     webix.message("Wrong scale option");
               }
            }
         },
         options: [{
            id: "days",
            value: "Days"
         }, {
            id: "weeks",
            value: "Weeks"
         }, {
            id: "months",
            value: "Months"
         }]
      }
   ]
};

It looks similar to our previously created menu. The paddingY property sets the top and bottom padding values to 0. The elements property defines the toolbar content, just as the data property in our menu example. Toolbar’s first element is our menu while the second one is a Segmented Button. It’s useful when you want to switch between the available values like the scale units in our example. One more event handler was used to manage the user’s choice, but this time it’s the onChange event. It fires after the currently selected button is changed. Our previously defined functions will change the scale according to the selected button ID. The option property defines the buttons (segments) within the control.

Finally, it’s time to add the toolbar to our chart. To do this, just add the toolbar variable to your layout code:

webix.ui({
   rows: [
      //row_1: header
      {
         type: "header",
         template: "Webix Gantt Chart"
      },
      //row_2: gantt chart
      {
         view: "dhx-gantt",
         init: function() {
            gantt.config.order_branch = true;
         },
         ready: function() {
            gantt.parse(tasks);
         }
      },
      toolbar
   ]
});

Here’s the result:

webix gantt chart

Our chart is scalable now. Menu icons will help a user to make his choice.

Conclusions

In this article we’ve seen how to build a dhtmlxGantt based Gantt chart app, set a proper scale according to its overall duration, and export it to a file for further needs. What we’ve got is a lightweight online chart creation tool.

There are just a couple of articles about the integration of Webix with dhtmlxGantt at the moment. However, according to this post titled Use case of Webix UI – Gantt PRO, recently Webix has been used to create GanttPRO – an advanced online Gantt chart app. This makes me guess that, by using the features and UI components described in the post, you’ll be able to considerably extend Gantt chart functionality.

If you want to check out the source code and a demo, you can visit this GitHub page.

Sponsors