feat: conditional coloring for big number chart (#23064)

Co-authored-by: Gerold Busch <gerold.busch@valtech.com>
This commit is contained in:
Gerold Busch
2023-05-01 17:44:46 +02:00
committed by GitHub
parent fd3030fc14
commit 61d8a0bd12
7 changed files with 111 additions and 9 deletions

View File

@@ -16,11 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
import { smartDateFormatter, t } from '@superset-ui/core';
import { GenericDataType, smartDateFormatter, t } from '@superset-ui/core';
import {
ControlPanelConfig,
D3_FORMAT_DOCS,
D3_TIME_FORMAT_OPTIONS,
Dataset,
getStandardizedControls,
sections,
} from '@superset-ui/chart-controls';
@@ -89,6 +90,45 @@ export default {
},
},
],
[
{
name: 'conditional_formatting',
config: {
type: 'ConditionalFormattingControl',
renderTrigger: true,
label: t('Conditional Formatting'),
description: t('Apply conditional color formatting to metric'),
shouldMapStateToProps() {
return true;
},
mapStateToProps(explore, _, chart) {
const verboseMap = explore?.datasource?.hasOwnProperty(
'verbose_map',
)
? (explore?.datasource as Dataset)?.verbose_map
: explore?.datasource?.columns ?? {};
const { colnames, coltypes } =
chart?.queriesResponse?.[0] ?? {};
const numericColumns =
Array.isArray(colnames) && Array.isArray(coltypes)
? colnames
.filter(
(colname: string, index: number) =>
coltypes[index] === GenericDataType.NUMERIC,
)
.map(colname => ({
value: colname,
label: verboseMap[colname] ?? colname,
}))
: [];
return {
columnOptions: numericColumns,
verboseMap,
};
},
},
},
],
],
},
],

View File

@@ -16,6 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
import {
ColorFormatters,
getColorFormatters,
} from '@superset-ui/chart-controls';
import {
getNumberFormatter,
GenericDataType,
@@ -40,6 +44,7 @@ export default function transformProps(
forceTimestampFormatting,
timeFormat,
yAxisFormat,
conditionalFormatting,
} = formData;
const refs: Refs = {};
const { data = [], coltypes = [] } = queriesData[0];
@@ -71,6 +76,12 @@ export default function transformProps(
const { onContextMenu } = hooks;
const defaultColorFormatters = [] as ColorFormatters;
const colorThresholdFormatters =
getColorFormatters(conditionalFormatting, data, false) ??
defaultColorFormatters;
return {
width,
height,
@@ -81,5 +92,6 @@ export default function transformProps(
subheader: formattedSubheader,
onContextMenu,
refs,
colorThresholdFormatters,
};
}

View File

@@ -128,10 +128,29 @@ class BigNumberVis extends React.PureComponent<BigNumberVizProps> {
}
renderHeader(maxHeight: number) {
const { bigNumber, headerFormatter, width } = this.props;
const { bigNumber, headerFormatter, width, colorThresholdFormatters } =
this.props;
// @ts-ignore
const text = bigNumber === null ? t('No data') : headerFormatter(bigNumber);
const hasThresholdColorFormatter =
Array.isArray(colorThresholdFormatters) &&
colorThresholdFormatters.length > 0;
let numberColor;
if (hasThresholdColorFormatter) {
colorThresholdFormatters!.forEach(formatter => {
const formatterResult = bigNumber
? formatter.getColorFromValue(bigNumber as number)
: false;
if (formatterResult) {
numberColor = formatterResult;
}
});
} else {
numberColor = 'black';
}
const container = this.createTemporaryContainer();
document.body.append(container);
const fontSize = computeMaxFontSize({
@@ -156,6 +175,7 @@ class BigNumberVis extends React.PureComponent<BigNumberVizProps> {
style={{
fontSize,
height: maxHeight,
color: numberColor,
}}
onContextMenu={onContextMenu}
>

View File

@@ -27,6 +27,7 @@ import {
QueryFormMetric,
TimeFormatter,
} from '@superset-ui/core';
import { ColorFormatters } from '@superset-ui/chart-controls';
import { BaseChartProps, Refs } from '../types';
export interface BigNumberDatum {
@@ -94,4 +95,5 @@ export type BigNumberVizProps = {
xValueFormatter?: TimeFormatter;
formData?: BigNumberWithTrendlineFormData;
refs: Refs;
colorThresholdFormatters?: ColorFormatters;
};