From 5437efa590a708e061d203373bdb9f64fd1f31e0 Mon Sep 17 00:00:00 2001 From: Junda Yang Date: Wed, 29 Aug 2018 15:37:39 -0700 Subject: [PATCH] Fix multilayer geoviz and color picker error (#5767) * Fix multilayer goeviz and color picker error * fix lint * remove props.data and improve merging list * nit --- .../deckgl/CategoricalDeckGLContainer.jsx | 14 ++++++++------ .../src/visualizations/deckgl/layers/arc.jsx | 7 ++++--- .../src/visualizations/deckgl/layers/scatter.jsx | 13 +++++++++---- .../assets/src/visualizations/deckgl/multi.jsx | 9 +++++---- superset/viz.py | 5 ++--- 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx index 1182312049..4c098ce90d 100644 --- a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx +++ b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx @@ -30,11 +30,11 @@ function getCategories(fd, data) { const propTypes = { slice: PropTypes.object.isRequired, - data: PropTypes.array.isRequired, mapboxApiKey: PropTypes.string.isRequired, setControlValue: PropTypes.func.isRequired, viewport: PropTypes.object.isRequired, getLayer: PropTypes.func.isRequired, + payload: PropTypes.object.isRequired, }; export default class CategoricalDeckGLContainer extends React.PureComponent { @@ -50,9 +50,9 @@ export default class CategoricalDeckGLContainer extends React.PureComponent { const fd = nextProps.slice.formData; const timeGrain = fd.time_grain_sqla || fd.granularity || 'PT1M'; - const timestamps = nextProps.data.map(f => f.__timestamp); + const timestamps = nextProps.payload.data.features.map(f => f.__timestamp); const { start, end, step, values, disabled } = getPlaySliderParams(timestamps, timeGrain); - const categories = getCategories(fd, nextProps.data); + const categories = getCategories(fd, nextProps.payload.data.features); return { start, end, step, values, disabled, categories }; } @@ -79,8 +79,9 @@ export default class CategoricalDeckGLContainer extends React.PureComponent { }); } getLayers(values) { - const fd = this.props.slice.formData; - let data = [...this.props.data]; + const { getLayer, payload, slice } = this.props; + const fd = slice.formData; + let data = [...payload.data.features]; // Add colors from categories or fixed color data = this.addColor(data, fd); @@ -103,7 +104,8 @@ export default class CategoricalDeckGLContainer extends React.PureComponent { data = data.filter(d => this.state.categories[d.cat_color].enabled); } - return [this.props.getLayer(fd, data, this.props.slice)]; + payload.data.features = data; + return [getLayer(fd, payload, slice)]; } toggleCategory(category) { const categoryState = this.state.categories[category]; diff --git a/superset/assets/src/visualizations/deckgl/layers/arc.jsx b/superset/assets/src/visualizations/deckgl/layers/arc.jsx index 80b5858aef..883ffbd6c6 100644 --- a/superset/assets/src/visualizations/deckgl/layers/arc.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/arc.jsx @@ -18,7 +18,8 @@ function getPoints(data) { return points; } -function getLayer(fd, data, slice) { +function getLayer(fd, payload, slice) { + const data = payload.data.features; const sc = fd.color_picker; const tc = fd.target_color_picker; return new ArcLayer({ @@ -40,17 +41,17 @@ function deckArc(slice, payload, setControlValue) { }; if (fd.autozoom) { - viewport = common.fitViewport(viewport, getPoints(payload.data.arcs)); + viewport = common.fitViewport(viewport, getPoints(payload.data.features)); } ReactDOM.render( , document.getElementById(slice.containerId), ); diff --git a/superset/assets/src/visualizations/deckgl/layers/scatter.jsx b/superset/assets/src/visualizations/deckgl/layers/scatter.jsx index 07590551ac..d9474a4770 100644 --- a/superset/assets/src/visualizations/deckgl/layers/scatter.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/scatter.jsx @@ -14,13 +14,18 @@ function getPoints(data) { return data.map(d => d.position); } -function getLayer(fd, data, slice) { - const dataWithRadius = data.map((d) => { +function getLayer(fd, payload, slice) { + const dataWithRadius = payload.data.features.map((d) => { let radius = unitToRadius(fd.point_unit, d.radius) || 10; if (fd.multiplier) { radius *= fd.multiplier; } - return { ...d, radius }; + if (d.color) { + return { ...d, radius }; + } + const c = fd.color_picker || { r: 0, g: 0, b: 0, a: 1 }; + const color = [c.r, c.g, c.b, c.a * 255]; + return { ...d, radius, color }; }); return new ScatterplotLayer({ @@ -49,11 +54,11 @@ function deckScatter(slice, payload, setControlValue) { ReactDOM.render( , document.getElementById(slice.containerId), ); diff --git a/superset/assets/src/visualizations/deckgl/multi.jsx b/superset/assets/src/visualizations/deckgl/multi.jsx index 9bd80750a9..8b35c86768 100644 --- a/superset/assets/src/visualizations/deckgl/multi.jsx +++ b/superset/assets/src/visualizations/deckgl/multi.jsx @@ -33,10 +33,11 @@ function deckMulti(slice, payload, setControlValue) { // Filters applied to multi_deck are passed down to underlying charts // note that dashboard contextual information (filter_immune_slices and such) aren't // taken into consideration here - let filters = subslice.form_data.filters.concat(fd.filters); - if (fd.extra_filters) { - filters = filters.concat(fd.extra_filters); - } + const filters = [ + ...(subslice.form_data.filters || []), + ...(fd.filters || []), + ...(fd.extra_filters || []), + ]; const subsliceCopy = { ...subslice, form_data: { diff --git a/superset/viz.py b/superset/viz.py index 5701beb81b..19b8a66012 100644 --- a/superset/viz.py +++ b/superset/viz.py @@ -2166,7 +2166,7 @@ class BaseDeckGLViz(BaseViz): fd = self.form_data # add NULL filters - if fd.get('filter_nulls'): + if fd.get('filter_nulls', True): self.add_null_filters() d = super(BaseDeckGLViz, self).query_obj() @@ -2432,10 +2432,9 @@ class DeckArc(BaseDeckGLViz): def get_data(self, df): d = super(DeckArc, self).get_data(df) - arcs = d['features'] return { - 'arcs': arcs, + 'features': d['features'], 'mapboxApiKey': config.get('MAPBOX_API_KEY'), }