Echarts 横轴标记线的实现

标记线可在图标随意位置绘制一条刻度,方便对数据进行参照对比。

默认情况下,横轴为 category 纵轴为连续的数值。所以标记线即为纵轴上对应某个值的横线。

如下来自 Echarts 官网文档中的示例展示了简单的标记线用法:

option = {
  xAxis: {
    type: "category",
    data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
  },
  yAxis: {},
  series: [{
    data: [820, 932, 901, 934, 1290, 1330, 1320],
    type: "line",
    markLine: {
      data: [{
        type: "average"
      }],
      silent: true
    }
  }]
}

image

标记线的位置

上面标记线配置部分的 data 决定了标记线的值,也就是处于纵轴的哪个位置:

    markLine: {
      data: [{
        type: "average"
      }],
      silent: true
    }

这里通过 type: average 指定的内建的均值标记线,系统自动算出所有数据源的平均值决定标记线的值。

通过指定 xy 可手动指定:

    markLine: {
      data: [{
        name:'标记线',
+        yAxis:333
      }],
      silent: true
    }

image

标记线的方向

横轴标记线,也很简单,指定 x 值即可。

option = {
  xAxis: {
    type: "category",
    data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
  },
  yAxis: {},
  series: [{
    data: [820, 932, 901, 934, 1290, 1330, 1320],
    type: "line",
    barWidth: 6,
    markLine: {
      data: [{
        name:'标记线',
        xAxis: 'Tue'
      }],
      silent: true
    }
  }]
}

image

需要注意的是,因为横轴是 category 类型,是一个个离散的点,所以标记线的位置,是需要落在这些确定的点上,比如上面 Tue 的横轴位置。

横轴任意位置标记线

如果要实现在横轴任意位置绘制标记线,就需要先创建好横轴对应的坐标点。比如星期一和星期二中间,加一个 noon 的位置。

option = {
  xAxis: {
    type: "category",
-   data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
+   data: ["Mon", "Noon","Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
  },
  yAxis: {},
  series: [{
    data: [820, 932, 901, 934, 1290, 1330, 1320],
    type: "line",
    barWidth: 6,
    markLine: {
      data: [{
        name:'标记线',
+       xAxis: 'Noon'
      }],
      silent: true
    }
  }]
}

image

但横轴新增的坐标值影响了原来拆线的展示,使得 category 的数量和 series data 的数量不匹配了。 同时这种做法下,标记线的位置也不是任意的,它参与到了横轴的刻度划分,并不是在原来 Mon, Tue 中间的位置。

所以为了实现,

  • 标记线不影响原来正常的横轴展示
  • 标记线不参与横轴刻度划分

需要实现类似于 y 轴那样的标记线效果。

首先把拆线图改为柱状图,同时减小 bar 的大小方便查看:

option = {
  xAxis: {
    type: "category",
    data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
  },
  yAxis: {},
  series: [{
    data: [820, 932, 901, 934, 1290, 1330, 1320],
-   type: “line”,
+  type: "bar",
+   barWidth: 6,
    markLine: {
      data: [{
        name:'标记线',
        yAxis:333
      }],
      silent: true
    }
  }]
}

效果:

image

然后把横轴由 category 类型切换成 time 类型,不能再使用 category 类型了,因为后者是离散的,不满足需求。而切换 time 之后,需要对数据做些调整,同时横轴的展示上,也是有方法进行自定义而恢复成之前想展示的星期或者其他时间格式的。

const data = [820, 932, 901, 934, 1290, 1330, 1320].map((v, i) => [
  new Date(new Date().getTime() + i * 24 * 60 * 60 * 1000)
    .toJSON()
    .substring(0, 19)
    .replace("T", " "),
  v,
]);
option = {
  xAxis: {
    type: "time",
    splitLine: {
        show: false,
      },
  },
  yAxis: {},
  series: [
    {
      data: data,
      type: "bar",
      barWidth: 6,
      markLine: {
        data: [
          {
            name: "标记线",
            xAxis: new Date(new Date().getTime() + 1 * 12 * 60 * 60 * 1000)
              .toJSON()
              .substring(0, 19)
              .replace("T", " "),
          },
        ],
        silent: true,
      },
    },
  ],
};

image

标记线的标签

标记线默认展示了其所在轴对应的值。当然,可以自定义:

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
const data = [820, 932, 901, 934, 1290, 1330, 1320].map((v, i) => [
  new Date(new Date().getTime() + i * 24 * 60 * 60 * 1000)
    .toJSON()
    .substring(0, 19)
    .replace("T", " "),
  v,
]);
option = {
  xAxis: {
    type: "time",
    splitLine: {
      show: false,
    },
  },
  yAxis: {},
  series: [
    {
      data: data,
      type: "bar",
      barWidth: 6,
      markLine: {
+       label: {
+        formatter: "{b}{c} 999",
+     },
        data: [
          {
            name: "标记线",
            xAxis: new Date(new Date().getTime() + 1 * 12 * 60 * 60 * 1000)
              .toJSON()
              .substring(0, 19)
              .replace("T", " "),
          },
        ],
        silent: true,
      },
    },
  ],
};

image

相关资源