Skip to content

Commit

Permalink
Added DeckGL.Polygon Layer w/ JS controls (apache#4227)
Browse files Browse the repository at this point in the history
* 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 (apache#4217)

As they are external resources.

* Fix tutorial doesn't match the current interface apache#4138 (apache#4215)

* [bugfix] markup and iframe viz raise 'Empty query' (apache#4225)

closes apache#4222

Related to: apache#4016

* [bugfix] time_pivot entry got missing in merge conflict (apache#4221)

PR here apache#3518 missed a
line of code while merging conflicts with time_pivot viz

* Improve deck.gl GeoJSON visualization (apache#4220)

* Improve geoJSON

* Addressing comments

* lint

* refactor to leverage line_column controls

* refactor to use DeckPathViz

* oops
  • Loading branch information
hughhhh committed Jan 18, 2018
1 parent ee77f11 commit 1c76d58
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 1 deletion.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions superset/assets/javascripts/explore/stores/controls.jsx
Expand Up @@ -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,
Expand Down
40 changes: 40 additions & 0 deletions superset/assets/javascripts/explore/stores/visTypes.js
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions superset/assets/visualizations/deckgl/layers/index.js
Expand Up @@ -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,
Expand All @@ -15,5 +16,6 @@ const layerGenerators = {
deck_scatter,
deck_geojson,
deck_arc,
deck_polygon,
};
export default layerGenerators;
28 changes: 28 additions & 0 deletions superset/assets/visualizations/deckgl/layers/polygon.jsx
@@ -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),
});
}
2 changes: 2 additions & 0 deletions superset/assets/visualizations/main.js
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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;
30 changes: 30 additions & 0 deletions superset/data/__init__.py
Expand Up @@ -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:
Expand Down
Binary file added superset/data/sf_population.json.gz
Binary file not shown.
13 changes: 12 additions & 1 deletion superset/viz.py
Expand Up @@ -1899,6 +1899,7 @@ def get_data(self, df):
if extra_props:
feature['extraProps'] = extra_props
features.append(feature)

return {
'features': features,
'mapboxApiKey': config.get('MAPBOX_API_KEY'),
Expand Down Expand Up @@ -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,
Expand All @@ -2003,10 +2005,19 @@ def get_properties(self, d):
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"""
Expand Down

0 comments on commit 1c76d58

Please sign in to comment.