echarts在使用中往往会遇到需要展示总量信息的情况,比较典型的就是3维统计的堆叠柱状图
堆叠是在柱状图的基础上,给几项设置同一stack来实现的。不考虑在tips中实现总和,有两种方式可以实现总和显示。
第一种:
原理:在原本堆叠的柱状图基础上,再堆叠一项,其值是各项之和。显然,这样就会变成多出一个与下边高度相等的柱形。然后我们设置这一项的label的position为insideBotton(如果是左右横向分布则是insideLeft),这样总量就显示在了原始项的顶部。最后,我们设置总和项的颜色透明(rgba(128, 128, 128, 0))即可。
优化:该方法会把原先的坐标给拉长两倍,即会有一半的区域是空白的没有图像的。比如,原先的总和是100,现在再加上一个100,就是一共200的刻度了。可以使用缩进,使图表整体向上(横向则是向右)缩进50%。对应的设置项是
grid: { left: "3%", right: "8%", bottom: "3%", containLabel: true }
第二种:
原理:在原本堆叠的柱状图的旁边,再起一个总和的柱形,显然这个柱形和原本的柱形的高度是相同的,然后我们将其平移(barGap: '-100%'),使其与原本的柱形重合,这样,最终的效果就是一个柱形了,高度也不会加倍。
优化:对于echarts的渲染,我们知道,是根据配置项绘制的canvas,而绘制的顺序就是我们代码书写的顺序。也就是说,如果我们将总和放在后边,那么就会是总和的柱形覆盖原本的柱形,原本柱形的颜色就看不到了。解决办法有2个:
1.将总和放在前边绘制,使用堆叠来覆盖总和的柱形;
2.总和在后边,设置总和的柱形的颜色为透明(同第一种方法中的设置)。
除此之外,对于总和文字的显示,如果我们设置显示在外部,那么就可能会出现超出可见区域的现象,处理方法同第一种方案中,调整grid。另外,对于总和的label和原始数据的label,要设置不同的position来避免重叠。如果想要总和看起来明显一些,可以给总和的柱形添加一个border。对于数据个数比较多又容易出现0导致重叠的问题,可以采用下边的0不显示或者如果position已经没办法比较重叠时,可以使用拼接换行符、值先按比例放大以扩大图形争取到空间,在显示文字的时候再按同比例缩小以争取现在来解决。
附完整的option代码:
1 let option = { 2 title: { 3 text: "当阳各学校招生情况", 4 subtext: "" 5 }, 6 tooltip: { 7 trigger: "axis", 8 axisPointer: { 9 type: "shadow" 10 } 11 }, 12 legend: { 13 data: ["军人", "房产", "户口", "经商", "务工"] 14 }, 15 grid: { 16 left: "3%", 17 right: "8%", 18 bottom: "3%", 19 containLabel: true 20 }, 21 xAxis: { 22 type: "value", 23 minInterval: 1 24 }, 25 yAxis: { 26 type: "category", 27 data: [] 28 }, 29 series: [ 30 { 31 name: "军人", 32 type: "bar", 33 stack: '总量', 34 data: [], 35 label: { 36 normal: { 37 show: true, 38 position: 'insideLeft', 39 formatter: function(v) { 40 return v.value || "" 41 } 42 } 43 }, 44 itemStyle: { 45 normal: { 46 color: 'red' 47 } 48 } 49 }, 50 { 51 name: "房产", 52 type: "bar", 53 stack: '总量', 54 //barWidth: "50px", 55 data: [], 56 label: { 57 normal: { 58 show: true, 59 position: 'insideLeft', 60 formatter: function(v) { 61 return v.value || "" 62 } 63 } 64 }, 65 itemStyle: { 66 normal: { 67 color: 'orange' 68 } 69 } 70 }, 71 { 72 name: "户口", 73 type: "bar", 74 stack: '总量', 75 data: [], 76 label: { 77 normal: { 78 show: true, 79 position: 'insideLeft', 80 formatter: function(v) { 81 return v.value || "" 82 } 83 } 84 }, 85 itemStyle: { 86 normal: { 87 color: 'yellowgreen' 88 } 89 } 90 }, 91 { 92 name: "经商", 93 type: "bar", 94 stack: '总量', 95 data: [], 96 label: { 97 normal: { 98 show: true, 99 position: 'insideLeft', 100 formatter: function(v) { 101 return v.value || "" 102 } 103 } 104 }, 105 itemStyle: { 106 normal: { 107 color: 'green' 108 } 109 } 110 }, 111 { 112 name: "务工", 113 type: "bar", 114 stack: '总量', 115 data: [], 116 label: { 117 normal: { 118 show: true, 119 position: 'insideLeft', 120 formatter: function(v) { 121 return v.value || "" 122 } 123 } 124 }, 125 itemStyle: { 126 normal: { 127 color: 'cornflowerblue' 128 } 129 } 130 }, 131 { 132 name: '总计', 133 type: 'bar', 134 stack: '总计', 135 barGap: '-100%', 136 label: { 137 normal: { 138 show: true, 139 position: 'right', 140 textStyle: { color: '#000' }, 141 formatter: function(v) { 142 return "总计:" + (v.value) 143 } 144 } 145 }, 146 itemStyle: { 147 normal: { 148 color: 'rgba(128, 128, 128, 0)', 149 borderWidth: 1, 150 borderColor: '#1FBCD2' 151 } 152 }, 153 data: [] 154 } 155 ] 156 };
其中
v.value || ""
是为了避免数据为0时都重叠在一起的现象。