Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show the sum of data values on top of stacked bar chart using Baidu ECharts

I've created a vertical stacked bar chart with Baidu ECharts.

Is it possible to show the sum of all values on top of the stack?

Edited : i have edited my example using the (very well explained) answer from @jeffrey but i get Uncaught TypeError: Cannot read property 'forEach' of undefined error. What am i doing wrong here ?

<!DOCTYPE html>
<html style="height: 100%">
   <head>
       <meta charset="utf-8">
   </head>
   <body style="height: 100%; margin: 0">
       <div id="container" style="height: 100%"></div>
       <script type="text/javascript" src="echarts-en.min.js"></script>
       <script type="text/javascript">
var     mySeries = [
            {
                name: 'Department 1',
                type: 'bar',
                stack: 'stack1',
                data: [320, 302, 301, 334, 390, 330, 320]
            },
            {
                name: 'Department 2',
                type: 'bar',
                stack: 'stack1',
                data: [120, 132, 101, 134, 90, 230, 210]
            },
            {
                name: 'Department 3',
                type: 'bar',
                stack: 'stack1',
                data: [220, 182, 191, 234, 290, 330, 310]
            },
            {
                name: 'Department 4',
                type: 'bar',
                stack: 'stack1',
                data: [150, 212, 201, 154, 190, 330, 410]
            },
            {
                name: 'Department 5',
                type: 'bar',
                stack: 'stack1',
                data: [185, 120, 55, 66, 77, 88, 40],
                label: {
                            normal: {
                                show: true,
                                position: 'top',
                                formatter: (params) => {
                                    let total = 0;
                                    this.series.forEach(serie => {
                                       total += serie.data[params.dataIndex];
                                    })
                                    return total;
                                }
                            }
                        }
            }
        ];

        var dom = document.getElementById("container");
        var myChart = echarts.init(dom);
        var option = null;

        option = {
            tooltip : {
                trigger: 'axis',
                axisPointer : {        
                    type : 'shadow'       
                }
            },
            legend: {
                data: ['Department 1', 'Department 2','Department 3','Department 4','Department 5'],
            },
            toolbox: {
                show: true,
                orient: 'vertical',
                left: 'right',
                top: 'center',
                feature: {
                    dataView: {show: false, readOnly: false},
                    magicType: {show: true, type: ['line', 'bar', 'stack', 'tiled']},
                    restore: {show: true},
                    saveAsImage: {show: true}
                }
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            yAxis:  {
                type: 'value'
            },
            xAxis: {
                type: 'category',
                data: ["Jen\n2018", "Feb\n2018", "Mar\n2018", "Apr\n2018", "May\n2018", "Jun\n2018", "Jul\n2018"]
            }
        };;

        myChart.setOption(option, true);

        myChart.setOption({
            series: mySeries
        })
        </script>
   </body>
</html> 
like image 899
fkossyvas Avatar asked Oct 15 '25 15:10

fkossyvas


1 Answers

To get a custom serie label you should use the label formatter.

When you define your series data outside of your chart object, and map it to this, you can access the data in the formatter. It is important to use the formatter, so the original label and values will not be altered (such as tooltips and legends).


First, we define your series. The formatter should be added to the last serie. This will be the serie on top of the stack, showing the label with the total value:

this.mySeries = [
    {
        name:'Dataset 1',
        type:'bar',
        stack: 'Stack 1',
        data: [120, 132, 101, 134, 90, 230, 210]
    },
    {
        name:'Dataset 2',
        type:'bar',
        stack: 'Stack 1',
        data: [220, 182, 191, 234, 290, 330, 310]
    },
    {
        name:'Dataset 3',
        type:'bar',
        stack: 'Stack 1',
        data: [820, 932, 901, 934, 1290, 1330, 1320],
        label: {
            normal: {
                show: true,
                position: 'top',
                formatter: (params) => {
                    let total = 0;
                    this.mySeries.forEach(serie => {
                       total += serie.data[params.dataIndex];
                    })
                    return total;
                }
            }
        }
    }
];

Here is the formatter again with annotations, so you can understand how this works:

label: {

    // You can choose from 'normal' (always visible )
    // and 'emphasis' (only visible on stack hover)
    normal: {

        // Enable the label
        show: true,

        // Position it on top of the stack
        position: 'top',

        // Add a label formatter
        // (params) holds all the data of the current serie and datapoint
        // You can use console.log(params) to check all available values
        formatter: (params) => {
            let total = 0;

            // Now we iterate over each of the series, and get the value of
            // the current xAxis datapoint by using the serie dataIndex
            this.mySeries.forEach(serie => {
               total += serie.data[params.dataIndex];
            })

            // The return value will be shown on top of your stack
            return total;
        }
    }
}

Now, all you have to do is map the series data to your chart object:

myChart.setOption({
    series: this.mySeries
})
like image 177
Jeffrey Roosendaal Avatar answered Oct 18 '25 03:10

Jeffrey Roosendaal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!