1. 问题呈现
场景描述:上图是一个实现的堆叠柱状图,测试发现点击图例时,存在以下问题:
1)因为label放在最后一类用formatter函数处理作为数据总和展示,所以当取消最后一类对应的图例时,它的label也会一起隐藏,页面上数据总和消失。
css
series: [
{...},
{...},
{
type: 'bar',
data: lowCount,
name: '低危',
stack: '总和',
itemStyle: { color: '#91cc75' },
label: {
show: true,
position: 'top',
color: '#57606f',
fontWeight: 'bold',
formatter: function(params) {
return dataValueList[params.dataIndex]; // dataValueList 固定的每列总和数组
}
}
}
]
2)因为数据总和不是动态计算的,所以当取消有数据的图例时,左侧刻度轴和柱状图发生变化,但页面上展示的是每列全部数据总和,而不是剩余图例的列数据总和。
2. 实现动态显示
思路 :绑定echats的图例的legendselectchanged
事件,每次图例change都重新计算数据的总和。
kotlin
const option = { ...... };
// 获取配置中的series数组
var series = option["series"];
// 第一次使用
var fun = function (params) {
var datavalue = 0;
for (var i = 0; i < series.length; i++) {
datavalue += series[i].data[params.dataIndex];
}
// 返回总数
return datavalue;
}
// 赋值最后一项的formatter
series[series.length - 1]["label"]["formatter"] = fun;
myChart.setOption(option);
除了动态计算每一列数据总和,还需要注意其它更改。因为上述问题中取消最后一类图例时导致label消失,所以初始需要给每一类对象都加上label,控制label的显隐来在效果上实现需求。
1)series数组中的每一项都要添加label
。默认给最上层的数据label的show为true,其他为false(如果没有初始值,后面点击图例时label更新不上)。
2)通过legendselectchanged
事件,可以监听到图例变化时已勾选的图例list,利用已勾选的图例,判断哪一类数据需要展示label,哪些不展示label。
3)legendselectchanged事件处理数据之后,重新setOption
,更新视图。
ini
// 监听图例点击事件
myChart.on('legendselectchanged', function(obj) {
// 获取点击的对象
console.log('obj.selected', obj);
var selObj = obj.selected;
var selArr = [];
for (var key in selObj) {
if (selObj[key]) {
for (var i = 0, l = series.length; i < l; i++) {
var changename = series[i]['name'];
if (changename == key) {
selArr.push(i);
}
}
}
}
console.log('selObj----selArr', selObj, selArr);
// 动态计算剩余图例的列数据总和
var fun = function(params) {
var datavalue = 0;
// 与name数组对比,相等则相加
for (let i = 0; i < selArr.length; i++) {
for (let j = 0; j < series.length; j++) {
if (selArr[i] == j) {
datavalue += series[j].data[params.dataIndex];
}
}
}
return datavalue;
};
// 先把每一项的label置为 fales
for (let j = 0; j < series.length; j++) {
series[j]['label']['show'] = false;
}
// 动态选取最上层那一项展示label,其它不展示,解决只有最后一项有label取消了label消失问题
for (let k = series.length - 1; k >= 0; k--) {
var name = series[k]['name'];
console.log('----name', name);
if (obj['selected'][name]) {
series[k]['label']['formatter'] = fun;
series[k]['label']['show'] = true;
break;
}
}
// this.$nextTick(() => {
// myChart.setOption(option);
// });
myChart.setOption(option);
});
实现效果展示: