Skip to content

Commit

Permalink
DECKGL integration
Browse files Browse the repository at this point in the history
Adding a new set of geospatial visualizations building on top of the
awesome deck.gl library. https://github.com/uber/deck.gl

While the end goal it to expose all types of layers and let users bind
their data to control most props exposed by the deck.gl API, this
PR focusses on a first set of visualizations and props:

* ScatterLayer
* HexagonLayer
* GridLayer
* ScreenGridLayer
  • Loading branch information
mistercrunch committed Nov 7, 2017
1 parent ccb87d3 commit bbe3fca
Show file tree
Hide file tree
Showing 30 changed files with 1,277 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / stateme
good-names=i,j,k,ex,Run,_,d,e,v,o,l,x,ts

# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
bad-names=foo,bar,baz,toto,tutu,tata,d,fd

# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Label, Popover, OverlayTrigger } from 'react-bootstrap';

import controls from '../../stores/controls';
import TextControl from './TextControl';
import SelectControl from './SelectControl';
import ControlHeader from '../ControlHeader';
import PopoverSection from '../../../components/PopoverSection';

const propTypes = {
onChange: PropTypes.func,
value: PropTypes.object,
isFloat: PropTypes.bool,
datasource: PropTypes.object,
default: PropTypes.object,
};

const defaultProps = {
onChange: () => {},
default: { type: 'fix', value: 5 },
};

export default class FixedOrMetricControl extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
const type = props.value ? props.value.type : props.default.type || 'fix';
const value = props.value ? props.value.value : props.default.value || '100';
this.state = {
type,
fixedValue: type === 'fix' ? value : '',
metricValue: type === 'metric' ? value : null,
};
}
onChange() {
this.props.onChange({
type: this.state.type,
value: this.state.type === 'fix' ? this.state.fixedValue : this.state.metricValue,
});
}
setType(type) {
this.setState({ type }, this.onChange);
}
setFixedValue(fixedValue) {
this.setState({ fixedValue }, this.onChange);
}
setMetric(metricValue) {
this.setState({ metricValue }, this.onChange);
}
renderPopover() {
const value = this.props.value || this.props.default;
const type = value.type || 'fix';
const metrics = this.props.datasource ? this.props.datasource.metrics : null;
return (
<Popover id="filter-popover">
<div style={{ width: '240px' }}>
<PopoverSection
title="Fixed"
isSelected={type === 'fix'}
onSelect={this.onChange.bind(this, 'fix')}
>
<TextControl
isFloat
onChange={this.setFixedValue.bind(this)}
onFocus={this.setType.bind(this, 'fix')}
value={this.state.fixedValue}
/>
</PopoverSection>
<PopoverSection
title="Based on a metric"
isSelected={type === 'metric'}
onSelect={this.onChange.bind(this, 'metric')}
>
<SelectControl
{...controls.metric}
name="metric"
options={metrics}
onFocus={this.setType.bind(this, 'metric')}
onChange={this.setMetric.bind(this)}
value={this.state.metricValue}
/>
</PopoverSection>
</div>
</Popover>
);
}
render() {
return (
<div>
<ControlHeader {...this.props} />
<OverlayTrigger
container={document.body}
trigger="click"
rootClose
ref="trigger"
placement="right"
overlay={this.renderPopover()}
>
<Label style={{ cursor: 'pointer' }}>
{this.state.type === 'fix' &&
<span>{this.state.fixedValue}</span>
}
{this.state.type === 'metric' &&
<span>
<span style={{ fontWeight: 'normal' }}>metric: </span>
<strong>{this.state.metricValue}</strong>
</span>
}
</Label>
</OverlayTrigger>
</div>
);
}
}

