echarts双Y轴,实现均分为包含刻度0的指定段数,同时对齐刻度

要实现强制分为指定段数,并且对齐刻度,需要用的配置分别为yAxis的max、min、interval

echarts5.3有个配置项alignTicks,在多个 y 轴为数值轴的时候,可以开启该配置项自动对齐刻度。只对'value''log'类型的轴有效。实际使用中,发现在双轴数据格式不同,且数值相差巨大的时候,达不到理想状态下的均分效果。

以下方法实现了,包含0刻度,且均分为指定段数,并且对齐左右刻度:

const row = 5;

const recursion = ({ min, max }: any) => {
  if ((max !== 0 && !max) || (min !== 0 && !min)) return;

  // 减少一位预定行数,用来展示0刻度
  const interval = Math.ceil((max - min) / (row - 1));

  // 将最大最小根据间隔取整
  max = Math.ceil(max / interval) * interval;
  min = Math.floor(min / interval) * interval;

  // 实际0刻度线以上间隔数
  const top = Math.ceil(Math.abs(max) / interval);
  // 实际0刻度线以下间隔数
  const bottom = Math.ceil(Math.abs(min) / interval);
  // 实际总间隔数
  const total = top + bottom;

  // 根据预定行数,重新推算包含0刻度的最终间隔
  const _interval = Math.ceil((total * interval) / row);
  // 根据最终推算间隔,重置最大数
  const _max = Math.ceil(_interval * row + min);
  // 根据最终推算间隔,重置最小数
  const _min = Math.floor(min / _interval) * _interval;
  // 推算过后的0刻度以上间隔数
  const _top = Math.ceil(Math.abs(_max) / _interval);
  // 推算过后的0刻度以下间隔数
  const _bottom = Math.ceil(Math.abs(_min) / _interval);

  if (_top + _bottom !== row) {
   return recursion({ min: _min, max: _max });
  }

  return {
   max: _max,
   min: _min,
   interval: _interval,
   top: _top,
   bottom: _bottom,
  };
};

// 计算最大最小和间隔
export const calc = (data: any) => {
  // 原始最大
  let max = data?.reduce((a: any, b: any) => Math.max(a, b), -Infinity);
  max = max < 0 ? 0 : max;

  // 原始最小
  let min = Math.min(...data);
  min = min > 0 ? 0 : min;

  return {
   ...recursion({ min, max }),
  };
};

 

将max、min、interval配置到对应yAxis后,得到如下效果:

可以看出,已经实现了强制包含0刻度,并且均分为5段,左右刻度对齐。

但是美中不足的是,0刻度没有对齐,下面进一步优化,实现0刻度对齐:

	let left: any = calc(left_list);
	let right: any = calc(right_list);

	// 值的比例
	const ratio = (left.max - left.min) / (right.max - right.min);

	if (ratio) {
		if (left.max < right.max * ratio) {
			// 同比例下,右边的最大值大,左边向右对齐
			left.max = Math.ceil(right.max * ratio);
		} else {
			// 同比例下,左边的最大值大,右边向左对齐
			right.max = Math.ceil(left.max / ratio);
		}

		if (left.min < right.min * ratio) {
			// 同比例下,左边最小值更小,右边向左边对齐
			right.min = Math.floor(left.min / ratio);
		} else {
			// 同比例下,右边最小值更小,左边向右边对齐
			left.min = Math.floor(right.min * ratio);
		}

		// 重新根据指定段数,计算最大最小和间隔
		left = recursion({ min: left.min, max: left.max });
		right = recursion({ min: right.min, max: right.max });
	}

通过上述方法,实现了多数情况下的0刻度对齐,但是仍旧存在不对齐的情况,后续再做探究。

posted @ 2025-04-19 09:54  SKILL·NULL  阅读(25)  评论(0)    收藏  举报