williaster closed pull request #6039: [SIP-5] Remove references to slice from
all deck.gl components.
URL: https://github.com/apache/incubator-superset/pull/6039
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx
b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx
index 0976ec00df..61c9eedc74 100644
--- a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx
+++ b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx
@@ -31,12 +31,14 @@ function getCategories(fd, data) {
}
const propTypes = {
- slice: PropTypes.object.isRequired,
+ formData: PropTypes.object.isRequired,
mapboxApiKey: PropTypes.string.isRequired,
setControlValue: PropTypes.func.isRequired,
viewport: PropTypes.object.isRequired,
getLayer: PropTypes.func.isRequired,
payload: PropTypes.object.isRequired,
+ onAddFilter: PropTypes.func,
+ onTooltip: PropTypes.func,
};
export default class CategoricalDeckGLContainer extends React.PureComponent {
@@ -49,7 +51,7 @@ export default class CategoricalDeckGLContainer extends
React.PureComponent {
/* eslint-disable-next-line react/sort-comp */
static getDerivedStateFromProps(nextProps) {
- const fd = nextProps.slice.formData;
+ const fd = nextProps.formData;
const timeGrain = fd.time_grain_sqla || fd.granularity || 'PT1M';
const timestamps = nextProps.payload.data.features.map(f => f.__timestamp);
@@ -70,8 +72,13 @@ export default class CategoricalDeckGLContainer extends
React.PureComponent {
this.setState(CategoricalDeckGLContainer.getDerivedStateFromProps(nextProps,
this.state));
}
getLayers(values) {
- const { getLayer, payload, slice } = this.props;
- const fd = slice.formData;
+ const {
+ getLayer,
+ payload,
+ formData: fd,
+ onAddFilter,
+ onTooltip,
+ } = this.props;
let data = [...payload.data.features];
// Add colors from categories or fixed color
@@ -96,7 +103,7 @@ export default class CategoricalDeckGLContainer extends
React.PureComponent {
}
payload.data.features = data;
- return [getLayer(fd, payload, slice)];
+ return [getLayer(fd, payload, onAddFilter, onTooltip)];
}
addColor(data, fd) {
const c = fd.color_picker || { r: 0, g: 0, b: 0, a: 1 };
@@ -142,14 +149,14 @@ export default class CategoricalDeckGLContainer extends
React.PureComponent {
disabled={this.state.disabled}
viewport={this.props.viewport}
mapboxApiAccessToken={this.props.mapboxApiKey}
- mapStyle={this.props.slice.formData.mapbox_style}
+ mapStyle={this.props.formData.mapbox_style}
setControlValue={this.props.setControlValue}
>
<Legend
categories={this.state.categories}
toggleCategory={this.toggleCategory}
showSingleCategory={this.showSingleCategory}
- position={this.props.slice.formData.legend_position}
+ position={this.props.formData.legend_position}
/>
</AnimatableDeckGLContainer>
</div>
diff --git a/superset/assets/src/visualizations/deckgl/createAdaptor.jsx
b/superset/assets/src/visualizations/deckgl/createAdaptor.jsx
new file mode 100644
index 0000000000..6dfe11b9d9
--- /dev/null
+++ b/superset/assets/src/visualizations/deckgl/createAdaptor.jsx
@@ -0,0 +1,30 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+const IDENTITY = x => x;
+
+class DeckGlChartInput {
+ constructor(slice, payload, setControlValue) {
+ this.formData = slice.formData;
+ this.payload = payload;
+ this.setControlValue = setControlValue;
+ this.viewport = {
+ ...this.formData.viewport,
+ width: slice.width(),
+ height: slice.height(),
+ };
+
+ this.onAddFilter = ((...args) => { slice.addFilter(...args); });
+ this.onTooltip = ((...args) => { slice.tooltip(...args); });
+ }
+}
+
+export default function createAdaptor(Component, transformProps = IDENTITY) {
+ return function adaptor(slice, payload, setControlValue) {
+ const chartInput = new DeckGlChartInput(slice, payload, setControlValue);
+ ReactDOM.render(
+ <Component {...transformProps(chartInput)} />,
+ document.querySelector(slice.selector),
+ );
+ };
+}
diff --git a/superset/assets/src/visualizations/deckgl/factory.jsx
b/superset/assets/src/visualizations/deckgl/factory.jsx
new file mode 100644
index 0000000000..fc61e34a5e
--- /dev/null
+++ b/superset/assets/src/visualizations/deckgl/factory.jsx
@@ -0,0 +1,87 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import DeckGLContainer from './DeckGLContainer';
+import CategoricalDeckGLContainer from './CategoricalDeckGLContainer';
+import { fitViewport } from './layers/common';
+
+const propTypes = {
+ formData: PropTypes.object.isRequired,
+ payload: PropTypes.object.isRequired,
+ setControlValue: PropTypes.func.isRequired,
+ viewport: PropTypes.object.isRequired,
+ onAddFilter: PropTypes.func,
+ onTooltip: PropTypes.func,
+};
+const defaultProps = {
+ onAddFilter() {},
+ onTooltip() {},
+};
+
+export function createDeckGLComponent(getLayer, getPoints) {
+ function Component(props) {
+ const {
+ formData,
+ payload,
+ setControlValue,
+ onAddFilter,
+ onTooltip,
+ viewport: originalViewport,
+ } = props;
+
+ const viewport = formData.autozoom
+ ? fitViewport(originalViewport, getPoints(payload.data.features))
+ : originalViewport;
+
+ const layer = getLayer(formData, payload, onAddFilter, onTooltip);
+
+ return (
+ <DeckGLContainer
+ mapboxApiAccessToken={payload.data.mapboxApiKey}
+ viewport={viewport}
+ layers={[layer]}
+ mapStyle={formData.mapbox_style}
+ setControlValue={setControlValue}
+ />
+ );
+ }
+
+ Component.propTypes = propTypes;
+ Component.defaultProps = defaultProps;
+
+ return Component;
+}
+
+export function createCategoricalDeckGLComponent(getLayer, getPoints) {
+ function Component(props) {
+ const {
+ formData,
+ payload,
+ setControlValue,
+ onAddFilter,
+ onTooltip,
+ viewport: originalViewport,
+ } = props;
+
+ const viewport = formData.autozoom
+ ? fitViewport(originalViewport, getPoints(payload.data.features))
+ : originalViewport;
+
+ return (
+ <CategoricalDeckGLContainer
+ formData={formData}
+ mapboxApiKey={payload.data.mapboxApiKey}
+ setControlValue={setControlValue}
+ viewport={viewport}
+ getLayer={getLayer}
+ payload={payload}
+ onAddFilter={onAddFilter}
+ onTooltip={onTooltip}
+ />
+ );
+ }
+
+ Component.propTypes = propTypes;
+ Component.defaultProps = defaultProps;
+
+ return Component;
+}
diff --git a/superset/assets/src/visualizations/deckgl/layers/arc.jsx
b/superset/assets/src/visualizations/deckgl/layers/arc.jsx
index 883ffbd6c6..e2a3233057 100644
--- a/superset/assets/src/visualizations/deckgl/layers/arc.jsx
+++ b/superset/assets/src/visualizations/deckgl/layers/arc.jsx
@@ -1,13 +1,7 @@
-/* eslint no-underscore-dangle: ["error", { "allow": ["", "__timestamp"] }] */
-
-import React from 'react';
-import ReactDOM from 'react-dom';
-
import { ArcLayer } from 'deck.gl';
-
-import CategoricalDeckGLContainer from '../CategoricalDeckGLContainer';
-
-import * as common from './common';
+import { commonLayerProps } from './common';
+import createAdaptor from '../createAdaptor';
+import { createCategoricalDeckGLComponent } from '../factory';
function getPoints(data) {
const points = [];
@@ -18,7 +12,7 @@ function getPoints(data) {
return points;
}
-function getLayer(fd, payload, slice) {
+export function getLayer(fd, payload, onAddFilter, onTooltip) {
const data = payload.data.features;
const sc = fd.color_picker;
const tc = fd.target_color_picker;
@@ -28,36 +22,8 @@ function getLayer(fd, payload, slice) {
getSourceColor: d => d.sourceColor || d.color || [sc.r, sc.g, sc.b, 255 *
sc.a],
getTargetColor: d => d.targetColor || d.color || [tc.r, tc.g, tc.b, 255 *
tc.a],
strokeWidth: (fd.stroke_width) ? fd.stroke_width : 3,
- ...common.commonLayerProps(fd, slice),
+ ...commonLayerProps(fd, onAddFilter, onTooltip),
});
}
-function deckArc(slice, payload, setControlValue) {
- const fd = slice.formData;
- let viewport = {
- ...fd.viewport,
- width: slice.width(),
- height: slice.height(),
- };
-
- if (fd.autozoom) {
- viewport = common.fitViewport(viewport, getPoints(payload.data.features));
- }
-
- ReactDOM.render(
- <CategoricalDeckGLContainer
- slice={slice}
- mapboxApiKey={payload.data.mapboxApiKey}
- setControlValue={setControlValue}
- viewport={viewport}
- getLayer={getLayer}
- payload={payload}
- />,
- document.getElementById(slice.containerId),
- );
-}
-
-module.exports = {
- default: deckArc,
- getLayer,
-};
+export default createAdaptor(createCategoricalDeckGLComponent(getLayer,
getPoints));
diff --git a/superset/assets/src/visualizations/deckgl/layers/common.jsx
b/superset/assets/src/visualizations/deckgl/layers/common.jsx
index 8a3ecc5c7c..a0b1e137c3 100644
--- a/superset/assets/src/visualizations/deckgl/layers/common.jsx
+++ b/superset/assets/src/visualizations/deckgl/layers/common.jsx
@@ -1,7 +1,6 @@
import React from 'react';
import { fitBounds } from 'viewport-mercator-project';
import d3 from 'd3';
-
import sandboxedEval from '../../../modules/sandbox';
export function getBounds(points) {
@@ -32,7 +31,7 @@ export function fitViewport(viewport, points, padding = 10) {
}
}
-export function commonLayerProps(formData, slice) {
+export function commonLayerProps(formData, onAddFilter, onTooltip) {
const fd = formData;
let onHover;
let tooltipContentGenerator;
@@ -49,13 +48,13 @@ export function commonLayerProps(formData, slice) {
if (tooltipContentGenerator) {
onHover = (o) => {
if (o.picked) {
- slice.setTooltip({
+ onTooltip({
content: tooltipContentGenerator(o),
x: o.x,
y: o.y,
});
} else {
- slice.setTooltip(null);
+ onTooltip(null);
}
};
}
@@ -66,7 +65,7 @@ export function commonLayerProps(formData, slice) {
window.open(href);
};
} else if (fd.table_filter && fd.line_type === 'geohash') {
- onClick = o => slice.addFilter(fd.line_column, [o.object[fd.line_column]],
false);
+ onClick = o => onAddFilter(fd.line_column, [o.object[fd.line_column]],
false);
}
return {
onClick,
diff --git a/superset/assets/src/visualizations/deckgl/layers/geojson.jsx
b/superset/assets/src/visualizations/deckgl/layers/geojson.jsx
index 72790f1efd..64a39a9d21 100644
--- a/superset/assets/src/visualizations/deckgl/layers/geojson.jsx
+++ b/superset/assets/src/visualizations/deckgl/layers/geojson.jsx
@@ -1,12 +1,13 @@
import React from 'react';
-import ReactDOM from 'react-dom';
+import PropTypes from 'prop-types';
import { GeoJsonLayer } from 'deck.gl';
// TODO import geojsonExtent from 'geojson-extent';
import DeckGLContainer from './../DeckGLContainer';
-import * as common from './common';
import { hexToRGB } from '../../../modules/colors';
import sandboxedEval from '../../../modules/sandbox';
+import { commonLayerProps } from './common';
+import createAdaptor from '../createAdaptor';
const propertyMap = {
fillColor: 'fillColor',
@@ -57,7 +58,7 @@ const recurseGeoJson = (node, propOverrides, extraProps) => {
}
};
-function getLayer(formData, payload, slice) {
+export function getLayer(formData, payload, onAddFilter, onTooltip) {
const fd = formData;
const fc = fd.fill_color_picker;
const sc = fd.stroke_color_picker;
@@ -88,35 +89,52 @@ function getLayer(formData, payload, slice) {
stroked: fd.stroked,
extruded: fd.extruded,
pointRadiusScale: fd.point_radius_scale,
- ...common.commonLayerProps(fd, slice),
+ ...commonLayerProps(fd, onAddFilter, onTooltip),
});
}
-function deckGeoJson(slice, payload, setControlValue) {
- const layer = getLayer(slice.formData, payload, slice);
- const viewport = {
- ...slice.formData.viewport,
- width: slice.width(),
- height: slice.height(),
- };
- if (slice.formData.autozoom) {
- // TODO get this to work
- // viewport = common.fitViewport(viewport,
geojsonExtent(payload.data.features));
- }
+const propTypes = {
+ formData: PropTypes.object.isRequired,
+ payload: PropTypes.object.isRequired,
+ setControlValue: PropTypes.func.isRequired,
+ viewport: PropTypes.object.isRequired,
+ onAddFilter: PropTypes.func,
+ onTooltip: PropTypes.func,
+};
+const defaultProps = {
+ onAddFilter() {},
+ onTooltip() {},
+};
+
+function deckGeoJson(props) {
+ const {
+ formData,
+ payload,
+ setControlValue,
+ onAddFilter,
+ onTooltip,
+ viewport,
+ } = props;
- ReactDOM.render(
+ // TODO get this to work
+ // if (formData.autozoom) {
+ // viewport = common.fitViewport(viewport,
geojsonExtent(payload.data.features));
+ // }
+
+ const layer = getLayer(formData, payload, onAddFilter, onTooltip);
+
+ return (
<DeckGLContainer
mapboxApiAccessToken={payload.data.mapboxApiKey}
viewport={viewport}
layers={[layer]}
- mapStyle={slice.formData.mapbox_style}
+ mapStyle={formData.mapbox_style}
setControlValue={setControlValue}
- />,
- document.getElementById(slice.containerId),
+ />
);
}
-module.exports = {
- default: deckGeoJson,
- getLayer,
-};
+deckGeoJson.propTypes = propTypes;
+deckGeoJson.defaultProps = defaultProps;
+
+export default createAdaptor(deckGeoJson);
diff --git a/superset/assets/src/visualizations/deckgl/layers/grid.jsx
b/superset/assets/src/visualizations/deckgl/layers/grid.jsx
index 16a538c906..0f5cf3149c 100644
--- a/superset/assets/src/visualizations/deckgl/layers/grid.jsx
+++ b/superset/assets/src/visualizations/deckgl/layers/grid.jsx
@@ -1,14 +1,10 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-
import { GridLayer } from 'deck.gl';
-
-import DeckGLContainer from './../DeckGLContainer';
-
-import * as common from './common';
+import { commonLayerProps } from './common';
import sandboxedEval from '../../../modules/sandbox';
+import createAdaptor from '../createAdaptor';
+import { createDeckGLComponent } from '../factory';
-function getLayer(formData, payload, slice) {
+export function getLayer(formData, payload, onAddFilter, onTooltip) {
const fd = formData;
const c = fd.color_picker;
let data = payload.data.features.map(d => ({
@@ -21,6 +17,7 @@ function getLayer(formData, payload, slice) {
const jsFnMutator = sandboxedEval(fd.js_data_mutator);
data = jsFnMutator(data);
}
+
return new GridLayer({
id: `grid-layer-${fd.slice_id}`,
data,
@@ -32,7 +29,7 @@ function getLayer(formData, payload, slice) {
outline: false,
getElevationValue: points => points.reduce((sum, point) => sum +
point.weight, 0),
getColorValue: points => points.reduce((sum, point) => sum + point.weight,
0),
- ...common.commonLayerProps(fd, slice),
+ ...commonLayerProps(fd, onAddFilter, onTooltip),
});
}
@@ -40,31 +37,4 @@ function getPoints(data) {
return data.map(d => d.position);
}
-function deckGrid(slice, payload, setControlValue) {
- const layer = getLayer(slice.formData, payload, slice);
- let viewport = {
- ...slice.formData.viewport,
- width: slice.width(),
- height: slice.height(),
- };
-
- if (slice.formData.autozoom) {
- viewport = common.fitViewport(viewport, getPoints(payload.data.features));
- }
-
- ReactDOM.render(
- <DeckGLContainer
- mapboxApiAccessToken={payload.data.mapboxApiKey}
- viewport={viewport}
- layers={[layer]}
- mapStyle={slice.formData.mapbox_style}
- setControlValue={setControlValue}
- />,
- document.getElementById(slice.containerId),
- );
-}
-
-module.exports = {
- default: deckGrid,
- getLayer,
-};
+export default createAdaptor(createDeckGLComponent(getLayer, getPoints));
diff --git a/superset/assets/src/visualizations/deckgl/layers/hex.jsx
b/superset/assets/src/visualizations/deckgl/layers/hex.jsx
index 14c9951df4..3dabb765dc 100644
--- a/superset/assets/src/visualizations/deckgl/layers/hex.jsx
+++ b/superset/assets/src/visualizations/deckgl/layers/hex.jsx
@@ -1,14 +1,10 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-
import { HexagonLayer } from 'deck.gl';
-
-import DeckGLContainer from './../DeckGLContainer';
-
-import * as common from './common';
+import { commonLayerProps } from './common';
import sandboxedEval from '../../../modules/sandbox';
+import createAdaptor from '../createAdaptor';
+import { createDeckGLComponent } from '../factory';
-function getLayer(formData, payload, slice) {
+export function getLayer(formData, payload, onAddFilter, onTooltip) {
const fd = formData;
const c = fd.color_picker;
let data = payload.data.features.map(d => ({
@@ -33,7 +29,7 @@ function getLayer(formData, payload, slice) {
outline: false,
getElevationValue: points => points.reduce((sum, point) => sum +
point.weight, 0),
getColorValue: points => points.reduce((sum, point) => sum + point.weight,
0),
- ...common.commonLayerProps(fd, slice),
+ ...commonLayerProps(fd, onAddFilter, onTooltip),
});
}
@@ -41,31 +37,4 @@ function getPoints(data) {
return data.map(d => d.position);
}
-function deckHex(slice, payload, setControlValue) {
- const layer = getLayer(slice.formData, payload, slice);
- let viewport = {
- ...slice.formData.viewport,
- width: slice.width(),
- height: slice.height(),
- };
-
- if (slice.formData.autozoom) {
- viewport = common.fitViewport(viewport, getPoints(payload.data.features));
- }
-
- ReactDOM.render(
- <DeckGLContainer
- mapboxApiAccessToken={payload.data.mapboxApiKey}
- viewport={viewport}
- layers={[layer]}
- mapStyle={slice.formData.mapbox_style}
- setControlValue={setControlValue}
- />,
- document.getElementById(slice.containerId),
- );
-}
-
-module.exports = {
- default: deckHex,
- getLayer,
-};
+export default createAdaptor(createDeckGLComponent(getLayer, getPoints));
diff --git a/superset/assets/src/visualizations/deckgl/layers/index.js
b/superset/assets/src/visualizations/deckgl/layers/index.js
index d8d25d5b0e..e98f74395b 100644
--- a/superset/assets/src/visualizations/deckgl/layers/index.js
+++ b/superset/assets/src/visualizations/deckgl/layers/index.js
@@ -18,4 +18,5 @@ const layerGenerators = {
deck_arc,
deck_polygon,
};
+
export default layerGenerators;
diff --git a/superset/assets/src/visualizations/deckgl/layers/path.jsx
b/superset/assets/src/visualizations/deckgl/layers/path.jsx
index 0951edd93c..ede01b2384 100644
--- a/superset/assets/src/visualizations/deckgl/layers/path.jsx
+++ b/superset/assets/src/visualizations/deckgl/layers/path.jsx
@@ -1,14 +1,10 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-
import { PathLayer } from 'deck.gl';
-
-import DeckGLContainer from './../DeckGLContainer';
-
-import * as common from './common';
+import { commonLayerProps } from './common';
import sandboxedEval from '../../../modules/sandbox';
+import createAdaptor from '../createAdaptor';
+import { createDeckGLComponent } from '../factory';
-function getLayer(formData, payload, slice) {
+export function getLayer(formData, payload, onAddFilter, onTooltip) {
const fd = formData;
const c = fd.color_picker;
const fixedColor = [c.r, c.g, c.b, 255 * c.a];
@@ -29,7 +25,7 @@ function getLayer(formData, payload, slice) {
data,
rounded: true,
widthScale: 1,
- ...common.commonLayerProps(fd, slice),
+ ...commonLayerProps(fd, onAddFilter, onTooltip),
});
}
@@ -41,31 +37,4 @@ function getPoints(data) {
return points;
}
-function deckPath(slice, payload, setControlValue) {
- const layer = getLayer(slice.formData, payload, slice);
- let viewport = {
- ...slice.formData.viewport,
- width: slice.width(),
- height: slice.height(),
- };
-
- if (slice.formData.autozoom) {
- viewport = common.fitViewport(viewport, getPoints(payload.data.features));
- }
-
- ReactDOM.render(
- <DeckGLContainer
- mapboxApiAccessToken={payload.data.mapboxApiKey}
- viewport={viewport}
- layers={[layer]}
- mapStyle={slice.formData.mapbox_style}
- setControlValue={setControlValue}
- />,
- document.getElementById(slice.containerId),
- );
-}
-
-module.exports = {
- default: deckPath,
- getLayer,
-};
+export default createAdaptor(createDeckGLComponent(getLayer, getPoints));
diff --git a/superset/assets/src/visualizations/deckgl/layers/polygon.jsx
b/superset/assets/src/visualizations/deckgl/layers/polygon.jsx
index e84b943f61..73537dcaa4 100644
--- a/superset/assets/src/visualizations/deckgl/layers/polygon.jsx
+++ b/superset/assets/src/visualizations/deckgl/layers/polygon.jsx
@@ -1,21 +1,17 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-
+import d3 from 'd3';
import { PolygonLayer } from 'deck.gl';
import { flatten } from 'lodash';
-import d3 from 'd3';
-
-import DeckGLContainer from './../DeckGLContainer';
-
-import * as common from './common';
import { colorScalerFactory } from '../../../modules/colors';
+import { commonLayerProps } from './common';
import sandboxedEval from '../../../modules/sandbox';
+import createAdaptor from '../createAdaptor';
+import { createDeckGLComponent } from '../factory';
function getPoints(features) {
return flatten(features.map(d => d.polygon), true);
}
-function getLayer(formData, payload, slice) {
+export function getLayer(formData, payload, onAddFilter, onTooltip) {
const fd = formData;
const fc = fd.fill_color_picker;
const sc = fd.stroke_color_picker;
@@ -49,36 +45,8 @@ function getLayer(formData, payload, slice) {
getLineWidth: fd.line_width,
extruded: fd.extruded,
fp64: true,
- ...common.commonLayerProps(fd, slice),
+ ...commonLayerProps(fd, onAddFilter, onTooltip),
});
}
-function deckPolygon(slice, payload, setControlValue) {
- const layer = getLayer(slice.formData, payload, slice);
- const fd = slice.formData;
- let viewport = {
- ...slice.formData.viewport,
- width: slice.width(),
- height: slice.height(),
- };
-
- if (fd.autozoom) {
- viewport = common.fitViewport(viewport, getPoints(payload.data.features));
- }
-
- ReactDOM.render(
- <DeckGLContainer
- mapboxApiAccessToken={payload.data.mapboxApiKey}
- viewport={viewport}
- layers={[layer]}
- mapStyle={slice.formData.mapbox_style}
- setControlValue={setControlValue}
- />,
- document.getElementById(slice.containerId),
- );
-}
-
-module.exports = {
- default: deckPolygon,
- getLayer,
-};
+export default createAdaptor(createDeckGLComponent(getLayer, getPoints));
diff --git a/superset/assets/src/visualizations/deckgl/layers/scatter.jsx
b/superset/assets/src/visualizations/deckgl/layers/scatter.jsx
index d9474a4770..b740ce19ba 100644
--- a/superset/assets/src/visualizations/deckgl/layers/scatter.jsx
+++ b/superset/assets/src/visualizations/deckgl/layers/scatter.jsx
@@ -1,20 +1,14 @@
-/* eslint no-underscore-dangle: ["error", { "allow": ["", "__timestamp"] }] */
-
-import React from 'react';
-import ReactDOM from 'react-dom';
-
import { ScatterplotLayer } from 'deck.gl';
-
-import CategoricalDeckGLContainer from '../CategoricalDeckGLContainer';
-import * as common from './common';
+import { commonLayerProps } from './common';
+import createAdaptor from '../createAdaptor';
+import { createCategoricalDeckGLComponent } from '../factory';
import { unitToRadius } from '../../../modules/geo';
-
function getPoints(data) {
return data.map(d => d.position);
}
-function getLayer(fd, payload, slice) {
+export function getLayer(fd, payload, slice) {
const dataWithRadius = payload.data.features.map((d) => {
let radius = unitToRadius(fd.point_unit, d.radius) || 10;
if (fd.multiplier) {
@@ -35,36 +29,8 @@ function getLayer(fd, payload, slice) {
radiusMinPixels: fd.min_radius || null,
radiusMaxPixels: fd.max_radius || null,
outline: false,
- ...common.commonLayerProps(fd, slice),
+ ...commonLayerProps(fd, slice),
});
}
-function deckScatter(slice, payload, setControlValue) {
- const fd = slice.formData;
- let viewport = {
- ...fd.viewport,
- width: slice.width(),
- height: slice.height(),
- };
-
- if (fd.autozoom) {
- viewport = common.fitViewport(viewport, getPoints(payload.data.features));
- }
-
- ReactDOM.render(
- <CategoricalDeckGLContainer
- slice={slice}
- mapboxApiKey={payload.data.mapboxApiKey}
- setControlValue={setControlValue}
- viewport={viewport}
- getLayer={getLayer}
- payload={payload}
- />,
- document.getElementById(slice.containerId),
- );
-}
-
-module.exports = {
- default: deckScatter,
- getLayer,
-};
+export default createAdaptor(createCategoricalDeckGLComponent(getLayer,
getPoints));
diff --git a/superset/assets/src/visualizations/deckgl/layers/screengrid.jsx
b/superset/assets/src/visualizations/deckgl/layers/screengrid.jsx
index b4df577d78..4331cec5f3 100644
--- a/superset/assets/src/visualizations/deckgl/layers/screengrid.jsx
+++ b/superset/assets/src/visualizations/deckgl/layers/screengrid.jsx
@@ -1,22 +1,19 @@
/* eslint no-underscore-dangle: ["error", { "allow": ["", "__timestamp"] }] */
import React from 'react';
-import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
-
import { ScreenGridLayer } from 'deck.gl';
-
import AnimatableDeckGLContainer from '../AnimatableDeckGLContainer';
-
-import * as common from './common';
import { getPlaySliderParams } from '../../../modules/time';
import sandboxedEval from '../../../modules/sandbox';
+import { commonLayerProps, fitViewport } from './common';
+import createAdaptor from '../createAdaptor';
function getPoints(data) {
return data.map(d => d.position);
}
-function getLayer(formData, payload, slice, filters) {
+export function getLayer(formData, payload, onAddFilter, onTooltip, filters) {
const fd = formData;
const c = fd.color_picker;
let data = payload.data.features.map(d => ({
@@ -47,21 +44,27 @@ function getLayer(formData, payload, slice, filters) {
maxColor: [c.r, c.g, c.b, 255 * c.a],
outline: false,
getWeight: d => d.weight || 0,
- ...common.commonLayerProps(fd, slice),
+ ...commonLayerProps(fd, onAddFilter, onTooltip),
});
}
const propTypes = {
- slice: PropTypes.object.isRequired,
+ formData: PropTypes.object.isRequired,
payload: PropTypes.object.isRequired,
setControlValue: PropTypes.func.isRequired,
viewport: PropTypes.object.isRequired,
+ onAddFilter: PropTypes.func,
+ onTooltip: PropTypes.func,
+};
+const defaultProps = {
+ onAddFilter() {},
+ onTooltip() {},
};
class DeckGLScreenGrid extends React.PureComponent {
/* eslint-disable-next-line react/sort-comp */
static getDerivedStateFromProps(nextProps) {
- const fd = nextProps.slice.formData;
+ const fd = nextProps.formData;
const timeGrain = fd.time_grain_sqla || fd.granularity || 'PT1M';
const timestamps = nextProps.payload.data.features.map(f => f.__timestamp);
@@ -89,14 +92,21 @@ class DeckGLScreenGrid extends React.PureComponent {
}
const layer = getLayer(
- this.props.slice.formData,
+ this.props.formData,
this.props.payload,
- this.props.slice,
+ this.props.onAddFilter,
+ this.props.onTooltip,
filters);
return [layer];
}
+
render() {
+ const { formData, payload } = this.props;
+ const viewport = formData.autozoom
+ ? fitViewport(this.props.viewport, getPoints(payload.data.features))
+ : this.props.viewport;
+
return (
<div>
<AnimatableDeckGLContainer
@@ -106,9 +116,9 @@ class DeckGLScreenGrid extends React.PureComponent {
getStep={this.state.getStep}
values={this.state.values}
disabled={this.state.disabled}
- viewport={this.props.viewport}
+ viewport={viewport}
mapboxApiAccessToken={this.props.payload.data.mapboxApiKey}
- mapStyle={this.props.slice.formData.mapbox_style}
+ mapStyle={this.props.formData.mapbox_style}
setControlValue={this.props.setControlValue}
aggregation
/>
@@ -118,31 +128,6 @@ class DeckGLScreenGrid extends React.PureComponent {
}
DeckGLScreenGrid.propTypes = propTypes;
+DeckGLScreenGrid.defaultProps = defaultProps;
-function deckScreenGrid(slice, payload, setControlValue) {
- const fd = slice.formData;
- let viewport = {
- ...fd.viewport,
- width: slice.width(),
- height: slice.height(),
- };
-
- if (fd.autozoom) {
- viewport = common.fitViewport(viewport, getPoints(payload.data.features));
- }
-
- ReactDOM.render(
- <DeckGLScreenGrid
- slice={slice}
- payload={payload}
- setControlValue={setControlValue}
- viewport={viewport}
- />,
- document.getElementById(slice.containerId),
- );
-}
-
-module.exports = {
- default: deckScreenGrid,
- getLayer,
-};
+export default createAdaptor(DeckGLScreenGrid);
diff --git a/superset/assets/src/visualizations/deckgl/multi.jsx
b/superset/assets/src/visualizations/deckgl/multi.jsx
index 8b35c86768..76a7072221 100644
--- a/superset/assets/src/visualizations/deckgl/multi.jsx
+++ b/superset/assets/src/visualizations/deckgl/multi.jsx
@@ -1,57 +1,87 @@
import React from 'react';
-import ReactDOM from 'react-dom';
+import PropTypes from 'prop-types';
import $ from 'jquery';
-
import DeckGLContainer from './DeckGLContainer';
import { getExploreLongUrl } from '../../explore/exploreUtils';
import layerGenerators from './layers';
+import createAdaptor from './createAdaptor';
+
+const propTypes = {
+ formData: PropTypes.object.isRequired,
+ payload: PropTypes.object.isRequired,
+ setControlValue: PropTypes.func.isRequired,
+ viewport: PropTypes.object.isRequired,
+};
+
+class DeckMulti extends React.PureComponent {
+ constructor(props) {
+ super(props);
+ this.state = { subSlicesLayers: {} };
+ }
+
+ componentDidMount() {
+ const { formData, payload } = this.props;
+ this.loadLayers(formData, payload);
+ }
+
+ componentWillReceiveProps(nextProps) {
+ const { formData, payload } = nextProps;
+ this.loadLayers(formData, payload);
+ }
+
+ loadLayers(formData, payload) {
+ this.setState({ subSlicesLayers: {} });
+ payload.data.slices.forEach((subslice) => {
+ // 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
+ const filters = [
+ ...(subslice.form_data.filters || []),
+ ...(formData.filters || []),
+ ...(formData.extra_filters || []),
+ ];
+ const subsliceCopy = {
+ ...subslice,
+ form_data: {
+ ...subslice.form_data,
+ filters,
+ },
+ };
+ const url = getExploreLongUrl(subsliceCopy.form_data, 'json');
+ $.get(url, (data) => {
+ const layer = layerGenerators[subsliceCopy.form_data.viz_type](
+ subsliceCopy.form_data,
+ data,
+ );
+ this.setState({
+ subSlicesLayers: {
+ ...this.state.subSlicesLayers,
+ [subsliceCopy.slice_id]: layer,
+ },
+ });
+ });
+ });
+ }
+
+ render() {
+ const { payload, viewport, formData, setControlValue } = this.props;
+ const { subSlicesLayers } = this.state;
-function deckMulti(slice, payload, setControlValue) {
- const subSlicesLayers = {};
- const fd = slice.formData;
- const render = () => {
- const viewport = {
- ...fd.viewport,
- width: slice.width(),
- height: slice.height(),
- };
const layers = Object.keys(subSlicesLayers).map(k => subSlicesLayers[k]);
- ReactDOM.render(
+
+ return (
<DeckGLContainer
mapboxApiAccessToken={payload.data.mapboxApiKey}
viewport={viewport}
layers={layers}
- mapStyle={fd.mapbox_style}
+ mapStyle={formData.mapbox_style}
setControlValue={setControlValue}
- />,
- document.getElementById(slice.containerId),
+ />
);
- };
- render();
- payload.data.slices.forEach((subslice) => {
- // 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
- const filters = [
- ...(subslice.form_data.filters || []),
- ...(fd.filters || []),
- ...(fd.extra_filters || []),
- ];
- const subsliceCopy = {
- ...subslice,
- form_data: {
- ...subslice.form_data,
- filters,
- },
- };
-
- const url = getExploreLongUrl(subsliceCopy.form_data, 'json');
- $.get(url, (data) => {
- const layer =
layerGenerators[subsliceCopy.form_data.viz_type](subsliceCopy.form_data, data);
- subSlicesLayers[subsliceCopy.slice_id] = layer;
- render();
- });
- });
+ }
}
-module.exports = deckMulti;
+
+DeckMulti.propTypes = propTypes;
+
+export default createAdaptor(DeckMulti);
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]