Superset 0.28三奏曲——安装、集成ECharts和汉化

1 环境和版本

操作系统:CentOS Linux release 7.5.1804 (Core)
python版本:3.6.4(直接安装Anaconda即可)

2 一奏曲——Superset安装(0.28版本)

Superset 0.22版本的看板中存在很多bug,比如:多个类型一样的图表加入到看板中,只有第一个图可以显示,其他同类型的图均显示不出。在最新版本中不存在,故建议安装最新版本Superset 0.28。
(1)万事开头难。首先咱们得要先安装Anaconda,因为接下来需要用到pip,去这里下载安装,最新Superset支持使用python3的版本。
(2)安装superset

pip install superset

   
   
   
   

划重点!用pip安装的最新版本Superset的目录与0.28.1版本源码有差异,其实是不全,去这里下载源码,下载好之后,要用源码中Superset\superset\assets下的src目录替换自己安装的superset的assets下的src目录即可,这个步骤为后续集成ECharts做准备。
(3)初始化

fabmanager create-admin --app superset   //创建管理员账号

superset db upgrade   //初始化数据库

superset load_examples   //载入模板数据

superset init   //初始化角色和权限

superset runserver -d -p 8088  //启动服务,端口号 8088,使用 -p 更改端口号

   
   
   
   

最后如果浏览器进入不了登录界面,这是因为防火墙的问题,打开就好了。
(4)后台运行superset
使用如下命令,就可以让superset在后台运行,就不用每一次启动服务了。

nohup superset runserver -d -p 8088 &

tail -f nohup.out 

   
   
   
   

有图有真相!
Superset 0.28三奏曲——安装、集成ECharts和汉化_第1张图片
(5)安装编译前端需要的js包
这一步是为接下来的ECharts集成做准备,进入到superset\static\assets下,在命令行中输入

npm install

   
   
   
   

(6)编译前端
需要的包全部安装完之后,进入superset\static\assets下,在命令行中输入

npm run dev

   
   
   
   

这一步如果报错,排除语法和权限问题,是包没有安装全的原因,一定要把包安装全才行。
我遇到的是这两个错误:Superset 0.28三奏曲——安装、集成ECharts和汉化_第2张图片

