【问题标题】:How can I add a sum at the top of an echarts stacked bar chart [which updates based on selected series]如何在 echarts 堆积条形图顶部添加总和 [根据所选系列更新]
【发布时间】:2020-08-05 12:35:53
【问题描述】:

已经回答了关于如何在 echarts 的堆积条形图顶部添加“总计”标签的问题(例如 this one

但是,我还希望在使用图例选择/取消选择系列时重新计算此总数(包括如果我在下面的示例中取消选择附加标签的最终系列)。这可能吗?

另一个问题的示例代码:

//example data
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],
  }
];

//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'
  },
})),

【问题讨论】:

    标签: javascript echarts


    【解决方案1】:

    是的,这是可能的。您需要添加在图例中选择的系列更改时侦听的处理程序。请参阅legendselectchanged 事件。

    在您的事件处理程序中,您需要过滤选择了哪些系列并重新计算总和,然后将标签附加到最后一个系列。

    为了将 sum 标签附加到最后一个系列,您可以创建如下函数:

    const seriesHandler = series => {
        return series.map((serie, index) => {
            if (index === series.length - 1) {
                return {
                    ...serie,
                    label: {
                        normal: {
                            show: true,
                            position: 'top',
                            formatter: params => {
                                let total = 0
                                series.forEach(s => {
                                    total += s.data[params.dataIndex]
                                })
                                return total
                            }
                        }
                    }
                }
            } else {
                return serie
            }
        })
    }
    

    并像这样创建 legendselectchanged 事件处理程序:

    const handleLegendSelectChanged = (event, series) => {
        const includedSeriesNames = []
        for (const [name, value] of Object.entries(event.selected)) {
            if (value) {
                includedSeriesNames.push(name)
            }
        }
    
        const includedSeries = series.filter(serie => {
            return includedSeriesNames.includes(serie.name)
        })
    
        return seriesHandler(includedSeries)
    }
    

    基本上它过滤显示(包括)哪个系列,并将总和标签附加到最后一个系列。

    请参阅下面的完整示例:

    <!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 src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.8.0/echarts.js"
            integrity="sha512-5/8+cwsZ4fICxk706J4H0/UMZT2LKivISN26mgN86wCD4AHFvdFOBm/95z3dKLpnaHNzzwKuoBtrbKv+++SLTg=="
            crossorigin="anonymous"></script>
        <script type="text/javascript">
            const 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],
                }
            ];
    
            const seriesHandler = series => {
                return series.map((serie, index) => {
                    if (index === series.length - 1) {
                        return {
                            ...serie,
                            label: {
                                normal: {
                                    show: true,
                                    position: 'top',
                                    formatter: params => {
                                        let total = 0
                                        series.forEach(s => {
                                            total += s.data[params.dataIndex]
                                        })
                                        return total
                                    }
                                }
                            }
                        }
                    } else {
                        return serie
                    }
                })
            }
    
            const handleLegendSelectChanged = (event, series) => {
                const includedSeriesNames = []
                for (const [name, value] of Object.entries(event.selected)) {
                    if (value) {
                        includedSeriesNames.push(name)
                    }
                }
    
                const includedSeries = series.filter(serie => {
                    return includedSeriesNames.includes(serie.name)
                })
    
                return seriesHandler(includedSeries)
            }
    
            const dom = document.getElementById("container");
            const myChart = echarts.init(dom);
    
            const option = {
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'shadow'
                    }
                },
                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"]
                },
                legend: {
                    data: ['Dataset 1', 'Dataset 2', 'Dataset 3']
                },
            };;
    
            myChart.setOption({
                ...option,
                series: seriesHandler(mySeries)
            })
    
            myChart.on('legendselectchanged', event => {
                myChart.setOption({
                    series: handleLegendSelectChanged(event, mySeries)
                })
            })
        </script>
    </body>
    
    </html>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      • 2023-02-21
      • 1970-01-01
      • 1970-01-01
      • 2020-09-14
      相关资源
      最近更新 更多