Implementation of Gantt Chart using Google Charts

Implementation of Gantt Chart using Google Charts

Motivation: When you can’t build the desired chart using Visualforce, you can use the vast Google Charts API.

What is Gantt Chart:

A Gantt chart is one of the most popular and useful ways of showing activities (tasks or events) displayed against time.On the left of the chart is a list of the activities and along the below is a suitable time scale. Each activity is represented by a bar; the position and length of the bar reflect the start date, duration and end date,dependencies  of the activity.This allows you to see at a glance:

• To know which activities are interrelated
• When each activity begins and ends

Does that mean we cannot use Gantt Chart in Salesforce?

No, the following article shows one of the  easiest ways to build Gantt Chart with the help of Google Charts.

Technologies Used: Apex class, Visualforce, Google Gantt chart and JavaScript.

Consider an example of Opportunity stages  where stages will be changed one after the other after the certain end time.Sometimes there may be chances of a direct move from the first stage to last as shown below.

To display dependency arrow you need to mention the dependency name while saving the record value.

gantt1

gantt2

If you hover on graph bar, respective bar details will be shown.

How to customize critical path in Gantt Chart?

The critical path in a Gantt chart is the path, or paths, that directly affect the finish date. The critical path in Google Gantt charts is colored red by default, and can be customized using the criticalPathStyle options. You can also turn off the critical path by setting criticalPathEnabled to false.

Critical path in Visualforce

[code language=”css”]
var options = {
height: 275,
Gantt: {
criticalPathEnabled:true //By default it will be true
}
};
[/code]

gantt3gantt4If you hover on graph bar, respective bar details will be shown.

We can also customize the charts based on certain attributes. For more detail refer Google charts for- Gantt Chart.

Controller Code:

We will pass a list of opportunities which are queried in controller method to javaScript function written in visualforce page using RemoteAction.

[sourcecode language=”html”]
global with sharing class googlegantchart {

public String oppList { get; set; }

@RemoteAction
global static Opportunity[] loadrecords() {
return [select Name,Task_Id__c,Task_Name__c, Start_Date__c, End_Date__c,Duration__c,Dependencies__c,Percent_Complete__c from opportunity where Task_Id__c!=Null];
}
}
[/sourcecode]

VisualForce Code:

We will set the way of displaying data as Gantt manner by using Google.charts.load( ‘current’, { ‘packages’: [‘gantt’]}) method. Google.charts.setOnLoadCallback(InitCharts) method is used to call the javascript method ‘InitCharts’. Javascript function ‘InitCharts’ in our execution calls the controller method and stores the result in result variable. We will pass this data to load function which will display the result in Gantt chart Manner.

[sourcecode language=”html”]
<apex:page controller=”googlegantchart”>
<apex:includeScript id=”a” value=”https://www.google.com/jsapi” />
<apex:sectionHeader title=”Google Charts + Javascript Remoting” subtitle=”Demo of Opportunity Stages” />
<div id=”chart_div” />

<script type=”text/javascript” src=”https://www.gstatic.com/charts/loader.js”></script>
<script type=”text/javascript”>
<!–loads the visualization in gant chart view–>
google.charts.load(‘current’, { ‘packages’: [‘gantt’]});
google.charts.setOnLoadCallback(InitCharts);

function InitCharts() {
<!– calls the function called ‘loadrecords’ in googlegantchart controller–>
googlegantchart.loadrecords(
<!– following the usual remoting syntax–>
function(result, event) {

var visualization = new google.visualization.Gantt(document.getElementById(‘chart_div’));
<!–adding data to Chart–>
var data = new google.visualization.DataTable();<!– variable declaration–>

data.addColumn(‘string’, ‘Task ID’);
data.addColumn(‘string’, ‘Task Name’);
data.addColumn(‘date’, ‘Start Date’);
data.addColumn(‘date’, ‘End Date’);
data.addColumn(‘number’, ‘Duration’);
data.addColumn(‘number’, ‘Percent Complete’);
data.addColumn(‘string’, ‘Dependencies’);

for (var i = 0; i < result.length; i++) {
var r = result[i];
data.addRow([/vc_column_text][/vc_column][/vc_row][vc_row nav_skin=”light” consent_include=”include”][vc_column css_animation=””][vc_column_text][r.Task_Id__c, r.Task_Name__c, new Date(r.Start_Date__c), new Date(r.End_Date__c), r.Duration__c,r.Percent_Complete__c,r.Dependencies__c][/vc_column_text][/vc_column][/vc_row][vc_row nav_skin=”light” consent_include=”include” el_class=”blog-page-content”][vc_column css_animation=””][vc_column_text]);
}
var options = {
height: 275,
gantt: {
criticalPathEnabled:true
}
};
visualization.draw(data, options);<!– draws a table that contains the result of data–>
},{escape:true});
}
</script>

