用 Echarts 实现阶梯图效果

在 ECharts 的官方示例中,提供了一个阶梯图(Step Line)的例子,但这只能算一个 “假阶梯”,如下图所示:

问题分析

该图存在两个主要问题:
  1. 首尾只有半阶: 阶梯的起始和结束位置不完整,缺少完整的阶梯效果。
  2. 鼠标 hover 效果仍是线条:在真正的阶梯图中,每个数字代表一阶,hover 效果应该覆盖整级阶梯,而官方示例中 hover 效果只作用于线条本身。
期望的效果是:每个阶梯单元完整显示,且鼠标交互区域覆盖整个阶梯块。

解决思路

事实上,ECharts 官方的 series 类型并不直接支持真正的阶梯图,需要通过 自定义系列(custom series) 来实现。
自定义的实现原理很简单:
  • 计算曲线的宽度和曲线的数据数量,得到每一阶的起始位置;
  • 绘制一条横线表示当前阶梯的水平段;
  • 在末尾处再画一条竖线,竖线的起止位置根据当前数据和下一条数据的数值计算得到。

完整代码示例

以下是一个完整的 ECharts 配置,实现真正的阶梯图效果:
option = {
  title: {
    text: 'Step Line'
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'shadow',
      shadowStyle: {
        color: 'rgba(150, 150, 150, 0.15)'
      }
    }
  },
  legend: {
    data: ['Step Start', 'Step Middle', 'Step End']
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  toolbox: {
    feature: {
      saveAsImage: {}
    }
  },
  xAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: 'Step Middle',
      type: 'custom',
      // 直接生成 [索引, 数值],消除外部 priceData 依赖
      data: [220, 282, 201, 234, 290, 430, 410].map((val, i) => [i, val]),
      renderItem: function (params, api) {
        const dataIndex = params.dataIndex;
        const value = api.value(1);
        const categoryIndex = api.value(0);

        const start = api.coord([categoryIndex, value]);
        const size = api.size([1, 0]);
        const halfBand = size[0] / 2;

        const children = [];

        // 水平中线(阶梯的横线)
        children.push({
          type: 'line',
          shape: {
            x1: start[0] - halfBand,
            y1: start[1],
            x2: start[0] + halfBand,
            y2: start[1]
          },
          style: {
            stroke: '#5EB7FF',
            lineWidth: 1.5
          }
        });

        // 垂直连接线(连接下一阶梯的竖线)
        if (dataIndex < 6) { // 总长7个,下标0~6,最后一个不画竖线
          const nextVal = [220, 282, 201, 234, 290, 430, 410][dataIndex + 1];
          const nextY = api.coord([categoryIndex + 1, nextVal])[1];
          children.push({
            type: 'line',
            shape: {
              x1: start[0] + halfBand,
              y1: start[1],
              x2: start[0] + halfBand,
              y2: nextY
            },
            style: {
              stroke: '#5EB7FF',
              lineWidth: 1.5
            }
          });
        }

        return {
          type: 'group',
          children: children
        };
      },
      itemStyle: { color: '#5EB7FF' },
      z: 10
    }
  ]
};

效果说明

  • 每个数据点对应一个完整的阶梯(横线 + 竖线),收尾完整;
  • 由于开启了 tooltip 的 axisPointer 类型为 shadow,hover 时会显示阴影区域,覆盖整级阶梯,达到预期的交互效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值