Superset可视化插件开发

创建可视化插件

前言

Superset 中的可视化是用 JavaScript 或 TypeScript 实现的。Superset 预装了几种可视化类型(以下简称 “viz 插件”),可在 superset-frontend/plugins 目录下找到。可视化插件在 superset-frontend/src/visualizations/presets/MainPreset.js 中添加到应用程序中。

注意:在开始下面的步骤前应确保你使用的是普通用户,使用root用户执行到yo @superset-ui/superset命令时会报错,目前还没有很好的解决办法。下面创建可视化插件的步骤可以跳过,直接下载可视化插件模板

创建一个简单的可视化插件

要开始使用,您需要 Superset Yeoman 生成器。建议使用您正在使用的 Superset 版本所附带的模板版本。安装方法如下:

npm i -g yo
cd superset-frontend/packages/generator-superset
npm i
npm link

之后,您就可以继续创建 viz 插件了。为您的 viz 插件创建一个新目录,前缀为 superset-plugin-chart,然后运行 Yeoman 生成器

mkdir /tmp/superset-plugin-chart-hello-world
cd /tmp/superset-plugin-chart-hello-world

初始化可视化插件:

yo @superset-ui/superset

之后,生成器会问几个问题(默认值应该没问题):

$ yo @superset-ui/superset
     _-----_     ╭──────────────────────────╮
    |       |    │      Welcome to the      │
    |--(o)--|    │    generator-superset    │
   `---------´   │        generator!        │
    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `
? Package name: superset-plugin-chart-hello-world
? Description: Hello World
? What type of chart would you like? Time-series chart
   create package.json
   create .gitignore
   create babel.config.js
   create jest.config.js
   create README.md
   create tsconfig.json
   create src/index.ts
   create src/plugin/buildQuery.ts
   create src/plugin/controlPanel.ts
   create src/plugin/index.ts
   create src/plugin/transformProps.ts
   create src/types.ts
   create src/SupersetPluginChartHelloWorld.tsx
   create test/index.test.ts
   create test/__mocks__/mockExportString.js
   create test/plugin/buildQuery.test.ts
   create test/plugin/transformProps.test.ts
   create types/external.d.ts
   create src/images/thumbnail.png

要构建可视化插件,请运行以下命令:

npm i --force
npm run build

或者,要在开发模式下运行可视化插件(每当进行更改时重建),请使用以下命令启动开发服务器:

npm run dev

要将软件包添加到 Superset,请进入 Superset 源文件夹中的 superset-frontend 子目录,运行以下命令:

npm i -S /tmp/superset-plugin-chart-hello-world

如果您将包发布到 npm,您自然也可以直接从那里安装。之后编辑 superset-frontend/src/visualizations/presets/MainPreset.js 并进行以下更改:

superset-frontend/src/visualizations/presets/MainPreset.js

import { SupersetPluginChartHelloWorld } from 'superset-plugin-chart-hello-world';

导入 viz 插件,然后将以下内容添加到传递给 plugins 属性的数组中:

superset-frontend/src/visualizations/presets/MainPreset.js

new SupersetPluginChartHelloWorld().configure({ key: 'ext-hello-world' }),

之后,在运行 Superset(例如开发服务器)时,就会显示 viz 插件:

superset/superset-frontend/

npm run dev-server

可视化插件源码讲解

上面的内容来自官方文档翻译,经过上面的步骤我们完成了可视化插件的创建以及如何添加到superset中,接下来将详细讲解可视化插件文件夹下包含哪些内容,逐步揭开superset的面纱,如何开发自己的可视化插件。

以echart pie 饼图为例,进入到可视化插件目录superset-frontend/plugins/plugin-chart-echarts/src/Pie,我们可以看到这样的目录结构:

.
├── buildQuery.ts
├── controlPanel.tsx
├── EchartsPie.tsx
├── images
│   ├── Pie1.jpg
│   ├── Pie2.jpg
│   ├── Pie3.jpg
│   ├── Pie4.jpg
│   └── thumbnail.png
├── index.ts
├── transformProps.ts
└── types.ts

EchartsPie.tsx

这是一个react 方法组件,接收一个由transformProps.ts返回的props,包含了图表组件所需的数据以及配置。图表组件的展示内容由你制定。

controlPanel.tsx

该文件主要包括一个对象,用于定义superset创建图表时左侧的控制面板,,其中包含可视化插件中使用的每个设置的数组。它将设置传递给主组件,由主组件创建数据可视化查询。

