文章目录

  • 服务地址
  • 前言
  • 集成echarts
    • 集成echarts柱状折线图 mix-line-bar
      • 流程
        • 1、 superset-frontend/src/visualizations/ 目录下
        • 2、 修改 superset-frontend/src/visualizations/presets/MainPreset.js
        • 3、 修改 superset-frontend/src/explore/components/controls/VizTypeControl.jsx
        • 4、新增 superset-frontend/src/explore/controlPanels/MixLineBar.js
        • 5、修改 superset-frontend/src/explore/controls.jsx 新增的一些自定义组件
        • 6. 修改 setupPlugins.ts
        • 7、修改package.json
        • 8. 后端 py 修改 superset/viz.py
        • 汉化与问题记录

服务地址

服务可以登录 http://dnu8k5.natappfree.cc体验,账号:user,密码:user。
git 地址:https://github.com/Sherhang/incubator-superset/tree/zh/

前言

目前superset官方项目处于快速迭代中,版本的差异很大,目前发布的稳定版为0.36,所以改造主要基于0.36版本。另外,目前的master分支对元数据库结构已经做了改动,不能向前兼容。

目前superset的前端用d3和nvd3来做,很多图表不符合中国人的使用习惯,d3的部分图表性能很差,所以必须进行定制化。

集成echarts

echarts官方link,

superset使用最新版本0.36,echarts4.7.0。主要参考link。这份教程给出的柱状折线图还不能达到实用的需求,比如格式调整,样式调整,字段分组等功能都没有做,后面我会把能实用的教程补齐。

集成echarts柱状折线图 mix-line-bar

这个柱状折线图完成的功能不全,仅仅帮助大家理解superset图表从后端到前端的渲染流程

流程

集成echarts柱状折线图 mix-line-bar
superset和echarts版本
前端目录 superset-frontend
首先0.36版本是比较新的版本,代码结构相比 0.30以前的改动还是比较大的,主要是前端的代码结构变化比较大, superset 把前端的插件单独放在一个superset-ui的项目中;superset中的前端代码主要放在superset-frontend的目录中

主要修改的地方

1、 superset-frontend/src/visualizations/ 目录下

1-1 新增文件夹MixLineBar,
主要新加的文件目录

1-2 新建文件夹 images 放入新增图表的图片
图片在echarts 上可以下载
https://www.echartsjs.com/examples/zh/index.html

选择你要接入的图表,然后右键另存为 就可以下载下来了
然后放在 images 文件下,可以转化为png

1-3 新增文件 MixLineBarChartPlugin.js

