superset设置查看权限_如何为Superset 添加一个自定义组件

本文所有代码和配置是基于superset Version 0.36.0

配置本地环境

首先从 Superset Github clone 代码到本地,并切换到0.36.0 分支

# clone repo
git clone https://github.com/apache/incubator-superset.git

# checkout release 0.36.0 
cd incubator-superset
git checkout tags/0.36.0

提前需要装好python 3.7,建议使用pyenv,不要用mac的system python

brew install pyenv
pyenv install 3.7.0
// 在当前superset目录下,设置python版本为3.7.0,
pyenv local 3.7.0

之后在根目录下 CONTIBUTING.md, 找到 Setup Local Environment for Development

根据文档,分别把后台和前端run起来

  1. 后台flask server
# 安装各种依赖
pip install -r requirements.txt
pip install -r requirements-dev.txt
pip install -e .

# 创建admin用户,记得记住用户名密码,之后要登陆
superset fab create-admin

# 脚本初始化和迁移数据库
superset db upgrade

# 脚本初始化用户和组的权限
superset init

# 脚本加载默认的图表和面板
superset load_examples

# run flask server
FLASK_ENV=development superset run -p 8088 --with-threads --reload --debugger

成功以后,后台会在 http://localhost:8088 运行

2. 前端

cd superset-frontend
# 使用package.lock 安装依赖
npm ci
# run dev server
npm run dev-server

打开 http://localhost:9000,界面如下

cabc5235ccb35d029d5f3fccacf39766.png

如果能看到页面,说明前后台的环境都配置好了。就可以开始添加自定义图表了。

添加自定义图表

394576f33c7315b188674e7c5ccafd1e.png

首先打开一个常规的创建/编辑 图表页面,左侧为 控制面板,右侧为图表。不同的图表的配置面板会有差异。

所以要添加一个自定义图表,主要有三步

  1. 【前端】添加自定义图表的面板 Data Tab
  2. 【前端】添加自定义图表以及面板的 Customize Tab
  3. 【后台】添加后台接口返回正确的数据给前端渲染。

1. 添加自定义图表的控制面板 Data Tab

控制面板主要分为两个部分

  1. Data 控制输出给图表的数据,做一些聚合,排序,计算的操作
  2. Customize 自定义,针对图表进行主题颜色替换,以及相关的显示配置,如表格是否分页,以及每页显示几条,以及是否添加搜索框

所以如果添加一个自定义图表,前端需要添加一个自定义的图表,以及图表对应的控制面板。

例如,我需要添加一个echarts的雷达图,这个在superset中没有类似的实现。

经过分析和对比,发现现在superset的pie chart的数据结构跟雷达图类似,那么可以把复用Pie Chart的控制面板的配置文件。

在 superset-frontend/src/explore/components/controls/index.js 这个文件中有所有的控制面板的组件,例如 MetricsControl 对应的就是页面中的Metric下拉框。如果你需要添加自定义的控制组件,可以在这里添加。

找到Pie Chart的控制面板配置文件, superset-frontend/src/explore/controlPanels/Pie.js

import { t } from '@superset-ui/translation';

export default {
  controlPanelSections: [
    // label对应的是每个section的标题
    // expand对应的是改section是否可以被展开
    // controlSetRows 定义的是每一行有几个组件,metric,adhoc_filters对应的是组件的key
    // 可以在superset-frontend/src/explore/controls.jsx
    // 中通过这些key找到对应的配置
    {
      label: t('Query'),
      expanded: true,
      controlSetRows: [
        ['metric'],
        ['adhoc_filters'],
        ['groupby'],
        ['row_limit'],
      ],
    },
    {
      label: t('Chart Options'),
      expanded: true,
      controlSetRows: [
        ['pie_label_type', 'number_format'],
        ['donut', 'show_legend'],
        ['show_labels', 'labels_outside'],
        ['color_scheme', 'label_colors'],
      ],
    },
  ],
  controlOverrides: {
    row_limit: {
      default: 25,
    },
    number_format: {
      description:
        t('D3 format syntax: https://github.com/d3/d3-format') +
        ' ' +
        t('Only applies when the "Label Type" is not set to a percentage.'),
    },
  },
};

在controlPanelSections中,controlSetRows对应的是配置面板中的layout以及对应的组件,例如,metric在superset-frontend/src/explore/controls.jsx的值为

const metrics = {
  type: 'MetricsControl',
  multi: true,
  label: t('Metrics'),
  validators: [v.nonEmpty],
  default: c => {
    const metric = mainMetric(c.savedMetrics);
    return metric ? [metric] : null;
  },
  mapStateToProps: state => {
    const datasource = state.datasource;
    return {
      columns: datasource ? datasource.columns : [],
      savedMetrics: datasource ? datasource.metrics : [],
      datasourceType: datasource && datasource.type,
    };
  },
  description: t('One or many metrics to display'),
};

