介绍
本教程是 为少
基于 Superset 0.37
, Superset 0.37
, Superset 0.37
版本的实操记录。
项目
这是一个系列
- 使用 Docker 探索 Superset BI 数据可视化平台,Docker Compose 搭建本地二次开发环境
- 使用 Docker 探索 Superset BI 数据可视化平台,Superset 数据可视化分析之超详细上手教程
前置基础
Flask 是什么?
Flask 是一个使用 Python 编写的轻量级 Web 应用框架。
NumPy 是什么?
NumPy是Python的一个用于科学计算的基础包。它提供了多维数组对象,多种衍生的对象(例如隐藏数组和矩阵)和一个用于数组快速运算的混合的程序,包括数学,逻辑,排序,选择,I/O,离散傅立叶变换,基础线性代数,基础统计操作,随机模拟等等。
Pandas 是什么?
Pandas是一个强大的分析结构化数据的工具集;它的使用基础是Numpy(提供高性能的矩阵运算);用于数据挖掘和数据分析,同时也提供数据清洗功能。
Echarts 是什么?
ECharts 是一款开源的、基于 web 的、跨平台的支持快速创建交互式可视化的框架,它易于使用、拥有丰富的内置交互以及高性能。ECharts 通过一套声明式的可视设计语言定制内置的图表类型,并且底层的流式架构和高性能的图形渲染器极大地提高了 ECharts 的扩展性和性能。
Echarts Multiple Y Axis 图表
接下来,我们就是要集成它到我们的 Superset
二次开发 Step-By-Step
使用容器环境安装 Echarts
docker-compose ps
docker-compose exec superset-node bash
cd /app/superset-frontend/
npm i echarts
visualizations 文件夹
它位于项目 superset-frontend/src/visualizations
我们在此处新建如下文件夹 EchartsMultipleYAxis
,它包含:
- images (可视化组件展示用的缩略图)
- thumbnail.png
- thumbnailLarge.png
- EchartsMultipleYAxisPlugin.jsx(组件核心逻辑)
- index.js(组件导出)
- options.js(Echarts Multiple Y Axis 图表官方默认配置项)
- transformProps.js(将 Superset 传过来的属性过滤一下)
EchartsMultipleYAxisPlugin.jsx
,为少
这里简单的写了一下(大家可以根据需求自行调整):
.....
function EchartsMultipleYAxisPlugin(elem, props) {
const {
width, height,
data, colorScheme,
} = props;
elem.style.width = width;
elem.style.height = height;
const echart = echarts.init(elem);
let colors = CategoricalColorNamespace.getScale(colorScheme).colors;
defaultOptions.color = colors;
const legend = [];
const xAxisData = [];
let xAxisDataFlag = true;
let yAxisMaxs = [];
defaultOptions.yAxis.forEach((y, index) => {
const sd = data[index];
const title = sd.key;
y.name = sd.key;
y.axisLabel.formatter = `{value}`;
y.axisLine.lineStyle.color = colors[index];
const seriesD = [];
defaultOptions.series[index].data = [];
sd.values.forEach((value) => {
xAxisDataFlag && xAxisData.push(value.x);
defaultOptions.series[index].data.push((value.y).toFixed(2));
})
defaultOptions.series[index].name = y.name
const yAxisMax = Math.max.apply(null, defaultOptions.series[index].data);
y.max = Math.ceil(yAxisMax) + 5;
yAxisMaxs.push(yAxisMax);
xAxisDataFlag = false;
defaultOptions.legend.data.push(y.name);
});
defaultOptions.xAxis[0].data = xAxisData;
echart.setOption(defaultOptions);
}
....
进入 presets/MainPreset.js
,加入如下两句:
......
import EchartsMultipleYAxisChartPlugin from "../EchartsMultipleYAxis";
......
new EchartsMultipleYAxisChartPlugin().configure({ key: 'echarts_multiple_y_axis' })
......
explore 文件夹
进入 superset-frontend/src/explore/components/controls/VizTypeControl.jsx
文件
加入 ‘echarts_multiple_y_axis’,排序一下。
const DEFAULT_ORDER = [
...other,
'echarts_multiple_y_axis'
]
进入 superset-frontend/src/explore/components/controlPanels
文件夹
我们在这里新建一个文件 EchartsMultipleYAxis.js
,为少
在这里加上相关配置。
import { t } from '@superset-ui/translation';
export default {
label: t('Echarts Multiple Y Axis Chart'),
controlPanelSections: [
{
label: t('Query'),
expanded: true,
controlSetRows: [
['metrics'],
['adhoc_filters'],
['groupby'],
['columns'],
['row_limit'],
['contribution'],
],
},
{
label: t('Chart Options'),
expanded: true,
controlSetRows: [
['color_scheme', 'label_colors'],
],
},
],
controlOverrides: {
groupby: {
label: t('Series'),
},
columns: {
label: t('Breakdowns'),
description: t('Defines how each series is broken down'),
},
},
};
setup 文件夹
进入 superset-frontend/src/explore/setupPlugins.ts
,加入如下代码:
....
.registerValue('echarts_multiple_y_axis', EchartsMultipleYAxis)
用来注册下这个插件。
viz.py 文件
我们加入如下 python
代码。
class EchartsMultipleYAxisViz(DistributionPieViz):
"""Echarts Multiple Y Axis Chart"""
viz_type = "echarts_multiple_y_axis"
verbose_name = _("Echarts Multiple Y Axis Chart")
is_timeseries = False
def query_obj(self) -> QueryObjectDict:
d = super().query_obj()
fd = self.form_data
if len(d["groupby"]) < len(fd.get("groupby") or []) + len(
fd.get("columns") or []
):
raise QueryObjectValidationError(
_("Can't have overlap between Series and Breakdowns")
)
if not fd.get("metrics"):
raise QueryObjectValidationError(_("Pick at least one metric"))
if not fd.get("groupby"):
raise QueryObjectValidationError(_("Pick at least one field for [Series]"))
return d
def get_data(self, df: pd.DataFrame) -> VizData:
if df.empty:
return None
fd = self.form_data
metrics = self.metric_labels
columns = fd.get("columns") or []
# pandas will throw away nulls when grouping/pivoting,
# so we substitute NULL_STRING for any nulls in the necessary columns
filled_cols = self.groupby + columns
df[filled_cols] = df[filled_cols].fillna(value=NULL_STRING)
row = df.groupby(self.groupby).sum()[metrics[0]].copy()
row.sort_values(ascending=False, inplace=True)
pt = df.pivot_table(index=self.groupby, columns=columns, values=metrics)
if fd.get("contribution"):
pt = pt.T
pt = (pt / pt.sum()).T
pt = pt.reindex(row.index)
chart_data = []
for name, ys in pt.items():
if pt[name].dtype.kind not in "biufc" or name in self.groupby:
continue
if isinstance(name, str):
series_title = name
else:
offset = 0 if len(metrics) > 1 else 1
series_title = ", ".join([str(s) for s in name[offset:]])
values = []
for i, v in ys.items():
x = i
if isinstance(x, (tuple, list)):
x = ", ".join([str(s) for s in x])
else:
x = str(x)
values.append({"x": x, "y": v})
d = {"key": series_title, "values": values}
chart_data.append(d)
return chart_data
关于 viz.py 代码细节
数据科学本身就是复杂的。
NumPy
or Pandas
都可以拿出来单独讲好久,好久,好久……
选择图表
看效果
参考 & 感谢
未完待续……
今天的文章使用 Docker 探索 Superset BI 数据可视化平台,动真格、二次开发新的可视化组件之集成 Echarts 图表 | 🏆 技术专题第三期征文分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/14815.html