superset 接入可视化echarts图表

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!