控制面板分为两个选项卡: “查询 “和 ”图表选项"。定义图表数据请求输入(如列和度量)的控件通常位于 “查询 ”部分, 而影响图表视觉外观或功能的控件则位于 “图表选项 ”部分。

控件的类型

这里有两种控件: 预定义控件和自定义控件

下面有几种预定义控件可以使用:

  • groupby: 按列分组(转换为 GROUP BY 语句)
  • series: 与 groupby 相同,但只有一个选择。
  • metrics: 多个度量(转换为聚合表达式:Sum、Avg、Max、Min等)
  • metric: 与 metrics 相同,但只有一个选择。
  • adhoc_filters:过滤器(根据过滤器类型转换为 WHERE 或 HAVING)
  • row_limit: 最大记录数(转换为 LIMIT 语句)

如果控制面板上同时有seriesgroupby控件,而用户选择col1作为series控件的值,并且col2 和 col3 作为groupby控件的值。 结果查询将包含三个groupby列。 这是因为我们认为 series 控件是一个 groupby 查询字段,其值将在生成查询时自动追加到 groupby 字段。

所有现有预定义的控件列表可在以下文件中找到:superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/sharedControls.tsx
可以看到有这些控件:

superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/sharedControls.tsx

export default {
  metrics: dndAdhocMetricsControl,
  metric: dndAdhocMetricControl,
  datasource: datasourceControl,
  viz_type,
  color_picker,
  metric_2: dndAdhocMetricControl2,
  linear_color_scheme,
  secondary_metric: dndSecondaryMetricControl,
  groupby: dndGroupByControl,
  columns: dndColumnsControl,
  granularity,
  granularity_sqla: dndGranularitySqlaControl,
  time_grain_sqla,
  time_range,
  row_limit,
  limit,
  timeseries_limit_metric: dndSortByControl,
  orderby: dndSortByControl,
  order_desc,
  series: dndSeriesControl,
  entity: dndEntityControl,
  x: dndXControl,
  y: dndYControl,
  size: dndSizeControl,
  y_axis_format,
  x_axis_time_format,
  adhoc_filters: dndAdhocFilterControl,
  color_scheme,
  time_shift_color,
  series_columns: dndColumnsControl,
  series_limit,
  series_limit_metric: dndSortByControl,
  legacy_order_by: dndSortByControl,
  truncate_metric,
  x_axis: dndXAxisControl,
  show_empty_columns,
  temporal_columns_lookup,
  currency_format,
  sort_by_metric,
};

自定义控件

可以通过导入必要的依赖关系和覆盖默认参数来定义自定义控件,然后将其放置在 “查询 ”部分的controlSetRows部分,而不是预定义控件中。
重写预定义控件:

controlPanel.tsx

const config: ControlPanelConfig = {
  controlPanelSections: [
    {
      label: t('Query'),
      expanded: true,
      controlSetRows: [
        ['groupby'],
        ['metric'],
        ['adhoc_filters'],
        ['row_limit'],
        [
          {
            name: 'sort_by_metric',
            config: {
              ...sharedControls.sort_by_metric,
              default: true,
            },
          },
        ],
      ],
    },
  ]
}

上面代码中导入了一个sort_by_metric组件,并且重写了default属性为true。

除了基本的下拉控件外,还有几种预定义的控件类型(可通过 type 属性设置)可以使用。一些常用的示例如下:

  • SelectControl: 用于选择单个或多个值的下拉菜单,通常为列
  • MetricsControl: 下拉选择度量标准,触发模态 来定义指标详情
  • AdhocFilterControl: 控制选择过滤器
  • CheckboxControl: 用于选择真/假值的复选框
  • SliderControl: 带有最小/最大值的滑块
  • TextControl: 文本输入控件

要了解更多控制输入类型,请查看以下文件: superset-frontend/src/explore/components/controls/index.js

自定义控件:

{
 name: 'show_labels_threshold',
 config: {
   type: 'TextControl',
   label: t('Percentage threshold'),
   renderTrigger: true,  // 如果值改变,会触发图表的渲染
   isFloat: true,
   default: 5,
   description: t(
     'Minimum threshold in percentage points for showing labels.',
   ),
 },
}

show_labels_threshold是你的字段名称,输入的值会保存在你定义的这个字段中。 有关config的更多配置参数,建议查看superset中的现有控件,并比较相关控制面板的编辑方式。

为确保正确填写所有控件,提供了以下验证器,来自 @superset-ui/core/lib/validator:

  • validateNonEmpty: 必须且至少有一个值
  • validateInteger: 必须是整数值
  • validateNumber: 必须是整数或小数值

有关控制输入类型,请参阅: superset-frontend/src/explore/components/controls/index.js

