diff --git a/superset/assets/src/explore/controlPanels/DeckArc.js b/superset/assets/src/explore/controlPanels/DeckArc.js index e0bee756fa..6341673db1 100644 --- a/superset/assets/src/explore/controlPanels/DeckArc.js +++ b/superset/assets/src/explore/controlPanels/DeckArc.js @@ -44,6 +44,7 @@ export default { ['color_picker', 'target_color_picker'], ['dimension', 'color_scheme', 'label_colors'], ['stroke_width', 'legend_position'], + ['legend_format', null], ], }, { diff --git a/superset/assets/src/explore/controlPanels/DeckPolygon.js b/superset/assets/src/explore/controlPanels/DeckPolygon.js index 25790216fb..cc29b84c5c 100644 --- a/superset/assets/src/explore/controlPanels/DeckPolygon.js +++ b/superset/assets/src/explore/controlPanels/DeckPolygon.js @@ -52,7 +52,7 @@ export default { ['linear_color_scheme', 'opacity'], ['num_buckets', 'break_points'], ['table_filter', 'toggle_polygons'], - ['legend_position', null], + ['legend_position', 'legend_format'], ], }, { diff --git a/superset/assets/src/explore/controlPanels/DeckScatter.js b/superset/assets/src/explore/controlPanels/DeckScatter.js index 8e60029fe2..e2c6308417 100644 --- a/superset/assets/src/explore/controlPanels/DeckScatter.js +++ b/superset/assets/src/explore/controlPanels/DeckScatter.js @@ -62,6 +62,7 @@ export default { label: t('Point Color'), controlSetRows: [ ['color_picker', 'legend_position'], + [null, 'legend_format'], ['dimension', 'color_scheme', 'label_colors'], ], }, diff --git a/superset/assets/src/explore/controls.jsx b/superset/assets/src/explore/controls.jsx index 3ddabd21ae..ae673de545 100644 --- a/superset/assets/src/explore/controls.jsx +++ b/superset/assets/src/explore/controls.jsx @@ -305,6 +305,16 @@ export const controls = { 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'), diff --git a/superset/assets/src/visualizations/Legend.jsx b/superset/assets/src/visualizations/Legend.jsx index fcaef02c84..355f632d34 100644 --- a/superset/assets/src/visualizations/Legend.jsx +++ b/superset/assets/src/visualizations/Legend.jsx @@ -18,13 +18,17 @@ */ import React from 'react'; import PropTypes from 'prop-types'; +import { formatNumber } from '@superset-ui/number-format'; import './Legend.css'; +const categoryDelimiter = ' - '; + const propTypes = { categories: PropTypes.object, toggleCategory: PropTypes.func, showSingleCategory: PropTypes.func, + format: PropTypes.string, position: PropTypes.oneOf([null, 'tl', 'tr', 'bl', 'br']), }; @@ -32,10 +36,34 @@ const defaultProps = { categories: {}, toggleCategory: () => {}, showSingleCategory: () => {}, + format: null, position: 'tr', }; export default class Legend extends React.PureComponent { + format(value) { + if (!this.props.format) { + return value; + } + + const numValue = parseFloat(value); + return formatNumber(this.props.format, numValue); + + } + + formatCategoryLabel(k) { + if (!this.props.format) { + return k; + } + + if (k.includes(categoryDelimiter)) { + const values = k.split(categoryDelimiter); + return this.format(values[0]) + categoryDelimiter + this.format(values[1]); + } + + return this.format(k); + } + render() { if (Object.keys(this.props.categories).length === 0 || this.props.position === null) { return null; @@ -51,7 +79,7 @@ export default class Legend extends React.PureComponent { onClick={() => this.props.toggleCategory(k)} onDoubleClick={() => this.props.showSingleCategory(k)} > - {icon} {k} + {icon} {this.formatCategoryLabel(k)} ); diff --git a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx index e1933a4b1b..7352b3d495 100644 --- a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx +++ b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx @@ -237,6 +237,7 @@ export default class CategoricalDeckGLContainer extends React.PureComponent { toggleCategory={this.toggleCategory} showSingleCategory={this.showSingleCategory} position={this.props.formData.legend_position} + format={this.props.formData.legend_format} /> diff --git a/superset/assets/src/visualizations/deckgl/layers/Polygon/Polygon.jsx b/superset/assets/src/visualizations/deckgl/layers/Polygon/Polygon.jsx index 3797d7e7eb..891856d043 100644 --- a/superset/assets/src/visualizations/deckgl/layers/Polygon/Polygon.jsx +++ b/superset/assets/src/visualizations/deckgl/layers/Polygon/Polygon.jsx @@ -274,6 +274,7 @@ class DeckGLPolygon extends React.Component { }