使用 echarts 的对数轴时发现,值为0或负数时会显示异常:
-
如果为 0 的数据出现在开始和结尾,例如:[0, 0, 10, 0],会不显示该节点。
-
如果为 0 的数据出现在中间,例如:[10, 20, 0, 5, 8],该节点不显示且该节点前后的节点会相连,展示出一种貌似有数据的状态。
-
如果为负数的数据出现,该负数节点不会显示。
相关issue:github.com/apache/incu…
示例:gallery.echartsjs.com/editor.html…
echarts 对这个问题在后续的版本可能会有完善,那么,现在该怎么处理一下呢?
总结一下三种处理办法:
壹、0 值处理为 null
0 值直接处理成 null, 干脆不显示了, 只是连接断开。 但带来一个问题,0 到其他数值也是一种趋势的展示,断开未免有点过于粗暴,丢失了一部分的图表功能。
不能应对负数情况。
贰、0 值处理为最小值
取一个比非零最小值更接近于 0 的数值。例如,[10, 5, 0, 1, 8] 转换为 [10, 5, 0.1, 1, 8]。
这种方式对于只包含整数的数据可以较好处理,数据的趋势也得以保留。
但如果遇到小数就有些不适宜了,由于log的原因,贴近于 0 的数据的距离被成倍放大,使得出现了另一种极值——极小,降低数据极端差值以使中间部分数据合理的展示出来的需求满足不了。
不能应对负数情况。
叁、 数据整体向上平移
将数据整体+1,这样既有趋势又不会遇到方法二里极小的问题。但是 formatter 将其还原为正常数据时会变成9、99、999这种,这种刻度确实有点丑…
不能应对负数情况。
肆、 自己实现一个对数轴
对正数直接使用 log 处理,0 特别处理,,负数则对其绝对值 log 处理后加负号,然后直接用正常数值轴展示,最后对 y 轴的刻度和 tooltip 进行处理。
此种方法可以比较完美的处理,对 0 和负数都支持良好 —— 相当于自己实现了对数轴。
但数据转化成对数后,Y 轴的刻度很难处理得完美(像 echarts 自带的对数轴刻度一样是漂亮的整数),还需要一定的实践。(可以看看 Graphics Gems 1 的 Nice numbers for graph labels 那章,echarts 的刻度实现就有参考这个)
实现效果:
实现对数轴的具体思路
思路:
- 确定数据中的最大最小值,以算出应该展示的区间(最大刻度、最小刻度、间隔)。
- 将非零数据进行以10为底的对数计算乘以之前计算好的间隔,通过如此计算后,得出数据绘制的趋势即与对数轴情况下的趋势一致。为零的数据直接为0即可。
- 如果所有数大于一,此时已绘制结束,但可能会出现小于一的数据,小于一的数据计算后会在坐标轴以下,因此需将数据整体加一个数值(将数据向上平移)。
- 将轴上刻度与 tooltip 格式化为正常的值(对于坐标刻度,使用10的n次方还原即可)。
具体操作请见源码。
↑使用线性轴模仿对数轴展示数据的demo,规避对数轴无法展示为0数据的问题,支持非负数。