2

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

2
+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

2
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

You must log in to answer this question.

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