feat: make all deckgl charts handle their own tooltips (#13)

* feat: make all deckgl charts handle their own tooltips

* fix: use destructuring
This commit is contained in:
Krist Wongsuphasawat 2020-03-19 16:30:42 -07:00 committed by Yongjie Zhao
parent f3e5a10518
commit 8fbeba101c
8 changed files with 78 additions and 45 deletions

View File

@ -58,8 +58,9 @@ export default class AnimatableDeckGLContainer extends React.PureComponent {
containerRef = React.createRef(); containerRef = React.createRef();
setTooltip = tooltip => { setTooltip = tooltip => {
if (this.containerRef.current) { const { current } = this.containerRef;
this.containerRef.current.setTooltip(tooltip); if (current) {
current.setTooltip(tooltip);
} }
}; };

View File

@ -66,7 +66,6 @@ const propTypes = {
getPoints: PropTypes.func.isRequired, getPoints: PropTypes.func.isRequired,
payload: PropTypes.object.isRequired, payload: PropTypes.object.isRequired,
onAddFilter: PropTypes.func, onAddFilter: PropTypes.func,
setTooltip: PropTypes.func,
width: PropTypes.number.isRequired, width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired, height: PropTypes.number.isRequired,
}; };
@ -147,7 +146,7 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
} }
getLayers(values) { getLayers(values) {
const { getLayer, payload, formData: fd, onAddFilter, setTooltip } = this.props; const { getLayer, payload, formData: fd, onAddFilter } = this.props;
let features = payload.data.features ? [...payload.data.features] : []; let features = payload.data.features ? [...payload.data.features] : [];
// Add colors from categories or fixed color // Add colors from categories or fixed color
@ -177,7 +176,7 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
data: { ...payload.data, features }, data: { ...payload.data, features },
}; };
return [getLayer(fd, filteredPayload, onAddFilter, setTooltip)]; return [getLayer(fd, filteredPayload, onAddFilter, this.setTooltip)];
} }
// eslint-disable-next-line class-methods-use-this // eslint-disable-next-line class-methods-use-this
@ -228,8 +227,9 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
} }
setTooltip = tooltip => { setTooltip = tooltip => {
if (this.containerRef.current) { const { current } = this.containerRef;
this.containerRef.current.setTooltip(tooltip); if (current) {
current.setTooltip(tooltip);
} }
}; };

View File

