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

[亡魂溺海] 提交于 2019-12-11 18:16:53

问题


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> 

回答1:


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
})



回答2:


Please see this answer, it helped me a lot, and I did a little simplification in the code, nothing relevant. I found the explanation easier. Basically you will use the formatter attribute inside the label, with some specifications

serie example

let series = [
{
    name: 'Reclamação',
    data: this.relatos_tipo_y.R,
},
{
    name: 'Elogio',
    data: this.relatos_tipo_y.E,
},
{
    name: 'Sugestão',
    data: this.relatos_tipo_y.S,
},
{
    name: 'Denúncia',
    data: this.relatos_tipo_y.D,
},

];

function for formatter

genFormatter = (series) => {
return (param) => {
    console.log(param);
    let sum = 0;
    series.forEach(item => {
        sum += item.data[param.dataIndex];
    });
    return sum
}

};

inside your chart options place this

series: series.map((item, index) => Object.assign(item, {
     type: 'bar',
     stack: true,
     label: {
         show: index === series.length - 1,
         formatter: genFormatter(series),
         fontSize: 20,
         color: 'black',
         position: 'top'
     },
})),

Click Here

It's very similar to the other answer, but I find it easier to understand the code.



来源:https://stackoverflow.com/questions/49114475/show-the-sum-of-data-values-on-top-of-stacked-bar-chart-using-baidu-echarts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!