直角坐标系图表-坐标轴刻度取值问题

 

复制代码
/**
 * 作者:雨山没睡饱
链接:https://juejin.cn/post/6919752747671617550
  来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 */
const getStandarInterval = (t) => {
  if (t <= 0.1) {
    t = 0.1;
  } else if (t <= 0.2) {
    t = 0.2;
  } else if (t <= 0.25) {
    t = 0.25;
  } else if (t <= 0.4) {
    t = 0.4;
  } else if (t <= 0.5) {
    t = 0.5;
  } else if (t <= 0.6) {
    t = 0.6;
  } else {
    t = 1;
  }
  return t;
};
/**
 * @param min 数据最小值
 * @param max 数据最大值
 * @param tickInterval 刻度区间
 */
const calcR = (min, max, tickInterval) => {
  let tempmin = 0;
  if (min < 0) {
    while (tempmin > min) {
      tempmin -= tickInterval;
    }
  } else {
    while (tempmin + tickInterval < min) {
      tempmin += tickInterval;
    }
  }
  min = tempmin;
  let tickCount = 1;
  while (tickCount * tickInterval + min < max) {
    tickCount++;
  }
  max = tickCount * tickInterval + min;
  return [min, max, tickCount];
};
/**
 * 获取符合bizcharts内置逻辑的最大值最小值分布
 * @param list 数据列表
 * @param tickCount 最大刻度数
 * @param startWith0 最大值或者最小值是否从零开始
 */
export function standardRange(
  list=[],
  tickCount = 5,
  startWith0 = true
){
  list = list.map(i => (isNaN(Number(i)) ? 0 : Number(i)));

  const log10 = (n) => Math.log(n) / Math.log(10);
  let max = Math.max(...list);
  let min = Math.min(...list);
  // 数据全部分布在x轴同一侧,而且需要从零开始计算
  if (startWith0 && min * max >= 0) {
    min = min > 0 ? 0 : min;
    max = max < 0 ? 0 : max;
  }
  if (max === min) {
    const t = Math.abs(min);
    const mag = t == 0 ? 1 : Math.pow(10, Math.floor(log10(t)));
    return calcR(min, max, mag);
  }

  // 刻度区间长度,和长度数量级
  let tickInterval, mag;
  const rawTickInterval = (max - min) / tickCount;
  // 计算数量级
  mag = Math.pow(10, Math.floor(log10(rawTickInterval)));
  if (mag == rawTickInterval) {
    mag = rawTickInterval;
  } else {
    mag = mag * 10;
  }
  tickInterval = rawTickInterval / mag;

  //选取规范步长
  const stepLen = getStandarInterval(tickInterval);
  tickInterval = stepLen * mag;

  let res = calcR(min, max, tickInterval);

  if (res[2] > tickCount) {
    // 如果最后计算得出的刻度数大于计算值,步长扩大一级
    tickInterval = getStandarInterval(stepLen + 0.1) * mag;
    res = calcR(min, max, tickInterval);
  }
  if(mag < 1){//对于小于1的值有精度问题这里对值进行了优化
    let toF =(mag+'').length-2
    res[0]=parseFloat(res[0].toFixed(toF))
    res[1]=parseFloat(res[1].toFixed(toF))
  }
  return res;
}
复制代码

 

posted @   前端路远且长  阅读(155)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示