zoukankan      html  css  js  c++  java
  • Echarts获取纵坐标刻度间距的算法思考

    概述

    近期面试问到了一些原理性的东西,所以打算把这个也做一个整理,记录下来,供以后开发时参考,相信对其他人也有用。

    Echarts获取纵坐标刻度间距的博文请见这里

    其实刚开始看Echarts的这段代码我也是一脸懵逼的,但是如果仔细看一下还是觉得挺简单的。

    原理

    首先,对于纵坐标,我们对它有一个期望的分段值,这个期望的分段值是通过最大数/分段数算出来的,代码如下:

    // this.data 是数据
    const round = true;
    const splitNumber = 4;
    const max = this.data.reduce((x,y) => x > y ? x : y);
    let val = max / splitNumber;
    

    然后,这个val就是我们的期望分段值,它可能是500,也可能是333等不规则的数。我们希望能够把它矫正为一个整十整百整千这样的数。怎么做呢?分为两步,第一步是确认到底是整十还是整百还是整千,其实就是看它的0有多少个。第二步是确定最高位上的数是多少,打个比方就是确定500、3000等里面的5、3。

    对于第一步很简单,我们对期望的分段值取10的对数,然后 floor 一下,最后还原就得到了:

    const exponent = Math.floor(Math.log(val) / Math.LN10);
    const exp10 = Math.pow(10, exponent);
    

    比如说,期望分段值是66666,因为他是整万的,所以我们期望得到10000,用上面的代码计算出来果然是10000.

    对于第二步,那就更简单了,只需要把66666/10000 = 6.6进行约分即可,我们可以约成7,那么70000就是我们的实际分段值。所以Echarts用了它自己的一套约分规则:

    // 如果传入了 round 参数,则往小的约分
    if (round) {
      if (f < 1.5) { nf = 1; }
      else if (f < 2.5) { nf = 2; }
      else if (f < 4) { nf = 3; }
      else if (f < 7) { nf = 5; }
      else { nf = 10; }
    }
    else {
      // 如果没有传入 round 参数,则往大的约分
      if (f < 1) { nf = 1; }
      else if (f < 2) { nf = 2; }
      else if (f < 3) { nf = 3; }
      else if (f < 5) { nf = 5; }
      else { nf = 10; }
    }
    

    实际上,我们这一步可以向上约分一个最近的整数就行了,比如1.5约分为2,4.6约分为5,7.3约分为8,但是Echarts这里只约到1、2、3、5、10这几个数,把大于5的全部越成了10,可能在实际生产环境中是为了好看吧。

    最后把我们第一步和第二步的值相乘就得到了最终的分段值,比如第一步是10000,第二步约成了3,那么最终的分段值为30000。不过最后Echarts处理了一下精度问题:

    // Fix 3 * 0.1 === 0.30000000000000004 issue (see IEEE 754).
    // 20 is the uppper bound of toFixed.
    return exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val;
    

    总结

    1.怎么样?是不是很简单呢?

    2.以后在其它地方进行分段的时候,可以参考这里的分段代码了。

  • 相关阅读:
    项目ITP(五) spring4.0 整合 Quartz 实现任务调度
    [Git 系列] WIN7下Git的安装
    Candy
    OSGI
    JAVA编程思想(1)
    [python] 字典和列表中的pop()函数
    R语言编程语法
    Linux 之创建工作目录-mkdir
    python 之 改变工作目录
    python 之 'and' 和 'or'
  • 原文地址:https://www.cnblogs.com/yangzhou33/p/13813911.html
Copyright © 2011-2022 走看看