This is an automated email from the ASF dual-hosted git repository. rusackas pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push: new b6bca9f Migrating shared DeckGL controls (#9455) b6bca9f is described below commit b6bca9f137b069716938ac1df5862c0b5d2c3461 Author: Evan Rusackas <e...@preset.io> AuthorDate: Mon Apr 6 18:37:25 2020 -0700 Migrating shared DeckGL controls (#9455) * Missed a couple unique controls! * new shared module, with filter_nulls export. * autozoom * dimension * nixing unneeded import * stroke_width * js_columns * remaining js_* controls * cleaning up unused stuff * legend_format * exports for prior commit * legend_position * line_column * fill_color_picker * filled, stroked, stroke_color_picker * grid_size, extruded * ... more gridsize * viewport * point_radius_fixed, spatial * multiplier, line_type, line_width * reverse_long_lat * lint :sparkles: --- CONTRIBUTING.md | 22 -- .../src/explore/controlPanels/DeckArc.js | 106 +++++- .../src/explore/controlPanels/DeckGeojson.js | 33 +- .../src/explore/controlPanels/DeckGrid.js | 30 +- .../src/explore/controlPanels/DeckHex.js | 30 +- .../src/explore/controlPanels/DeckMulti.js | 3 +- .../src/explore/controlPanels/DeckPath.js | 48 ++- .../src/explore/controlPanels/DeckPolygon.js | 62 ++-- .../src/explore/controlPanels/DeckScatter.js | 57 ++- .../src/explore/controlPanels/DeckScreengrid.js | 29 +- .../src/explore/controlPanels/Shared_DeckGL.jsx | 383 +++++++++++++++++++++ superset-frontend/src/explore/controls.jsx | 306 +--------------- 12 files changed, 668 insertions(+), 441 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5accddb..c3570d9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1093,7 +1093,6 @@ Note the `y_axis_format` is defined under various section for some charts. | `add_to_dash` | _N/A_ | | | `all_columns_y` | _N/A_ | | | `annotation_layers` | _N/A_ | | -| `autozoom` | _N/A_ | | | `bar_stacked` | _N/A_ | | | `cache_timeout` | _N/A_ | | | `code` | _N/A_ | | @@ -1104,17 +1103,11 @@ Note the `y_axis_format` is defined under various section for some charts. | `country_fieldtype` | _N/A_ | | | `date_filter` | _N/A_ | | | `default_filters` | _N/A_ | | -| `dimension` | _N/A_ | | -| `end_spatial` | _N/A_ | | | `entity` | _N/A_ | | | `expanded_slices` | _N/A_ | | | `extra_filters` | _N/A_ | | -| `extruded` | _N/A_ | | -| `fill_color_picker` | _N/A_ | | -| `filled` | _N/A_ | | | `filter_immune_slice_fields` | _N/A_ | | | `filter_immune_slices` | _N/A_ | | -| `filter_nulls` | _N/A_ | | | `flt_col_0` | _N/A_ | | | `flt_col_1` | _N/A_ | | | `flt_eq_0` | _N/A_ | | @@ -1122,22 +1115,15 @@ Note the `y_axis_format` is defined under various section for some charts. | `flt_op_0` | _N/A_ | | | `flt_op_1` | _N/A_ | | | `goto_dash` | _N/A_ | | -| `grid_size` | _N/A_ | | | `import_time` | _N/A_ | | | `instant_filtering` | _N/A_ | | -| `js_columns` | _N/A_ | | | `label` | _N/A_ | | -| `legend_position` | _N/A_ | | -| `line_column` | _N/A_ | | -| `line_type` | _N/A_ | | -| `line_width` | _N/A_ | | | `linear_color_scheme` | _N/A_ | | | `log_scale` | _N/A_ | | | `mapbox_label` | _N/A_ | | | `mapbox_style` | _N/A_ | | | `markup_type` | _N/A_ | | | `min_periods` | _N/A_ | | -| `multiplier` | _N/A_ | | | `new_dashboard_name` | _N/A_ | | | `new_slice_name` | _N/A_ | | | `normalize_across` | _N/A_ | | @@ -1147,14 +1133,12 @@ Note the `y_axis_format` is defined under various section for some charts. | `pandas_aggfunc` | _N/A_ | | | `period_ratio_type` | _N/A_ | | | `perm` | _N/A_ | | -| `point_radius_fixed` | _N/A_ | | | `rdo_save` | _N/A_ | | | `reduce_x_ticks` | _N/A_ | | | `refresh_frequency` | _N/A_ | | | `remote_id` | _N/A_ | | | `resample_fillmethod` | _N/A_ | | | `resample_how` | _N/A_ | | -| `reverse_long_lat` | _N/A_ | | | `rolling_periods` | _N/A_ | | | `rolling_type` | _N/A_ | | | `rose_area_proportion` | _N/A_ | | @@ -1173,14 +1157,8 @@ Note the `y_axis_format` is defined under various section for some charts. | `show_sqla_time_granularity` | _N/A_ | | | `show_values` | _N/A_ | | | `slice_name` | _N/A_ | | -| `spatial` | _N/A_ | | -| `start_spatial` | _N/A_ | | -| `stroke_color_picker` | _N/A_ | | -| `stroke_width` | _N/A_ | | -| `stroked` | _N/A_ | | | `table_filter` | _N/A_ | | | `timed_refresh_immune_slices` | _N/A_ | | | `url` | _N/A_ | | | `userid` | _N/A_ | | -| `viewport` | _N/A_ | | | `viewport_zoom` | _N/A_ | | diff --git a/superset-frontend/src/explore/controlPanels/DeckArc.js b/superset-frontend/src/explore/controlPanels/DeckArc.js index 1a8c3b9..43fc52c 100644 --- a/superset-frontend/src/explore/controlPanels/DeckArc.js +++ b/superset-frontend/src/explore/controlPanels/DeckArc.js @@ -18,6 +18,21 @@ */ import { t } from '@superset-ui/translation'; import timeGrainSqlaAnimationOverrides from './timeGrainSqlaAnimationOverrides'; +import { nonEmpty, integer } from '../validators'; +import { columnChoices, PRIMARY_COLOR } from '../controls'; +import { formatSelectOptions } from '../../modules/utils'; +import { + filterNulls, + autozoom, + dimension, + jsColumns, + jsDataMutator, + jsTooltip, + jsOnclickHref, + legendFormat, + legendPosition, + viewport, +} from './Shared_DeckGL'; export default { requiresTime: true, @@ -26,44 +41,99 @@ export default { label: t('Query'), expanded: true, controlSetRows: [ - ['start_spatial', 'end_spatial'], - ['row_limit', 'filter_nulls'], + [ + { + name: 'start_spatial', + config: { + type: 'SpatialControl', + label: t('Start Longitude & Latitude'), + validators: [nonEmpty], + description: t('Point to your spatial columns'), + mapStateToProps: state => ({ + choices: columnChoices(state.datasource), + }), + }, + }, + { + name: 'end_spatial', + config: { + type: 'SpatialControl', + label: t('End Longitude & Latitude'), + validators: [nonEmpty], + description: t('Point to your spatial columns'), + mapStateToProps: state => ({ + choices: columnChoices(state.datasource), + }), + }, + }, + ], + ['row_limit', filterNulls], ['adhoc_filters'], ], }, { label: t('Map'), controlSetRows: [ - ['mapbox_style', 'viewport'], - ['autozoom', null], + ['mapbox_style', viewport], + [autozoom, null], ], }, { label: t('Arc'), controlSetRows: [ - ['color_picker', 'target_color_picker'], - ['dimension', 'color_scheme', 'label_colors'], - ['stroke_width', 'legend_position'], - ['legend_format', null], + [ + 'color_picker', + { + name: 'target_color_picker', + config: { + label: t('Target Color'), + description: t('Color of the target location'), + type: 'ColorPickerControl', + default: PRIMARY_COLOR, + renderTrigger: true, + }, + }, + ], + [ + { + ...dimension, + label: t('Categorical Color'), + description: t( + 'Pick a dimension from which categorical colors are defined', + ), + }, + 'color_scheme', + 'label_colors', + ], + [ + { + name: 'stroke_width', + color: { + type: 'SelectControl', + freeForm: true, + label: t('Stroke Width'), + validators: [integer], + default: null, + renderTrigger: true, + choices: formatSelectOptions([1, 2, 3, 4, 5]), + }, + }, + legendPosition, + ], + [legendFormat, null], ], }, { label: t('Advanced'), controlSetRows: [ - ['js_columns'], - ['js_data_mutator'], - ['js_tooltip'], - ['js_onclick_href'], + [jsColumns], + [jsDataMutator], + [jsTooltip], + [jsOnclickHref], ], }, ], controlOverrides: { - dimension: { - label: t('Categorical Color'), - description: t( - 'Pick a dimension from which categorical colors are defined', - ), - }, size: { validators: [], }, diff --git a/superset-frontend/src/explore/controlPanels/DeckGeojson.js b/superset-frontend/src/explore/controlPanels/DeckGeojson.js index e41c3e3..3756177 100644 --- a/superset-frontend/src/explore/controlPanels/DeckGeojson.js +++ b/superset-frontend/src/explore/controlPanels/DeckGeojson.js @@ -20,6 +20,19 @@ import { t } from '@superset-ui/translation'; import { nonEmpty, integer } from '../validators'; import { formatSelectOptions } from '../../modules/utils'; import { columnChoices } from '../controls'; +import { + filterNulls, + jsColumns, + jsDataMutator, + jsTooltip, + jsOnclickHref, + fillColorPicker, + strokeColorPicker, + filled, + stroked, + extruded, + viewport, +} from './Shared_DeckGL'; export default { requiresTime: true, @@ -43,23 +56,23 @@ export default { }, null, ], - ['row_limit', 'filter_nulls'], + ['row_limit', filterNulls], ['adhoc_filters'], ], }, { label: t('Map'), controlSetRows: [ - ['mapbox_style', 'viewport'], - // TODO ['autozoom', null], + ['mapbox_style', viewport], + // TODO [autozoom, null], // import { autozoom } from './Shared_DeckGL' ], }, { label: t('GeoJson Settings'), controlSetRows: [ - ['fill_color_picker', 'stroke_color_picker'], - ['filled', 'stroked'], - ['extruded', null], + [fillColorPicker, strokeColorPicker], + [filled, stroked], + [extruded, null], [ { name: 'point_radius_scale', @@ -79,10 +92,10 @@ export default { { label: t('Advanced'), controlSetRows: [ - ['js_columns'], - ['js_data_mutator'], - ['js_tooltip'], - ['js_onclick_href'], + [jsColumns], + [jsDataMutator], + [jsTooltip], + [jsOnclickHref], ], }, ], diff --git a/superset-frontend/src/explore/controlPanels/DeckGrid.js b/superset-frontend/src/explore/controlPanels/DeckGrid.js index 51ed6f0..8a48edd 100644 --- a/superset-frontend/src/explore/controlPanels/DeckGrid.js +++ b/superset-frontend/src/explore/controlPanels/DeckGrid.js @@ -18,6 +18,18 @@ */ import { t } from '@superset-ui/translation'; import { nonEmpty } from '../validators'; +import { + filterNulls, + autozoom, + jsColumns, + jsDataMutator, + jsTooltip, + jsOnclickHref, + extruded, + gridSize, + viewport, + spatial, +} from './Shared_DeckGL'; export default { requiresTime: true, @@ -26,26 +38,26 @@ export default { label: t('Query'), expanded: true, controlSetRows: [ - ['spatial', 'size'], - ['row_limit', 'filter_nulls'], + [spatial, 'size'], + ['row_limit', filterNulls], ['adhoc_filters'], ], }, { label: t('Map'), controlSetRows: [ - ['mapbox_style', 'viewport'], - ['color_picker', 'autozoom'], - ['grid_size', 'extruded'], + ['mapbox_style', viewport], + ['color_picker', autozoom], + [gridSize, extruded], ], }, { label: t('Advanced'), controlSetRows: [ - ['js_columns'], - ['js_data_mutator'], - ['js_tooltip'], - ['js_onclick_href'], + [jsColumns], + [jsDataMutator], + [jsTooltip], + [jsOnclickHref], ], }, ], diff --git a/superset-frontend/src/explore/controlPanels/DeckHex.js b/superset-frontend/src/explore/controlPanels/DeckHex.js index 01e221b..6edf4cd 100644 --- a/superset-frontend/src/explore/controlPanels/DeckHex.js +++ b/superset-frontend/src/explore/controlPanels/DeckHex.js @@ -21,6 +21,18 @@ import { formatSelectOptions, formatSelectOptionsForRange, } from '../../modules/utils'; +import { + filterNulls, + autozoom, + jsColumns, + jsDataMutator, + jsTooltip, + jsOnclickHref, + extruded, + gridSize, + viewport, + spatial, +} from './Shared_DeckGL'; export default { requiresTime: true, @@ -29,17 +41,17 @@ export default { label: t('Query'), expanded: true, controlSetRows: [ - ['spatial', 'size'], - ['row_limit', 'filter_nulls'], + [spatial, 'size'], + ['row_limit', filterNulls], ['adhoc_filters'], ], }, { label: t('Map'), controlSetRows: [ - ['mapbox_style', 'viewport'], - ['color_picker', 'autozoom'], - ['grid_size', 'extruded'], + ['mapbox_style', viewport], + ['color_picker', autozoom], + [gridSize, extruded], [ { name: 'js_agg_function', @@ -75,10 +87,10 @@ export default { { label: t('Advanced'), controlSetRows: [ - ['js_columns'], - ['js_data_mutator'], - ['js_tooltip'], - ['js_onclick_href'], + [jsColumns], + [jsDataMutator], + [jsTooltip], + [jsOnclickHref], ], }, ], diff --git a/superset-frontend/src/explore/controlPanels/DeckMulti.js b/superset-frontend/src/explore/controlPanels/DeckMulti.js index f05e6f3..119e672 100644 --- a/superset-frontend/src/explore/controlPanels/DeckMulti.js +++ b/superset-frontend/src/explore/controlPanels/DeckMulti.js @@ -18,6 +18,7 @@ */ import { t } from '@superset-ui/translation'; import { nonEmpty } from '../validators'; +import { viewport } from './Shared_DeckGL'; export default { requiresTime: true, @@ -26,7 +27,7 @@ export default { label: t('Map'), expanded: true, controlSetRows: [ - ['mapbox_style', 'viewport'], + ['mapbox_style', viewport], [ { name: 'deck_slices', diff --git a/superset-frontend/src/explore/controlPanels/DeckPath.js b/superset-frontend/src/explore/controlPanels/DeckPath.js index 246d5ec..ddedcc4 100644 --- a/superset-frontend/src/explore/controlPanels/DeckPath.js +++ b/superset-frontend/src/explore/controlPanels/DeckPath.js @@ -17,6 +17,19 @@ * under the License. */ import { t } from '@superset-ui/translation'; +import { + filterNulls, + autozoom, + jsColumns, + jsDataMutator, + jsTooltip, + jsOnclickHref, + lineColumn, + viewport, + lineWidth, + lineType, + reverseLongLat, +} from './Shared_DeckGL'; export default { requiresTime: true, @@ -25,8 +38,17 @@ export default { label: t('Query'), expanded: true, controlSetRows: [ - ['line_column', 'line_type'], - ['row_limit', 'filter_nulls'], + [ + lineColumn, + { + ...lineType, + choices: [ + ['polyline', 'Polyline'], + ['json', 'JSON'], + ], + }, + ], + ['row_limit', filterNulls], ['adhoc_filters'], ], }, @@ -34,27 +56,19 @@ export default { label: t('Map'), expanded: true, controlSetRows: [ - ['mapbox_style', 'viewport'], - ['color_picker', 'line_width'], - ['reverse_long_lat', 'autozoom'], + ['mapbox_style', viewport], + ['color_picker', lineWidth], + [reverseLongLat, autozoom], ], }, { label: t('Advanced'), controlSetRows: [ - ['js_columns'], - ['js_data_mutator'], - ['js_tooltip'], - ['js_onclick_href'], + [jsColumns], + [jsDataMutator], + [jsTooltip], + [jsOnclickHref], ], }, ], - controlOverrides: { - line_type: { - choices: [ - ['polyline', 'Polyline'], - ['json', 'JSON'], - ], - }, - }, }; diff --git a/superset-frontend/src/explore/controlPanels/DeckPolygon.js b/superset-frontend/src/explore/controlPanels/DeckPolygon.js index 75439df..99c4f99 100644 --- a/superset-frontend/src/explore/controlPanels/DeckPolygon.js +++ b/superset-frontend/src/explore/controlPanels/DeckPolygon.js @@ -19,6 +19,28 @@ import { t } from '@superset-ui/translation'; import timeGrainSqlaAnimationOverrides from './timeGrainSqlaAnimationOverrides'; import { formatSelectOptions } from '../../modules/utils'; +import { + filterNulls, + autozoom, + jsColumns, + jsDataMutator, + jsTooltip, + jsOnclickHref, + legendFormat, + legendPosition, + lineColumn, + fillColorPicker, + strokeColorPicker, + filled, + stroked, + extruded, + viewport, + pointRadiusFixed, + multiplier, + lineWidth, + lineType, + reverseLongLat, +} from './Shared_DeckGL'; export default { requiresTime: true, @@ -27,29 +49,32 @@ export default { label: t('Query'), expanded: true, controlSetRows: [ - ['line_column', 'line_type'], + [ + { ...lineColumn, label: t('Polygon Column') }, + { ...lineType, label: t('Polygon Encoding') }, + ], ['adhoc_filters'], - ['metric', 'point_radius_fixed'], + ['metric', { ...pointRadiusFixed, label: t('Elevation') }], ['row_limit', null], - ['reverse_long_lat', 'filter_nulls'], + [reverseLongLat, filterNulls], ], }, { label: t('Map'), expanded: true, controlSetRows: [ - ['mapbox_style', 'viewport'], - ['autozoom', null], + ['mapbox_style', viewport], + [autozoom, null], ], }, { label: t('Polygon Settings'), expanded: true, controlSetRows: [ - ['fill_color_picker', 'stroke_color_picker'], - ['filled', 'stroked'], - ['extruded', 'multiplier'], - ['line_width', null], + [fillColorPicker, strokeColorPicker], + [filled, stroked], + [extruded, multiplier], + [lineWidth, null], [ 'linear_color_scheme', { @@ -110,16 +135,16 @@ export default { }, }, ], - ['legend_position', 'legend_format'], + [legendPosition, legendFormat], ], }, { label: t('Advanced'), controlSetRows: [ - ['js_columns'], - ['js_data_mutator'], - ['js_tooltip'], - ['js_onclick_href'], + [jsColumns], + [jsDataMutator], + [jsTooltip], + [jsOnclickHref], ], }, ], @@ -127,15 +152,6 @@ export default { metric: { validators: [], }, - line_column: { - label: t('Polygon Column'), - }, - line_type: { - label: t('Polygon Encoding'), - }, - point_radius_fixed: { - label: t('Elevation'), - }, time_grain_sqla: timeGrainSqlaAnimationOverrides, }, }; diff --git a/superset-frontend/src/explore/controlPanels/DeckScatter.js b/superset-frontend/src/explore/controlPanels/DeckScatter.js index dcc5f19..dcd5e1f 100644 --- a/superset-frontend/src/explore/controlPanels/DeckScatter.js +++ b/superset-frontend/src/explore/controlPanels/DeckScatter.js @@ -19,6 +19,21 @@ import { t } from '@superset-ui/translation'; import timeGrainSqlaAnimationOverrides from './timeGrainSqlaAnimationOverrides'; import { nonEmpty } from '../validators'; +import { + filterNulls, + autozoom, + dimension, + jsColumns, + jsDataMutator, + jsTooltip, + jsOnclickHref, + legendFormat, + legendPosition, + viewport, + spatial, + pointRadiusFixed, + multiplier, +} from './Shared_DeckGL'; export default { requiresTime: true, @@ -38,8 +53,8 @@ export default { label: t('Query'), expanded: true, controlSetRows: [ - ['spatial', null], - ['row_limit', 'filter_nulls'], + [spatial, null], + ['row_limit', filterNulls], ['adhoc_filters'], ], }, @@ -47,15 +62,15 @@ export default { label: t('Map'), expanded: true, controlSetRows: [ - ['mapbox_style', 'viewport'], - ['autozoom', null], + ['mapbox_style', viewport], + [autozoom, null], ], }, { label: t('Point Size'), controlSetRows: [ [ - 'point_radius_fixed', + pointRadiusFixed, { name: 'point_unit', config: { @@ -109,34 +124,38 @@ export default { }, }, ], - ['multiplier', null], + [multiplier, null], ], }, { label: t('Point Color'), controlSetRows: [ - ['color_picker', 'legend_position'], - [null, 'legend_format'], - ['dimension', 'color_scheme', 'label_colors'], + ['color_picker', legendPosition], + [null, legendFormat], + [ + { + ...dimension, + label: t('Categorical Color'), + description: t( + 'Pick a dimension from which categorical colors are defined', + ), + }, + 'color_scheme', + 'label_colors', + ], ], }, { label: t('Advanced'), controlSetRows: [ - ['js_columns'], - ['js_data_mutator'], - ['js_tooltip'], - ['js_onclick_href'], + [jsColumns], + [jsDataMutator], + [jsTooltip], + [jsOnclickHref], ], }, ], controlOverrides: { - dimension: { - label: t('Categorical Color'), - description: t( - 'Pick a dimension from which categorical colors are defined', - ), - }, size: { validators: [], }, diff --git a/superset-frontend/src/explore/controlPanels/DeckScreengrid.js b/superset-frontend/src/explore/controlPanels/DeckScreengrid.js index f20c02b..eaffd7c 100644 --- a/superset-frontend/src/explore/controlPanels/DeckScreengrid.js +++ b/superset-frontend/src/explore/controlPanels/DeckScreengrid.js @@ -19,6 +19,17 @@ import { t } from '@superset-ui/translation'; import { nonEmpty } from '../validators'; import timeGrainSqlaAnimationOverrides from './timeGrainSqlaAnimationOverrides'; +import { + filterNulls, + autozoom, + jsColumns, + jsDataMutator, + jsTooltip, + jsOnclickHref, + gridSize, + viewport, + spatial, +} from './Shared_DeckGL'; export default { requiresTime: true, @@ -27,30 +38,30 @@ export default { label: t('Query'), expanded: true, controlSetRows: [ - ['spatial', 'size'], - ['row_limit', 'filter_nulls'], + [spatial, 'size'], + ['row_limit', filterNulls], ['adhoc_filters'], ], }, { label: t('Map'), controlSetRows: [ - ['mapbox_style', 'viewport'], - ['autozoom', null], + ['mapbox_style', viewport], + [autozoom, null], ], }, { label: t('Grid'), expanded: true, - controlSetRows: [['grid_size', 'color_picker']], + controlSetRows: [[gridSize, 'color_picker']], }, { label: t('Advanced'), controlSetRows: [ - ['js_columns'], - ['js_data_mutator'], - ['js_tooltip'], - ['js_onclick_href'], + [jsColumns], + [jsDataMutator], + [jsTooltip], + [jsOnclickHref], ], }, ], diff --git a/superset-frontend/src/explore/controlPanels/Shared_DeckGL.jsx b/superset-frontend/src/explore/controlPanels/Shared_DeckGL.jsx new file mode 100644 index 0000000..61344fe --- /dev/null +++ b/superset-frontend/src/explore/controlPanels/Shared_DeckGL.jsx @@ -0,0 +1,383 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// These are control configurations that are shared ONLY within the DeckGL viz plugin repo. + +import React from 'react'; +import { t } from '@superset-ui/translation'; +import ColumnOption from '../../components/ColumnOption'; +import { D3_FORMAT_OPTIONS, columnChoices, PRIMARY_COLOR } from '../controls'; +import { DEFAULT_VIEWPORT } from '../../explore/components/controls/ViewportControl'; + +import { nonEmpty } from '../validators'; + +const timeColumnOption = { + verbose_name: 'Time', + column_name: '__timestamp', + description: t( + 'A reference to the [Time] configuration, taking granularity into ' + + 'account', + ), +}; + +const groupByControl = { + type: 'SelectControl', + multi: true, + freeForm: true, + label: t('Group by'), + default: [], + includeTime: false, + description: t('One or many controls to group by'), + optionRenderer: c => <ColumnOption column={c} showType />, + valueRenderer: c => <ColumnOption column={c} />, + valueKey: 'column_name', + allowAll: true, + filterOption: (opt, text) => + (opt.column_name && + opt.column_name.toLowerCase().indexOf(text.toLowerCase()) >= 0) || + (opt.verbose_name && + opt.verbose_name.toLowerCase().indexOf(text.toLowerCase()) >= 0), + promptTextCreator: label => label, + mapStateToProps: (state, control) => { + const newState = {}; + if (state.datasource) { + newState.options = state.datasource.columns.filter(c => c.groupby); + if (control && control.includeTime) { + newState.options.push(timeColumnOption); + } + } + return newState; + }, + commaChoosesOption: false, +}; + +const sandboxUrl = + 'https://github.com/apache/incubator-superset/' + + 'blob/master/superset-frontend/src/modules/sandbox.js'; +const jsFunctionInfo = ( + <div> + {t( + 'For more information about objects are in context in the scope of this function, refer to the', + )} + <a href={sandboxUrl}>{t(" source code of Superset's sandboxed parser")}.</a> + . + </div> +); + +function jsFunctionControl( + label, + description, + extraDescr = null, + height = 100, + defaultText = '', +) { + return { + type: 'TextAreaControl', + language: 'javascript', + label, + description, + height, + default: defaultText, + aboveEditorSection: ( + <div> + <p>{description}</p> + <p>{jsFunctionInfo}</p> + {extraDescr} + </div> + ), + mapStateToProps: state => ({ + warning: !state.common.conf.ENABLE_JAVASCRIPT_CONTROLS + ? t( + 'This functionality is disabled in your environment for security reasons.', + ) + : null, + readOnly: !state.common.conf.ENABLE_JAVASCRIPT_CONTROLS, + }), + }; +} + +export const filterNulls = { + name: 'filter_nulls', + config: { + type: 'CheckboxControl', + label: t('Ignore null locations'), + default: true, + description: t('Whether to ignore locations that are null'), + }, +}; + +export const autozoom = { + name: 'autozoom', + config: { + type: 'CheckboxControl', + label: t('Auto Zoom'), + default: true, + renderTrigger: true, + description: t( + 'When checked, the map will zoom to your data after each query', + ), + }, +}; + +export const dimension = { + name: 'dimension', + config: { + ...groupByControl, + label: t('Dimension'), + description: t('Select a dimension'), + multi: false, + default: null, + }, +}; + +export const jsColumns = { + name: 'js_columns', + config: { + ...groupByControl, + label: t('Extra data for JS'), + default: [], + description: t( + 'List of extra columns made available in Javascript functions', + ), + }, +}; + +export const jsDataMutator = { + name: 'js_data_mutator', + config: jsFunctionControl( + t('Javascript data interceptor'), + t( + 'Define a javascript function that receives the data array used in the visualization ' + + 'and is expected to return a modified version of that array. This can be used ' + + 'to alter properties of the data, filter, or enrich the array.', + ), + ), +}; + +export const jsTooltip = { + name: 'js_tooltip', + config: jsFunctionControl( + t('Javascript tooltip generator'), + t( + 'Define a function that receives the input and outputs the content for a tooltip', + ), + ), +}; + +export const jsOnclickHref = { + name: 'js_onclick_href', + config: jsFunctionControl( + t('Javascript onClick href'), + t('Define a function that returns a URL to navigate to when user clicks'), + ), +}; + +export const legendFormat = { + name: 'legend_format', + config: { + label: t('Legend Format'), + description: t('Choose the format for legend values'), + type: 'SelectControl', + clearable: false, + default: D3_FORMAT_OPTIONS[0], + choices: D3_FORMAT_OPTIONS, + renderTrigger: true, + }, +}; + +export const legendPosition = { + name: 'legend_position', + config: { + label: t('Legend Position'), + description: t('Choose the position of the legend'), + type: 'SelectControl', + clearable: false, + default: 'tr', + choices: [ + [null, 'None'], + ['tl', 'Top left'], + ['tr', 'Top right'], + ['bl', 'Bottom left'], + ['br', 'Bottom right'], + ], + renderTrigger: true, + }, +}; + +export const lineColumn = { + name: 'line_column', + config: { + type: 'SelectControl', + label: t('Lines column'), + default: null, + description: t('The database columns that contains lines information'), + mapStateToProps: state => ({ + choices: columnChoices(state.datasource), + }), + validators: [nonEmpty], + }, +}; + +export const fillColorPicker = { + name: 'fill_color_picker', + config: { + label: t('Fill Color'), + description: t( + ' Set the opacity to 0 if you do not want to override the color specified in the GeoJSON', + ), + type: 'ColorPickerControl', + default: PRIMARY_COLOR, + renderTrigger: true, + }, +}; + +export const strokeColorPicker = { + name: 'stroke_color_picker', + config: { + label: t('Stroke Color'), + description: t( + ' Set the opacity to 0 if you do not want to override the color specified in the GeoJSON', + ), + type: 'ColorPickerControl', + default: PRIMARY_COLOR, + renderTrigger: true, + }, +}; + +export const filled = { + name: 'filled', + config: { + type: 'CheckboxControl', + label: t('Filled'), + renderTrigger: true, + description: t('Whether to fill the objects'), + default: true, + }, +}; + +export const stroked = { + name: 'stroked', + config: { + type: 'CheckboxControl', + label: t('Stroked'), + renderTrigger: true, + description: t('Whether to display the stroke'), + default: false, + }, +}; + +export const extruded = { + name: 'extruded', + config: { + type: 'CheckboxControl', + label: t('Extruded'), + renderTrigger: true, + default: true, + description: 'Whether to make the grid 3D', + }, +}; + +export const gridSize = { + name: 'grid_size', + config: { + type: 'TextControl', + label: t('Grid Size'), + renderTrigger: true, + default: 20, + isInt: true, + description: t('Defines the grid size in pixels'), + }, +}; + +export const viewport = { + name: 'viewport', + config: { + type: 'ViewportControl', + label: t('Viewport'), + renderTrigger: false, + description: t('Parameters related to the view and perspective on the map'), + // default is whole world mostly centered + default: DEFAULT_VIEWPORT, + // Viewport changes shouldn't prompt user to re-run query + dontRefreshOnChange: true, + }, +}; + +export const spatial = { + name: 'spatial', + config: { + type: 'SpatialControl', + label: t('Longitude & Latitude'), + validators: [nonEmpty], + description: t('Point to your spatial columns'), + mapStateToProps: state => ({ + choices: columnChoices(state.datasource), + }), + }, +}; + +export const pointRadiusFixed = { + name: 'point_radius_fixed', + config: { + type: 'FixedOrMetricControl', + label: t('Point Size'), + default: { type: 'fix', value: 1000 }, + description: t('Fixed point radius'), + mapStateToProps: state => ({ + datasource: state.datasource, + }), + }, +}; + +export const multiplier = { + name: 'multiplier', + config: { + type: 'TextControl', + label: t('Multiplier'), + isFloat: true, + renderTrigger: true, + default: 1, + description: t('Factor to multiply the metric by'), + }, +}; + +export const lineType = { + name: 'line_type', + config: { + type: 'SelectControl', + label: t('Lines encoding'), + clearable: false, + default: 'json', + description: t('The encoding format of the lines'), + choices: [ + ['polyline', 'Polyline'], + ['json', 'JSON'], + ['geohash', 'geohash (square)'], + ], + }, +}; + +export const reverseLongLat = { + name: 'reverse_long_lat', + config: { + type: 'CheckboxControl', + label: t('Reverse Lat & Long'), + default: false, + }, +}; diff --git a/superset-frontend/src/explore/controls.jsx b/superset-frontend/src/explore/controls.jsx index c4e8ea5..c640438 100644 --- a/superset-frontend/src/explore/controls.jsx +++ b/superset-frontend/src/explore/controls.jsx @@ -70,16 +70,15 @@ import { } from '../modules/utils'; import * as v from './validators'; import ColumnOption from '../components/ColumnOption'; -import { DEFAULT_VIEWPORT } from '../explore/components/controls/ViewportControl'; import { TIME_FILTER_LABELS } from './constants'; const categoricalSchemeRegistry = getCategoricalSchemeRegistry(); const sequentialSchemeRegistry = getSequentialSchemeRegistry(); -const PRIMARY_COLOR = { r: 0, g: 122, b: 135, a: 1 }; +export const PRIMARY_COLOR = { r: 0, g: 122, b: 135, a: 1 }; // input choices & options -const D3_FORMAT_OPTIONS = [ +export const D3_FORMAT_OPTIONS = [ ['SMART_NUMBER', 'Adaptative formating'], ['.1s', '.1s (12345.432 => 10k)'], ['.3s', '.3s (12345.432 => 12.3k)'], @@ -177,19 +176,6 @@ const metric = { default: props => mainMetric(props.savedMetrics), }; -const sandboxUrl = - 'https://github.com/apache/incubator-superset/' + - 'blob/master/superset-frontend/src/modules/sandbox.js'; -const jsFunctionInfo = ( - <div> - {t( - 'For more information about objects are in context in the scope of this function, refer to the', - )} - <a href={sandboxUrl}>{t(" source code of Superset's sandboxed parser")}.</a> - . - </div> -); - export function columnChoices(datasource) { if (datasource && datasource.columns) { return datasource.columns @@ -201,38 +187,6 @@ export function columnChoices(datasource) { return []; } -function jsFunctionControl( - label, - description, - extraDescr = null, - height = 100, - defaultText = '', -) { - return { - type: 'TextAreaControl', - language: 'javascript', - label, - description, - height, - default: defaultText, - aboveEditorSection: ( - <div> - <p>{description}</p> - <p>{jsFunctionInfo}</p> - {extraDescr} - </div> - ), - mapStateToProps: state => ({ - warning: !state.common.conf.ENABLE_JAVASCRIPT_CONTROLS - ? t( - 'This functionality is disabled in your environment for security reasons.', - ) - : null, - readOnly: !state.common.conf.ENABLE_JAVASCRIPT_CONTROLS, - }), - }; -} - export const controls = { metrics, @@ -277,60 +231,6 @@ export const controls = { renderTrigger: true, }, - target_color_picker: { - label: t('Target Color'), - description: t('Color of the target location'), - type: 'ColorPickerControl', - default: PRIMARY_COLOR, - renderTrigger: true, - }, - - legend_position: { - label: t('Legend Position'), - description: t('Choose the position of the legend'), - type: 'SelectControl', - clearable: false, - default: 'tr', - choices: [ - [null, 'None'], - ['tl', 'Top left'], - ['tr', 'Top right'], - ['bl', 'Bottom left'], - ['br', 'Bottom right'], - ], - renderTrigger: true, - }, - - legend_format: { - label: t('Legend Format'), - description: t('Choose the format for legend values'), - type: 'SelectControl', - clearable: false, - default: D3_FORMAT_OPTIONS[0], - choices: D3_FORMAT_OPTIONS, - renderTrigger: true, - }, - - fill_color_picker: { - label: t('Fill Color'), - description: t( - ' Set the opacity to 0 if you do not want to override the color specified in the GeoJSON', - ), - type: 'ColorPickerControl', - default: PRIMARY_COLOR, - renderTrigger: true, - }, - - stroke_color_picker: { - label: t('Stroke Color'), - description: t( - ' Set the opacity to 0 if you do not want to override the color specified in the GeoJSON', - ), - type: 'ColorPickerControl', - default: PRIMARY_COLOR, - renderTrigger: true, - }, - metric_2: { ...metric, label: t('Right Axis Metric'), @@ -367,16 +267,6 @@ export const controls = { ), }, - autozoom: { - type: 'CheckboxControl', - label: t('Auto Zoom'), - default: true, - renderTrigger: true, - description: t( - 'When checked, the map will zoom to your data after each query', - ), - }, - bar_stacked: { type: 'CheckboxControl', label: t('Stacked Bars'), @@ -505,13 +395,6 @@ export const controls = { }, groupby: groupByControl, - dimension: { - ...groupByControl, - label: t('Dimension'), - description: t('Select a dimension'), - multi: false, - default: null, - }, columns: { ...groupByControl, @@ -536,36 +419,6 @@ export const controls = { freeForm: true, }, - spatial: { - type: 'SpatialControl', - label: t('Longitude & Latitude'), - validators: [v.nonEmpty], - description: t('Point to your spatial columns'), - mapStateToProps: state => ({ - choices: columnChoices(state.datasource), - }), - }, - - start_spatial: { - type: 'SpatialControl', - label: t('Start Longitude & Latitude'), - validators: [v.nonEmpty], - description: t('Point to your spatial columns'), - mapStateToProps: state => ({ - choices: columnChoices(state.datasource), - }), - }, - - end_spatial: { - type: 'SpatialControl', - label: t('End Longitude & Latitude'), - validators: [v.nonEmpty], - description: t('Point to your spatial columns'), - mapStateToProps: state => ({ - choices: columnChoices(state.datasource), - }), - }, - longitude: { type: 'SelectControl', label: t('Longitude'), @@ -588,13 +441,6 @@ export const controls = { }), }, - filter_nulls: { - type: 'CheckboxControl', - label: t('Ignore null locations'), - default: true, - description: t('Whether to ignore locations that are null'), - }, - polygon: { type: 'SelectControl', label: t('Polygon Column'), @@ -607,16 +453,6 @@ export const controls = { }), }, - stroke_width: { - type: 'SelectControl', - freeForm: true, - label: t('Stroke Width'), - validators: [v.integer], - default: null, - renderTrigger: true, - choices: formatSelectOptions([1, 2, 3, 4, 5]), - }, - all_columns_x: { type: 'SelectControl', label: 'X', @@ -890,15 +726,6 @@ export const controls = { ), }, - multiplier: { - type: 'TextControl', - label: t('Multiplier'), - isFloat: true, - renderTrigger: true, - default: 1, - description: t('Factor to multiply the metric by'), - }, - rolling_periods: { type: 'TextControl', label: t('Periods'), @@ -909,15 +736,6 @@ export const controls = { ), }, - 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'), @@ -1111,14 +929,6 @@ export const controls = { 'users to hit an [Apply] button', }, - extruded: { - type: 'CheckboxControl', - label: t('Extruded'), - renderTrigger: true, - default: true, - description: 'Whether to make the grid 3D', - }, - show_brush: { type: 'SelectControl', label: t('Show Range Filter'), @@ -1310,16 +1120,6 @@ export const controls = { description: t('Base layer map style'), }, - point_radius_fixed: { - type: 'FixedOrMetricControl', - label: t('Point Size'), - default: { type: 'fix', value: 1000 }, - description: t('Fixed point radius'), - mapStateToProps: state => ({ - datasource: state.datasource, - }), - }, - global_opacity: { type: 'TextControl', label: t('Opacity'), @@ -1330,17 +1130,6 @@ export const controls = { ), }, - viewport: { - type: 'ViewportControl', - label: t('Viewport'), - renderTrigger: false, - description: t('Parameters related to the view and perspective on the map'), - // default is whole world mostly centered - default: DEFAULT_VIEWPORT, - // Viewport changes shouldn't prompt user to re-run query - dontRefreshOnChange: true, - }, - viewport_zoom: { type: 'TextControl', label: t('Zoom'), @@ -1440,97 +1229,6 @@ export const controls = { controlName: 'TimeSeriesColumnControl', }, - line_column: { - type: 'SelectControl', - label: t('Lines column'), - default: null, - description: t('The database columns that contains lines information'), - mapStateToProps: state => ({ - choices: columnChoices(state.datasource), - }), - validators: [v.nonEmpty], - }, - line_type: { - type: 'SelectControl', - label: t('Lines encoding'), - clearable: false, - default: 'json', - description: t('The encoding format of the lines'), - choices: [ - ['polyline', 'Polyline'], - ['json', 'JSON'], - ['geohash', 'geohash (square)'], - ], - }, - - line_width: { - type: 'TextControl', - label: t('Line width'), - renderTrigger: true, - isInt: true, - default: 10, - description: t('The width of the lines'), - }, - - reverse_long_lat: { - type: 'CheckboxControl', - label: t('Reverse Lat & Long'), - default: false, - }, - - js_data_mutator: jsFunctionControl( - t('Javascript data interceptor'), - t( - 'Define a javascript function that receives the data array used in the visualization ' + - 'and is expected to return a modified version of that array. This can be used ' + - 'to alter properties of the data, filter, or enrich the array.', - ), - ), - - js_data: jsFunctionControl( - t('Javascript data mutator'), - t( - 'Define a function that receives intercepts the data objects and can mutate it', - ), - ), - - js_tooltip: jsFunctionControl( - t('Javascript tooltip generator'), - t( - 'Define a function that receives the input and outputs the content for a tooltip', - ), - ), - - js_onclick_href: jsFunctionControl( - t('Javascript onClick href'), - t('Define a function that returns a URL to navigate to when user clicks'), - ), - - js_columns: { - ...groupByControl, - label: t('Extra data for JS'), - default: [], - description: t( - 'List of extra columns made available in Javascript functions', - ), - }, - - stroked: { - type: 'CheckboxControl', - label: t('Stroked'), - renderTrigger: true, - description: t('Whether to display the stroke'), - default: false, - }, - - filled: { - type: 'CheckboxControl', - label: t('Filled'), - renderTrigger: true, - description: t('Whether to fill the objects'), - default: true, - }, - filter_configs: { type: 'CollectionControl', label: 'Filters',