JS65 Echarts双Y轴刻度对齐

需求

系统中有这样一个图标,X轴为天,双Y轴,左侧为百分比,右侧为当日各种车辆数目的汇总,理想状态如下:

但是线上发现了问题,由于左侧Y轴是强制按照20为间隔进行分割,而右侧没有设置分割,是有Echarts自动计算得来,按照50进行分割,Y轴总共分割为5份,当右侧Y轴的max250时,恰好左右侧Y轴可以对其,但是当右侧外轴的max300时,那么两个Y周的刻度就不会重合,不是很美观:

需要解决这个问题

手动计算最大值

解决这个问题,就需要指定两个Y轴的最大值、最小值和间隔,让两个Y轴刻度强制对齐。以左侧外轴为基准,min0max100interval20,右侧Y轴也按照这样的比例手动计算maxinterval

首先计算出max,其实Echarts的max属性可以接受一个函数作为值,函数的参数value包含两个属性maxmin就是各个系列(我的例子中就是按天为单位的数组)的实际最大值。但是为了动态计算间隔,我没有使用这个参数,而是手动计算了最大值:

function getCeilMaxSumByColumn(arr = []) {
  // 默认值
  const DEFAULT_MAX = 100;
  // 近似的间隔值
  const IDEAL_INTERVAL = 50;
  if (arr.length === 0) {
    return DEFAULT_MAX;
  }
  // 按列求和,取最大值
  const getMaxSumByColumn = arr => arr.reduce((result, current) = > {
    current.forEach((num, day) = > {
      if (!result[day]) {
        result[day] = {
          total: 0
        };
      }
      result[day].total += num;
    });
    return result;
  }, []).sort((a, b) => b.total - a.total)[0].total;
  // 
  const max = getMaxSumByColumn(arr);
  if (max <= 0) {
    return DEFAULT_MAX;
  }
  // 按照间隔
  return Math.round(max);
},

然后在第二Y轴的设置中,max就取这个值,intervalmax * 0.2,结果如下:

可以看到,两个Y轴对齐了,但是为了对齐,右侧Y轴的刻度会有小数,虽然可以通过formatter来消除,但是结果仍然不是整齐的数字,所以对上面的函数进行了优化,按照50为间隔来取max,比如5,结果就是5051对应100105对应150,计算的方法一开始难住了我,后来发现也没那么难,挺简单,对结果除以50,取结果的整数部分向上四舍五入,然后再乘以50即可:

/**
 * 获取二维数组按列求和的最大值,并按照 50 为分割,向上近似取值,例如输入
 * [
 *     [1, 2, 3],
 *     [4, 5, 6],
 *     [7, 8, 9],
 * ]
 * 按列求和,第三列求和值最大为18,位于[0, 50],输出结果为 50
 * @param arr { array } 输入的二维数组
 * @returns {number} 返回按列求和后的最大近似值
 */
function getCeilMaxSumByColumn(arr = []) {
  // 默认值
  const DEFAULT_MAX = 100;
  // 近似的间隔值
  const IDEAL_INTERVAL = 50;
  if (arr.length === 0) {
    return DEFAULT_MAX;
  }
  // 按列求和,取最大值
  const getMaxSumByColumn = arr => arr.reduce((result, current) = > {
    current.forEach((num, day) => {
      if (!result[day]) {
        result[day] = {
          total: 0
        };
      }
      result[day].total += num;
    });
    return result;
  }, []).sort((a, b) = > b.total - a.total)[0].total;
  // 
  const max = getMaxSumByColumn(arr);
  if (max <= 0) {
    return DEFAULT_MAX;
  }
  // 按照间隔
  return Math.ceil(max / IDEAL_INTERVAL) * IDEAL_INTERVAL;
},

结果:

Done!

参考

发布了382 篇原创文章 · 获赞 91 · 访问量 33万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览