Visualizing Salesforce Standard Reports Using Chart.js, Apex, and Lightning Web Components (LWC)
Salesforce provides powerful reporting capabilities, but sometimes a visual representation of data can be more insightful. In this blog post, we’ll explore how to visualize Salesforce standard reports using Chart.js, Apex, and Lightning Web Components (LWC). We’ll leverage existing code to demonstrate fetching report data and visualizing it in an interactive format.
1. Overview of the Approach
The goal is to:
- Fetch data from Salesforce reports using an Apex class.
- Process the data in LWC.
- Visualize the data using Chart.js.
2. Setting Up the Apex Class
We'll begin by creating an Apex class to retrieve report data. This class will run a report, parse the data, and return it in a format suitable for visualization.
apexpublic class ReportParse { @AuraEnabled(cacheable=true) public static String getReportData(String reportId) { List<Object> reportData = new List<Object>(); Reports.ReportResults results = Reports.ReportManager.runReport(reportId, true); Reports.Dimension dim = results.getGroupingsDown(); Reports.GroupingValue[] groupingValues = dim.getGroupings(); if (!groupingValues.isEmpty()) { for (Reports.GroupingValue group : groupingValues) { String factMapKey = group.getKey() + '!T'; Reports.ReportFactWithDetails factDetails = (Reports.ReportFactWithDetails) results.getFactMap().get(factMapKey); Reports.SummaryValue summaryValue = factDetails.getAggregates()[0]; reportData.add(new ReportWrapper(group.getLabel(), group.getValue(), summaryValue.getLabel())); } } else { // Handle detail rows if no groupings exist } return JSON.serialize(reportData); } }
3. Creating the Lightning Web Component (LWC)
Next, we’ll build the LWC that will allow users to select a report and visualize its data using Chart.js.
3.1 HTML Template
Here’s the HTML template for the LWC:
<template>
<lightning-card title="Salesforce Report Visualization">
<div class="slds-grid slds-gutters slds-p-horizontal_large">
<div class="slds-col">
<lightning-combobox
label="Owner"
value={value}
placeholder="Select Value"
options={options}
onchange={handleChange}></lightning-combobox>
</div>
<div class="slds-col">
<lightning-combobox
label="Time"
value={value}
placeholder="Select Value"
options={option}
onchange={handleChange}></lightning-combobox>
</div>
</div>
<div class="slds-m-around_medium">
<lightning-datatable
key-field="id"
data={da}
columns={columns}>
</lightning-datatable>
</div>
<div style="display: flex; flex-wrap: wrap;">
<div style="width: 750px; margin:auto">
<c-chart type="horizontalBar" responsive="true">
<c-dataset labels={opportunities}>
<c-data label="# of Revenue" detail={Amount} backgroundcolor="rgba(50, 150, 237, 1)" bordercolor="rgba(50, 150, 237, 1)" borderwidth="1"></c-data>
</c-dataset>
<c-title text="Horizontal Chart"></c-title>
<c-legend position="bottom"></c-legend>
<c-cartesian-category-axis axis="y" position="left"></c-cartesian-category-axis>
<c-cartesian-linear-axis axis="x" ticks-beginatzero="true"></c-cartesian-linear-axis>
</c-chart>
</div>
<div style="width: 700px; margin:auto">
<c-chart type="bar" responsive="true">
<c-title text="Category"></c-title>
<c-dataset labels={stages}>
<c-data label="# of stages" detail={count} backgroundcolor='[
"rgba(82, 183, 216, 1)",
"rgba(225, 96, 50, 1)",
"rgba(255, 176, 59, 1)"
]'></c-data>
</c-dataset>
<c-cartesian-category-axis axis="x" position="bottom" title-display="true" title-labelstring="Category axis"></c-cartesian-category-axis>
<c-cartesian-linear-axis axis="y" ticks-stepsize="15" position="right" title-display="true" title-labelstring="Linear axis"></c-cartesian-linear-axis>
</c-chart>
</div>
<div style="width: 700px; margin:auto">
<c-chart type="pie" responsive="true">
<c-dataset labels={stages}>
<c-data label="# of stages" detail={count} backgroundcolor='[
"rgba(119, 185, 242, .75)",
"rgba(195, 152, 245, .75)",
"rgba(78, 211, 200, .75)"
]'></c-data>
</c-dataset>
<c-title text="Pie Chart"></c-title>
<c-legend position="right"></c-legend>
</c-chart>
</div>
</div>
</lightning-card>
</template>
4. JavaScript Controller
The JavaScript controller will fetch data from the Apex class and handle user interactions:
import { LightningElement, track, wire } from 'lwc';
import getAll from '@salesforce/apex/Opportunitycontroller.getAll';
export default class Filters extends LightningElement {
@track opportunities = [];
@track Amount = [];
@track stages = [];
@track count = [];
@track da = [];
@track columns = [
{ label: 'Opportunity Name', fieldName: 'Name', type: 'text' },
{ label: 'Amount', fieldName: 'Amount', type: 'text' },
{ label: 'Stage Name', fieldName: 'StageName', type: 'text' }
];
value = 'Owner';
@wire(getAll)
all({ data, error }) {
if (data) {
this.processData(data);
} else if (error) {
console.error(error);
}
}
processData(data) {
let keycount = {};
for (let record of data) {
this.opportunities.push(record.Name);
this.Amount.push(record.Amount);
keycount[record.StageName] = (keycount[record.StageName] || 0) + 1;
}
this.stages = Object.keys(keycount);
this.count = Object.values(keycount);
this.da = data; // Store data for the datatable
}
handleChange(event) {
this.value = event.detail.value;
// Logic to filter data based on selected value
}
}
---Wrapper---
public class columnwrapper {
string label;
string fieldName;
string type;
public columnwrapper(string label,string fieldName,string type){
this.label=label;
this.fieldName=fieldName;
this.type=type;
}
}
5. Putting It All Together
To use this setup:
- Deploy the Apex Class and LWC to your Salesforce org.
- Add the LWC to a Lightning App Page or Record Page.
- Test the Component by selecting different filters to see the charts update accordingly.
Conclusion
By combining Apex, LWC, and Chart.js, you can create a powerful visualization tool for Salesforce reports. This approach enhances data analysis and helps stakeholders make informed decisions based on visually represented data.
Comments
Post a Comment