@ -36,16 +36,16 @@ const propTypes = {
setControlValue: PropTypes.func.isRequired, setControlValue: PropTypes.func.isRequired,
viewport: PropTypes.object.isRequired, viewport: PropTypes.object.isRequired,
onAddFilter: PropTypes.func, onAddFilter: PropTypes.func,
setTooltip: PropTypes.func,
onSelect: PropTypes.func, onSelect: PropTypes.func,
}; };
const defaultProps = { const defaultProps = {
onAddFilter() {}, onAddFilter() {},
setTooltip() {},
onSelect() {}, onSelect() {},
}; };
class DeckMulti extends React.PureComponent { class DeckMulti extends React.PureComponent {
containerRef = React.createRef();
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { subSlicesLayers: {} }; this.state = { subSlicesLayers: {} };
@ -96,7 +96,7 @@ class DeckMulti extends React.PureComponent {
subsliceCopy.form_data, subsliceCopy.form_data,
json, json,
this.props.onAddFilter, this.props.onAddFilter,
this.props.setTooltip, this.setTooltip,
[], [],
this.props.onSelect, this.props.onSelect,
); );
@ -111,6 +111,13 @@ class DeckMulti extends React.PureComponent {
}); });
} }
setTooltip = tooltip => {
const { current } = this.containerRef;
if (current) {
current.setTooltip(tooltip);
}
};
render() { render() {
const { payload, formData, setControlValue } = this.props; const { payload, formData, setControlValue } = this.props;
const { subSlicesLayers } = this.state; const { subSlicesLayers } = this.state;
@ -119,6 +126,7 @@ class DeckMulti extends React.PureComponent {
return ( return (
<DeckGLContainer <DeckGLContainer
ref={this.containerRef}
mapboxApiAccessToken={payload.data.mapboxApiKey} mapboxApiAccessToken={payload.data.mapboxApiKey}
viewport={this.state.viewport || this.props.viewport} viewport={this.state.viewport || this.props.viewport}
layers={layers} layers={layers}

View File

@ -35,18 +35,18 @@ const propTypes = {
setControlValue: PropTypes.func.isRequired, setControlValue: PropTypes.func.isRequired,
viewport: PropTypes.object.isRequired, viewport: PropTypes.object.isRequired,
onAddFilter: PropTypes.func, onAddFilter: PropTypes.func,
setTooltip: PropTypes.func,
width: PropTypes.number.isRequired, width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired, height: PropTypes.number.isRequired,
}; };
const defaultProps = { const defaultProps = {
onAddFilter() {}, onAddFilter() {},
setTooltip() {},
}; };
export function createDeckGLComponent(getLayer, getPoints) { export function createDeckGLComponent(getLayer, getPoints) {
// Higher order component // Higher order component
class Component extends React.PureComponent { class Component extends React.PureComponent {
containerRef = React.createRef();
constructor(props) { constructor(props) {
super(props); super(props);
@ -80,19 +80,26 @@ export function createDeckGLComponent(getLayer, getPoints) {
this.setState({ viewport }); this.setState({ viewport });
} }
// eslint-disable-next-line class-methods-use-this
computeLayer(props) { computeLayer(props) {
const { formData, payload, onAddFilter, setTooltip } = props; const { formData, payload, onAddFilter } = props;
return getLayer(formData, payload, onAddFilter, setTooltip); return getLayer(formData, payload, onAddFilter, this.setTooltip);
} }
setTooltip = tooltip => {
const { current } = this.containerRef;
if (current) {
current.setTooltip(tooltip);
}
};
render() { render() {
const { formData, payload, setControlValue, height, width } = this.props; const { formData, payload, setControlValue, height, width } = this.props;
const { layer, viewport } = this.state; const { layer, viewport } = this.state;
return ( return (
<DeckGLContainer <DeckGLContainer
ref={this.containerRef}
mapboxApiAccessToken={payload.data.mapboxApiKey} mapboxApiAccessToken={payload.data.mapboxApiKey}
viewport={viewport} viewport={viewport}
layers={[layer]} layers={[layer]}
@ -113,7 +120,7 @@ export function createDeckGLComponent(getLayer, getPoints) {
export function createCategoricalDeckGLComponent(getLayer, getPoints) { export function createCategoricalDeckGLComponent(getLayer, getPoints) {
function Component(props) { function Component(props) {
const { formData, payload, setControlValue, setTooltip, viewport, width, height } = props; const { formData, payload, setControlValue, viewport, width, height } = props;
return ( return (
<CategoricalDeckGLContainer <CategoricalDeckGLContainer
@ -123,7 +130,6 @@ export function createCategoricalDeckGLComponent(getLayer, getPoints) {
viewport={viewport} viewport={viewport}
getLayer={getLayer} getLayer={getLayer}
payload={payload} payload={payload}
setTooltip={setTooltip}
getPoints={getPoints} getPoints={getPoints}
width={width} width={width}
height={height} height={height}

View File

@ -136,35 +136,45 @@ const propTypes = {
setControlValue: PropTypes.func.isRequired, setControlValue: PropTypes.func.isRequired,
viewport: PropTypes.object.isRequired, viewport: PropTypes.object.isRequired,
onAddFilter: PropTypes.func, onAddFilter: PropTypes.func,
setTooltip: PropTypes.func,
}; };
const defaultProps = { const defaultProps = {
onAddFilter() {}, onAddFilter() {},
setTooltip() {},
}; };
function deckGeoJson(props) { class DeckGLGeoJson extends React.Component {
const { formData, payload, setControlValue, onAddFilter, setTooltip, viewport } = props; containerRef = React.createRef();
// TODO get this to work setTooltip = tooltip => {
// if (formData.autozoom) { const { current } = this.containerRef;
// viewport = common.fitViewport(viewport, geojsonExtent(payload.data.features)); if (current) {
// } current.setTooltip(tooltip);
}
};
const layer = getLayer(formData, payload, onAddFilter, setTooltip); render() {
const { formData, payload, setControlValue, onAddFilter, viewport } = this.props;
return ( // TODO get this to work
<DeckGLContainer // if (formData.autozoom) {
mapboxApiAccessToken={payload.data.mapboxApiKey} // viewport = common.fitViewport(viewport, geojsonExtent(payload.data.features));
viewport={viewport} // }
layers={[layer]}
mapStyle={formData.mapbox_style} const layer = getLayer(formData, payload, onAddFilter, this.setTooltip);
setControlValue={setControlValue}
/> return (
); <DeckGLContainer
ref={this.containerRef}
mapboxApiAccessToken={payload.data.mapboxApiKey}
viewport={viewport}
layers={[layer]}
mapStyle={formData.mapbox_style}
setControlValue={setControlValue}
/>
);
}
} }
deckGeoJson.propTypes = propTypes; DeckGLGeoJson.propTypes = propTypes;
deckGeoJson.defaultProps = defaultProps; DeckGLGeoJson.defaultProps = defaultProps;
export default deckGeoJson; export default DeckGLGeoJson;

View File

@ -259,8 +259,9 @@ class DeckGLPolygon extends React.Component {
} }
setTooltip = tooltip => { setTooltip = tooltip => {
if (this.containerRef.current) { const { current } = this.containerRef;
this.containerRef.current.setTooltip(tooltip); if (current) {
current.setTooltip(tooltip);
} }
}; };

View File

@ -89,16 +89,16 @@ const propTypes = {
setControlValue: PropTypes.func.isRequired, setControlValue: PropTypes.func.isRequired,
viewport: PropTypes.object.isRequired, viewport: PropTypes.object.isRequired,
onAddFilter: PropTypes.func, onAddFilter: PropTypes.func,
setTooltip: PropTypes.func,
width: PropTypes.number.isRequired, width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired, height: PropTypes.number.isRequired,
}; };
const defaultProps = { const defaultProps = {
onAddFilter() {}, onAddFilter() {},
setTooltip() {},
}; };
class DeckGLScreenGrid extends React.PureComponent { class DeckGLScreenGrid extends React.PureComponent {
containerRef = React.createRef();
constructor(props) { constructor(props) {
super(props); super(props);
@ -170,19 +170,27 @@ class DeckGLScreenGrid extends React.PureComponent {
this.props.formData, this.props.formData,
this.props.payload, this.props.payload,
this.props.onAddFilter, this.props.onAddFilter,
this.props.setTooltip, this.setTooltip,
filters, filters,
); );
return [layer]; return [layer];
} }
setTooltip = tooltip => {
const { current } = this.containerRef;
if (current) {
current.setTooltip(tooltip);
}
};
render() { render() {
const { formData, payload, setControlValue } = this.props; const { formData, payload, setControlValue } = this.props;
return ( return (
<div> <div>
<AnimatableDeckGLContainer <AnimatableDeckGLContainer
ref={this.containerRef}
aggregation aggregation
getLayers={this.getLayers} getLayers={this.getLayers}
start={this.state.start} start={this.state.start}

View File

@ -20,7 +20,7 @@ const NOOP = () => {};
export default function transformProps(chartProps) { export default function transformProps(chartProps) {
const { width, height, rawFormData, queryData, hooks } = chartProps; const { width, height, rawFormData, queryData, hooks } = chartProps;
const { onAddFilter = NOOP, setControlValue = NOOP, setTooltip = NOOP } = hooks; const { onAddFilter = NOOP, setControlValue = NOOP } = hooks;
return { return {
formData: rawFormData, formData: rawFormData,
@ -28,7 +28,6 @@ export default function transformProps(chartProps) {
onAddFilter, onAddFilter,
payload: queryData, payload: queryData,
setControlValue, setControlValue,
setTooltip,
viewport: { viewport: {
...rawFormData.viewport, ...rawFormData.viewport,
height, height,