首先介绍下背景:最近,接到一个任务,将数据可视化展示出来。项目是基于Vue的,开搞呗,安装echarts库。。。按照官方的说明文档,开始实现,效果如下:
看着好像也没啥问题。
想多了,从上图中,还不能看出数据大小的明显差异,但到了测试环境,由于数据的差异过大,有的是个数级别的,有的是百万级别的,结果就导致了那些个数据较小的柱子基本看不出来,高度太低(因为echarts是根据数据的大小分配高度的)。没办法,查了一圈官方文档也没啥眉目,就百度了下,看到了 “数据映射”关键词,开始动手实现第一步:先将y轴等分成几份(这里是5等分),然后设置最小值(这里设置成0),由于数据是接口返回的,这里最大值不设置,由库自己定,然后自定义y轴的刻度标签显示:
yAxis: { type: 'value', min: 0, splitLine: { show: false }, interval: this.interval, axisLabel: { formatter: (v, ix) => { if (this.max <= this.boundary) { return v } else { let vl switch (ix) { case 0: vl = this.ylabel[0] break case 1: vl = this.ylabel[1] break case 2: vl = this.ylabel[2] break case 3: vl = this.ylabel[3] break case 4: vl = this.ylabel[4] break case 5: vl = this.ylabel[5] break } return vl } } }}
interval是强制设置坐标轴分割间隔,因为我是五等分y轴,所以这里的interval值是0.2倍最大值(最大值在第二步中会获取并存在data中),这里的刻度值我是按照[0,10,0.1max,0.2max,0.5max,max]设置,需要说明的是,这里的刻度标签仅仅是展示变了,实际上其代表的值没变,所以需要数据映射。
第二步:y轴设置好了之后,就开始关键的数据映射了,简单理解就是将原始数据通过计算变成可以分布在处理过的y轴上的数据,
// 数据映射处理if (this.max > this.boundary) { drt = rt.map(el => { return el.map((elv, elix) => { if (elix == 0) { return elv } else if (elv >= this.ylabel[0] && elv <= this.ylabel[1]) { return (elv / this.ylabel[1]) * this.interval } else if (elv > this.ylabel[1] && elv <= this.ylabel[2]) { return (elv / this.ylabel[2]) * this.interval + this.interval } else if (elv > this.ylabel[2] && elv <= this.ylabel[3]) { return (elv / this.ylabel[3]) * this.interval + this.interval * 2 } else if (elv > this.ylabel[3] && elv <= this.ylabel[4]) { return (elv / this.ylabel[4]) * this.interval + this.interval * 3 } else { return (elv / this.ylabel[5]) * this.interval + this.interval * 4 } }) }) return drt}
这里要注意保存处理前的数据,即实际数据,到此,图表即可满足需求
和之前的对比,可以看出,数值较小时,也能明显展示,不足的是,鼠标放在柱子上的提示框会展示处理之后的数据,即非实际数据,所以我们需要将提示框展示的数据处理下。第三步:设置tooltip
tooltip: { formatter: params => { if (this.max <= this.boundary) { return `${params.seriesName}${params.name}:${params.data[params.seriesIndex + 1]}` } else { const va = this.od[params.dataIndex][params.seriesIndex + 1] return `${params.seriesName}${params.name}:${va}` } }}
这里使用之前保存的原始数据,这样就不用因为反计算导致精度有差异了。
搞定!