FixedOrMetricControl.propTypes = propTypes;
FixedOrMetricControl.defaultProps = defaultProps;
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const propTypes = {
multi: PropTypes.bool,
name: PropTypes.string.isRequired,
onChange: PropTypes.func,
onFocus: PropTypes.func,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array]),
showHeader: PropTypes.bool,
optionRenderer: PropTypes.func,
Expand All @@ -34,6 +35,7 @@ const defaultProps = {
label: null,
multi: false,
onChange: () => {},
onFocus: () => {},
showHeader: true,
optionRenderer: opt => opt.label,
valueRenderer: opt => opt.label,
Expand Down Expand Up @@ -115,6 +117,7 @@ export default class SelectControl extends React.PureComponent {
clearable: this.props.clearable,
isLoading: this.props.isLoading,
onChange: this.onChange,
onFocus: this.props.onFocus,
optionRenderer: VirtualizedRendererWrap(this.props.optionRenderer),
valueRenderer: this.props.valueRenderer,
selectComponent: this.props.freeForm ? Creatable : Select,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import * as v from '../../validators';
import ControlHeader from '../ControlHeader';

const propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string,
description: PropTypes.string,
onChange: PropTypes.func,
onFocus: PropTypes.func,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
Expand All @@ -18,9 +16,8 @@ const propTypes = {
};

const defaultProps = {
label: null,
description: null,
onChange: () => {},
onFocus: () => {},
value: '',
isInt: false,
isFloat: false,
Expand Down Expand Up @@ -64,6 +61,7 @@ export default class TextControl extends React.Component {
type="text"
placeholder=""
onChange={this.onChange}
onFocus={this.props.onFocus}
value={value}
/>
</FormGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Label, Popover, OverlayTrigger } from 'react-bootstrap';
import { decimal2sexagesimal } from 'geolib';

import TextControl from './TextControl';
import ControlHeader from '../ControlHeader';

const PARAMS = [
'longitude',
'latitude',
'zoom',
'bearing',
'pitch',
];

const propTypes = {
onChange: PropTypes.func.isRequired,
value: PropTypes.object,
default: PropTypes.object,
};

const defaultProps = {
onChange: () => {},
default: { type: 'fix', value: 5 },
value: {
longitude: 6.85236157047845,
latitude: 31.222656842808707,
zoom: 1,
bearing: 0,
pitch: 0,
},
};

export default class ViewportControl extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
}
onChange(ctrl, value) {
this.props.onChange({
...this.props.value,
[ctrl]: value,
});
}
renderTextControl(ctrl) {
return (
<div>
{ctrl}
<TextControl
value={this.props.value[ctrl]}
onChange={this.onChange.bind(this, ctrl)}
isFloat
/>
</div>
);
}
renderPopover() {
return (
<Popover id="filter-popover" title="Viewport">
{PARAMS.map(ctrl => this.renderTextControl(ctrl))}
</Popover>
);
}
renderLabel() {
if (this.props.value.longitude && this.props.value.latitude) {
return (
decimal2sexagesimal(this.props.value.longitude) +
' | ' +
decimal2sexagesimal(this.props.value.latitude)
);
}
return 'N/A';
}
render() {
return (
<div>
<ControlHeader {...this.props} />
<OverlayTrigger
container={document.body}
trigger="click"
rootClose
ref="trigger"
placement="right"
overlay={this.renderPopover()}
>
<Label style={{ cursor: 'pointer' }}>
{this.renderLabel()}
</Label>
</OverlayTrigger>
</div>
);
}
}

ViewportControl.propTypes = propTypes;
ViewportControl.defaultProps = defaultProps;
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import ColorSchemeControl from './ColorSchemeControl';
import DatasourceControl from './DatasourceControl';
import DateFilterControl from './DateFilterControl';
import FilterControl from './FilterControl';
import FixedOrMetricControl from './FixedOrMetricControl';
import HiddenControl from './HiddenControl';
import SelectAsyncControl from './SelectAsyncControl';
import SelectControl from './SelectControl';
import TextAreaControl from './TextAreaControl';
import TextControl from './TextControl';
import TimeSeriesColumnControl from './TimeSeriesColumnControl';
import ViewportControl from './ViewportControl';
import VizTypeControl from './VizTypeControl';

const controlMap = {
Expand All @@ -23,12 +25,14 @@ const controlMap = {
DatasourceControl,
DateFilterControl,
FilterControl,
FixedOrMetricControl,
HiddenControl,
SelectAsyncControl,
SelectControl,
TextAreaControl,
TextControl,
TimeSeriesColumnControl,
ViewportControl,
VizTypeControl,
};
export default controlMap;
Loading

0 comments on commit bbe3fca

Please sign in to comment.