Recently i have worked with a POC to display barchart using chart.js in lightning web component.
Use Case
For an an energy utility company , display electric usage information for an customer during notified outage (Event). Usage basically the actual consumption of electric kilo watt(KW) value on every 15 mins interval.
X Axis will display : 15 mins interval Time
Y Axis will display : Usage(KW)
Let's talk about how to implement it..?
Source Code:
As a prerequisite we would need chart.js framework to be loaded as static resource , download the the latest version from https://github.com/chartjs/Chart.js and upload as zip.
Now create the component called "barChartDemo"
barChartDemo.html :
barChartDemo.js :
Apex Class :
Code Explanation :
In the JavaScript class file, you need to include below two imports to access the functionality of the third-party JavaScript library.
Use Case
For an an energy utility company , display electric usage information for an customer during notified outage (Event). Usage basically the actual consumption of electric kilo watt(KW) value on every 15 mins interval.
Bar-chart should present the usage data of the customer for the event day where 15-minute interval data (kW) to be presented in the chart .
Y Axis will display : Usage(KW)
Color coding:
- The event intervals to be shaded in blue if the demand is below FSL(Target Threshold)
- The event intervals to be shaded in red if the demand is above FSL
Let's talk about how to implement it..?
Source Code:
As a prerequisite we would need chart.js framework to be loaded as static resource , download the the latest version from https://github.com/chartjs/Chart.js and upload as zip.
Now create the component called "barChartDemo"
barChartDemo.html :
1 2 3 4 5 | <template> <div class ='slds-box slds-theme_default custom-background' > <canvas class="chart" width="200" height="100" lwc:dom="manual"></canvas> </div> </template> |
barChartDemo.js :
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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | /** * @File Name : barChartDemo.js * @Description : dynamic bar chart to display usage data on 15 mins interval * @Author : Swarup satpati * @Modification Log : * Ver Date Author Modification * 1.0 7/2/2020 swarup satpati demo Version **/ import { LightningElement, track, wire,api } from 'lwc'; /*chart.js library*/ import chartjs from '@salesforce/resourceUrl/ChartJsBIP'; import plugins from '@salesforce/resourceUrl/chartjsannotation'; /*To import third-party JavaScript or CSS library, use the platformResourceLoader module.*/ import { loadScript, loadStyle } from 'lightning/platformResourceLoader'; import { ShowToastEvent } from 'lightning/platformShowToastEvent'; import getusage from '@salesforce/apex/UsageData.getUsageData' export default class BarChartDemo extends LightningElement { @api eventname='Event-011166'; @api said='1449702025'; @api eventstarttime; @api eventendtime; @api chartData; @api Data @track fslvalue=75; @track starttime; @track endtime; @api label=[]; @api usage=[]; error; @api chart; chartjsInitialized = false; renderedCallback() { this.init(); console.log('initialized...'+this.chartjsInitialized); if (this.chartjsInitialized) { return; } this.chartjsInitialized = true; } init(){ getusage({ EventName:this.eventname, SAID:this.said}) .then(data => { console.log('****data***'+JSON.stringify(data)); for(let key in data) { //console.log('label.. data'+JSON.stringify(data[key].label)); this.label.push(data[key].label); this.usage.push(data[key].usagekw); } console.log('usage..'+JSON.stringify(this.usage)); console.log('label..'+JSON.stringify(this.label)); Promise.all([ loadScript(this, chartjs + '/Chart.min.js'), loadStyle(this, chartjs + '/Chart.min.css'), loadStyle(this, plugins + '/chartjs-plugin-annotation.min.js'), loadStyle(this, plugins + '/chartjs-plugin-annotation.js') ]) .then(() => { // disable Chart.js CSS injection console.log('draw chart..'+JSON.stringify(this.usage)); window.Chart.platform.disableCSSInjection = true; this.chartjsInitialized = true; this.diaplayChart(); } ) .catch((error) => { this.error = error; }); }) .catch(error => { console.log('The error ', error); }); } diaplayChart(){ var chartColors = { red: 'rgb(255, 99, 132)', blue: 'rgb(54, 162, 235)' }; var horizonalLinePlugin = { afterDraw: function(chartInstance) { var yScale = chartInstance.scales["y-axis-0"]; var canvas = chartInstance.chart; var ctx = canvas.ctx; var index; var line; var style; var yValue; if (chartInstance.options.horizontalLine) { for (index = 0; index < chartInstance.options.horizontalLine.length; index++) { line = chartInstance.options.horizontalLine[index]; if (!line.style) { style = " (169,169,169, .6)"; } else { style = line.style; } if (line.y) { yValue = yScale.getPixelForValue(line.y); } else { yValue = 0; } ctx.lineWidth = 1; if (yValue) { ctx.beginPath(); ctx.moveTo(0, yValue); ctx.lineTo(canvas.width, yValue); ctx.strokeStyle = style; ctx.stroke(); } if (line.text) { ctx.fillStyle = style; ctx.fillText(line.text, 0, yValue + ctx.lineWidth); } } return; }; } }; Chart.pluginService.register(horizonalLinePlugin); console.log('usage kw..>>'+JSON.stringify(this.usage)); console.log('label..>>'+JSON.stringify(this.label)); var ctx = this.template.querySelector(".chart"); var lineChart = new Chart(ctx, { type: 'bar', data: { labels: this.label, datasets: [{ label: 'KW', backgroundColor: [], data: this.usage, borderColor: 'rgba(121, 159, 222, 1)', fill: true, pointBackgroundColor: "#26B99A", pointBorderWidth: 2, pointHoverRadius: 5, pointRadius: 2, bezierCurve: true, pointHitRadius: 10 }] }, options: { legend: { position: 'top', padding: 10, }, animation: { //animateScale: true, //animateRotate: true, duration:0 }, scales: { yAxes: [{ scaleLabel: { display: true, labelString: 'Usage(kW)' } }], xAxes: [{ scaleLabel: { display: true, labelString: 'Timing' } }] }, "horizontalLine": [{ "y": this.fslvalue, "style":"rgba(30,139,195,0.5)", "text": "FSL(KW)" }], responsive: true } }); console.log('chart update..'); var dataset = lineChart.data.datasets[0]; for (var i = 0; i < dataset.data.length; i++) { console.log('value..'+dataset.data[i]); if (dataset.data[i] > this.fslvalue) { //lineChart.data.datasets[0].backgroundColor[i] = chartColors.red; dataset.backgroundColor[i] = chartColors.red; } else{ console.log('in else...'); dataset.backgroundColor[i] = chartColors.blue; //lineChart.data.datasets[0].backgroundColor.push('rgb(54, 162, 235)'); console.log('in else...'); } } lineChart.update(); } } |
Apex Class :
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 | public with sharing class UsageData { @AuraEnabled public static List<DataSet> getUsageData(String EventName,String SAID){ List<Dataset> dataset=new List<dataset>(); DRMI_BIP_Compliance_Report__c CMReport= [ SELECT Id, SA_ID__c, Event_Name__c,isApproved__c,Event_Date__c,Event_KWh__c,Rep_Name__c,Load_Zone__c, Rep_Phone__c, Address__c, City__c, Name,Excess_Energy_Charge__c,FSL_ComplianceReport__c,Firm_Service_Level__c,Total_excess_energy_charge_c__c,Subject_to_Retest__c,Excess_enregy_in_kw__c,(SELECT id, Usage_Data_in_Kw__c,Hour_Ending__c ,Time_Ending__c from DRMI_BIP_Compliance_Report_Usage__r order by Time_Ending__c),(SELECT id ,Charges__c,Incentives__c,Month_Year__c from DRMI_BIP_Compliance_Report_Summary__r ) FROM DRMI_BIP_Compliance_Report__c where Event_Name__c=:EventName and SA_ID__c=:SAID limit 1 ]; for(DRMI_BIP_Compliance_Report_Usage__c usageRow: CMReport.DRMI_BIP_Compliance_Report_Usage__r){ String Tm=usageRow.Hour_Ending__c; decimal kw=usageRow.Usage_Data_in_Kw__c; dataSet.add(new DataSet(Tm ,kw)); } return dataset; } public class DataSet{ public DataSet(String label ,decimal usagekw){ this.label = label ; this.usagekw = usagekw ; } @AuraEnabled public String label {get;set;} @AuraEnabled public decimal usagekw {get;set;} } } |
Code Explanation :
In the JavaScript class file, you need to include below two imports to access the functionality of the third-party JavaScript library.
1 2 3 4 5 | /*chart.js library*/ import chartjs from '@salesforce/resourceUrl/ChartJsBIP'; import plugins from '@salesforce/resourceUrl/chartjsannotation'; /*To import third-party JavaScript or CSS library, use the platformResourceLoader module.*/ import { loadScript, loadStyle } from 'lightning/platformResourceLoader'; |
The loadScript module is used to load the JavaScript file. The method returns a JavaScript promise which you need to resolve in your code. Below is an example of how to use the loadScript method:
1 2 3 4 5 6 7 8 9 10 11 12 13 | Promise.all([ loadScript(this, chartjs + '/Chart.min.js'), loadStyle(this, chartjs + '/Chart.min.css'), loadStyle(this, plugins + '/chartjs-plugin-annotation.min.js'), loadStyle(this, plugins + '/chartjs-plugin-annotation.js') ]) .then(() => { // disable Chart.js CSS injection console.log('draw chart..'+JSON.stringify(this.usage)); window.Chart.platform.disableCSSInjection = true; this.chartjsInitialized = true; this.diaplayChart(); } ) |
For horizontal Line i have registered "horizonalLinePlugin "to draw the reference line in the bar chart.
Hope you are enjoying my post !
Output :
This is just an example to demonstrate how to use chart.js in advanced level .Happy Coding !!