ECharts 的 TypeScript 实践

12,962 阅读3分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。

获取 ECharts 的类型

图表系列类型

系列类型的后缀都为SeriesOption。 ​

echarts/charts中可以获取类型:

import {
  // 柱状图
  BarSeriesOption,
  // 折线/面积图
  LineSeriesOption,
} from 'echarts/charts';

组件类型

组件类型的后缀都为ComponentOption。 ​

可以从echarts/components中获取:

import {
  // 标题组件
  TitleComponentOption,
  // 提示框组件
  TooltipComponentOption,
  // 直角坐标系内绘图网格组件
  GridComponentOption,
} from 'echarts/components';

其他类型

在定义图表配置的时候,可以有两种方式来进行定义。一个类型是EChartsOption,另一个是ComposeOption。 ​

ComposeOption

使用ComposeOption可以组合一些必须拥有的组件、图表类型的配置。 例如:

import { ComposeOption } from 'echarts/core';
// ...

type ECOption = ComposeOption<
  | TitleComponentOption
  | TooltipComponentOption
  | XAXisOption
  | YAXisOption
  | BarSeriesOption
>;

const option: ECOption = {
  title: {
    text: 'ECharts 入门示例',
  },
  tooltip: { show: true },
  xAxis: {
    data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
  },
  yAxis: {},
  series: [
    {
      name: '销量',
      type: 'bar',
      data: [5, 20, 36, 10, 10, 20],
    },
  ],
};

ComposeOption主要是针对组合的类型,如果这时你在option中加个grid属性,是不会检查的。 主要是检查已经提供的类型,例如你想在series下面加个折线图 ,那么就会报错。

{
  series: [
    {
      name: '销量',
      type: 'bar',
      data: [5, 20, 36, 10, 10, 20],
    },
    {
      // 报错,因为类型只能是 bar,你在进行输入的时候,智能提示也只有 bar
      type: 'line',
    }
  ],
}

坐标轴组件可以从两个地方导入,是等价的。

import { XAXisComponentOption, YAXisComponentOption } from 'echarts';

import { XAXisOption, YAXisOption } from 'echarts/types/dist/shared'; 

EChartsOption

如果你懒得去进行组合,那么使用EChartsOption就相当于所有的组件和图表的类型了。

import {
  EChartsOption,
} from 'echarts/types/dist/shared';

const option: EChartsOption = {
	// 智能提示会给你图表配置的所有属性
};

我们可以看看ECharts实例对象的setOption方法,限制为可以转换为ECBasicOption类型。

setOption<Opt extends ECBasicOption>(option: Opt, notMerge?: boolean, lazyUpdate?: boolean): void;
setOption<Opt extends ECBasicOption>(option: Opt, opts?: SetOptionOpts): void;

EChartsOption的定义就是继承ECBasicOption的。

interface EChartsOption extends ECBasicOption {...}

类型总结

  1. 图表系列类型

后缀都为SeriesOption,可以从两个路径获取:

import { BarSeriesOption } from 'echarts/charts';
import { BarSeriesOption } from "echarts";

  1. 图表组件类型

后缀都为ComponentOption,也可以从两个路径获取:

import { TooltipComponentOption } from 'echarts/components';

// 上面路径获取不到,就从这个路径获取
import { TooltipComponentOption } from "echarts";

  1. 其它

ComposeOptionEChartsOption的获取路径不同。

import { ComposeOption } from 'echarts/core';
import { EChartsOption } from 'echarts/types/dist/shared';

总而言之,要是获取不到的类型都可以从入口进行获取,也就是import { xxx } from 'echarts'。 反正你在进行编码时,IDE也有提示,会帮你进行导入。

在 Vue3 中使用 ECharts

Vue 版本 3.2 以上,ECharts 5.2.2以上 演示代码省略了部分代码,详情请看我的Git仓库

封装一个最基础的图表组件来进行演示:

<template>
  <div ref="chartRef"></div>
</template>

<script setup lang="ts">
const props = defineProps<Props>();
const chartRef = ref<HTMLElement>();
const { option } = toRefs(props);
let chartInstance: EChartsType | null = null;

function getEchartsInstance() {
  return chartInstance;
}

/**
 * 对外暴露属性
 */
defineExpose<BaseChartExpose>({
  getEchartsInstance,
});

onMounted(() => {
  // 创建图表
  chartInstance = echarts.init(
    chartRef.value as HTMLElement,
    undefined,
    props.echartsInitOpts
  );
  chartInstance.setOption(props.option as EChartsOption);
});

// 更新图表
watch(
  option,
  () => {
    chartInstance?.setOption(props.option as EChartsOption);
  },
  {
    deep: true,
  }
);
</script>

使用上面的基础图表组件:

<template>
  <div class="echarts-demo1">
    <base-chart
      ref="baseChart"
      :option="option"
      :echarts-init-opts="echartsInitOpts"
    />
  </div>
</template>

<script setup lang="ts">
const echartsInitOpts: EChartsInitOpts = {
  width: 300,
  height: 300,
};

// 引用 <base-chart> 组件实例
const baseChart = ref<ComponentPublicInstance<unknown, BaseChartExpose>>();
onMounted(() => {
  // 获取 echarts 实例
  const chartInstance = baseChart.value?.getEchartsInstance();
});
</script>

需要注意的问题:

在上面代码中,如果使用ref来包裹ECharts示例对象好像是更方便的,例如这样:

const chartInstance = ref<EChartsType>()

defineExpose({
  chartInstance,
});

onMounted(() => {
  chartInstance.value = echarts.init(
    chartRef.value as HTMLElement,
    undefined,
    props.echartsInitOpts
  );
  chartInstance.value.setOption(props.option as EChartsOption);
});

但是在使用折线图(series-line)的时候,tooltip会出不来(暂时是用到折线图的时候出不来),试了下几种其它的图表是没有问题的,很神奇,可能是因为ECharts实例被代理了之后出现了问题,所以需要注意一下。 ​