// label 为该组件显示在控制面板的名称
// type 为对应的UI组件
const metric = {
  ...metrics,
  multi: false,
  label: t('Metric'),
  description: t('Metric'),
  default: props => mainMetric(props.savedMetrics),
};

这里metric对应的type是 MetricsControl

可以在superset-frontend/src/explore/components/controls/index.js中找到MetricsControl对应的UI组件为 superset-frontend/src/explore/components/controls/MetricsControl.jsx

这样控制面板就通过superset-frontend/src/explore/controlPanels文件夹下面的js文件,对不同类型的图表进行配置。

那么现在来添加自定义雷达图的控制面板

  1. 在这个目录 superset-frontend/src/explore/controlPanels 下创建一个新的文件 CustomTable.js, 为了防止以后superset也会支持雷达图,加了一个前缀custom防止重名。此处我直接复制Pie.js,重命名为CustomTable.js
  2. 在superset-frontend/src/setup/setupPlugins.ts 注册一下新的控制面板配置,代码如下
// ... 此处省略
import { getChartControlPanelRegistry } from '@superset-ui/chart';
import MainPreset from '../visualizations/presets/MainPreset';
import setupPluginsExtra from './setupPluginsExtra';

import Area from '../explore/controlPanels/Area';
// ... 此处省略

// 引入自定义的控制面板配置
import CustomTable from '../explore/controlPanels/CustomTable';

export default function setupPlugins() {
  new MainPreset().register();

  // TODO: Remove these shims once the control panel configs are moved into the plugin package.
  getChartControlPanelRegistry()
    .registerValue('area', Area)
    // ... 此处省略
    // 注册控制面板,custom_table就是我将要引入的图表的key
    // 那么如果图表的key是custom_table的时候,
    // 页面会使用CustomRader这个配置来显示控制面板
    .registerValue('custom_radar', CustomRader);

  setupPluginsExtra();
}

那么控制面板就添加好了,接下来添加雷达图

2. 添加自定义图表

  1. 在superset-frontend/src/visualizations底下新建目录 CustomRadar

也可以复制Pie Chart的目录以及文件格式,Pie Chart的实现在另一个repo

打开Pie Chart的目录

55d1402b14f3982b7559206cf11c2aba.png
  • images对应的是Pie Chart的图标,包括一大一小
  • controPanel.ts 对应的是控制面板的Customize Tab,就是自定义配置,因为每个图表的自定义配置差别比较大,所以跟图表放在了一起。
  • index.js 对应的是图表具体的实现

在 superset-frontend/src/visualizations/presets/MainPreset.js 中注册新的图表

import { Preset } from '@superset-ui/core';
// ...
import {
  AreaChartPlugin,
  // ...
} from '@superset-ui/legacy-preset-chart-nvd3';
// 引入自定义图表
import CustomRadar from '自定义组件的目录/custom-radar';

export default class MainPreset extends Preset {
  constructor() {
    super({
      name: 'Legacy charts',
      presets: [new DeckGLChartPreset()],
      plugins: [
        new AreaChartPlugin().configure({ key: 'area' }),
        // ...
        // 注册自定义图表
        new CustomRadar().configure({ key: 'custom-radar' }),
      ],
    });
  }
}

注册完以后,可以参照其他的plugin的实现来实现自定义的图表。

3. 添加对应接口

添加完自定义图表和控制面板以后,还需要配置相应的接口来拿取数据,打开python文件

superset/viz.py​github.com

里面包含了所有图表获取数据的接口,所有接口的实现都需要继承BaseViz,BaseViz的具体实现可以查看链接,例如Pie图表,定义了viz_type, verbose_name, credits, is_timeseries, 这些参数是每个图表都需要定义的。之后实现get_data这个方法就可以了。df 参数为pandas的dataFrame数据。可以对这个数据进操作之后返回。

其实BaseViz里面实现的get_json调用了get_payload,之后才调用了get_data。所以继承了BaseViz以后只需要重写get data方法就可以了。

// ...
class DistributionPieViz(NVD3Viz):

    """Annoy visualization snobs with this controversial pie chart"""

    viz_type = "pie"
    verbose_name = _("Distribution - NVD3 - Pie Chart")
    is_timeseries = False

    def get_data(self, df: pd.DataFrame) -> VizData:
        if df.empty:
            return None
        metric = self.metric_labels[0]
        df = df.pivot_table(index=self.groupby, values=[metric])
        df.sort_values(by=metric, ascending=False, inplace=True)
        df = df.reset_index()
        df.columns = ["x", "y"]
        return df.to_dict(orient="records")
// ...

viz_types = {
    o.viz_type: o
    for o in globals().values()
    if (
        inspect.isclass(o)
        and issubclass(o, BaseViz)
        and o.viz_type not in config["VIZ_TYPE_BLACKLIST"]
    )
}

之后重启后台和前端就能使用自定义的图表了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值