我们可从官方源码中看到控件是如何定义的,例如行限制控件:

superset-frontend/src/explore/components/controls/index.js

const row_limit: SharedControlConfig<'SelectControl'> = {
  type: 'SelectControl',
  freeForm: true,
  label: t('Row limit'),
  clearable: false,
  mapStateToProps: state => ({ maxValue: state?.common?.conf?.SQL_MAX_ROW }),
  validators: [
    legacyValidateInteger,
    (v, state) => validateMaxValue(v, state?.maxValue || DEFAULT_MAX_ROW),
  ],
  default: 10000,
  choices: formatSelectOptions(ROW_LIMIT_OPTIONS),
  description: t(
    'Limits the number of the rows that are computed in the query that is the source of the data used for this chart.',
  ),
};

所以,只需使用共享控件中的预设选项,你就能建立自己的控制面板。选择你需要的控件名称,然后像这样设置即可:

const config: ControlPanelConfig = {
  controlPanelSections: [
    {
      label: t('Query'),
      expanded: true,
      controlSetRows: [
        ['entity'],  
        ['adhoc_filters'],
        ['row_limit'], 
				//... 
				//其他的控件
				//...       
      ],
    },
    ...
  ]
}

你可能会好奇,我们在定义的控件的值是存储在哪的?这些值又该如何获取呢?

  1. 这些值Superset会为你保存到一个formData的对象中,其中key是你定义的控件名称,value是用户在界面输入数据,这个formData会在你保存图表时存储在图表的元数据中。
  2. superset会将formData传递给transformProps.ts文件中定义的transformPropsprops,你能够通过props.formData解包出你想要的控件值。

buildQuery.ts

定义查询数据的方式。每次打开图表时,图表会向服务器发起请求http://example.com/api/v1/chart/data请求图表的数据,可以看到请求负载为:

buildQuery 函数用于创建一个 QueryContext 实例,并将其发送到图表数据端点. 除了包含要使用的数据源信息外,它还指定了返回的类型(如完整有效载荷:full、样本:samples、查询:query)和格式(如 CSV 或 JSON), 以及是否从数据源强制刷新数据,而不是使用缓存的数据副本。想要知道更多返回类型,请查看:superset/common/query_actions.py:193

你也可以看到你定义的控件的值存放在form_data中,当你保存图表时,这些值最终会为你存放在服务器中,你下次去请求获取图表时返回这些数据。

更重要的是,QueryContext 包含一个属性 queries,它是一个数组,其中包含QueryObjects 的数组。 一个 QueryObject 可以指定列、度量和过滤器等。通常只需在 baseQueryObject 的基础上指定一个查询即可, 但对于一些更高级的用例,可以在 QueryObject 中定义后处理操作,或者在 viz 需要多个不同结果集时定义多个查询。

transformProps.ts

从图表数据端点收到成功响应后调用此函数,用于在将传入数据发送到可视化之前对其进行转换。

transformProps 函数向数据可视化组件返回额外的或修改的Props时非常有用。你也可以从 EchartsPie.tsx 文件访问直接formData,但在这里提供自定义props通常便于集成依赖特定props的第三方库。
对 chartProps 中属性的描述:

  • heightwidth: 图表所在 DOM 元素的高度/宽度
  • formData: 发送到后端的图表数据请求有效载荷。
  • queriesData: 接收到的图表数据响应的有效载荷 从后端获取。queriesData` 的一些重要属性:
    • data: 是一个包含数据的数组,每一行都包含一个将列/别名映射到其值的对象。
      例如: [{ col1: 'abc', metric1: 10 }, { col1: 'xyz', metric1: 20 }]
    • rowcountdata中的行数
    • query: 发出的查询。

注意

请注意:应用程序加载时会缓存 transformProps 函数。在开发过程中通过热加载对 transformProps 函数进行更改时,只有重新启动开发服器才能看到更改。

index.ts

定义图表插件,配置插件的元数据。

这些元数据我们能够在superset新建图表中看到:

images

这个目录用于存放图表的缩略图。

总结

相信从上面阅读下来对可视化插件的整个架构有了大致的了解,有了这部分基础,在接下来的章节中,会使用3个小练习来带大家熟悉如何二次开发可视化插件。在实际情况中,superset已经提供了大部分常用的图表类型,这些图表类型也能够满足我们的开发需求,有些图表可能在某些功能上不满足我们的需求,我们可以在原有图表的基础上进行二次开发、改造来达到我们的需求。

练习1:修改Echarts图表符号

练习2:Echarts图表SVG渲染

练习3:自定义配色方案​​​​​​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值