跳到主要内容

练习2:Echarts图表SVG渲染

我们可以看到Superset中的Echarts图表都是使用canvas来渲染的。

Superset 并不支持 SVG 渲染选项,我觉得 Superset 没有提供 SVG 渲染的选项是有他的考虑在里面的, 虽然 SVG 使用浏览器内置的缩放功能时不会模糊,但是在数据量较大(经验判断 > 1k)、较多交互时使用 Canvas 更适合。 而 Superset 的目标是面向大数据分析,不支持 SVG 渲染也是可以理解,但在实际情况中有的客户会对图表的清晰度有很高的需求,SVG 渲染也是必须的。

既然 Superset 使用的是 Echarts 来做图标库,那 Echarts 支持的功能,Superset 也是能实现的。下图是我实现的 SVG、Canvas 选择组件以及图形效果:

再上图我们可以看到这个单选组件,可以选择 SVG 还是 Canvas 渲染,并且前端图表也是使用 SVG 渲染出来了。不多说,接下来看代码:
首先从定义控件的代码开始

superset-frontend/plugins/plugin-chart-echarts/src/constants.ts
export const DEFAULT_ECHART_OPTS = {
renderer: 'canvas',
};

经过练习1,相信这部分的代码不需要过多讲解了。

我们来回顾一下echart如何使用渲染器的:

import * as echarts from 'echarts';
import * as echarts from 'echarts/core';
// 可以根据需要选用只用到的渲染器
import { SVGRenderer, CanvasRenderer } from 'echarts/renderers';

echarts.use([SVGRenderer, CanvasRenderer]);

// 使用 Canvas 渲染器(默认)
var chart = echarts.init(containerDom, null, { renderer: 'canvas' });
// 等价于:
var chart = echarts.init(containerDom);

// 使用 SVG 渲染器
var chart = echarts.init(containerDom, null, { renderer: 'svg' });

然后来看看 Superset 是如何创建echart实例的(截取了第129行片段代码):

chartRef.current = init(divRef.current);

知道该怎么做了吧。

superset-frontend/plugins/plugin-chart-echarts/src/types.ts
import type { EChartsInitOpts } from 'echarts/core';

export interface EchartsProps {
height: number;
width: number;
echartInitOpts?: EChartsInitOpts; // 此处添加
echartOptions: EChartsCoreOption;
eventHandlers?: EventHandlers;
zrEventHandlers?: EventHandlers;
selectedValues?: Record<number, string>;
forceClear?: boolean;
refs: Refs;
}

export interface BaseTransformedProps<F> {
echartOptions: EChartsCoreOption;
formData: F;
height: number;
onContextMenu?: (
clientX: number,
clientY: number,
filters?: ContextMenuFilters,
) => void;
setDataMask?: SetDataMaskHook;
onLegendStateChanged?: (state: LegendState) => void;
filterState?: FilterState;
refs: Refs;
width: number;
emitCrossFilters?: boolean;
coltypeMapping?: Record<string, number>;
echartInitOpts?: EChartsInitOpts; // 此处添加
}

在上面的代码中:

  • types.ts:在这里我们更改了 EchartsPropsBaseTransformedProps 类型的定义,使它可以接收一个 echartInitOpts 参数。
  • Echart.tsx:在这个文件中将 Echart 组件接收到的 Props 解包获取到 echartInitOpts ,然后修改了 init 方法。
  • transformProps.ts:这里将 formData 解包获取到控制件中的 renderer,然后构建 echartInitOpts 返回出去。
  • EchartsTimeseries.tsx:解包 props 获取到 echartInitOpts 传递给 Echart 组件。

一整个流程下来都是在定义 controlPanel 的控件,然后传递控件值。