0

I have a requirement to display Account and its child Accounts using Gantt Chart. Here is my Logic:

Controller:

public with Sharing class Account_Gantt {
    public Account ParentRecord{get; set;}
    public Account ChildRecord{get; set;}
    public Account_Gantt() {
        ParentRecord = [SELECT Id, Name,start_date__c, end_date__c FROM Account  WHERE name = 'Test Parent Account'];
    }
    public Account_Gantt(Account_Gantt Controller){
         ChildRecord = [SELECT ID, Name, start_date__c, end_date__c from Account where parent_account__r.name = 'Test Parent Account'];
    }
}

VF Page:

<apex:page controller="Account_Gantt"  extensions="Account_Gantt" standardStylesheets="false" showHeader="false">
    <head>
       <apex:stylesheet value="{!URLFOR($Resource.Timeline, 'codebase/dhtmlxgantt.css')}"/>
    <apex:includeScript value="{!URLFOR($Resource.Timeline, 'codebase/dhtmlxgantt.js')}"/>
        <style type="text/css" media="screen">
            html, body { margin:0px; padding:0px; height:100%; overflow:hidden; }
        </style>
    </head>
    <body>
        <div id="gantt_here" style='width:100%; height:100%;'></div>
        <script type="text/javascript">
            let ganttDataArr = [];
            for(let newParntObj=1; newParntObj <=1; newParntObj++ ) {
                let ganttDataObj = {};
                ganttDataObj["id"] = newParntObj;
                ganttDataObj["text"] = "{!ParentRecord.Name}";
                ganttDataObj["start_date"] = new Date("{!ParentRecord.start_date__c}");
                ganttDataObj["duration"] = 18;
                //ganttDataObj["order"] = "10";
                ganttDataObj["progress"] = "0.6";
                ganttDataObj["open"] = true;
                ganttDataArr.push(ganttDataObj);
            }
        
            for(let newObj = ganttDataArr.length+1; newObj <= 15; ++newObj ) {
                let ganttDataObj = {};
                ganttDataObj["id"] = newObj;
                ganttDataObj["text"] = "{!ChildRecord.Name}";
                ganttDataObj["start_date"] = new Date("{!ParentRecord.start_date__c}");
                ganttDataObj["duration"] = newObj*2;
                ganttDataObj["order"] = '10';
                ganttDataObj["progress"] = newObj%2;
                ganttDataObj["parent"] = '1';
                ganttDataArr.push(ganttDataObj);
            }

            let tasks =  {
                data: ganttDataArr,
                links:[
                    { id:1, source:1, target:2, type:"1"},
                    { id:2, source:2, target:3, type:"0"},
                    { id:3, source:3, target:4, type:"0"},
                    { id:4, source:2, target:5, type:"2"},
                ]
            };
                    
            gantt.init("gantt_here");
            gantt.parse(tasks);
                    
        </script>        
    </body>
</apex:page>

Under the Parent Account, I have 15 child Accounts. The issue here is that I could able to see Parent Account Name in the chart but not Child Accounts. I am seeing only the blank values instead of proper account names. The screenshot is as follows:

Gantt

Can anyone please let me know how to display all the 15 child account names under the parent account in the chart?

1
  • Your declaration of ChildRecord needs to be a list and you need to iterate over the list
    – cropredy
    Commented Jul 1, 2021 at 15:19

1 Answer 1

0

@SFDCUser the below is a generic code which should solve your problem. Let me know if it helps!

Visualforce Page:

