Echarts MarkLine不在数据范围内的完美处理

480 阅读3分钟

场景

折线图展示数据,例如数据是 [50, 43, 47, 48, 58, 56, 55]

将数据用echarts绘制成图表,是这个效果:

截屏2025-06-29 20.49.45.png

在此基础上,我们需要再展示一下最大值、最小值、平均数等数据,均可以使用markline的配置,得到如下图所示的效果:

截屏2025-06-29 20.51.52.png

最大值、最小值、平均数、中位数,这些数据一定是在原始数据范围内的,标线一定能看到。

如果设置标线数据为85,这条数据已经在刻度范围之外了,虽然我们新增了markline的配置,但页面上看不到。

{
    yAxis: 85,
    name: '优秀',
    lineStyle: {
      color: '#EFCA2A',
      width: 1,
    },
    label: {
      color: '#EFCA2A'
    }
  }

如果我们想在页面上看到markline,有什么方法呢?

方案一:自定义min和max

我们在原始数据中和markline中取到最大值和最小值,将其赋值给max和min,传给echarts的options,这样就能百分百确保所有数据不越界了。

截屏2025-06-29 20.59.01.png

这种方法的缺点就是没有触发echarts内部计算刻度的算法,导致Y轴刻度数据并不nice。

此时,我们需要探索一下Echarts中计算Y轴刻度的算法,把原始数据和85合并一下,自动生成Y轴刻度。

方案二:再画一条隐藏的折线图

直接用堆叠的方式画另一条线,把85这条数据放进去即可:

{
  data: [null, null, null, null, null, null, 85],
  type: 'line',
  itemStyle: {
    color: 'transparent'
  }
}

截屏2025-06-29 21.09.47.png

上述所有的例子,Y轴刻度都是从0开始,有时候会导致数据在页面上特别靠上,可以设置scale,让Y轴根据数据自动适应,如下图,最小刻度计算后,从40开始了。

截屏2025-06-29 22.03.48.png

看一下echarts源码,找一下计算刻度的算法是怎样的

ECharts 有用于优化坐标轴的刻度显示,使其更加美观和易读。这个算法的实现可以在 ECharts 的源码中找到。https://github.com/apache/echarts/blob/master/src/scale/Scale.ts

这个算法的目的是生成一个美观的刻度,如果不使用这个算法,刻度就会变成方案一的那种效果。

大致步骤:

  1. 计算得到实际的min和max(如上面的例子所示,算出[0, 100][40, 90]

  2. 计算合适的步长,一般是用(max - min) / splitNumber,再调整成合适的值;

  3. 看看这个步长是否覆盖了min和max,最终生成刻度数据;

我们可以通过echarts对象获取到相关数据:

const yAxisModel = myChart.getModel().getComponent('yAxis');
const extent = yAxisModel.axis.scale._extent; // 范围 [min, max]
const interval = yAxisModel.axis.scale._interval; // 刻度间隔
const ticks = []; // 刻度值数组
for (let val = extent[0]; val <= extent[1]; val += interval) {
  ticks.push(val);
}
console.log(extent, interval, ticks)

截屏2025-06-29 21.49.29.png