Salesforce Report, KPI Dashboard and Chart.JS




In previous post I showed how we can use Plotly in Salesofrce Lightning component.
Another powerful library for graphs is Chart.Js.

I created recently package that allow to setup KPI and view them in custom dashboard using either Plotly or Chart.JS.
The latest question I was facing is how I can include Salesforce standard reports in the KPI dashboard. 
We do know that Salesforce reports have some limitations, but still they are commonly and if there are logic that can be achieve with the standard tool we should use it.

The good thing is that Salesforce have almost

As a demo, I implemented the same example from the
The Lightning component updated to use the chart.js static resource



1
2
3
4
5
6
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" controller="PlotlyDemoController">
    <ltng:require scripts="/resource/chartJS/Chart.bundle.js" afterScriptsLoaded="{!c.scriptsLoaded}"/>
    <div style="width:600px;height:400px;">
     <canvas id="myDiv" ></canvas>
    </div>
</aura:component>

The Lightning JS controller was updated to match the chart js input



 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
({
    scriptsLoaded : function(component, event, helper) {
        var getAccountDataAction = component.get("c.getAccountData");
        
        getAccountDataAction.setParams({
            'accountId' : component.get("v.recordId")
        });
        
        getAccountDataAction.setCallback(this, function(response){
            
            var resData = JSON.parse(response.getReturnValue());
            
            
            var ctx = document.getElementById('myDiv').getContext('2d');
            var myChart = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: resData.labels,
                    datasets: [{
                        data: resData.values,
                        backgroundColor: '#1f77b4'
                    }]
                },
                options: {
                    responsive:true,
                    maintainAspectRatio: false
                }
            });
        });
        
        $A.enqueueAction(getAccountDataAction);
    }
})

And last the the apex controller was changed to read its input from standard report (+building Salesforce standard report that show the opportunity grouped by  type).



 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
public with sharing class PlotlyDemoController{  
    
    @AuraEnabled
    public static String getAccountData(String accountId){
    
        map<String, object> m_retData = new map<String, object>();
        
        map<String, decimal> m_oppType_Amt = new map<String, decimal>();
        
        Report rep = [select Id from Report where DeveloperName = 'Account_Opp_Report1'];
        
        //Run the report
        Reports.ReportResults repResult = Reports.ReportManager.runReport(rep.Id, false);
        
        //Read result and grouping property
        list<Reports.GroupingValue> l_groupingValue = repResult.getGroupingsDown().getGroupings();
        map<String,Reports.ReportFact> m_reportFact = repResult.getFactMap();

        map<String, object> m_cell_sumValue = new map<String, object>();
        
        //Store each per each uniuque cell its summary value
        for(String keyFact : m_reportFact.keyset()){
            list<Reports.SummaryValue> l_summryValues = m_reportFact.get(keyFact).getAggregates();
            String keyToUse = m_reportFact.get(keyFact).getKey().replace('!T', '');
    
            m_cell_sumValue.put(keyToUse, l_summryValues.get(0).getValue());    //*Might have several summaries. In this assume the first summary if the sum amount that we need
        }
        
        //Per each grouping label store it in the final result
        for(Reports.GroupingValue grupingItem : l_groupingValue){
            m_oppType_Amt.put(grupingItem.getLabel(), decimal.valueOf(String.valueOf(m_cell_sumValue.get(grupingItem.getKey()))));
        }        
        
        m_retData.put('labels', m_oppType_Amt.keySet());
        m_retData.put('values', m_oppType_Amt.values());
        
        return JSON.serialize(m_retData);
    }

}


Finally, this is a quick demo how I used all those items together in the KPI dashboard app.







No comments:

Post a Comment

Retire of Permission on Profiles

If you are working as a Salesforce admin/developer you've probably heard somewhere that Salesforce is planning to make a significant cha...