如何在ECharts堆叠柱状图中显示总计与百分比
解决方案
针对你提出的两个ECharts堆叠柱状图优化需求,以下是具体代码修改实现:
1. 提前计算年度总计值
首先新增计算逻辑,得到每个年份的堆叠总和,后续用于顶部标签展示和百分比计算:
const currencyFormat = new Intl.NumberFormat(undefined, { style: 'currency', currency: ledger.ccy, maximumFractionDigits: 0, }); // 新增百分比格式化器 const percentFormat = new Intl.NumberFormat(undefined, { style: 'percent', minimumFractionDigits: 2, maximumFractionDigits: 2, }); const years = helpers.iterateYears(ledger.dateFirst, ledger.dateLast); const amounts = {}; for (let query of panel.queries) { amounts[query.name] = {}; for (let row of query.result) { amounts[query.name][row.year] = -row.value[ledger.ccy]; } } // 计算每个年份的堆叠总和 const totalByYear = {}; years.forEach(year => { totalByYear[year] = panel.queries.reduce((sum, query) => { return sum + (amounts[query.name][year] ?? 0); }, 0); });
2. 实现柱状顶部显示总和
通过添加一个仅渲染标签的空柱状系列,在每个柱子顶部展示年度总计:
// 生成原系列后,追加显示总和的空系列 const series = panel.queries.map((query) => ({ type: 'bar', barWidth: '30%', name: query.name, stack: query.stack, data: years.map((year) => amounts[query.name][year] ?? 0), })).concat([{ type: 'bar', stack: panel.queries[0]?.stack, // 和其他系列共用同一堆叠组 barWidth: 0, // 隐藏柱子本体 data: years.map(year => 0), // 数据设为0,不影响堆叠高度 label: { show: true, position: 'top', formatter: (params) => currencyFormat.format(totalByYear[params.name]), fontSize: 12, fontWeight: 'bold' }, silent: true, // 禁用交互,避免干扰原系列的点击事件 }]);
3. 实现Tooltip显示数值+百分比
替换原有的valueFormatter为自定义格式化器,同时展示当前项金额和占年度总计的百分比:
return { tooltip: { formatter: (params) => { const year = params.name; const total = totalByYear[year]; const currentValue = params.value; // 处理总计为0的边界情况,避免NaN const percent = total > 0 ? currentValue / total : 0; return `${params.seriesName}<br/>${currencyFormat.format(currentValue)} (${percentFormat.format(percent)})`; }, }, xAxis: { type: 'category', data: years, axisTick: { alignWithLabel: true } }, yAxis: { axisLabel: { formatter: currencyFormat.format, }, }, series: series, onClick: (event) => { const query = panel.queries.find((q) => q.name === event.seriesName); if (query) { const link = query.link.replaceAll("#", "%23").replace("{year}", event.name); window.open(link); } }, };
关键说明
- 新增的
percentFormat确保百分比显示两位小数,符合示例中的精度要求; - 空柱状系列通过
barWidth:0隐藏视觉元素,仅保留顶部标签,silent:true避免干扰原系列的点击交互; - Tooltip格式化逻辑中处理了总计为0的边界情况,防止出现无效百分比;
- 所有计算逻辑基于原有的数据结构,无需修改查询源。
内容的提问来源于stack exchange,提问作者user4979733
相关产品推荐
相关产品推荐

