记一种echarts绘制不均匀刻度的方法

3,168 阅读1分钟

​首先介绍下背景:最近,接到一个任务,将数据可视化展示出来。项目是基于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}<br>${params.name}${params.data[params.seriesIndex + 1]}`    } else {      const va = this.od[params.dataIndex][params.seriesIndex + 1]      return `${params.seriesName}<br>${params.name}${va}`    }  }}

这里使用之前保存的原始数据,这样就不用因为反计算导致精度有差异了。

搞定!