superset添加echarts图
为支持更多可视化图表,我司准备在seperset原始D3图表基础上,继续增加echarts可视化图表的类型,以供客户更直观的看到数据。这篇文章里将分为四个步骤,每个步骤紧密联系,缺一不可。
效果图:
目前已添加echarts图表。
最后通过查询,我们得到的实体数据通过添加的echarts图表已经显示。
步骤一:选择添加的echarts图,[charts官方实例]echarts.baidu.com/examples/
我选择了堆叠条形图:bar-y-category-stack(这个英文名称就是对应顶部链接最后的名称,本文添加的图表的所有名称都叫bar-y-category-stack,因为添加的多了方便辨别区分)
1.1 在visualizations文件夹下建立echarts_bar_y_category.js文件,这个文件是做echarts配置项。
import echarts from 'echarts';
function echartsAngularGaugeVis(slice, payload) {
const div = d3.select(slice.selector);
const sliceId = 'echarts_slice_' + slice.formData.slice_id;
const html = '<div id="main" style="width: ' + slice.width() + '' + 'px;height:' + slice.height() + 'px;">hahah</div>';
div.html(html); // reset
var myChart = echarts.init(document.getElementById('main'));
const params = payload.data;
console.log(params, 123);
var data_name = [];
var series = [];
var data_values = [];
var series_data = [];
params.forEach(function (item, index, array) {
data_name.push(item['key']);
item['values'].forEach(function (i, index, array) {
data_values.push(i['y']);
});
series_data = {
name:item['key'],
type: 'bar',
data: data_values
};
series.push(series_data)
});
var category_name = [];
params[0]['values'].forEach(function (item, index, array) {
category_name.push(item['x'])
});
const option = {
// title: {
// text: 'undefined - 无标题'
// },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value',
boundaryGap: [0, 0.01]
},
yAxis: {
type: 'category',
data: category_name
},
series: series
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
}
module.exports = echartsAngularGaugeVis;
复制代码
1.2 保存图片(路径是\superset\static\assets\images\viz_thumbnails)
步骤二:添加文件。找到superset\static\assets\images\viz_thumbnails下的index.js
2.1 VIZ_TYPES这个对象里添加 echarts_bar_y_category: 'echarts_bar_y_category'
2.2 vizMap添加 [VIZ_TYPES.echarts_bar_y_category]: require('./echarts_bar_y_category.js'),
步骤三:查询条件配置。找到superset\static\assets\src\explore目录下的visTypes.js
echarts_bar_y_category: {
label: t('Echarts Bar Y Category'), // 表的名称
showOnExplore: true,
controlPanelSections: [ // 查询条件配置参数,每个图的参数都不一样
{
label: t('Query'),
expanded: true,
controlSetRows: [
['metrics'],
['groupby'],
['columns'],
['row_limit'],
['contribution'],
],
},
{
label: t('Chart Options'),
expanded: true,
controlSetRows: [
['color_scheme'],
['show_legend', 'show_bar_value'],
['bar_stacked', 'order_bars'],
['y_axis_format', 'y_axis_label'],
['show_controls', null],
],
},
{
label: t('X Axis'),
expanded: true,
controlSetRows: [
['x_axis_label', 'bottom_margin'],
['x_ticks_layout', 'reduce_x_ticks'],
],
},
],
controlOverrides: {
groupby: {
label: t('Series'),
},
columns: {
label: t('Breakdowns'),
description: t('Defines how each series is broken down'),
},
},
},
复制代码
步骤三:后端数据导出给前端的viz.py文件配置。
class Echarts_Bar_Y_Category(DistributionPieViz):
"""A good old bar chart"""
viz_type = 'echarts_bar_y_category'
verbose_name = _('Bar Y Category')
is_timeseries = False
def query_obj(self):
d = super(Echarts_Bar_Y_Category, self).query_obj() # noqa
fd = self.form_data
if (
len(d['groupby']) <
len(fd.get('groupby') or []) + len(fd.get('columns') or [])
):
raise Exception(
_("Can't have overlap between Series and Breakdowns"))
if not fd.get('metrics'):
raise Exception(_('Pick at least one metric'))
if not fd.get('groupby'):
raise Exception(_('Pick at least one field for [Series]'))
return d
def get_data(self, df):
fd = self.form_data
row = df.groupby(self.groupby).sum()[self.metrics[0]].copy()
row.sort_values(ascending=False, inplace=True)
columns = fd.get('columns') or []
pt = df.pivot_table(
index=self.groupby,
columns=columns,
values=self.metrics)
if fd.get('contribution'):
pt = pt.fillna(0)
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, string_types):
series_title = name
elif len(self.metrics) > 1:
series_title = ', '.join(name)
else:
l = [str(s) for s in name[1:]] # noqa: E741
series_title = ', '.join(l)
values = []
for i, v in ys.items():
x = i
if isinstance(x, (tuple, list)):
x = ', '.join([text_type(s) for s in x])
else:
x = text_type(x)
values.append({
'x': x,
'y': v,
})
d = {
'key': series_title,
'values': values,
}
chart_data.append(d)
return chart_data
复制代码
至此 完结!best regards!