diff --git a/superset/assets/javascripts/explore/stores/visTypes.js b/superset/assets/javascripts/explore/stores/visTypes.js index 4b0120d3bd9c8..f935a5b6c6a3f 100644 --- a/superset/assets/javascripts/explore/stores/visTypes.js +++ b/superset/assets/javascripts/explore/stores/visTypes.js @@ -373,6 +373,15 @@ export const visTypes = { ['grid_size', 'extruded'], ], }, + { + label: t('Advanced'), + controlSetRows: [ + ['js_columns'], + ['js_data_mutator'], + ['js_tooltip'], + ['js_onclick_href'], + ], + }, ], controlOverrides: { size: { @@ -402,6 +411,15 @@ export const visTypes = { ['grid_size', 'extruded'], ], }, + { + label: t('Advanced'), + controlSetRows: [ + ['js_columns'], + ['js_data_mutator'], + ['js_tooltip'], + ['js_onclick_href'], + ], + }, ], controlOverrides: { size: { @@ -469,6 +487,15 @@ export const visTypes = { ['grid_size', 'color_picker'], ], }, + { + label: t('Advanced'), + controlSetRows: [ + ['js_columns'], + ['js_data_mutator'], + ['js_tooltip'], + ['js_onclick_href'], + ], + }, ], controlOverrides: { size: { @@ -582,6 +609,15 @@ export const visTypes = { ['stroke_width', null], ], }, + { + label: t('Advanced'), + controlSetRows: [ + ['js_columns'], + ['js_data_mutator'], + ['js_tooltip'], + ['js_onclick_href'], + ], + }, ], }, diff --git a/superset/assets/visualizations/deckgl/layers/arc.jsx b/superset/assets/visualizations/deckgl/layers/arc.jsx index 38bd1e826f37d..8e04e9af52a37 100644 --- a/superset/assets/visualizations/deckgl/layers/arc.jsx +++ b/superset/assets/visualizations/deckgl/layers/arc.jsx @@ -1,16 +1,26 @@ import { ArcLayer } from 'deck.gl'; -export default function arcLayer(formData, payload) { +import * as common from './common'; +import sandboxedEval from '../../../javascripts/modules/sandbox'; + +export default function arcLayer(formData, payload, slice) { const fd = formData; const fc = fd.color_picker; - const data = payload.data.arcs.map(d => ({ + let data = payload.data.arcs.map(d => ({ ...d, color: [fc.r, fc.g, fc.b, 255 * fc.a], })); + if (fd.js_data_mutator) { + // Applying user defined data mutator if defined + const jsFnMutator = sandboxedEval(fd.js_data_mutator); + data = jsFnMutator(data); + } + return new ArcLayer({ id: `path-layer-${fd.slice_id}`, data, strokeWidth: (fd.stroke_width) ? fd.stroke_width : 3, + ...common.commonLayerProps(fd, slice), }); } diff --git a/superset/assets/visualizations/deckgl/layers/grid.jsx b/superset/assets/visualizations/deckgl/layers/grid.jsx index a461eb98e53a1..ed970d297650f 100644 --- a/superset/assets/visualizations/deckgl/layers/grid.jsx +++ b/superset/assets/visualizations/deckgl/layers/grid.jsx @@ -1,12 +1,22 @@ import { GridLayer } from 'deck.gl'; -export default function getLayer(formData, payload) { +import * as common from './common'; +import sandboxedEval from '../../../javascripts/modules/sandbox'; + +export default function getLayer(formData, payload, slice) { const fd = formData; const c = fd.color_picker; - const data = payload.data.features.map(d => ({ + let data = payload.data.features.map(d => ({ ...d, color: [c.r, c.g, c.b, 255 * c.a], })); + + if (fd.js_data_mutator) { + // Applying user defined data mutator if defined + const jsFnMutator = sandboxedEval(fd.js_data_mutator); + data = jsFnMutator(data); + } + return new GridLayer({ id: `grid-layer-${fd.slice_id}`, data, @@ -18,5 +28,6 @@ export default function getLayer(formData, payload) { outline: false, getElevationValue: points => points.reduce((sum, point) => sum + point.weight, 0), getColorValue: points => points.reduce((sum, point) => sum + point.weight, 0), + ...common.commonLayerProps(fd, slice), }); } diff --git a/superset/assets/visualizations/deckgl/layers/hex.jsx b/superset/assets/visualizations/deckgl/layers/hex.jsx index 0e33e9495305a..86fb5349d5053 100644 --- a/superset/assets/visualizations/deckgl/layers/hex.jsx +++ b/superset/assets/visualizations/deckgl/layers/hex.jsx @@ -1,13 +1,22 @@ import { HexagonLayer } from 'deck.gl'; -export default function getLayer(formData, payload) { +import * as common from './common'; +import sandboxedEval from '../../../javascripts/modules/sandbox'; + +export default function getLayer(formData, payload, slice) { const fd = formData; const c = fd.color_picker; - const data = payload.data.features.map(d => ({ + let data = payload.data.features.map(d => ({ ...d, color: [c.r, c.g, c.b, 255 * c.a], })); + if (fd.js_data_mutator) { + // Applying user defined data mutator if defined + const jsFnMutator = sandboxedEval(fd.js_data_mutator); + data = jsFnMutator(data); + } + return new HexagonLayer({ id: `hex-layer-${fd.slice_id}`, data, @@ -19,5 +28,6 @@ export default function getLayer(formData, payload) { outline: false, getElevationValue: points => points.reduce((sum, point) => sum + point.weight, 0), getColorValue: points => points.reduce((sum, point) => sum + point.weight, 0), + ...common.commonLayerProps(fd, slice), }); } diff --git a/superset/assets/visualizations/deckgl/layers/screengrid.jsx b/superset/assets/visualizations/deckgl/layers/screengrid.jsx index 54edd9eaba0f1..ca589cd8d568f 100644 --- a/superset/assets/visualizations/deckgl/layers/screengrid.jsx +++ b/superset/assets/visualizations/deckgl/layers/screengrid.jsx @@ -1,13 +1,22 @@ import { ScreenGridLayer } from 'deck.gl'; -export default function getLayer(formData, payload) { +import * as common from './common'; +import sandboxedEval from '../../../javascripts/modules/sandbox'; + +export default function getLayer(formData, payload, slice) { const fd = formData; const c = fd.color_picker; - const data = payload.data.features.map(d => ({ + let data = payload.data.features.map(d => ({ ...d, color: [c.r, c.g, c.b, 255 * c.a], })); + if (fd.js_data_mutator) { + // Applying user defined data mutator if defined + const jsFnMutator = sandboxedEval(fd.js_data_mutator); + data = jsFnMutator(data); + } + // Passing a layer creator function instead of a layer since the // layer needs to be regenerated at each render return new ScreenGridLayer({ @@ -19,5 +28,6 @@ export default function getLayer(formData, payload) { maxColor: [c.r, c.g, c.b, 255 * c.a], outline: false, getWeight: d => d.weight || 0, + ...common.commonLayerProps(fd, slice), }); } diff --git a/superset/viz.py b/superset/viz.py index 27eac63dd4155..6fa7d98715406 100644 --- a/superset/viz.py +++ b/superset/viz.py @@ -2077,7 +2077,7 @@ def get_data(self, df): arcs = d['features'] return { - 'arcs': [arc['position'] for arc in arcs], + 'arcs': arcs, 'mapboxApiKey': config.get('MAPBOX_API_KEY'), }