DECKGL integration - Phase 1 (#3771)

* DECKGL integration

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

* Addressing comments

* lint

* Linting

* Addressing chri's comments
This commit is contained in:
Maxime Beauchemin
2017-11-16 00:30:02 -08:00
committed by Grace Guo
parent 1c545d3a2d
commit 3a8af5d0b0
31 changed files with 1308 additions and 11 deletions

View File

@@ -1,7 +1,8 @@
import React from 'react';
import { formatSelectOptionsForRange, formatSelectOptions } from '../../modules/utils';
import * as v from '../validators';
import { ALL_COLOR_SCHEMES, spectrums } from '../../modules/colors';
import { colorPrimary, ALL_COLOR_SCHEMES, spectrums } from '../../modules/colors';
import { defaultViewport } from '../../modules/geo';
import MetricOption from '../../components/MetricOption';
import ColumnOption from '../../components/ColumnOption';
import OptionDescription from '../../components/OptionDescription';
@@ -135,6 +136,14 @@ export const controls = {
}),
},
color_picker: {
label: t('Fixed Color'),
description: t('Use this to define a static color for all circles'),
type: 'ColorPickerControl',
default: colorPrimary,
renderTrigger: true,
},
annotation_layers: {
type: 'SelectAsyncControl',
multi: true,
@@ -424,6 +433,13 @@ export const controls = {
},
groupby: groupByControl,
dimension: {
...groupByControl,
label: t('Dimension'),
description: t('Select a dimension'),
multi: false,
default: null,
},
columns: Object.assign({}, groupByControl, {
label: t('Columns'),
@@ -441,6 +457,28 @@ export const controls = {
}),
},
longitude: {
type: 'SelectControl',
label: t('Longitude'),
default: 1,
validators: [v.nonEmpty],
description: t('Select the longitude column'),
mapStateToProps: state => ({
choices: (state.datasource) ? state.datasource.all_cols : [],
}),
},
latitude: {
type: 'SelectControl',
label: t('Latitude'),
default: 1,
validators: [v.nonEmpty],
description: t('Select the latitude column'),
mapStateToProps: state => ({
choices: (state.datasource) ? state.datasource.all_cols : [],
}),
},
all_columns_x: {
type: 'SelectControl',
label: 'X',
@@ -730,6 +768,14 @@ export const controls = {
'with the [Periods] text box'),
},
multiplier: {
type: 'TextControl',
label: t('Multiplier'),
isFloat: true,
default: 1,
description: t('Factor to multiply the metric by'),
},
rolling_periods: {
type: 'TextControl',
label: t('Periods'),
@@ -738,6 +784,15 @@ export const controls = {
'relative to the time granularity selected'),
},
grid_size: {
type: 'TextControl',
label: t('Grid Size'),
renderTrigger: true,
default: 20,
isInt: true,
description: t('Defines the grid size in pixels'),
},
min_periods: {
type: 'TextControl',
label: t('Min Periods'),
@@ -1043,6 +1098,14 @@ export const controls = {
),
},
extruded: {
type: 'CheckboxControl',
label: t('Extruded'),
renderTrigger: true,
default: true,
description: ('Whether to make the grid 3D'),
},
show_brush: {
type: 'CheckboxControl',
label: t('Range Filter'),
@@ -1255,6 +1318,7 @@ export const controls = {
mapbox_style: {
type: 'SelectControl',
label: t('Map Style'),
renderTrigger: true,
choices: [
['mapbox://styles/mapbox/streets-v9', 'Streets'],
['mapbox://styles/mapbox/dark-v9', 'Dark'],
@@ -1288,6 +1352,15 @@ export const controls = {
'number of points (>1000) will cause lag.'),
},
point_radius_fixed: {
type: 'FixedOrMetricControl',
label: t('Point Size'),
description: t('Fixed point radius'),
mapStateToProps: state => ({
datasource: state.datasource,
}),
},
point_radius: {
type: 'SelectControl',
label: t('Point Radius'),
@@ -1308,6 +1381,22 @@ export const controls = {
description: t('The unit of measure for the specified point radius'),
},
point_unit: {
type: 'SelectControl',
label: t('Point Unit'),
default: 'square_m',
clearable: false,
choices: [
['square_m', 'Square meters'],
['square_km', 'Square kilometers'],
['square_miles', 'Square miles'],
['radius_m', 'Radius in meters'],
['radius_km', 'Radius in kilometers'],
['radius_miles', 'Radius in miles'],
],
description: t('The unit of measure for the specified point radius'),
},
global_opacity: {
type: 'TextControl',
label: t('Opacity'),
@@ -1317,6 +1406,15 @@ export const controls = {
'Between 0 and 1.'),
},
viewport: {
type: 'ViewportControl',
label: t('Viewport'),
renderTrigger: true,
description: t('Parameters related to the view and perspective on the map'),
// default is whole world mostly centered
default: defaultViewport,
},
viewport_zoom: {
type: 'TextControl',
label: t('Zoom'),
@@ -1370,6 +1468,7 @@ export const controls = {
color: {
type: 'ColorPickerControl',
label: t('Color'),
default: colorPrimary,
description: t('Pick a color'),
},

View File

@@ -294,6 +294,153 @@ export const visTypes = {
},
},
deck_hex: {
label: t('Deck.gl - Hexagons'),
requiresTime: true,
controlPanelSections: [
{
label: t('Query'),
expanded: true,
controlSetRows: [
['longitude', 'latitude'],
['groupby', 'size'],
['row_limit'],
],
},
{
label: t('Map'),
controlSetRows: [
['mapbox_style', 'viewport'],
['color_picker', null],
['grid_size', 'extruded'],
],
},
],
controlOverrides: {
size: {
label: t('Height'),
description: t('Metric used to control height'),
validators: [v.nonEmpty],
},
},
},
deck_grid: {
label: t('Deck.gl - Grid'),
requiresTime: true,
controlPanelSections: [
{
label: t('Query'),
expanded: true,
controlSetRows: [
['longitude', 'latitude'],
['groupby', 'size'],
['row_limit'],
],
},
{
label: t('Map'),
controlSetRows: [
['mapbox_style', 'viewport'],
['color_picker', null],
['grid_size', 'extruded'],
],
},
],
controlOverrides: {
size: {
label: t('Height'),
description: t('Metric used to control height'),
validators: [v.nonEmpty],
},
},
},
deck_screengrid: {
label: t('Deck.gl - Screen grid'),
requiresTime: true,
controlPanelSections: [
{
label: t('Query'),
expanded: true,
controlSetRows: [
['longitude', 'latitude'],
['groupby', 'size'],
['row_limit'],
],
},
{
label: t('Map'),
controlSetRows: [
['mapbox_style', 'viewport'],
],
},
{
label: t('Grid'),
controlSetRows: [
['grid_size', 'color_picker'],
],
},
],
controlOverrides: {
size: {
label: t('Weight'),
description: t("Metric used as a weight for the grid's coloring"),
validators: [v.nonEmpty],
},
},
},
deck_scatter: {
label: t('Deck.gl - Scatter plot'),
requiresTime: true,
controlPanelSections: [
{
label: t('Query'),
expanded: true,
controlSetRows: [
['longitude', 'latitude'],
['groupby'],
['row_limit'],
],
},
{
label: t('Map'),
controlSetRows: [
['mapbox_style', 'viewport'],
],
},
{
label: t('Point Size'),
controlSetRows: [
['point_radius_fixed', 'point_unit'],
['multiplier', null],
],
},
{
label: t('Point Color'),
controlSetRows: [
['color_picker', null],
['dimension', 'color_scheme'],
],
},
],
controlOverrides: {
all_columns_x: {
label: t('Longitude Column'),
validators: [v.nonEmpty],
},
all_columns_y: {
label: t('Latitude Column'),
validators: [v.nonEmpty],
},
dimension: {
label: t('Categorical Color'),
description: t('Pick a dimension from which categorical colors are defined'),
},
},
},
area: {
label: t('Time Series - Stacked'),
requiresTime: true,
@@ -1062,9 +1209,8 @@ export const visTypes = {
{
label: t('Viewport'),
controlSetRows: [
['viewport_longitude'],
['viewport_latitude'],
['viewport_zoom'],
['viewport_longitude', 'viewport_latitude'],
['viewport_zoom', null],
],
},
],