From a00e7ec61484c5cf3cb2e0576bea6eb456377c9f Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Mon, 15 Oct 2018 09:26:59 -0700 Subject: [PATCH] Rename onTooltip to setTooltip (#6103) * rename onTooltip to setTooltip * fix typo (cherry picked from commit dc7b6f2baea5ecd1aedea81a416b9781935b977e) (cherry picked from commit 86aa6b4d9d1ca659e49aa6ad40c037915f4d8cd2) --- .../deckgl/CategoricalDeckGLContainer.jsx | 33 +++++-- .../visualizations/deckgl/createAdaptor.jsx | 30 +++++++ .../src/visualizations/deckgl/factory.jsx | 87 +++++++++++++++++++ .../visualizations/deckgl/layers/Arc/Arc.jsx | 4 +- .../deckgl/layers/Geojson/Geojson.jsx | 44 +++++++--- .../deckgl/layers/Grid/Grid.jsx | 4 +- .../visualizations/deckgl/layers/Hex/Hex.jsx | 4 +- .../deckgl/layers/Path/Path.jsx | 4 +- .../deckgl/layers/Polygon/Polygon.jsx | 4 +- .../deckgl/layers/Screengrid/Screengrid.jsx | 13 ++- .../visualizations/deckgl/layers/common.jsx | 6 +- 11 files changed, 195 insertions(+), 38 deletions(-) create mode 100644 superset/assets/src/visualizations/deckgl/createAdaptor.jsx create mode 100644 superset/assets/src/visualizations/deckgl/factory.jsx diff --git a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx index 0d1394bab14f4..01bcf24ab3d3a 100644 --- a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx +++ b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx @@ -35,6 +35,8 @@ const propTypes = { viewport: PropTypes.object.isRequired, getLayer: PropTypes.func.isRequired, payload: PropTypes.object.isRequired, + onAddFilter: PropTypes.func, + setTooltip: PropTypes.func, }; export default class CategoricalDeckGLContainer extends React.PureComponent { @@ -89,9 +91,14 @@ export default class CategoricalDeckGLContainer extends React.PureComponent { this.setState({ viewport }); } getLayers(values) { - const { getLayer, payload, slice } = this.props; - const fd = slice.formData; - let features = [...payload.data.features]; + const { + getLayer, + payload, + formData: fd, + onAddFilter, + setTooltip, + } = this.props; + const data = [...payload.data.features]; // Add colors from categories or fixed color features = this.addColor(features, fd); @@ -114,12 +121,20 @@ export default class CategoricalDeckGLContainer extends React.PureComponent { features = features.filter(d => this.state.categories[d.cat_color].enabled); } - const filteredPayload = { - ...payload, - data: { ...payload.data, features }, - }; - - return [getLayer(fd, filteredPayload, slice)]; + payload.data.features = data; + return [getLayer(fd, payload, onAddFilter, setTooltip)]; + } + addColor(data, fd) { + const c = fd.color_picker || { r: 0, g: 0, b: 0, a: 1 }; + const colorFn = getScale(fd.color_scheme).toFunction(); + return data.map((d) => { + let color; + if (fd.dimension) { + color = hexToRGB(colorFn(d.cat_color), c.a * 255); + return { ...d, color }; + } + return d; + }); } toggleCategory(category) { const categoryState = this.state.categories[category]; diff --git a/superset/assets/src/visualizations/deckgl/createAdaptor.jsx b/superset/assets/src/visualizations/deckgl/createAdaptor.jsx new file mode 100644 index 0000000000000..080bf682cc968 --- /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.setTooltip = ((...args) => { slice.setTooltip(...args); }); + } +} + +export default function createAdaptor(Component, transformProps = IDENTITY) { + return function adaptor(slice, payload, setControlValue) { + const chartInput = new DeckGlChartInput(slice, payload, setControlValue); + ReactDOM.render( + , + 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 0000000000000..73d48af77705a --- /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, + setTooltip: PropTypes.func, +}; +const defaultProps = { + onAddFilter() {}, + setTooltip() {}, +}; + +export function createDeckGLComponent(getLayer, getPoints) { + function Component(props) { + const { + formData, + payload, + setControlValue, + onAddFilter, + setTooltip, + viewport: originalViewport, + } = props; + + const viewport = formData.autozoom + ? fitViewport(originalViewport, getPoints(payload.data.features)) + : originalViewport; + + const layer = getLayer(formData, payload, onAddFilter, setTooltip); + + return ( + + ); + } + + Component.propTypes = propTypes; + Component.defaultProps = defaultProps; + + return Component; +} + +export function createCategoricalDeckGLComponent(getLayer, getPoints) { + function Component(props) { + const { + formData, + payload, + setControlValue, + onAddFilter, + setTooltip, + viewport: originalViewport, + } = props; + + const viewport = formData.autozoom + ? fitViewport(originalViewport, getPoints(payload.data.features)) + : originalViewport; + + return ( + + ); + } + + Component.propTypes = propTypes; + Component.defaultProps = defaultProps; + + return Component; +} diff --git a/superset/assets/src/visualizations/deckgl/layers/Arc/Arc.jsx b/superset/assets/src/visualizations/deckgl/layers/Arc/Arc.jsx index ee62caa7631a4..9dd580d4258e7 100644 --- a/superset/assets/src/visualizations/deckgl/layers/Arc/Arc.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/Arc/Arc.jsx @@ -17,7 +17,7 @@ function getPoints(data) { return points; } -function getLayer(fd, payload, slice) { +export function getLayer(fd, payload, onAddFilter, setTooltip) { const data = payload.data.features; const sc = fd.color_picker; const tc = fd.target_color_picker; @@ -27,7 +27,7 @@ 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, setTooltip), }); } diff --git a/superset/assets/src/visualizations/deckgl/layers/Geojson/Geojson.jsx b/superset/assets/src/visualizations/deckgl/layers/Geojson/Geojson.jsx index 8eb4f79505498..a90aefd4f6da2 100644 --- a/superset/assets/src/visualizations/deckgl/layers/Geojson/Geojson.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/Geojson/Geojson.jsx @@ -58,7 +58,7 @@ const recurseGeoJson = (node, propOverrides, extraProps) => { } }; -function getLayer(formData, payload, slice) { +export function getLayer(formData, payload, onAddFilter, setTooltip) { const fd = formData; const fc = fd.fill_color_picker; const sc = fd.stroke_color_picker; @@ -89,21 +89,39 @@ function getLayer(formData, payload, slice) { stroked: fd.stroked, extruded: fd.extruded, pointRadiusScale: fd.point_radius_scale, - ...common.commonLayerProps(fd, slice), + ...commonLayerProps(fd, onAddFilter, setTooltip), }); } -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, + setTooltip: PropTypes.func, +}; +const defaultProps = { + onAddFilter() {}, + setTooltip() {}, +}; + +function deckGeoJson(props) { + const { + formData, + payload, + setControlValue, + onAddFilter, + setTooltip, + viewport, + } = props; + + // TODO get this to work + // if (formData.autozoom) { + // viewport = common.fitViewport(viewport, geojsonExtent(payload.data.features)); + // } + + const layer = getLayer(formData, payload, onAddFilter, setTooltip); ReactDOM.render( ({ @@ -31,7 +31,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, setTooltip), }); } diff --git a/superset/assets/src/visualizations/deckgl/layers/Hex/Hex.jsx b/superset/assets/src/visualizations/deckgl/layers/Hex/Hex.jsx index c8283a5dfa0be..32cf54803f906 100644 --- a/superset/assets/src/visualizations/deckgl/layers/Hex/Hex.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/Hex/Hex.jsx @@ -7,7 +7,7 @@ import sandboxedEval from '../../../../modules/sandbox'; import createAdaptor from '../../createAdaptor'; import { createDeckGLComponent } from '../../factory'; -function getLayer(formData, payload, slice) { +export function getLayer(formData, payload, onAddFilter, setTooltip) { const fd = formData; const c = fd.color_picker; let data = payload.data.features.map(d => ({ @@ -32,7 +32,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, setTooltip), }); } diff --git a/superset/assets/src/visualizations/deckgl/layers/Path/Path.jsx b/superset/assets/src/visualizations/deckgl/layers/Path/Path.jsx index f676c9dc69fac..7de17d37f58a2 100644 --- a/superset/assets/src/visualizations/deckgl/layers/Path/Path.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/Path/Path.jsx @@ -7,7 +7,7 @@ import sandboxedEval from '../../../../modules/sandbox'; import createAdaptor from '../../createAdaptor'; import { createDeckGLComponent } from '../../factory'; -function getLayer(formData, payload, slice) { +export function getLayer(formData, payload, onAddFilter, setTooltip) { const fd = formData; const c = fd.color_picker; const fixedColor = [c.r, c.g, c.b, 255 * c.a]; @@ -28,7 +28,7 @@ function getLayer(formData, payload, slice) { data, rounded: true, widthScale: 1, - ...common.commonLayerProps(fd, slice), + ...commonLayerProps(fd, onAddFilter, setTooltip), }); } diff --git a/superset/assets/src/visualizations/deckgl/layers/Polygon/Polygon.jsx b/superset/assets/src/visualizations/deckgl/layers/Polygon/Polygon.jsx index 5351db35f5d15..668883256b565 100644 --- a/superset/assets/src/visualizations/deckgl/layers/Polygon/Polygon.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/Polygon/Polygon.jsx @@ -13,7 +13,7 @@ function getPoints(features) { return _.flatten(features.map(d => d.polygon), true); } -function getLayer(formData, payload, slice) { +export function getLayer(formData, payload, onAddFilter, setTooltip) { const fd = formData; const fc = fd.fill_color_picker; const sc = fd.stroke_color_picker; @@ -47,7 +47,7 @@ function getLayer(formData, payload, slice) { getLineWidth: fd.line_width, extruded: fd.extruded, fp64: true, - ...common.commonLayerProps(fd, slice), + ...commonLayerProps(fd, onAddFilter, setTooltip), }); } diff --git a/superset/assets/src/visualizations/deckgl/layers/Screengrid/Screengrid.jsx b/superset/assets/src/visualizations/deckgl/layers/Screengrid/Screengrid.jsx index 7a4f93d2da059..62e0d79c1dc70 100644 --- a/superset/assets/src/visualizations/deckgl/layers/Screengrid/Screengrid.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/Screengrid/Screengrid.jsx @@ -15,7 +15,7 @@ function getPoints(data) { return data.map(d => d.position); } -function getLayer(formData, payload, slice, filters) { +export function getLayer(formData, payload, onAddFilter, setTooltip, filters) { const fd = formData; const c = fd.color_picker; let data = payload.data.features.map(d => ({ @@ -46,7 +46,7 @@ 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, setTooltip), }); } @@ -55,6 +55,12 @@ const propTypes = { payload: PropTypes.object.isRequired, setControlValue: PropTypes.func.isRequired, viewport: PropTypes.object.isRequired, + onAddFilter: PropTypes.func, + setTooltip: PropTypes.func, +}; +const defaultProps = { + onAddFilter() {}, + setTooltip() {}, }; class DeckGLScreenGrid extends React.PureComponent { @@ -94,7 +100,8 @@ class DeckGLScreenGrid extends React.PureComponent { const layer = getLayer( this.props.slice.formData, this.props.payload, - this.props.slice, + this.props.onAddFilter, + this.props.setTooltip, filters); return [layer]; diff --git a/superset/assets/src/visualizations/deckgl/layers/common.jsx b/superset/assets/src/visualizations/deckgl/layers/common.jsx index b67ae7dcb12c7..4ecb56c4ef2f5 100644 --- a/superset/assets/src/visualizations/deckgl/layers/common.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/common.jsx @@ -31,7 +31,7 @@ export function fitViewport(viewport, points, padding = 10) { } } -export function commonLayerProps(formData, slice) { +export function commonLayerProps(formData, onAddFilter, setTooltip) { const fd = formData; let onHover; let tooltipContentGenerator; @@ -48,13 +48,13 @@ export function commonLayerProps(formData, slice) { if (tooltipContentGenerator) { onHover = (o) => { if (o.picked) { - slice.setTooltip({ + setTooltip({ content: tooltipContentGenerator(o), x: o.x, y: o.y, }); } else { - slice.setTooltip(null); + setTooltip(null); } }; }