使用百度 ECharts 在堆积条形图顶部显示数据值的总和

Posted

技术标签:

【中文标题】使用百度 ECharts 在堆积条形图顶部显示数据值的总和【英文标题】:Show the sum of data values on top of stacked bar chart using Baidu ECharts 【发布时间】:2018-03-05 15:57:38 【问题描述】:

我用Baidu ECharts 创建了一个垂直的stacked bar chart。

是否可以在栈顶显示所有值的sum

编辑: 我已经使用@jeffrey 的(很好解释的)答案编辑了我的示例,但我得到 Uncaught TypeError: Cannot read property 'forEach' of undefined 错误。我在这里做错了什么?

<!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> 

【问题讨论】:

您收到错误,因为您创建了var mySeries,但在格式化程序中,您使用this.mySeries 引用它,因此它是undefined @Jeffrey :即使我将其定义为this.mySeries,它也不起作用。我做了一个 jsfiddle 在这里测试它:link 我检查了,我犯了一个错误(对不起!)。 forEach 应该是this.mySeries.forEach()。 Now your fiddle works :) 是的!谢谢@Jeffrey 的解决方案!很抱歉,我认为我无法将此解决方案标记为 OK,因为我的声誉少于 15 :-( @fkossyvas 接受答案没有信誉阈值。询问后您需要等待 15 分钟,仅此而已。见How does accepting an answer work? 【参考方案1】:

要获得自定义serie label,您应该使用label formatter。

当您在图表对象外部定义系列数据并将其映射到this 时,您可以访问格式化程序中的数据。使用格式化程序很重要,因此原始标签和值不会被更改(例如工具提示和图例)。


首先,我们定义您的系列。格式化程序应该添加到 last 系列中。这将是堆栈顶部的系列,显示带有总值的标签:

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;
                
            
        
    
];

这里又是带有注释的格式化程序,所以你可以理解它是如何工作的:

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;
        
    


现在,您只需将系列数据映射到图表对象:

myChart.setOption(
    series: this.mySeries
)

【讨论】:

一个系列可以有2个标签吗?在同一个示例中,在系列中心和第三个数据集上有标签;一个在中心,另一个在顶部【参考方案2】:

请看这个答案,它对我帮助很大,而且我在代码中做了一点简化,没有什么相关的。我发现解释更容易。基本上你会在标签内使用 formatter 属性,并带有一些规范

系列示例

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,
,

];

格式化函数

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

;

在你的图表选项中放置这个

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

与其他答案非常相似,但我发现代码更容易理解。

【讨论】:

以上是关于使用百度 ECharts 在堆积条形图顶部显示数据值的总和的主要内容,如果未能解决你的问题,请参考以下文章

重叠条形图 apache echarts 百度

在 ggplot2 中的堆积条形图上显示数据值

在 ggplot2 中的堆积条形图上显示数据值

在Seaborn中绘制堆积条形图以显示聚类[重复]

使用 C++ 使用 openGL 以图形方式表示堆积条形图

用于循环的php数组管理显示堆积的条形图