Chart.Js how to hide datapoints with "0" value in Stacked Bar Chart

Viewed 620

I want to hide some bars that dont have a useful value ("0") but I am not sure about how to do it, since I cannot use any Chart.Js plugins and I cannot just hide the whole Dataset since I am using a SQL Table to get the Values "into" Chart.Js.

I would like to hide the 0-Values on the chart

Note: I only want to hide the Value not the whole bar itself.

    //coloring the bars from light blue (receiverColor) to dark blue (performancePayColor)
    var receiverColor = "#7ec0ee";
    var timeWageColor = "#368DD6";
    var performancePayColor = "#214B7D";

    //removing of chart when openening a new OE
    // var chartContainer = document.getElementById('chartContainer');
    // chartContainer.innerHTML = "";

    for (var x = 0; x < charts.length; x++) {
        var chartData = charts[x];

        var sumChartValues = [];

        //adding up the Arrays
        for (var i = 0; i < chartData.GE.length; i++) {
            sumChartValues.push(chartData.GE[i] + chartData.LL[i] + chartData.ZL[i]);
        }

        //creating a TempChart canvas with same values as chart1 to be able to delete Chart1 canvas
        var chart = document.createElement("canvas");
        chart.id = "Chart" + x;

        //make the Charts responsive
        var width = $(window).width(); 
        var paddingL; //= 0;
        var paddingR; //= 0;

        if (width >= 2560) {
           // chart.height = height / 2.2;
            chart.width = width / 2.2;
            paddingL = 25;
            paddingR = 25;
        }
            else if (width >= 1440) {
               // chart.height = height / 2.2;
                chart.width = width / 2.2;
                paddingL = 25;
                paddingR = 25;
            }

            else if (width >= 1024) {
               // chart.height = height / 2.2;
                chart.width = width / 2.5;
                paddingL = 20;
                paddingR = 20;
            }

            else if (width >= 768) {
               // chart.height = height / 2;
                chart.width = width / 1.25;
                paddingL = 30;
                paddingR = 30;
            }

            else {
                //chart.height = height;
                chart.width = width / 1.25;
            } 
        
        document.getElementById("chartContainer").appendChild(chart);

        //var originalOnClick = Chart.defaults.global.legend.onClick;

        new Chart("Chart" + x, {
            //barchart is what we use normally, change type if something else is needed.
            type: "bar",

            data: {
                //labels is for the Values of the first x-Axis (we normally use KW)
                labels: chartData.KW,

                //datasets are the Bars that are displayed on the charts (each Dataset is one different Bar part a.e. a different color and value on one bar and KW)
                datasets: [
                    {
                        label: "Leistungslohn",
                        backgroundColor: performancePayColor,
                        data: chartData.LL,
                        xAxesID: "lowerXAxis",
                    },

                    {
                        label: "Zeitlohn",
                        backgroundColor: timeWageColor,
                        data: chartData.ZL,
                        xAxesID: "lowerXAxis"
                    },
                    {
                        label: "Gehaltsempfänger",
                        backgroundColor: receiverColor,
                        data: chartData.GE,
                        xAxesID: "lowerXAxis"
                    }]
            },
            options: {
                //Set the Chart responsive
                maintainAspectRatio: true,
                responsive: false,

                layout: {
                    padding: {
                        left: paddingL,
                        right: paddingR
                    }
                },

                //Dynamic Chart title display on top of the Legend
                title: {
                    size: '200',
                    display: true,
                    text: chartData.O_Long[0] + ' (' + chartData.O_Short[0] + ')',
                },
                //Enables legend Over the bars (Leistungslohn, Zeitlohn and Gehaltsempfänger)
                legend: {
                    display: true,
                    position: 'bottom'
                },
                //Enables tooltips when hovering over bars
                tooltips: {
                    enabled: true
                },

                hover: {
                    //disables number flickering when moving mouse across bars
                    animationDuration: 0,
                    //disables hover effect (change of bar color when hovering over a bar)
                    mode: null
                },

                animation: {
                    //duration = build up time for the chart in ms, 0 = no visible animation.
                    duration: 0,
                    onComplete: function () {
                        //Shows bar values on top of each bar and Formats them
                        var ctx = this.chart.ctx;
                        var legendItems = this.chart.legend.legendItems;
                        var max = this.chart.scales['y-axis-0'].max;
                        ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'bold', Chart.defaults.global.defaultFontFamily);
                        //coloring the values white
                        ctx.fillStyle = this.chart.config.options.defaultFontColor = "#FFF";
                        ctx.textAlign = 'center';
                        ctx.textBaseline = 'middle';

                        //Calculation of the required scale
                        var chartHeight = this.height;
                        this.data.datasets.forEach(function (dataset) {
                            var index = -1;
                            for (var i = 0; i < legendItems.length; i++) {
                                if (legendItems[i].text == dataset.label && !legendItems[i].hidden) {
                                    index = i;
                                    break;
                                }
                            }
                            if (index != -1) {
                                for (var i = 0; i < dataset.data.length; i++) {
                                    var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
                                    ctx.fillText(dataset.data[i], model.x, model.y + (dataset.data[i] / max * ((chartHeight / 2) - 50)));
                                }
                            }
                        })

                        //hide zero values

                    },
                },
                scales: {
                    xAxes: [{
                        //Stacks mutliple Datasets on top of each other
                        ID: "lowerXAxis",
                        stacked: true,
                        gridLines: {
                            //removes x-Axes grid lines
                            display: false
                        }
                    },
                    //Second x-Axes:
                    {
                        ID: "upperXAxis",
                        position: "top",
                        offset: true,
                        gridLines: {
                            //removes x-Axes grid lines
                            display: false
                        }
                    }],

                    yAxes: [{
                        //Stacks mutliple Datasets on top of each other
                        stacked: true,
                        scaleLabel: {
                            offset: true,
                            display: true,
                            labelString: 'Anzahl Personen',
                        },
                        ticks: {
                            //Makes the chart start at 0 to prevent negative values and to prevent formatting errors
                            beginAtZero: true,
                        }
                    }]
                }
            }
        });
    }
}```
1 Answers

Inside the options.animation.onComplete callback function, you draw the text using ctx.fillText(...). Simply don't draw the text in case the value is zero.

To do so, you should add an if statement as follows:

if (dataset.data[i] > 0) {
  ctx.fillText(dataset.data[i], model.x, model.y + (dataset.data[i] / max * ((chartHeight / 2) - 50)));
}

In case the values are defined as strings as your question could suggest, the if statement may have to be changed slightly (i.e if (dataset.data[i] != '0') {).

Related