ERROR in ./src/visualizations/index.js 86:19
Module parse failed: Unexpected token (86:19)
You may need an appropriate loader to handle this file type.
| var loadNvd3 = function () {
|   function loadNvd3() {
>     return loadVis(import( /* webpackChunkName: "nvd3_vis" */'./nvd3/adaptor.jsx'));
|   }
| 
 @ ./src/modules/AnnotationTypes.js 15:15-30
 @ ./src/chart/chartAction.js
 @ ./src/explore/components/ExploreViewContainer.jsx
 @ ./src/explore/App.jsx
 @ ./src/explore/index.jsx
 @ multi babel-polyfill ./src/explore/index.jsx

   
   
   
   

把包安装全之后,再执行npm run dev命令,编译就通过了。之后在ECharts集成时就可以看到实时编译的网页效果了。

3 二奏曲——Superset集成ECharts(重点)

Superset集成ECharts其实说来也简单,主要操作5个地方,分别是:
(1)后端文件
处理传入前端的数据格式
superset/viz.py
(2)前后端函数匹配文件
superset/static/assets/src/visualizations/index.js
(3)你的新增图表名称.js
superset/static/assets/src/visualizations/你的新增图表名称.js
(4)前端图标配置区组件设置
它是Superset左侧的GroupBy等组件的开关,需根据你新增的图表要用的数据格式选择合适的组件
superset/static/assets/src/explore/visTypes.jsx
(5)缩略图
superset/static/assets/images/viz_thumbnails
下面来举两个集成Echarts图表的例子

3.1 极坐标柱状图

(1)后端文件
进入到superset/viz.py文件中,在BaseViz类的下方和TableViz的上方加入如下代码(与其他的相似):

class EchartsBarPolar(BaseViz):
    viz_type = 'echarts_bar_polar' #对应前端的名字
    is_timeseries = False
    def should_be_timeseries(self):
        fd = self.form_data
        conditions_met = (
            (fd.get('granularity') and fd.get('granularity') != 'all') or
            (fd.get('granularity_sqla') and fd.get('time_grain_sqla'))
        )
        if fd.get('include_time') and not conditions_met:
            raise Exception(_(
                'Pick a granularity in the Time section or '
                "uncheck 'Include Time'"))
        return fd.get('include_time')
    def query_obj(self):
        d = super(EchartsBarPolar, self).query_obj()
        fd = self.form_data
        if fd.get('all_columns') and (fd.get('groupby') or fd.get('metrics')):
            raise Exception(_(
                'Choose either fields to [Group By] and [Metrics] or '
                '[Columns], not both'))
        sort_by = fd.get('timeseries_limit_metric')
        if fd.get('all_columns'):
            d['columns'] = fd.get('all_columns')
            d['groupby'] = []
            order_by_cols = fd.get('order_by_cols') or []
            d['orderby'] = [json.loads(t) for t in order_by_cols]
        elif sort_by:
            if sort_by not in d['metrics']:
                d['metrics'] += [sort_by]
            d['orderby'] = [(sort_by, not fd.get('order_desc', True))]
        if 'percent_metrics' in fd:
            d['metrics'] = d['metrics'] + list(filter(
                lambda m: m not in d['metrics'],
                fd['percent_metrics'],
            ))
        d['is_timeseries'] = self.should_be_timeseries()
        return d
    def get_data(self, df):
        fd = self.form_data
        if not self.should_be_timeseries() and DTTM_ALIAS in df:
            del df[DTTM_ALIAS]
        return dict(
            records=df.to_dict(orient='records'),
            columns=list(df.columns),
        )

   
   
   
   

(2)前后端函数匹配文件
进入到superset/static/assets/src/visualizations/index.js文件中,
在export const VIZ_TYPES里新增

echarts_bar_polar: 'echarts_bar_polar',

   
   
   
   

在const vizMap里新增

[VIZ_TYPES.echarts_bar_polar]: () => loadVis(import(/*webpackChunkName: 'echarts_bar_polar' */ './echarts_bar_polar.js')),

   
   
   
   

(3)echarts_bar_polar.js
在superset/static/assets/src/visualizations文件夹下,放入echarts_bar_polar.js文件,代码如下:

import echarts from 'echarts';
import {getColorFromScheme} from '../javascripts/modules/colors';
function EchartsBarPolarVis(slice, payload) {
    var div = d3.select(slice.selector);
    const sliceId = 'e_bar_polar' + slice.formData.slice_id
    var html = '
'; div.html(html); var myChart = echarts.init(document.getElementById(sliceId)); var option = { angleAxis: { type: 'category', data: [], z: 10 }, radiusAxis: {}, polar: {}, series: [] }; myChart.setOption(option); const fd = slice.formData; const json = payload.data; const data = json; const records = data['records']; const data_column = data.columns; const metrics = fd.metrics; const group_by = fd.groupby; var legend_name = []; var axis_name = []; var series_data = []; for (var i = 0; i < records.length; i++) { axis_name.push(records[i][data_column[0]]); } for (var i = 0; i < metrics.length; i++) { legend_name.push(metrics[i]); var tmp_data = []; for (var j = 0; j < records.length; j++) { tmp_data.push(records[j][metrics[i]]); } series_data.push( { type: 'bar', data: tmp_data, coordinateSystem: 'polar', name: legend_name[i], stack: 'a' } ) } var option2 = { angleAxis: { data: axis_name }, series: series_data }; myChart.setOption(option2); } module.exports = EchartsBarPolarVis;

(4)前端图标配置区组件设置
进入superset/static/assets/src/explore/visTypes.jsx文件中,在export const visTypes里新增如下代码:

echarts_bar_polar: {
        label: t('Bar Polar'),
        showOnExplore: true,
        controlPanelSections: [
            {
                label: t('GROUP BY'),
                controlSetRows: [
                    ['groupby'],
                    ['metrics'],
                    ['percent_metrics'],
                    ['include_time'],
                    ['timeseries_limit_metric', 'order_desc'],
                ],
            },
            {
                label: t('NOT GROUPED BY'),
                description: t('Use this section if you want to query atomic rows'),
                controlSetRows: [
                    ['all_columns'],
                    ['order_by_cols'],
                ],
            },
            {
                label: t('Options'),
                controlSetRows: [
                    ['table_timestamp_format'],
                    ['row_limit', 'page_length'],
                    ['include_search', 'table_filter'],
                ],
            },
        ],
        controlOverrides: {
            metrics: {
                validators: [],
            },
            time_grain_sqla: {
                default: null,
            },
        },
    },

   
   
   
   

(5)缩略图
在superset/static/assets/images/viz_thumbnails文件夹下放入极坐标柱状图的缩略图
Superset 0.28三奏曲——安装、集成ECharts和汉化_第3张图片
到此极坐标柱状图就集成好啦,快来看看下面的效果吧!

Superset 0.28三奏曲——安装、集成ECharts和汉化_第4张图片

3.2 中国地图(可下钻至市级)

(1)后端文件
进入到superset/viz.py文件中,在BaseViz类的下方和TableViz的上方加入如下代码(与其他的相似):

class ChinaMap(BaseViz):
    """ ChinaMap viz """
    viz_type = 'ChinaMap' 
    verbose_name = _('ChinaMap')
    is_timeseries = False
    def get_data(self, df):
        form_data = self.form_data
        df.sort_values(by=df.columns[0], inplace=True)
        print(df.values.tolist())
        ori_data = df.values.tolist()
        data = [{'name' : ori_data[i][0], 'value' : ori_data[i][1]} for i in range(len(ori_data))]
        data_name = [ori_data[i][0] for i in range(len(ori_data))]
        max_data = max([ori_data[i][1] for i in range(len(ori_data))])
        min_data = min([ori_data[i][1] for i in range(len(ori_data))])
        return [data, data_name, max_data, min_data]

   
   
   
   

(2)前后端函数匹配文件
进入到superset/static/assets/src/visualizations/index.js文件中,
在export const VIZ_TYPES里新增

ChinaMap: 'ChinaMap',

   
   
   
   

在const vizMap里新增

[VIZ_TYPES.ChinaMap]: () => loadVis(import(/*webpackChunkName: 'ChinaMap' */ './ChinaMap.js')),

   
   
   
   

(3)ChinaMap.js
在superset/static/assets/src/visualizations文件夹下,放入ChinaMap.js文件,代码如下:

import echarts from 'echarts';
require('echarts/map/js/china.js');
require('echarts/map/js/province/index.js');
function ChinaMapVis(slice, payload) {
    const div = d3.select(slice.selector);
    const sliceId = 'echarts_slice_' + slice.formData.slice_id;
    const html = '
'; div.html(html); // reset const myChart = echarts.init(document.getElementById(sliceId)); const get_data = payload.data; const data_value = get_data[0]; const data_name = get_data[1]; const max_data = get_data[2]; const min_data = get_data[3]; const option = { title : { subtext:'点击进入下一级,双击返回中国地图', x:'center', bottom:'5%' }, tooltip : { trigger: 'item', formatter: "{c}" }, toolbox: { show: true, orient: 'vertical', left: 'right', top: 'center', feature: { dataView: {readOnly: false}, restore: {}, saveAsImage: {} } }, visualMap: { //type: 'continuous', min: min_data, max: max_data, text:['高','低'], realtime: false, calculable: true, //right:'-15%', inRange:{ color: ['#d0f4fc', '#a9dbf6', '#9cd3f4', '#93cdf3', '#83c2f0', '#6eb5ed', 'yellow'] } }, series : [ { type : 'map', map: 'china', selectedMode: 'single', roam: 'scale', data : data_value, label: { normal: { show: true, textStyle:{color:"#b6a38a"} }, emphasis: { show: true, textStyle:{color:"#ff6347"} } }, itemStyle: { emphasis: { areaColor:"#2e4783", borderWidth: 0 } } } ] }; myChart.setOption(option); myChart.on('mouseover', function (params) { var dataIndex = params.dataIndex; console.log(dataIndex); }); myChart.on('click', function (chinaParam) { if (chinaParam.name == chinaParam.name &&data_name.indexOf(chinaParam.name)>-1) { var option = myChart.getOption(); option.series[0].map = chinaParam.name; myChart.setOption(option); } }); myChart.on('dblclick', function (chinaParam) { if (myChart.getOption().series[0].map != 'china') { var option = myChart.getOption(); option.series[0].map = 'china'; myChart.setOption(option); } }); } module.exports = ChinaMapVis;

(4)前端图标配置区组件设置
进入superset/static/assets/src/explore/visTypes.jsx文件中,在export const visTypes里新增如下代码:

ChinaMap: {
        label: t('ChinaMap'),
        showOnExplore: true,
        controlPanelSections: [
            {
                label: t('GROUP BY'),
                controlSetRows: [
                    ['groupby'],
                    ['metrics'],
                    ['percent_metrics'],
                    ['include_time'],
                    ['timeseries_limit_metric', 'order_desc'],
                ],
            },
            {
                label: t('NOT GROUPED BY'),
                description: t('Use this section if you want to query atomic rows'),
                controlSetRows: [
                    ['all_columns'],
                    ['order_by_cols'],
                ],
            },
            {
                label: t('Options'),
                controlSetRows: [
                    ['table_timestamp_format'],
                    ['row_limit', 'page_length'],
                    ['include_search', 'table_filter'],
                ],
            },
        ],
        controlOverrides: {
            metrics: {
                validators: [],
            },
            time_grain_sqla: {
                default: null,
            },
        },
    },

   
   
   
   

(5)缩略图
在superset/static/assets/images/viz_thumbnails文件夹下放入中国地图的缩略图
Superset 0.28三奏曲——安装、集成ECharts和汉化_第5张图片
到此中国地图就集成好啦,快来看看下面的效果吧!点击中国地图的省份可以下钻到市级,双击返回中国地图。
Superset 0.28三奏曲——安装、集成ECharts和汉化_第6张图片
在上面的图中点击北京市,可进行下钻,双击可返回中国地图。
Superset 0.28三奏曲——安装、集成ECharts和汉化_第7张图片

4 三奏曲——汉化

在superset/translations/zh/LC_MESSAGES安装目录下有两个文件:messages.po文件和messages.json文件,只需要把这两个文件中的英文对应的中文添上,这可是个费时的工作,然后编译即可。
(1)messages.po文件
在msgstr字段中添上对应的中文
Superset 0.28三奏曲——安装、集成ECharts和汉化_第8张图片
(2)messages.json文件
在[""]中添上对应的中文
Alt
(3)设置默认语言为中文
在superset目录下有一个config.py文件,编辑它,找到BABEL_DEFAULT_LOCALE处,更改为’zh’,如下图:
Superset 0.28三奏曲——安装、集成ECharts和汉化_第9张图片
(4)编译
翻译完英文之后就可以在superset目录下进行编译了 ,命令如下:

pybabel compile -d translations

   
   
   
   

重启Superset即可看到汉化之后的成果啦!

5 总结

从升级安装Superset,到Superset集成ECharts,最后在汉化,这个过程总共用了七天的时间,收获还是很大的,有了些进步,对于前后端也有了些认识。回头再看看Superset这个BI工具真的太棒了,各种图非常炫,对于数据的分析也是非常轻松。可视化是数据的一种重要的呈现形式,也是数据分析的“最后一公里”,Superset绝对算得上一名有实力的高富帅,快来使用吧!

原文链接:https://blog.csdn.net/qq_33703137/article/details/87874277

Superset 0.28三奏曲——安装、集成ECharts和汉化_第10张图片
欢迎关注,本号将持续分享本人在编程路上的各种见闻。

你可能感兴趣的:(Superset 0.28三奏曲——安装、集成ECharts和汉化)