JavaScript Echarts柱状图Label重叠与立体化优化方案
本文针对Echarts柱状图中Label重叠及立体化展示问题提供解决方案。首先通过动态计算Y轴最大值与数据占比,调整小数值Label位置以解决重叠;其次结合普通柱状图与象形柱图,动态调整象形图大小与偏移量,实现数据长度自适应的立体效果,并解决Z轴层级导致的Label覆盖问题。
问题1
当项目数据记录较多或数值较大时,图表中常出现标签(label)相互重叠的现象,如图所示。

解决方案
针对上述问题,解决思路如下:
1、求Y轴的最大值(我们用Y轴的最大值,去计算每个柱子在整个图中的占比)
2、计算每个数据的占比
3、占比小于某个值的label,向上移动一定距离
技术实现
求Y轴的最大值
由上图可知,我们有计划值、完成值两组数据,且这两组值共用一个Y轴。

上图为观察的5组数据的值。
echarts默认分割段数为5,为了计算最大值,我们还默认为5。刚开始从网上找了一个求最大值的公式,计算后如上图的第一行,发现步长不好看,有可能还会有小数。
后来使用echarts默认的最大值,为上图第二行。
数据的最大值为上图的第三行。
最大值的步长为第四行。
默认步长为第五行。
经观察及多次试验发现步长可通过如下公式计算:
// 获取步长
const getStep = (value, count) => { // count是计算的层数
let num = Math.ceil(value / 10);
return num > 15 ? getStep(num, count + 1) : num * Math.pow(10, count);
}
// 求最大值
let stepVal = getStep(_.max(dataList) / 5, 1); // dataList - 计划值、完成值组成的数组
maxVal = stepVal * 5;计算每个数据的占比
经上步可计算出每个数据在整个图中的占比。
let planRatio = parseFloat((plan / maxVal * 100).toFixed(2)); // 计划比
let nowRatio = parseFloat((now / maxVal * 100).toFixed(2)); // 完成比移动label
通过各数据的占比,计算两者之间的差值,当差距小于n时,让该值的label向上移动。
// 移动label
data1.forEach((item, index) => {
let planRatio = parseFloat((item / maxVal * 100).toFixed(2)); // 计划比
let nowRatio = parseFloat((data2[index] / maxVal * 100).toFixed(2)); // 完成比
let nowVal;
if (data2[index] === 0) {
nowVal = data2[index];
} else { // 两个比值小于5,错落显示
nowVal = Math.abs(nowRatio - planRatio) < 4 ? {value: data2[index], label: {offset: [0, -20]}} : data2[index];
}
option.series[0].data.push(item);
option.series[1].data.push(nowVal);
})最终效果图

问题2
为了视觉上更直观,客户要求将平面柱状图改成立体柱状图,效果如下。

思路
普通柱状图(bar)+ 象形柱图(pictorialBar)

难点1
由于数据是不固定的,所以当数据量大的时候,普通柱状图的柱子宽度会自适应,而象形图的大小确是固定的,所以会出现顶部椭圆和柱子宽度不匹配的现象,如下图

解决方案
根据数据长度,动态设置象形图的大小及偏移位置。
// 不同数据长度对应不同柱子宽度
const getSymbolSize = () => {
let len = dataName.length;
switch (len) {
case 6:
return [24, 10];
case 7:
return [20, 8];
case 8:
return [18, 8];
default:
return [24, 10];
}
}
// 不同数据长度对应不同柱子偏移
const getSymbolOffset = (i) => {
let len = dataName.length;
switch (len) {
case 6:
return i === 2 ? [-12, -6] : [12, -6];
case 7:
return i === 2 ? [-11, -5] : [11, -5];
case 8:
return i == 2 ? [-9, -5] : [9, -5];
default:
return i === 2 ? [-12, -6] : [12, -6];
}
}难点2
在echarts图中,z值控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。由于象形图的z值比柱状图的z值大,所以会把柱状图的label值给覆盖了,如下图。

解决方案
将label值根据数据的大小动态的显示到柱状图或者象形图上。
PS:不可以直接显示到象形图上,因为数据值很小的情况只看到了象形图,所以不显示象形图

到此这篇关于JavaScript Echarts柱状图label优化中问题针对讲解的文章就介绍到这了,更多相关JavaScript Echarts柱状图内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
优化JS回到顶部性能:防抖节流与requestAnimationFrame应用
2026-11-05 16:33:51
JS中Array、Set与Map的区别及应用场景选择
2026-11-05 16:03:02
PixiJS 常见报错排查:纹理跨域、黑屏与内存泄漏解决
2026-11-05 10:05:21
JS数组find与filter取值区别及性能对比
2026-11-05 08:39:21
通过添加时间戳参数强制刷新JS资源
2026-11-05 08:32:36
