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/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 61d8a0bd12 feat: conditional coloring for big number chart (#23064)
61d8a0bd12 is described below

commit 61d8a0bd1206ffc96ea2f9284e4c238241fcca79
Author: Gerold Busch <[email protected]>
AuthorDate: Mon May 1 17:44:46 2023 +0200

    feat: conditional coloring for big number chart (#23064)
    
    Co-authored-by: Gerold Busch <[email protected]>
---
 .../src/utils/getColorFormatters.ts                | 14 +++++---
 .../test/utils/getColorFormatters.test.ts          | 19 ++++++++++
 .../src/BigNumber/BigNumberTotal/controlPanel.ts   | 42 +++++++++++++++++++++-
 .../src/BigNumber/BigNumberTotal/transformProps.ts | 12 +++++++
 .../src/BigNumber/BigNumberViz.tsx                 | 22 +++++++++++-
 .../plugin-chart-echarts/src/BigNumber/types.ts    |  2 ++
 .../FormattingPopoverContent.tsx                   |  9 +++--
 7 files changed, 111 insertions(+), 9 deletions(-)

diff --git 
a/superset-frontend/packages/superset-ui-chart-controls/src/utils/getColorFormatters.ts
 
b/superset-frontend/packages/superset-ui-chart-controls/src/utils/getColorFormatters.ts
index f613beb074..1a6aa140a6 100644
--- 
a/superset-frontend/packages/superset-ui-chart-controls/src/utils/getColorFormatters.ts
+++ 
b/superset-frontend/packages/superset-ui-chart-controls/src/utils/getColorFormatters.ts
@@ -62,6 +62,7 @@ export const getColorFunction = (
     colorScheme,
   }: ConditionalFormattingConfig,
   columnValues: number[],
+  alpha?: boolean,
 ) => {
   let minOpacity = MIN_OPACITY_BOUNDED;
   const maxOpacity = MAX_OPACITY;
@@ -176,10 +177,13 @@ export const getColorFunction = (
     const compareResult = comparatorFunction(value, columnValues);
     if (compareResult === false) return undefined;
     const { cutoffValue, extremeValue } = compareResult;
-    return addAlpha(
-      colorScheme,
-      getOpacity(value, cutoffValue, extremeValue, minOpacity, maxOpacity),
-    );
+    if (alpha === undefined || alpha) {
+      return addAlpha(
+        colorScheme,
+        getOpacity(value, cutoffValue, extremeValue, minOpacity, maxOpacity),
+      );
+    }
+    return colorScheme;
   };
 };
 
@@ -187,6 +191,7 @@ export const getColorFormatters = memoizeOne(
   (
     columnConfig: ConditionalFormattingConfig[] | undefined,
     data: DataRecord[],
+    alpha?: boolean,
   ) =>
     columnConfig?.reduce(
       (acc: ColorFormatters, config: ConditionalFormattingConfig) => {
@@ -204,6 +209,7 @@ export const getColorFormatters = memoizeOne(
             getColorFromValue: getColorFunction(
               config,
               data.map(row => row[config.column!] as number),
+              alpha,
             ),
           });
         }
diff --git 
a/superset-frontend/packages/superset-ui-chart-controls/test/utils/getColorFormatters.test.ts
 
b/superset-frontend/packages/superset-ui-chart-controls/test/utils/getColorFormatters.test.ts
index 4b957f628c..7daa3f968d 100644
--- 
a/superset-frontend/packages/superset-ui-chart-controls/test/utils/getColorFormatters.test.ts
+++ 
b/superset-frontend/packages/superset-ui-chart-controls/test/utils/getColorFormatters.test.ts
@@ -188,6 +188,25 @@ describe('getColorFunction()', () => {
     expect(colorFunction(150)).toBeUndefined();
   });
 
+  it('getColorFunction BETWEEN_OR_EQUAL without opacity', () => {
+    const colorFunction = getColorFunction(
+      {
+        operator: COMPARATOR.BETWEEN_OR_EQUAL,
+        targetValueLeft: 50,
+        targetValueRight: 100,
+        colorScheme: '#FF0000',
+        column: 'count',
+      },
+      countValues,
+      false,
+    );
+    expect(colorFunction(25)).toBeUndefined();
+    expect(colorFunction(50)).toEqual('#FF0000');
+    expect(colorFunction(75)).toEqual('#FF0000');
+    expect(colorFunction(100)).toEqual('#FF0000');
+    expect(colorFunction(125)).toBeUndefined();
+  });
+
   it('getColorFunction BETWEEN_OR_LEFT_EQUAL', () => {
     const colorFunction = getColorFunction(
       {
diff --git 
a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts
 
b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts
index daacaa283a..abe4ce215f 100644
--- 
a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts
+++ 
b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts
@@ -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,
+                };
+              },
+            },
+          },
+        ],
       ],
     },
   ],
diff --git 
a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts
 
b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts
index e690b1ef52..8624e5bc54 100644
--- 
a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts
+++ 
b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts
@@ -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,
   };
 }
diff --git 
a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx 
b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx
index 4762a789d0..112e21657f 100644
--- 
a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx
+++ 
b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx
@@ -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}
       >
diff --git 
a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/types.ts 
b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/types.ts
index f0a17e708b..c517fcc0b9 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/types.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/types.ts
@@ -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;
 };
diff --git 
a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
 
b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
index d50e71608b..154255eee7 100644
--- 
a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
+++ 
b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
@@ -39,9 +39,12 @@ const JustifyEnd = styled.div`
 `;
 
 const colorSchemeOptions = (theme: SupersetTheme) => [
-  { value: theme.colors.success.light1, label: t('green') },
-  { value: theme.colors.alert.light1, label: t('yellow') },
-  { value: theme.colors.error.light1, label: t('red') },
+  { value: theme.colors.success.light1, label: t('success') },
+  { value: theme.colors.alert.light1, label: t('alert') },
+  { value: theme.colors.error.light1, label: t('error') },
+  { value: theme.colors.success.dark1, label: t('success dark') },
+  { value: theme.colors.alert.dark1, label: t('alert dark') },
+  { value: theme.colors.error.dark1, label: t('error dark') },
 ];
 
 const operatorOptions = [

Reply via email to