apt-get update
apt-get install vim
apt-get install zip
接上一篇博客 docker安装完superset之后:
前端: 安装node.js,创建前端编译环境
① 在您的计算机配置中添加存储库:
curl -sL https://deb.nodesource.com/setup_10.x | bash -
② 安装node.js
apt-get install -y nodejs
③ 测试是否安装成功
node -v
npm -v
正式的二次开发添加echarts:
①注意先别着急,现在本地下载一份源码,由于我装的是0.28的版本,因此下载一份源码 ,下载完源码由于链接不生效,需要将incubator-superset-0.28\superset\assets 的assets文件夹整个复制一份到incubator-superset-0.28\superset\static\下,替换之前打不开的assets文件夹
https://github.com/apache/incubator-superset
② docker下载之后发现再src的包不完整,因此需要将刚本地下载的源码的src打包上传到docker中去。
rz ./src.zip
注:当rz出现乱码时,使用rz -be (机器编码不一致造成的,windows文件默认是gbk编码 ,linux文件默认是 utf-8编码)
docker cp ./src.zip 3ebdf90132cb:/usr/local/lib/python3.6/site-packages/superset/static/assets/
③集成echarts图表需要7个地方需要修改,我是采用的再外面统一修改之后上传进去
注意:再此处建议用 root权限登录docker
docker exec -it -u root 3ebdf90132cb bash
1.docker cp ./viz.py 3ebdf90132cb:/usr/local/lib/python3.6/site-packages/superset/
2.docker cp ./index.js 3ebdf90132cb:/usr/local/lib/python3.6/site-packages/superset/static/assets/src/visualizations/
3.docker cp ./echarts_bar_polar.js 3ebdf90132cb:/usr/local/lib/python3.6/site-packages/superset/static/assets/src/visualizations/
4.docker cp ./visTypes.jsx 3ebdf90132cb:/usr/local/lib/python3.6/site-packages/superset/static/assets/src/explore/
5.docker cp ./echarts_bar_polar.png 3ebdf90132cb:/usr/local/lib/python3.6/site-packages/superset/static/assets/images/viz_thumbnails/
6.vi /usr/local/lib/python3.6/site-packages/superset/static/assets/src/modules/colors.js
7.superset/static/assets/package.json 新增 "echarts" : "^4.2.0-rc.2",
下面一步步展开来说:
第一步: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),
)
第二步: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')),
第三步:superset/static/assets/src/visualizations目录下新增echarts_bar_polar.js文件
import echarts from 'echarts';
import {getColorFromScheme} from '../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;
第四步: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,
},
},
},
第五步:superset/static/assets/images/viz_thumbnails文件夹下放入缩略图,命名为echarts_bar_polar.png
第六步:superset/static/assets/src/modules/colors.js 文件进行修改,直接将js文件全部用如下代码覆盖
import d3 from 'd3';
import sequentialSchemes from './colorSchemes/sequential';
export const BRAND_COLOR = '#00A699';
export const PRIMARY_COLOR = { r: 0, g: 122, b: 135, a: 1 };
export const bnbColors = [
'#ff5a5f', // rausch
'#7b0051', // hackb
'#007A87', // kazan
'#00d1c1', // babu
'#8ce071', // lima
'#ffb400', // beach
'#b4a76c', // barol
'#ff8083',
'#cc0086',
'#00a1b3',
'#00ffeb',
'#bbedab',
'#ffd266',
'#cbc29a',
'#ff3339',
'#ff1ab1',
'#005c66',
'#00b3a5',
'#55d12e',
'#b37e00',
'#988b4e',
];
const d3Category10 = d3.scale.category10().range();
const d3Category20 = d3.scale.category20().range();
const d3Category20b = d3.scale.category20b().range();
const d3Category20c = d3.scale.category20c().range();
const googleCategory10c = [
'#3366cc',
'#dc3912',
'#ff9900',
'#109618',
'#990099',
'#0099c6',
'#dd4477',
'#66aa00',
'#b82e2e',
'#316395',
];
const googleCategory20c = [
'#3366cc',
'#dc3912',
'#ff9900',
'#109618',
'#990099',
'#0099c6',
'#dd4477',
'#66aa00',
'#b82e2e',
'#316395',
'#994499',
'#22aa99',
'#aaaa11',
'#6633cc',
'#e67300',
'#8b0707',
'#651067',
'#329262',
'#5574a6',
'#3b3eac',
];
export const ALL_COLOR_SCHEMES = {
bnbColors,
d3Category10,
d3Category20,
d3Category20b,
d3Category20c,
googleCategory10c,
googleCategory20c,
};
export function hexToRGB(hex, alpha = 255) {
if (!hex) {
return [0, 0, 0, alpha];
}
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return [r, g, b, alpha];
}
export const getColorFromScheme = (function () {
const seen = {};
const forcedColors = {};
return function (s, scheme, forcedColor) {
if (!s) {
return;
}
const selectedScheme = scheme ? ALL_COLOR_SCHEMES[scheme] : ALL_COLOR_SCHEMES.bnbColors;
let stringifyS = String(s).toLowerCase();
/* next line is for superset series that should have the same color*/
stringifyS = stringifyS.replace('---', '');
if (forcedColor && !forcedColors[stringifyS]) {
forcedColors[stringifyS] = forcedColor;
}
if (forcedColors[stringifyS]) {
return forcedColors[stringifyS];
}
if (seen[selectedScheme] === undefined) {
seen[selectedScheme] = {};
}
if (seen[selectedScheme][stringifyS] === undefined) {
seen[selectedScheme][stringifyS] = Object.keys(seen[selectedScheme]).length;
}
/* eslint consistent-return: 0 */
return selectedScheme[seen[selectedScheme][stringifyS] % selectedScheme.length];
};
}());
export const colorScalerFactory = function (colors, data, accessor, extents, outputRGBA = false) {
// Returns a linear scaler our of an array of color
if (!Array.isArray(colors)) {
/* eslint no-param-reassign: 0 */
colors = sequentialSchemes[colors];
}
let ext = [0, 1];
if (extents) {
ext = extents;
}
if (data) {
ext = d3.extent(data, accessor);
}
const chunkSize = (ext[1] - ext[0]) / (colors.length - 1);
const points = colors.map((col, i) => ext[0] + (i * chunkSize));
const scaler = d3.scale.linear().domain(points).range(colors).clamp(true);
if (outputRGBA) {
return v => hexToRGB(scaler(v));
}
return scaler;
};
第七步:superset/static/assets/package.json 文件中 新增
"echarts" : "^4.2.0-rc.2",
以上全部都齐全之后,在superset/static/assets 目录下执行:
npm install
npm run dev
之后我习惯重启一下docker
dockers ps
docker restart 3ebdf90132cb
还有需要致谢一下两位大佬的博客,让我有许多学习地方,特别感谢~ 笔芯♥
https://blog.csdn.net/qq_33172735/article/details/87708374
https://blog.csdn.net/qq_33703137/article/details/87874277#commentsedit