Skip to content

Commit

Permalink
[SIP-5] Remove references to slice from all deck.gl components. (#6039)
Browse files Browse the repository at this point in the history
* start removing slice.

* migrate arc

* refactor arc

* refactor path

* refactor deck polygon

* remove commented code

* refactor factory function

* refactor grid

* refactor hex

* refactor polygon

* refactor scatter

* refactor geojson

* refactor screengrid

* remove unnecessary nesting

* add proptypes

* add proptypes

* refactor deck.gl Multi

* fix lint

* Use export syntax instead of module.exports
  • Loading branch information
kristw authored and williaster committed Oct 12, 2018
1 parent 5282f39 commit 2a7b64f
Show file tree
Hide file tree
Showing 14 changed files with 312 additions and 347 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -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 };
Expand Down Expand Up @@ -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>
Expand Down
30 changes: 30 additions & 0 deletions superset/assets/src/visualizations/deckgl/createAdaptor.jsx
Original file line number Diff line number Diff line change
@@ -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),
);
};
}
87 changes: 87 additions & 0 deletions superset/assets/src/visualizations/deckgl/factory.jsx
Original file line number Diff line number Diff line change
@@ -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;
}
46 changes: 6 additions & 40 deletions superset/assets/src/visualizations/deckgl/layers/arc.jsx
Original file line number Diff line number Diff line change
@@ -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 = [];
Expand All @@ -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;
Expand All @@ -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));
9 changes: 4 additions & 5 deletions superset/assets/src/visualizations/deckgl/layers/common.jsx
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
};
}
Expand All @@ -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,
Expand Down
64 changes: 41 additions & 23 deletions superset/assets/src/visualizations/deckgl/layers/geojson.jsx
Original file line number Diff line number Diff line change
@@ -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',
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Loading

0 comments on commit 2a7b64f

Please sign in to comment.