import { t } from '@superset-ui/translation';
import { ChartMetadata, ChartPlugin } from '@superset-ui/chart';
import transformProps from './transformProps';
import thumbnail from './images/thumbnail.png';const metadata = new ChartMetadata({name: t('Mix Line Bar'),description: '',credits: ['https://www.echartsjs.com/examples/en/editor.html?c=mix-line-bar'],thumbnail,
});export default class MixLineBarChartPlugin extends ChartPlugin {constructor() {super({metadata,transformProps,loadChart: () => import('./ReactMixLineBar.js'), // 前端渲染逻辑});}
}

1-4 新增文件 ReactMixLineBar.js 注册

import reactify from '@superset-ui/chart/esm/components/reactify';
import Component from './MixLineBar';export default reactify(Component);

1-5 新增文件 transformProps.js 前端后端数据转换

export default function transformProps(chartProps) {const {width, height, queryData, formData} = chartProps;// formData 前端页面的数据// queryData  后端返回的数据return {data: queryData.data,width,height,formData,legend: queryData.data.legend,x_data: queryData.data.x_data,series: queryData.data.data,};}

1-6 新增文件 MixLineBar.js 前端渲染图表主要逻辑

import echarts from 'echarts';
import d3 from 'd3';
import PropTypes from 'prop-types';
import { CategoricalColorNamespace } from '@superset-ui/color';// 数据类型检查
const propTypes = {data: PropTypes.object,width: PropTypes.number,height: PropTypes.number,
};function MixLineBar(element, props) {const {width,height,data,formData,x_data,series,legend,} = props; // transformProps.js 返回的数据const fd = formData// 配置y轴显示信息const left_y_min = fd.leftYMInconst left_y_max = fd.leftYMaxconst left_y_interval = fd.leftYIntervalconst right_y_min = fd.rightYMinconst right_y_max = fd.rightYMaxconst right_y_interval = fd.rightYInterval// y轴别名const y_axis_label = fd.yAxisLabelconst y_axis_2_label = fd.yAxis2Label// 右边y轴 对应的 指标列const right_y_column = fd.rightYColumn// 为了适配颜色const colorFn = CategoricalColorNamespace.getScale(fd.colorScheme);var colors = []if (colorFn && colorFn.colors) {colors = colorFn.colors}const colors_len = colors.length// y轴配置格式var yAxis_1 = {type: 'value',name: 'Left_Y_Axis',axisLabel: {formatter: '{value}'}}var yAxis_2 = {type: 'value',name: 'Right_Y_Axis',axisLabel: {formatter: '{value}'}}if (left_y_min !== undefined) {yAxis_1['min'] = left_y_min}if (left_y_max != undefined) {yAxis_1['max'] = left_y_max}if (left_y_interval != undefined) {yAxis_1['interval'] = left_y_interval}if (right_y_min != undefined) {yAxis_2['min'] = right_y_min}if (right_y_max != undefined) {yAxis_2['max'] = right_y_max}if (right_y_interval != undefined) {yAxis_2['interval'] = right_y_interval}if (y_axis_label != undefined){yAxis_1['name'] = y_axis_label}if (y_axis_2_label != undefined){yAxis_2['name'] = y_axis_2_label}// 处理series 显示的数据 [{'name':xx, 'type':xx, 'data':xx, 'yAxisIndex':xx}]// 重新请求时, 默认展示左y,for (let i = 0; i < series.length; i++) {var serie = series[i]serie['yAxisIndex'] = 0if (right_y_column != undefined && right_y_column.indexOf(serie.name) >= 0) {serie['yAxisIndex'] = 1}if(colors_len>0){serie['itemStyle'] = {'color': colors[i%colors_len]}}}const div = d3.select(element);const sliceId = 'mix-bar-line-' + fd.sliceId;const html = '<div id='+ sliceId + ' style="height:' + height + 'px; width:' + width + 'px;"></div>';div.html(html);// init echarts,light 为制定主题,可以查看官方apivar myChart = echarts.init(document.getElementById(sliceId), 'light');// echarts 渲染图表的数据格式 在官网可以查看var option = {tooltip: {trigger: 'axis',axisPointer: {type: 'cross',crossStyle: {color: '#999'}}},legend: {data: legend, //[] x轴的数据},xAxis: [{type: 'category',data: x_data,axisPointer: {type: 'shadow'}}],yAxis: [yAxis_1,yAxis_2,],series: series,};myChart.setOption(option);
}MixLineBar.displayName = 'Mix Line Bar';
MixLineBar.propTypes = propTypes;export default MixLineBar;

2、 修改 superset-frontend/src/visualizations/presets/MainPreset.js

// 开头导入
import MixLineBarChartPlugin from '../MixLineBar/MixLineBarChartPlugin'// 末尾添加
new MixLineBarChartPlugin().configure({ key: 'mix_line_bar' }),

3、 修改 superset-frontend/src/explore/components/controls/VizTypeControl.jsx

 //找到 DEFAULT_ORDER 这个变量 数组末尾 添加 新图表'mix_line_bar',

4、新增 superset-frontend/src/explore/controlPanels/MixLineBar.js

前端页面布局

/***   https://www.echartsjs.com/examples/zh/editor.html?c=mix-line-bar*   mix line bar*/
import { t } from '@superset-ui/translation';export default {requiresTime: true,controlPanelSections: [{label: t('Chart Options'),expanded: true,controlSetRows: [['color_scheme', 'label_colors'],],},{label: t('X Axis'),expanded: true,controlSetRows: [['groupby'],],},{label: t('Line Type'),expanded: true,controlSetRows: [['line_metrics'],],},{label: t('Bar Type'),expanded: true,controlSetRows: [['bar_metrics'],],},{label: t('Real Y Axis 2 Display Columns'),expanded: true,controlSetRows: [['right_y_column'],],},{label: t('Y Axis 1 Scale Value Setting'),expanded: true,controlSetRows: [['left_y_min', 'left_y_max', 'left_y_interval'],['y_axis_label']],},{label: t('Y Axis 2 Scale Value Setting'),expanded: true,controlSetRows: [['right_y_min', 'right_y_max', 'right_y_interval'],['y_axis_2_label']],},{label: t('Query'),expanded: true,controlSetRows: [['adhoc_filters'],],},],controlOverrides: {},
};

5、修改 superset-frontend/src/explore/controls.jsx 新增的一些自定义组件

// 后面的是注释 如有影响请删掉

  line_metrics: {...metrics, // 继承multi: true, // 多选clearable: true, // 是否可调用, true当作sqlvalidators: [], // 是否可以为空label: t('Line Type Metrics'),description: t('Metrics for which line type are to be displayed'),},bar_metrics: {...metrics,multi: true,clearable: true,validators: [],label: t('Bar Type Metrics'),description: t('Metrics for which bar type are to be displayed'),},y_metrics_2: {...metrics, multi: true,validators: [],default:null,label: t('Y Axis 2 Columns'),description: t('Select the numeric columns to display in Right-Y-Axis'),},left_y_min: {type: 'TextControl', //文本输入label: t('Left Y Min'),renderTrigger: true,isInt: true,description: t('Left Y Min'),},left_y_max: {type: 'TextControl',label: t('Left Y Max'),renderTrigger: true,isInt: true,description: t('Left Y Max'),},left_y_interval: {type: 'TextControl',label: t('Left Y Interval'),renderTrigger: true,isInt: true,description: t('Left Y Interval'),},right_y_min: {type: 'TextControl',label: t('Right Y Min'),renderTrigger: true,isInt: true,description: t('Right Y Min'),},right_y_max: {type: 'TextControl',label: t('Right Y Max'),renderTrigger: true,isInt: true,description: t('Right Y Max'),},right_y_interval: {type: 'TextControl',label: t('Right Y Interval'),renderTrigger: true,isInt: true,description: t('Right Y Interval'),},y_axis_2_label: {type: 'TextControl',label: t('Y Axis 2 Label'),renderTrigger: true,default: '',},right_y_column: {type: 'SelectControl',freeForm: true,renderTrigger: true,multi: true,label: t('Y Axis 2 Column'),description: t('Choose or add metrics (label) to display in right y axis'),},

6. 修改 setupPlugins.ts

superset-frontend/src/setup/setupPlugins.ts

// 开头引入
import MixLineBar from '../explore/controlPanels/MixLineBar';// 末尾注册
.registerValue('mix_line_bar', MixLineBar)

7、修改package.json

// 新增引入 echarts 版本
"echarts": "^4.7.0"

8. 后端 py 修改 superset/viz.py

图表处理的逻辑都在这个文件中

1、修改地方 找到 METRIC_KEYS 数组后 添加2个字符串(自定义的组件)

"line_metrics", "bar_metrics",

2、修改地方,新增新图表后端逻辑

class MixLineBarViz(NVD3Viz):""" mix line bar"""viz_type = "mix_line_bar"verbose_name = _("Mix Line Bar")# 是否排序sort_series = False# 是否对time 做处理 _timestampis_timeseries = Falsedef query_obj(self):# check bar column, line column 是否重复bar_metrics = self.form_data.get('bar_metrics')line_metrics = self.form_data.get('line_metrics')if not bar_metrics and not line_metrics:raise Exception(_("Please choose metrics on line or bar type"))bar_metrics = [] if not bar_metrics else bar_metricsline_metrics = [] if not line_metrics else line_metricsintersection = [m for m in bar_metrics if m in line_metrics]if intersection:raise Exception(_("Please choose different metrics on line and bar type"))d = super().query_obj()return ddef to_series(self, df, classed=""):"""拼接 前端渲染需要的数据:param df::param classed::return: {'legend':[], 'bar':[], 'line':[]}"""cols = []for col in df.columns:if col == "":cols.append("N/A")elif col is None:cols.append("NULL")else:cols.append(col)df.columns = colsseries = df.to_dict("series")# [{}]bar_metrics = self.form_data.get('bar_metrics', [])bar_metrics = [] if not bar_metrics else bar_metricsline_metrics = self.form_data.get('line_metrics', [])line_metrics = [] if not line_metrics else line_metricsmetrics = self.all_metricslegend, data = [], []for mt in metrics:m_label = utils.get_metric_name(mt)ys = series[m_label]if df[m_label].dtype.kind not in "biufc":continuelegend.append(m_label)info = {"name": m_label,"data": [ys.get(ds, None) for ds in df.index],"type": ''}if mt in bar_metrics:info['type'] = 'bar'elif mt in line_metrics:info['type'] = 'line'else:continuedata.append(info)chart_data = {'legend': legend,'data': data,'x_data': [str(ds) if not isinstance(ds, tuple) else ','.join(map(str, ds)) for ds in df.index]}return chart_datadef get_data(self, df: pd.DataFrame):# 后端返回的数据df = df.pivot_table(index=self.groupby, values=self.metric_labels)chart_data = self.to_series(df)return chart_data

echarts mix-line-bar 图表字段理解
官方 构建新图表option 例子
https://www.echartsjs.com/examples/zh/editor.html?c=mix-line-bar

echarts 配置手册 options 参数
https://www.echartsjs.com/zh/option.html#series-bar

echarts api文档
https://www.echartsjs.com/zh/api.html#echarts
——————————————————————————————————————————

严格按照教程执行,最后添加echarts可以直接用npm 安装一下这一个包就可以,npm install echarts@4.7.0

最后

superset init
superset run
npm run buuild
npm run dev

汉化与问题记录

  • 问题记录

    1. expore报错:xpected string or bytes-like object
    2. Mix Line Bar:返回 ‘mix_line_bar’
    3. 点击An error occurred while loading the SQL,报错An error occurred while loading the SQL

    1和3问题解决:数据源里面不能有全是NULL的列。

    问题3:我把class MixLineBarViz(NVD3Viz):加错位置了,不能加在末尾,因为末尾有个注册,要加在incubator-superset\superset\viz.py 和其它类同级的地方,约2890行。

  • 问题记录
    选择图表类型发现新增的图表比例不一样,用win自带的画图3D编辑,把画布改成512*512即可。

    新图表名称修改:superset/viz.py + 2984: verbose_name = _(“Mix Line Bar”)
    我们仍然用国际化的方案。在translations/zh/文件夹下找到message.*三个文件

    message.json末尾(这个文件其实也可以用 po2json messages.po messages.json -f jed1.x -p 来生成。

             "Line Width": ["线宽"],"Mix Line Bar":["柱状折线图"]
    

    message.po末尾添加,我这里顺便把源码没有完成的汉化注释取消了,以后需要手动在代码里添加了。

    源码在 5176行开始都是没有完成的。

    #: src\visualizations\MixLineBar\MixLineBarChartPlugin.js:8
    msgid "Mix Line Bar"
    msgstr "柱状折线图"#: src\explore\controls.jsx:1969  src\explore\controlPanels\MixLineBar.js:27
    msgid "Line Type"
    msgstr "折线图"#: src\explore\controls.jsx:1969
    msgid "Line Type Metrics"
    msgstr "折线图字段"#:incubator-superset-0.36\superset-frontend\src\explore\controlPanels\MixLineBar.js:34
    msgid "Bar Type"
    msgstr "柱状图"#: src\explore\controls.jsx:1978
    msgid "Bar Type Metrics"
    msgstr "柱状图字段"#:incubator-superset-0.36\superset-frontend\src\explore\controlPanels\MixLineBar.js:41
    msgid "Real Y Axis 2 Display Columns"
    msgstr "Y2轴显示的列"#:incubator-superset-0.36\superset-frontend\src\explore\controls.jsx:1987,2044
    msgid "Y Axis 2 Column"
    msgstr "选择Y2轴的列"#:incubator-superset-0.36\superset-frontend\src\explore\controlPanels\MixLineBar.js:49
    msgid "Y Axis 1 Scale Value Setting"
    msgstr "Y轴标度值设置"#:incubator-superset-0.36\superset-frontend\src\explore\controls.jsx:1992,1995
    msgid "Left Y Min"
    msgstr "Y轴下边界"#:incubator-superset-0.36\superset-frontend\src\explore\controls.jsx:1999,2002
    msgid "Left Y Max"
    msgstr "Y轴上边界"#:incubator-superset-0.36\superset-frontend\src\explore\controls.jsx:2006,2009
    msgid "Left Y Interval"
    msgstr "Y轴比例尺间隔"#:incubator-superset-0.36\superset-frontend\src\explore\controlPanels\MixLineBar.js:57
    msgid "Y Axis 2 Scale Value Setting"
    msgstr "Y2轴标度值设置"#:incubator-superset-0.36\superset-frontend\src\explore\controls.jsx:2013,2016
    msgid "Right Y Min"
    msgstr "Y2轴下边界"#:incubator-superset-0.36\superset-frontend\src\explore\controls.jsx:2020,2023
    msgid "Right Y Max"
    msgstr "Y2轴上边界"#:incubator-superset-0.36\superset-frontend\src\explore\controls.jsx:2027,2030
    msgid "Right Y Interval"
    msgstr "Y2轴比例尺间隔"#:incubator-superset-0.36\superset-frontend\src\explore\controls.jsx:2034
    msgid "Y Axis 2 Label"
    msgstr "Y2轴标签"
    

    回到superset文件夹,在env0.36虚拟环境下运行

    pybabel compile -d translations  # 汉化
    cd translations/zh/LC_MESSAGES
    po2json messages.po messages.json -f jed1.x -p   # -f -p 参数可以参考官网
    

    然后 superset init,superset run, npm run build, npm run dev即可。

    优化:incubator-superset-0.36\superset-frontend\src\visualizations\MixLineBar\MixLineBar.js添加保存等动作toolbox。

     // echarts 渲染图表的数据格式 在官网可以查看var option = {tooltip: {trigger: 'axis',axisPointer: {type: 'cross',crossStyle: {color: '#999'}}},toolbox: {feature: {dataView: {show: true, readOnly: false},magicType: {show: true, type: ['line', 'bar']},restore: {show: true},saveAsImage: {show: true}}},
    

    问题记录:图例不支持自定义,且改了中文标签依然显示的实例英文的SQL表达式 。
    解决:点击simple上面的编辑按钮,这里填入你想显示的标签。

    问题记录:Y2轴无法选择要显示的列。
    解决方案:并非bug,这里需要你把需要使用的列手动输入一个SQL表达式:比如在选择了折线图有个字段SUM(a),想把它对齐右侧Y轴,那就在自定义那里填上去。

superset集成echarts相关推荐

  1. Apache Superset集成Echarts

    一.环境准备 1.1 软件环境 npm,nodejs 二.主要步骤 2.1.添加漏斗图模型 cd venv/lib/python2.7/site-packages/supersetvi viz.py ...

  2. superset集成echarts,自定义图表开发

    环境 系统:centos7 python版本:3.7.6 superset版本:0.30 echarts版本:4.2.0以上 说明 因为一开始使用pip(安装方法)直接安装的时候,进入安装路径下没有s ...

  3. 获取this_小程序获取微信运动步数并集成echarts报表显示

    需求 现在运动计步非常的火,大家常用的计步工具一般有keep.咕咚.微信运动和其他移动设备等,本文是基于微信小程序获取用户的微信运动数据并可视化呈现出来. 先看一下最终实现效果: 微信运动规则 在开发 ...

  4. 在Leaflet地图上集成Echarts

    需求背景: 现在我要在地图上加上Echarts的散点图还有线集,看起来就很牛B的那种.上效果图: 需求分析: 我先看了看Echarts官网上有提供加载地图的例子,主要包括三种方式: 1.加载js格式的 ...

  5. 小程序获取微信运动步数并集成echarts报表显示

    需求 现在运动计步非常的火,大家常用的计步工具一般有keep.咕咚.微信运动和其他移动设备等,本文是基于微信小程序获取用户的微信运动数据并可视化呈现出来. 先看一下最终实现效果: 微信运动规则 在开发 ...

  6. vue集成echarts map3d地图(省市下穿)

    最近项目中需要集成echarts中的map3D地图,开发过程中遇到过不少问题,这里mark下,有遇到相应问题的伙伴欢迎一起交流 相关源码下载 1.世界地图.js,中国地图.js,中国各省份地图.js ...

  7. Superset集成Basic Line Chart(二重奏:mapStateToProps)

    superset版本:0.28 echarts版本:3.8.5 这篇我们来到Basic Line chart的集成,这之前安装各种软件巴拉巴拉的不再赘述,可以去我上一篇查看哦. 之所以写集成Basic ...

  8. EBS 请求输出Html报表集成Echarts

    百度开源的ECharts有样式丰富且美观的报表类型可供选用,可以将其集成至EBS请求输出的Html报表中,这其实就是一个生成Html数据的过程. 定义输出类型为HTML的请求我就不在此处赘述. 我们以 ...

  9. superset集成echarts--添加Line折线图

    环境  Python 3.8.10 windows 10 专业版 node v16.16.0 superset1.5 一.\superset\superset-frontend\src\visuali ...

最新文章

  1. 如何检测如果滚动条是否可见控件上
  2. (九)HTML5本地存储——本地数据库SQLLite的使用
  3. 对事务的特性ACID的理解
  4. 虚拟服务器问题,虚拟主机常见的五大问题
  5. 【CodeForces - 219D 】Choosing Capital for Treeland (树形dp)
  6. 转网口显示未识别的网络_已有1700万用户携号转网 超99%用户1小时内办结
  7. 三星s9android recovery,三星手机怎么进入recovery模式?详细图文教程指导
  8. bcb series清除前面的点_新iPhone前面板曝光:丑刘海还在,但边框窄了
  9. hive分桶表join_Hive知识梳理
  10. python截图模块_pyscreenshot
  11. 网页特效代码大全网址
  12. ELK官方文档:在Kibana加密通讯
  13. iOS申请真机调试证书 图文详解
  14. 使用Python读取pdf文件
  15. 安装cPanelWHM 技巧
  16. 关于高精度交流恒流源设计是怎样的?
  17. xp无线网卡开启的服务器,笔记本xp系统开启无线网卡的方法
  18. bzoj1615 【Usaco2008 Mar】The Loathsome Hay Baler 麻烦的干草打包机
  19. 财富自由的概念(通向财富自由学习笔记一)
  20. java+vue实现前后端导出html的word文档

热门文章

  1. 【算法】深度搜索(DFS) 和 广度搜索(BFS)
  2. linux驱动管道,Xilinx Linux 如何理解V4L2的管道驱动程序
  3. 阿里持续投入文娱,“细火慢炖”的卡位战
  4. ps人物素描及黑白上色
  5. 转型之路:从数字化到数智化〡数智洞察
  6. 深度分析AI新职位丨人工智能训练师是什么?做什么的?发展前景如何?
  7. 《视频解密》中文版(第四版) 第七章 数字视频处理(第一部分)
  8. window.open打开新标签页面
  9. c语言20s计数器,计数器延时程序与级联程序的plc梯形图实现
  10. linux运行docker容器,添加映射端口