</apex:page>
[/sourcecode]

Summary:

Gantt Chart gives you a visual of the current status of your project/task compared to what was originally planned. It also shows you the dependencies between tasks. If your plans need to be changed, you can add tasks, edit existing ones, and set new dependencies right here.

 Related Links

View code in GitHub

Javascript Remoting

Visualforce Charting API

Google Charts API

5 thoughts on “Implementation of Gantt Chart using Google Charts”

  1. Hello All,

    I want to create a google Gantt chart in a VF page, but I have an error “Invalid data table format: column #4 must be of type ‘number’.” just when delcaring the DataTable,

    VF Page code :

    https://www.gstatic.com/charts/loader.js

    google.charts.load(‘current’, { ‘packages’: [‘gantt’]});
    google.charts.setOnLoadCallback(InitCharts);

    function InitCharts() {

    var data = new google.visualization.DataTable();

    data.addColumn(‘string’, ‘Release’);
    data.addColumn(‘string’, ‘Phase’);
    data.addColumn(‘date’, ‘StartDate’);
    data.addColumn(‘date’, ‘EndDate’);

    googlegantchart.loadrecords(

    function(result, event) {

    var visualization = new google.visualization.Gantt(document.getElementById(‘chart_div’));

    for (var i = 0; i < result.length; i++) {
    var r = result[i];

    data.addRow([r.Release__r.Name, r.Milestone_Name__c, new Date(r.Planned_Start_Date__c), new Date(r.Planned_End_Date__c)]);

    }
    var options = {
    height: 275
    };

    visualization.draw(data, options);
    },{escape:true});

    }

    global class googlegantchart {

    public String oppList { get; set; }

    @RemoteAction
    global static Milestone__c[] loadrecords() {
    return [select Release__r.Name, Milestone_Name__c, Planned_Start_Date__c, Planned_End_Date__c from Milestone__c
    where Add_to_Timeline__c = true];
    }
    }

    the data is well retrieved, I have one row retrieved by the query and I can see that in the console.

    Furthermore even when I delete the row that populates the DataTable I keep having the same error,

    Could you please help me with this ?

    Thank you

  2. Sorry this is the VF page code :

    https://www.gstatic.com/charts/loader.js

    google.charts.load(‘current’, { ‘packages’: [‘gantt’]});
    google.charts.setOnLoadCallback(InitCharts);

    function InitCharts() {

    var data = new google.visualization.DataTable();

    data.addColumn(‘string’, ‘Release’);
    data.addColumn(‘string’, ‘Phase’);
    data.addColumn(‘date’, ‘StartDate’);
    data.addColumn(‘date’, ‘EndDate’);

    googlegantchart.loadrecords(

    function(result, event) {

    var visualization = new google.visualization.Gantt(document.getElementById(‘chart_div’));

    for (var i = 0; i < result.length; i++) {
    var r = result[i];

    data.addRow([r.Release__r.Name, r.Milestone_Name__c, new Date(r.Planned_Start_Date__c), new Date(r.Planned_End_Date__c)]);

    }
    var options = {
    height: 275
    };

    visualization.draw(data, options);
    },{escape:true});

    }

  3. Thank you! This is great! Any chance that you could elaborate on how to pass an ID from a custom object using a detail button into the SELECT statement in the controller?

Leave a Comment

Your email address will not be published. Required fields are marked *

Recent Posts

marketing cloud growth empowered by data cloud features and ai
Marketing Cloud Growth Empowered by Data Cloud Features and AI
spx with react a guide to react and spfx integration
SPFx with React: A Guide to React and SPFx Integration
salesforce-tabs-a-guide-to-crafting-custom-images-for-tab-styles
Salesforce Tabs: A Guide to Crafting Custom Images for Tab Styles
the future of automation how playwright is revolutionizing the testing industry
The Future of Automation: How Playwright is Revolutionizing the testing Industry
hyperforce for uae
Hyperforce for UAE
Scroll to Top