1

I am trying to use chartjs-plugin-datalabels plugin to display labels on a bar chart in LWC. ChartJS version is 2.80. I loaded the plugin as below and registered the plugin as specified in the documentation. However, the data labels are not loaded.

import { LightningElement, api, wire, track } from 'lwc';
import getSpendings from '@salesforce/apex/ClassName.getSpendings';
import chartjs from '@salesforce/resourceUrl/chartjs_v280';
import ChartDataLabels1 from '@salesforce/resourceUrl/ChartjsPluginDataLabels';
import { loadScript } from 'lightning/platformResourceLoader';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class AwTopVendorSpend extends LightningElement {
    @api customerId;
    @api months;
    @track thisMonth;
    @track lastMonth;
    @track previousMonth;

     // getters and setters becuase the users can select a month from the html to view that month's data
    _selectedMonthNumber
    @api 
    get selectedMonthNumber(){
        return this._selectedMonthNumber;
    }
    set selectedMonthNumber(value){

        this._selectedMonthNumber = value;
        switch (value) {
            case 1:
                this.thisMonth = 'Jan';
                this.lastMonth = 'Dec';
                this.previousMonth = 'Nov';
                break;
            case 2:
                this.thisMonth = 'Feb';
                this.lastMonth = 'Nov';
                this.previousMonth = 'Dec';
                break;
            default:
                this.thisMonth = this.months[value-1];
                this.lastMonth = this.months[value-2];
                this.previousMonth = this.months[value-3];
                break;
        }
    }

    
    @track labels=[];
    @track secondLastMonthSpend = [];
    @track lastMonthSpend = [];
    @track currentMonthSpend = [];

    isChartJsInitialized;

    renderedCallback() {
        if (this.isChartJsInitialized) {
            return;
        }
        // load chartjs, ChartDataLabels from the static resource
        Promise.all([
            loadScript(this, chartjs),
            loadScript(this, ChartDataLabels1)
        ])
        .then(() => {
            this.isChartJsInitialized = true;
        })
        .catch(error => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error loading Chart',
                    message: error.message,
                    variant: 'error',
                })
            );
        });
    }


    //Getting spendings
    @wire(getSpendings, { accountId : '$customerId', selectedMonth : '$_selectedMonthNumber'})
    wiredSpendings({ error, data }) {
        if (data) {
            
            let spendings = JSON.parse(data);
            this.labels = Object.keys(spendings);

            let vendorSpendMap = spendings;
            this.secondLastMonthSpend = [];
            this.lastMonthSpend = [];
            this.currentMonthSpend = [];


            this.labels.forEach(item => {
                let spends = vendorSpendMap[item];
                this.secondLastMonthSpend.push(spends[0]);
                this.lastMonthSpend.push(spends[1]);
                this.currentMonthSpend.push(spends[2]);
            });
            this.Initializechart();
        } else if (error) {
            console.error('Error in getting spending details', error);
        }
    }


    Initializechart(){


        var piechart;
        var ctx = this.template.querySelector(".bar-chart").getContext('2d');


        piechart = new Chart(ctx, {
            
            type: 'bar',
            data: {
                labels: this.labels,
                datasets: [{
                    label: this.previousMonth,
                    backgroundColor: '#A9C5E5',
                    data: this.secondLastMonthSpend
                }, {
                    label: this.lastMonth,
                    backgroundColor: '#9E54F3',
                    data: this.lastMonthSpend
                }, {
                    label: this.thisMonth,
                    backgroundColor: "#3196EB",
                    data: this.currentMonthSpend
                }]
            },
            plugins: [ChartDataLabels], //registring plugin
            options: {
                responsive: true,
                legend: {
                    position: 'bottom'
                }
            }
        });
    }
}

Sample response from the class looks like below

spendings = {
    'Amazon':  [1800, 2300, 2020],
    'Apple':  [1500, 3000, 2000],
    'Google':  [500, 300, 800],
    'Microsoft':  [500, 800, 6100]
}

And on the html, I can see the chart but without the labels. Both chartJS and the plugin codes are uploaded as static resources.

Chart js bar chart output in lwc

UPDATE

I moved the position of 'plugins: [ChartDataLabels]' to just before 'options' as mentioned in the documentation. Now I see an error in the console. I am clueless as the function 'getDataVisibility' is not present in the version 2.8.0 if Chart.JS.

enter image description here

2 Answers 2

1
+50

Downloading chartjs-plugin-datalabels from https://github.com/chartjs/chartjs-plugin-datalabels/tags ...

Firstly, downloading v1.0.0. "chartjs-plugin-datalabels.js" and searching the file for "getDataVisibility" as shown on your screenshot - it's nowhere.

Secondly, downloading v2.0.0 "chartjs-plugin-datalabels.js" and looking at line 1259 as pointed out in your screenshot, I see the malicious call to getDataVisibility, right in afterDatasetUpdate.

As you pointed out in the comment, the correct version is v1.0.0. It's just not linked up on the chartjs-plugin-datalabels page for this version very intuitively...

I've just gave your component code a try with the v1.0.0 and it works :-) I've added the following section under "legend" to verify I can manipulate "something" with genuine plugin means:

plugins: {
    datalabels: {
        color: "orange",
        labels: {
            title: {
                font: {
                    weight: "bold"
                }
            }
        }
    }
}

Here's some "Orange":

screenshot

0

There is an official plugin for Chart.js 2.7.0+ to do this: Datalabels

Otherwise, you can loop through the points / bars onAnimationComplete and display the values

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.