mirror of https://github.com/apache/superset.git
Added DeckGL.Polygon Layer w/ JS controls (#4227)
* Working polygon layer for deckGL * add js controls * add thumbnail * better description * refactor to leverage line_column controls * templates: open code and documentation on a new tab (#4217) As they are external resources. * Fix tutorial doesn't match the current interface #4138 (#4215) * [bugfix] markup and iframe viz raise 'Empty query' (#4225) closes https://github.com/apache/incubator-superset/issues/4222 Related to: https://github.com/apache/incubator-superset/pull/4016 * [bugfix] time_pivot entry got missing in merge conflict (#4221) PR here https://github.com/apache/incubator-superset/pull/3518 missed a line of code while merging conflicts with time_pivot viz * Improve deck.gl GeoJSON visualization (#4220) * Improve geoJSON * Addressing comments * lint * refactor to leverage line_column controls * refactor to use DeckPathViz * oops
This commit is contained in:
parent
cab8e7d22d
commit
5079b2aa95
Binary file not shown.
After Width: | Height: | Size: 433 KiB |
|
@ -571,6 +571,16 @@ export const controls = {
|
|||
}),
|
||||
},
|
||||
|
||||
polygon: {
|
||||
type: 'SelectControl',
|
||||
label: t('Polygon Column'),
|
||||
validators: [v.nonEmpty],
|
||||
description: t('Select the polygon column. Each row should contain JSON.array(N) of [longitude, latitude] points'),
|
||||
mapStateToProps: state => ({
|
||||
choices: (state.datasource) ? state.datasource.all_cols : [],
|
||||
}),
|
||||
},
|
||||
|
||||
point_radius_scale: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
|
|
|
@ -517,6 +517,46 @@ export const visTypes = {
|
|||
],
|
||||
},
|
||||
|
||||
deck_polygon: {
|
||||
label: t('Deck.gl - Polygon'),
|
||||
requiresTime: true,
|
||||
controlPanelSections: [
|
||||
{
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['line_column', 'line_type'],
|
||||
['row_limit', null],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Map'),
|
||||
controlSetRows: [
|
||||
['mapbox_style', 'viewport'],
|
||||
['reverse_long_lat', null],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Polygon Settings'),
|
||||
controlSetRows: [
|
||||
['fill_color_picker', 'stroke_color_picker'],
|
||||
['filled', 'stroked'],
|
||||
['extruded', null],
|
||||
['point_radius_scale', null],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Advanced'),
|
||||
controlSetRows: [
|
||||
['js_columns'],
|
||||
['js_datapoint_mutator'],
|
||||
['js_tooltip'],
|
||||
['js_onclick_href'],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
deck_arc: {
|
||||
label: t('Deck.gl - Arc'),
|
||||
requiresTime: true,
|
||||
|
|
|
@ -6,6 +6,7 @@ import deck_hex from './hex';
|
|||
import deck_scatter from './scatter';
|
||||
import deck_geojson from './geojson';
|
||||
import deck_arc from './arc';
|
||||
import deck_polygon from './polygon';
|
||||
|
||||
const layerGenerators = {
|
||||
deck_grid,
|
||||
|
@ -15,5 +16,6 @@ const layerGenerators = {
|
|||
deck_scatter,
|
||||
deck_geojson,
|
||||
deck_arc,
|
||||
deck_polygon,
|
||||
};
|
||||
export default layerGenerators;
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import { PolygonLayer } from 'deck.gl';
|
||||
|
||||
import * as common from './common';
|
||||
import sandboxedEval from '../../../javascripts/modules/sandbox';
|
||||
|
||||
export default function polygonLayer(formData, payload, slice) {
|
||||
const fd = formData;
|
||||
const fc = fd.fill_color_picker;
|
||||
let data = payload.data.features.map(d => ({
|
||||
...d,
|
||||
fillColor: [fc.r, fc.g, fc.b, 255 * fc.a],
|
||||
}));
|
||||
|
||||
if (fd.js_datapoint_mutator) {
|
||||
// Applying user defined data mutator if defined
|
||||
const jsFnMutator = sandboxedEval(fd.js_datapoint_mutator);
|
||||
data = data.map(jsFnMutator);
|
||||
}
|
||||
|
||||
return new PolygonLayer({
|
||||
id: `path-layer-${fd.slice_id}`,
|
||||
data,
|
||||
filled: fd.filled,
|
||||
stroked: fd.stoked,
|
||||
extruded: fd.extruded,
|
||||
...common.commonLayerProps(fd, slice),
|
||||
});
|
||||
}
|
|
@ -48,6 +48,7 @@ export const VIZ_TYPES = {
|
|||
deck_geojson: 'deck_geojson',
|
||||
deck_multi: 'deck_multi',
|
||||
deck_arc: 'deck_arc',
|
||||
deck_polygon: 'deck_polygon',
|
||||
};
|
||||
|
||||
const vizMap = {
|
||||
|
@ -95,6 +96,7 @@ const vizMap = {
|
|||
[VIZ_TYPES.deck_path]: deckglFactory,
|
||||
[VIZ_TYPES.deck_geojson]: deckglFactory,
|
||||
[VIZ_TYPES.deck_arc]: deckglFactory,
|
||||
[VIZ_TYPES.deck_polygon]: deckglFactory,
|
||||
[VIZ_TYPES.deck_multi]: require('./deckgl/multi.jsx'),
|
||||
};
|
||||
export default vizMap;
|
||||
|
|
|
@ -1552,6 +1552,36 @@ def load_paris_iris_geojson():
|
|||
tbl.fetch_metadata()
|
||||
|
||||
|
||||
def load_sf_population_polygons():
|
||||
tbl_name = 'sf_population_polygons'
|
||||
|
||||
with gzip.open(os.path.join(DATA_FOLDER, 'sf_population.json.gz')) as f:
|
||||
df = pd.read_json(f)
|
||||
df['contour'] = df.contour.map(json.dumps)
|
||||
|
||||
df.to_sql(
|
||||
tbl_name,
|
||||
db.engine,
|
||||
if_exists='replace',
|
||||
chunksize=500,
|
||||
dtype={
|
||||
'zipcode': BigInteger,
|
||||
'population': BigInteger,
|
||||
'contour': Text,
|
||||
'area': BigInteger,
|
||||
},
|
||||
index=False)
|
||||
print("Creating table {} reference".format(tbl_name))
|
||||
tbl = db.session.query(TBL).filter_by(table_name=tbl_name).first()
|
||||
if not tbl:
|
||||
tbl = TBL(table_name=tbl_name)
|
||||
tbl.description = "Population density of San Francisco"
|
||||
tbl.database = get_or_create_main_db()
|
||||
db.session.merge(tbl)
|
||||
db.session.commit()
|
||||
tbl.fetch_metadata()
|
||||
|
||||
|
||||
def load_bart_lines():
|
||||
tbl_name = 'bart_lines'
|
||||
with gzip.open(os.path.join(DATA_FOLDER, 'bart-lines.json.gz')) as f:
|
||||
|
|
Binary file not shown.
|
@ -1899,6 +1899,7 @@ class BaseDeckGLViz(BaseViz):
|
|||
if extra_props:
|
||||
feature['extraProps'] = extra_props
|
||||
features.append(feature)
|
||||
|
||||
return {
|
||||
'features': features,
|
||||
'mapboxApiKey': config.get('MAPBOX_API_KEY'),
|
||||
|
@ -1982,6 +1983,7 @@ class DeckPathViz(BaseDeckGLViz):
|
|||
|
||||
viz_type = 'deck_path'
|
||||
verbose_name = _('Deck.gl - Paths')
|
||||
deck_viz_key = 'path'
|
||||
deser_map = {
|
||||
'json': json.loads,
|
||||
'polyline': polyline.decode,
|
||||
|
@ -2003,10 +2005,19 @@ class DeckPathViz(BaseDeckGLViz):
|
|||
if fd.get('reverse_long_lat'):
|
||||
path = (path[1], path[0])
|
||||
return {
|
||||
'path': path,
|
||||
self.deck_viz_key: path,
|
||||
}
|
||||
|
||||
|
||||
class DeckPolygon(DeckPathViz):
|
||||
|
||||
"""deck.gl's Polygon Layer"""
|
||||
|
||||
viz_type = 'deck_polygon'
|
||||
deck_viz_key = 'polygon'
|
||||
verbose_name = _('Deck.gl - Polygon')
|
||||
|
||||
|
||||
class DeckHex(BaseDeckGLViz):
|
||||
|
||||
"""deck.gl's DeckLayer"""
|
||||
|
|
Loading…
Reference in New Issue