<apex:page controller="Account_Gantt" standardStylesheets="false" showHeader="false">
    <head>
        <apex:stylesheet value="{!URLFOR($Resource.Timeline, 'gantt/codebase/dhtmlxgantt.css')}"/>
        <apex:includeScript value="{!URLFOR($Resource.Timeline, 'gantt/codebase/dhtmlxgantt.js')}"/>
        <style type="text/css" media="screen">
            html, body { margin:0px; padding:0px; height:100%; overflow:hidden; }
        </style>
    </head>
    <body>
        <div id="gantt_here" style='width:100%; height:100%;'></div>
        <script type="text/javascript">
            let ganttDataArr = [];
            let acctResultJSON = {!strJSON}; // store the apex variable that we serialized.
            
            // iterate over all accounts that are returned by apex
            for (let key of Object.keys(acctResultJSON)) {
                let ganttDataObj = {};
                ganttDataObj["id"] = acctResultJSON[key]["Id"];
                ganttDataObj["text"] = acctResultJSON[key]["Name"];
                if (acctResultJSON[key]["Start_Date__c"] != null) {
                    ganttDataObj["start_date"] = new Date(acctResultJSON[key]["Start_Date__c"]);
                } else {
                    ganttDataObj["start_date"] = new Date();
                }
                ganttDataObj["duration"] = 18;
                ganttDataObj["progress"] = "0.6";
                ganttDataObj["open"] = true;
                
                if( acctResultJSON[key]["ChildAccounts"].totalSize > 0 ) {
                    for (let childKey = 0; childKey < acctResultJSON[key]["ChildAccounts"].totalSize; childKey++) {
                        let ganttChildDataObj = {};
                        ganttChildDataObj["id"] = acctResultJSON[key]["ChildAccounts"]["records"][childKey]["Id"];
                        ganttChildDataObj["text"] = acctResultJSON[key]["ChildAccounts"]["records"][childKey]["Name"];
                        if (acctResultJSON[key]["ChildAccounts"]["records"][childKey]["Start_Date__c"] != null) {
                            ganttChildDataObj["start_date"] = new Date(acctResultJSON[key]["ChildAccounts"]["records"][childKey]["Start_Date__c"]);
                        } else {
                            ganttChildDataObj["start_date"] = new Date();
                        }
                        ganttChildDataObj["duration"] = 18/acctResultJSON[key]["ChildAccounts"].totalSize;
                        ganttChildDataObj["order"] = '10';
                        ganttChildDataObj["progress"] = "0.6";
                        ganttChildDataObj["parent"] = acctResultJSON[key]["Id"];
                        ganttDataArr.push(ganttChildDataObj);
                    }
                }
                
                ganttDataArr.push(ganttDataObj);
            }
        
            let tasks =  {
                data: ganttDataArr,
                links:[
                    { id:1, source:1, target:2, type:"1"},
                    { id:2, source:2, target:3, type:"0"},
                    { id:3, source:3, target:4, type:"0"},
                    { id:4, source:2, target:5, type:"2"},
                ]
            };
                    
            gantt.init("gantt_here");
            gantt.parse(tasks);
                    
        </script>        
    </body>
</apex:page>

Apex controller:

public with sharing class Account_Gantt {
    public List<SObject> accountRecordsList {get; set;}
    public String strJSON {get; set;}
    public Account_Gantt() {
        AggregateResult[] accountWithChildren = [SELECT COUNT(Id) countChildren, ParentId FROM Account GROUP BY ParentId];
        Set<Id> accountIds = new Set<Id>();
        for (AggregateResult ar : accountWithChildren) {
            if( ar.get('ParentId') != null ) {
                accountIds.add( (Id)ar.get('ParentId') );
            }
        }
        accountRecordsList = [SELECT Id, Name, start_date__c, end_date__c, ParentId, (SELECT Id, Name FROM ChildAccounts) FROM Account WHERE Id IN: accountIds];
        strJSON = JSON.serialize(accountRecordsList);
    }
}

enter image description here

6
  • Here Parent and Child are from the same object. Could you please suggest an update so that this logic works for the same object lookup?
    – SFDCUser
    Commented Jul 2, 2021 at 9:21
  • The above code i posted will work for account. As you can see the code, Parent and Child are account. You don't need two separate queries, instead i used inner query. Commented Jul 2, 2021 at 9:28
  • My bad, the relationship name was wrong and now I could able to query parent and child from same object. But in the UI, I am seeing blank screen and in console, i found this error: Uncaught TypeError: Cannot read property 'totalSize' of undefined.
    – SFDCUser
    Commented Jul 2, 2021 at 9:30
  • Did you choose Parent Account field on any Account? ChildAccounts inner query pulls all Accounts which has ParentId field on Account populated, if not chosen then you will get this error. You may want to put a condition check like below if( sobjResultJSON[key]["ChildAccounts"].totalSize > 0 && "ChildAccounts" in sobjResultJSON[key] ) { to resolve the issue. Commented Jul 2, 2021 at 9:35
  • This is now working and many thanks for the code. One last help, If possible, could you please let me know how to add grandchild tasks under child tasks as layer 3. I have different dates in child account records as Live_Date__c, Test_Date__c, Process_Date__c and these dates should come as grandchild under each child. Could you please suggest on how to do so.
    – SFDCUser
    Commented Jul 2, 2021 at 11:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .