Gantt Chart with Colorful Bars in Salesforce Lightning | #SalesforceDevelopment #GanttCharts



In this blog you will find complete code snippet to create a Gantt Chart in Salesforce Lightning. We will use google Gantt Chart script and we will customize it to display Gantt Chart dynamically in our Salesforce Org.

GanttChart.vfp

 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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<apex:page controller="GanttChartCtrl">
    <apex:form >
        <html>
            <head>
                <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
                <script type="text/javascript">
                    google.charts.load('current', {'packages':['gantt']});
                google.charts.setOnLoadCallback(drawChart);
                function daysToMilliseconds(days) {
                    return days * 24 * 60 * 60 * 1000;
                }
                
                var Name = '{!Name}';
                Name = Name.replace("[","");
                Name = Name.replace("]","");
                var NameArr=Name.split(',');
                
                var startDate = '{!SDate}';
                startDate = startDate.replace("[","");
                startDate = startDate.replace("]","");
                var startDateArr=startDate.split(',');
                
                var endDate = '{!EDate}';
                endDate = endDate.replace("[","");
                endDate = endDate.replace("]","");
                var endDateArr=endDate.split(',');
                
                var duration = '{!Duration}';
                duration = duration.replace("[","");
                duration = duration.replace("]","");
                var durationArr=duration.split(',');
                
                var tstatus = '{!tStatus}';
                tstatus = tstatus.replace("[","");
                tstatus = tstatus.replace("]","");
                var tstatusArr=tstatus.split(',');
                
                function drawChart() {
                    
                    var data = new google.visualization.DataTable();
                    data.addColumn('string', 'Task ID');
                    data.addColumn('string', 'Task Name');
                    data.addColumn('string', 'Resource');
                    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 < NameArr.length; i++) {
                        var color='';
                        console.log('###Status :'+tstatusArr[i]);
                        if(tstatusArr[i].trim() == 'Completed'){
                            color='sports';
                        }
                        if(tstatusArr[i].trim() == 'In Progress'){
                            color='winter';
                        }
                        if(tstatusArr[i].trim() == 'Not Started'){
                            color='autumn';
                        }
                        var j=i+1;
                        var sd=startDateArr[i].replace('-',',');
                        sd=sd.replace('-',',');
                        var ed=endDateArr[i].replace('-',',');
                        ed = ed.replace('-',',');
                        data.addRow([NameArr[i], NameArr[i],color,new Date(sd), new Date(ed), daysToMilliseconds(durationArr[i]),  0,  null]);
                    } 
                    
                    var options = {
                        height: 400,
                        gantt: {
                            trackHeight: 30
                        }
                    };
                    
                    var chart = new google.visualization.Gantt(document.getElementById('chart_div'));
                    
                    chart.draw(data, options);
                }
                </script>
            </head>
            <body>
                <div id="chart_div"></div>
            </body>
        </html>
    </apex:form>
</apex:page>


GanttChartCtrl.apxc

 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
public class Vlog_GanttChartCtrl {
	public List<String> Name{get;set;}
    public List<String> SDate{get;set;}
    public List<String> EDate{get;set;}
    public List<Integer> Duration{get;set;}
    public List<String> tStatus{get;set;}
    
    public Vlog_GanttChartCtrl(){
        List<Task> taskList = new List<Task>();
        Name = new List<String>();
        SDate = new List<String>();
        EDate = new List<String>();
        Duration = new List<Integer>();
        tStatus=new List<String>();
        
        Integer dd;
        Integer month;
        Integer year;
        
        String whatId= ApexPages.currentPage().getParameters().get('id');
        taskList = [SELECT Id, Subject, CreatedDate, ActivityDate, Status  FROM Task WHERE WhatId=:whatId];     
        for(Task ts:taskList){
            tStatus.add(ts.Status);
            Date todayDate = System.Date.today();
            dd = todayDate.day();
            month=todayDate.month();
            year = todayDate.year();
            Name.add(ts.Subject);
            SDate.add(year+'-'+month+'-'+dd);
            dd = ts.ActivityDate.day();
            month=ts.ActivityDate.month();
            year = ts.ActivityDate.year();
            EDate.add(year+'-'+month+'-'+dd);
            Integer dt = (system.today()).daysBetween(Date.valueOf(ts.ActivityDate));
            Duration.add(dt);
        }
    }
}


GanttChartCtrlTest.apxc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@isTest
private class Vlog_GanttChartCtrlTest {
    @testSetup static void setup() {
        Account a = new Account(Name='Sample Account');
        insert a;
        List<Task> tasks = new List<Task>();
        tasks.add(new Task(
            ActivityDate = Date.today().addDays(7),
            Subject='Sample Task',
            WhatId = a.Id,
            OwnerId = UserInfo.getUserId(),
            Status='In Progress'));
        
        insert tasks;
    }
    @isTest static void GanttChartTest(){
        List<Account> accList = [SELECT Id FROM Account limit 1];
        ApexPages.currentPage().getParameters().put('id',accList[0].Id);
        Test.startTest();
        Vlog_GanttChartCtrl obj = new Vlog_GanttChartCtrl();
        Test.stopTest();
    }
}


Checkout complete video tutorial below

 If you have any question please leave a comment below.

If you would like to add something to this post please leave a comment below.
Share this blog with your friends if you find it helpful somehow !

Thanks
Happy Coding :)

Post a Comment

22 Comments

  1. Hi Kapil,

    Thanks for all your help, i was already created a gantt chart for my org by following your guide, it was working till last 15 days but suddenly i tried today in productions the page is not showing anything and it is kind of blank , however the page is working correctly on sandboxes do you have any idea on it?

    Appreciate your help.

    Thanks

    ReplyDelete
    Replies
    1. Hi Raj,
      Glad to hear that it helped you ! Are you using it in a child page ? If it's working fine in sandbox could you please deploy that VF page separately once and try to run in directly !
      Also let me know if you get any error so we could get specific cause of this issue.

      Delete
    2. The page is working properly in sandbox and i am using it as a vf tab , but suddenly since yesterday whenever a user is accessing the tab in production the page loads and shows blank .

      Delete
    3. Do you have same data for the page in Sandbox also ? Could you please check the console once ?

      Delete
  2. Hi sir,
    can you please tell me is drag and drop is possible in this google gantt chart ? if yes how to do it ?

    Thanks in advance !

    ReplyDelete
    Replies
    1. Hi, yes you can. It's just javascript and you can add drag and drop in it. Checkout this video for drag & drop scripts https://youtu.be/vhY7hhxo-dY

      Delete
    2. Thanks ! I am new to aura component and I have one doubt that for drag and drop is only Aura is option ? because you created Gantt chart in VF so I am little bit confused.

      Delete
    3. Its pure javascript, you can have it wherever you want :)

      Delete
  3. Hey thanks a lot for the Tutorial! Really helpful.
    Do you know if there is a chance to add to the Visualforce page the legends labels (with colours) of the resource that i am grouping by?

    Thanks for your time!

    ReplyDelete
  4. Hi can you please help how to change the colors of the bar , and also how to add completion percentage , when i am adding any value after fetching data from the query its not loading the gantt chart. Your quick response would be highly appreciated.

    ReplyDelete
    Replies
    1. Hi, are you getting any error in console for the same?

      Delete
    2. if i add the percentage complete the gantt chart is not getting dispalyed. I added like this
      var percentComplete = '{!percentComplete}';
      percentComplete = percentComplete.replace("[","");
      percentComplete = percentComplete.replace("]","");
      var percentCompleteArr = percentComplete.split(',');
      var taskPercent = percentCompleteArr[i];
      data.addRow([NameArr[i], NameArr[i],color,new Date(sd), new Date(ed), daysToMilliseconds(durationArr[i]), taskPercent , null]);
      and also added the field in apex class.
      and for color change its not taking the colors im giving its getting overriden bt the colors provided by google gantt chart

      Delete
    3. i am facing the same issue that you faced in the video of colorchange of the bars depending on the status change is there a fix for it ?

      Delete
    4. Make sure you are passing a number value and not with % symbol. Also I would suggest you to check it once by giving manual value of percentage complete and see if you are getting expected result.

      Delete
    5. This comment has been removed by the author.

      Delete
    6. This comment has been removed by the author.

      Delete
  5. This comment has been removed by the author.

    ReplyDelete
  6. And also the color change thing is also not working , any suggestions for that

    ReplyDelete
  7. Hi Kapil..I found a solution for the color change depending on the task status values, hope it will help others as well.
    In the above code the following needs to be added for it
    var container = document.getElementById('chart_div');
    var chart = new google.visualization.Gantt(container);
    var observer = new MutationObserver(function (mutations) {
    Array.prototype.forEach.call(container.getElementsByTagName('path'), function(bar, index) {
    if (data.getValue(index, 2) =='Not Started') {
    bar.setAttribute('fill', '#FFFF00');
    console.log('Not Started');
    }
    });
    });
    observer.observe(container, {
    childList: true,
    subtree: true
    });

    chart.draw(data, options);
    }

    ReplyDelete
    Replies
    1. basically passing the value of status in 'Resource' and comparing and adding the color for it

      Delete
    2. Awesome, thanks for sharing it here Komal. It will definitely help others.

      Delete