You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by li...@apache.org on 2024/03/27 16:28:01 UTC

(superset) branch table-time-comparison-color created (now f92eff21c0)

This is an automated email from the ASF dual-hosted git repository.

lilykuang pushed a change to branch table-time-comparison-color
in repository https://gitbox.apache.org/repos/asf/superset.git


      at f92eff21c0 multi select for conditional color formatter

This branch includes the following new commits:

     new 6e69fa8ff8 added visual formatting section
     new c71c472b97 implement basic color formatter
     new e352871a99 update type
     new f92eff21c0 multi select for conditional color formatter

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(superset) 01/04: added visual formatting section

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lilykuang pushed a commit to branch table-time-comparison-color
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 6e69fa8ff8cfcdff178dc1d8e7a515d76aa2b1ca
Author: lilykuang <ji...@gmail.com>
AuthorDate: Mon Mar 18 14:54:48 2024 -0700

    added visual formatting section
---
 .../plugin-chart-table/src/controlPanel.tsx        | 82 ++++++++++++----------
 1 file changed, 46 insertions(+), 36 deletions(-)

diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
index cf0ad3d952..93402978b7 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
@@ -479,82 +479,92 @@ const config: ControlPanelConfig = {
               description: t('Whether to include a client-side search box'),
             },
           },
+        ],
+        [
           {
-            name: 'show_cell_bars',
+            name: 'allow_rearrange_columns',
             config: {
               type: 'CheckboxControl',
-              label: t('Cell bars'),
+              label: t('Allow columns to be rearranged'),
               renderTrigger: true,
-              default: true,
+              default: false,
               description: t(
-                'Whether to display a bar chart background in table columns',
+                "Allow end user to drag-and-drop column headers to rearrange them. Note their changes won't persist for the next time they open the chart.",
               ),
+              visibility: ({ controls }) =>
+                !controls?.enable_time_comparison?.value ||
+                !isFeatureEnabled(FeatureFlag.ChartPluginsExperimental),
             },
           },
         ],
         [
           {
-            name: 'align_pn',
+            name: 'column_config',
             config: {
-              type: 'CheckboxControl',
-              label: t('Align +/-'),
+              type: 'ColumnConfigControl',
+              label: t('Customize columns'),
+              description: t('Further customize how to display each column'),
+              width: 400,
+              height: 320,
               renderTrigger: true,
-              default: false,
-              description: t(
-                'Whether to align background charts with both positive and negative values at 0',
-              ),
+              shouldMapStateToProps() {
+                return true;
+              },
+              mapStateToProps(explore, _, chart) {
+                return {
+                  queryResponse: chart?.queriesResponse?.[0] as
+                    | ChartDataResponseResult
+                    | undefined,
+                };
+              },
             },
           },
+        ],
+      ],
+    },
+    {
+      label: t('Visual formatting'),
+      expanded: true,
+      controlSetRows: [
+        [
           {
-            name: 'color_pn',
+            name: 'show_cell_bars',
             config: {
               type: 'CheckboxControl',
-              label: t('Color +/-'),
+              label: t('Show Cell bars'),
               renderTrigger: true,
               default: true,
               description: t(
-                'Whether to colorize numeric values by whether they are positive or negative',
+                'Whether to display a bar chart background in table columns',
               ),
             },
           },
         ],
         [
           {
-            name: 'allow_rearrange_columns',
+            name: 'align_pn',
             config: {
               type: 'CheckboxControl',
-              label: t('Allow columns to be rearranged'),
+              label: t('Align +/-'),
               renderTrigger: true,
               default: false,
               description: t(
-                "Allow end user to drag-and-drop column headers to rearrange them. Note their changes won't persist for the next time they open the chart.",
+                'Whether to align background charts with both positive and negative values at 0',
               ),
-              visibility: ({ controls }) =>
-                !controls?.enable_time_comparison?.value ||
-                !isFeatureEnabled(FeatureFlag.ChartPluginsExperimental),
             },
           },
         ],
         [
           {
-            name: 'column_config',
+            name: 'color_pn',
             config: {
-              type: 'ColumnConfigControl',
-              label: t('Customize columns'),
-              description: t('Further customize how to display each column'),
-              width: 400,
-              height: 320,
+              type: 'CheckboxControl',
+              label: t('add colors to cell bars for +/-'),
               renderTrigger: true,
-              shouldMapStateToProps() {
-                return true;
-              },
-              mapStateToProps(explore, _, chart) {
-                return {
-                  queryResponse: chart?.queriesResponse?.[0] as
-                    | ChartDataResponseResult
-                    | undefined,
-                };
-              },
+              default: true,
+              description: t(
+                'Whether to colorize numeric values by whether they are positive or negative',
+              ),
             },
           },
         ],


(superset) 02/04: implement basic color formatter

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lilykuang pushed a commit to branch table-time-comparison-color
in repository https://gitbox.apache.org/repos/asf/superset.git

commit c71c472b976df316cc6a4b901ec2ee9a3a83e454
Author: lilykuang <ji...@gmail.com>
AuthorDate: Mon Mar 25 20:22:14 2024 -0700

    implement basic color formatter
---
 .../plugins/plugin-chart-table/src/TableChart.tsx  | 37 +++++++++-
 .../plugin-chart-table/src/controlPanel.tsx        | 75 ++++++++++++++++++++-
 .../plugin-chart-table/src/transformProps.ts       | 78 +++++++++++++++++++++-
 .../plugins/plugin-chart-table/src/types.ts        |  6 ++
 4 files changed, 188 insertions(+), 8 deletions(-)

diff --git a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
index c274296ccd..ef564fdf27 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
@@ -59,7 +59,11 @@ import {
 } from '@ant-design/icons';
 
 import { isEmpty } from 'lodash';
-import { DataColumnMeta, TableChartTransformedProps } from './types';
+import {
+  ColorSchemeEnum,
+  DataColumnMeta,
+  TableChartTransformedProps,
+} from './types';
 import DataTable, {
   DataTableProps,
   SearchInputProps,
@@ -248,6 +252,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
     onContextMenu,
     emitCrossFilters,
     enableTimeComparison,
+    basicColorFormatter,
   } = props;
   const comparisonColumns = [
     { key: 'all', label: t('Display all') },
@@ -692,7 +697,11 @@ export default function TableChart<D extends DataRecord = DataRecord>(
         Array.isArray(columnColorFormatters) &&
         columnColorFormatters.length > 0;
 
+      const hasBasicColorFormatter =
+        Array.isArray(basicColorFormatter) && basicColorFormatter.length > 0;
+
       const valueRange =
+        !hasBasicColorFormatter &&
         !hasColumnColorFormatters &&
         (config.showCellBars === undefined
           ? showCellBars
@@ -728,6 +737,17 @@ export default function TableChart<D extends DataRecord = DataRecord>(
           const html = isHtml ? { __html: text } : undefined;
 
           let backgroundColor;
+          let arrow = '';
+          const originKey = column.key.substring(column.label.length).trim();
+          if (!hasColumnColorFormatters && hasBasicColorFormatter) {
+            backgroundColor =
+              basicColorFormatter[row.index][originKey]?.backgroundColor;
+            arrow =
+              column.label === comparisonLabels[0]
+                ? basicColorFormatter[row.index][originKey]?.mainArrow
+                : '';
+          }
+
           if (hasColumnColorFormatters) {
             columnColorFormatters!
               .filter(formatter => formatter.column === column.key)
@@ -773,6 +793,15 @@ export default function TableChart<D extends DataRecord = DataRecord>(
               `}
           `;
 
+          const arrowStyles = css`
+            color: ${basicColorFormatter &&
+            basicColorFormatter[row.index][originKey]?.arrowColor ===
+              ColorSchemeEnum.Green
+              ? theme.colors.success.base
+              : theme.colors.error.base};
+            margin-right: ${theme.gridUnit}px;
+          `;
+
           const cellProps = {
             // show raw number in title in case of numeric values
             title: typeof value === 'number' ? String(value) : undefined,
@@ -838,10 +867,14 @@ export default function TableChart<D extends DataRecord = DataRecord>(
                   className="dt-truncate-cell"
                   style={columnWidth ? { width: columnWidth } : undefined}
                 >
+                  {arrow && <span css={arrowStyles}>{arrow}</span>}
                   {text}
                 </div>
               ) : (
-                text
+                <>
+                  {arrow && <span css={arrowStyles}>{arrow}</span>}
+                  {text}
+                </>
               )}
             </StyledCell>
           );
diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
index 93402978b7..6fcdcd825d 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
@@ -50,7 +50,8 @@ import {
   getStandardizedControls,
 } from '@superset-ui/chart-controls';
 
-import { PAGE_SIZE_OPTIONS } from './consts';
+import { COMPARISON_PREFIX, PAGE_SIZE_OPTIONS } from './consts';
+import { ColorSchemeEnum } from './types';
 
 function getQueryMode(controls: ControlStateMapping): QueryMode {
   const mode = controls?.query_mode?.value;
@@ -153,6 +154,33 @@ const percentMetricsControl: typeof sharedControls.metrics = {
   validators: [],
 };
 
+const processComparisonColumns = (columns: any[]) =>
+  columns
+    .map(col => {
+      if (!col.label.includes(COMPARISON_PREFIX)) {
+        return [
+          {
+            label: `${t('Main')} ${col.label}`,
+            value: `${t('Main')} ${col.value}`,
+          },
+          {
+            label: `# ${col.label}`,
+            value: `# ${col.value}`,
+          },
+          {
+            label: `△ ${col.label}`,
+            value: `△ ${col.value}`,
+          },
+          {
+            label: `% ${col.label}`,
+            value: `% ${col.value}`,
+          },
+        ];
+      }
+      return [];
+    })
+    .flat();
+
 const config: ControlPanelConfig = {
   controlPanelSections: [
     {
@@ -568,13 +596,47 @@ const config: ControlPanelConfig = {
             },
           },
         ],
+        [
+          {
+            name: 'comparison_color_enabled',
+            config: {
+              type: 'CheckboxControl',
+              label: t('basic conditional formatting for comparison '),
+              renderTrigger: true,
+              default: false,
+              description: t('Add color for positive/negative change'),
+            },
+          },
+        ],
+        [
+          {
+            name: 'comparison_color_scheme',
+            config: {
+              type: 'SelectControl',
+              label: t('color scheme for comparison'),
+              default: ColorSchemeEnum.Green,
+              renderTrigger: true,
+              choices: [
+                [ColorSchemeEnum.Green, 'Green for increase, red for decrease'],
+                [ColorSchemeEnum.Red, 'Red for increase, green for decrease'],
+              ],
+              visibility: ({ controls }) =>
+                controls?.comparison_color_enabled?.value === true,
+              description: t(
+                'Adds color to the chart symbols based on the positive or ' +
+                  'negative change from the comparison value.',
+              ),
+            },
+          },
+        ],
         [
           {
             name: 'conditional_formatting',
             config: {
               type: 'ConditionalFormattingControl',
               renderTrigger: true,
-              label: t('Conditional formatting'),
+              label: t('Custom Conditional Formatting'),
+              multi: true,
               description: t(
                 'Apply conditional color formatting to numeric columns',
               ),
@@ -602,9 +664,16 @@ const config: ControlPanelConfig = {
                           label: verboseMap[colname] ?? colname,
                         }))
                     : [];
+
+                const columnOptions = Boolean(
+                  explore?.controls?.enable_time_comparison?.value,
+                )
+                  ? processComparisonColumns(numericColumns || [])
+                  : numericColumns;
+
                 return {
                   removeIrrelevantConditions: chartStatus === 'success',
-                  columnOptions: numericColumns,
+                  columnOptions,
                   verboseMap,
                 };
               },
diff --git a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
index 64fb198016..8a39f4b4dd 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
@@ -43,6 +43,7 @@ import {
 import isEqualColumns from './utils/isEqualColumns';
 import DateWithFormatter from './utils/DateWithFormatter';
 import {
+  ColorSchemeEnum,
   DataColumnMeta,
   TableChartProps,
   TableChartTransformedProps,
@@ -374,7 +375,74 @@ const transformProps = (
     conditional_formatting: conditionalFormatting,
     allow_rearrange_columns: allowRearrangeColumns,
     enable_time_comparison: enableTimeComparison = false,
+    comparison_color_enabled: comparisonColorEnabled = false,
+    comparison_color_scheme: comparisonColorScheme = ColorSchemeEnum.Green,
   } = formData;
+
+  const calculateColorAndArrow = (percentDifferenceNum: number) => {
+    if (percentDifferenceNum === 0) {
+      return {
+        arrow: '',
+        arrowColor: '',
+        basicBackgroundColor: 'rgba(255, 191, 161, 0.2)',
+      };
+    }
+    const isPositive = percentDifferenceNum > 0;
+    const arrow = isPositive ? '↑' : '↓';
+    const arrowColor =
+      comparisonColorScheme === ColorSchemeEnum.Green
+        ? isPositive
+          ? ColorSchemeEnum.Green
+          : ColorSchemeEnum.Red
+        : isPositive
+          ? ColorSchemeEnum.Red
+          : ColorSchemeEnum.Green;
+    const basicBackgroundColor =
+      comparisonColorScheme === ColorSchemeEnum.Green
+        ? `rgba(${isPositive ? '0,150,0' : '150,0,0'},0.2)`
+        : `rgba(${isPositive ? '150,0,0' : '0,150,0'},0.2)`;
+
+    return { arrow, arrowColor, basicBackgroundColor };
+  };
+
+  const getBasicColorFormatter = memoizeOne(
+    function processComparisonDataRecords(
+      originalData: DataRecord[] | undefined,
+      originalColumns: DataColumnMeta[],
+    ) {
+      // Transform data
+      return originalData?.map(originalItem => {
+        const item: any = {};
+        originalColumns.forEach(origCol => {
+          if (
+            (origCol.isMetric || origCol.isPercentMetric) &&
+            !origCol.key.includes(COMPARISON_PREFIX) &&
+            origCol.isNumeric
+          ) {
+            const originalValue = originalItem[origCol.key] || 0;
+            const comparisonValue = origCol.isMetric
+              ? originalItem?.[`${COMPARISON_PREFIX}${origCol.key}`] || 0
+              : originalItem[`%${COMPARISON_PREFIX}${origCol.key.slice(1)}`] ||
+                0;
+            const { percentDifferenceNum } = calculateDifferences(
+              originalValue as number,
+              comparisonValue as number,
+            );
+
+            const { arrow, arrowColor, basicBackgroundColor } =
+              calculateColorAndArrow(percentDifferenceNum);
+
+            item[`${origCol.key}`] = {};
+            item[`${origCol.key}`].mainArrow = arrow;
+            item[`${origCol.key}`].arrowColor = arrowColor;
+            item[`${origCol.key}`].backgroundColor = basicBackgroundColor;
+          }
+        });
+        return item;
+      });
+    },
+  );
+
   const canUseTimeComparison =
     enableTimeComparison &&
     isFeatureEnabled(FeatureFlag.ChartPluginsExperimental) &&
@@ -407,15 +475,18 @@ const transformProps = (
     showTotals && queryMode === QueryMode.Aggregate
       ? totalQuery?.data[0]
       : undefined;
-  const columnColorFormatters =
-    getColorFormatters(conditionalFormatting, data) ?? defaultColorFormatters;
 
   const comparisonTotals = processComparisonTotals(totals);
-
   const passedData = canUseTimeComparison ? comparisonData || [] : data;
   const passedTotals = canUseTimeComparison ? comparisonTotals : totals;
   const passedColumns = canUseTimeComparison ? comparisonColumns : columns;
 
+  const basicColorFormatter =
+    comparisonColorEnabled && getBasicColorFormatter(baseQuery?.data, columns);
+  const columnColorFormatters =
+    getColorFormatters(conditionalFormatting, passedData) ??
+    defaultColorFormatters;
+
   return {
     height,
     width,
@@ -447,6 +518,7 @@ const transformProps = (
     allowRearrangeColumns,
     onContextMenu,
     enableTimeComparison: canUseTimeComparison,
+    basicColorFormatter,
   };
 };
 
diff --git a/superset-frontend/plugins/plugin-chart-table/src/types.ts b/superset-frontend/plugins/plugin-chart-table/src/types.ts
index 1806eddb1a..f4ca8473f1 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/types.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/types.ts
@@ -137,6 +137,12 @@ export interface TableChartTransformedProps<D extends DataRecord = DataRecord> {
     filters?: ContextMenuFilters,
   ) => void;
   enableTimeComparison?: boolean;
+  basicColorFormatter?: any;
+}
+
+export enum ColorSchemeEnum {
+  'Green' = 'Green',
+  'Red' = 'Red',
 }
 
 export default {};


(superset) 03/04: update type

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lilykuang pushed a commit to branch table-time-comparison-color
in repository https://gitbox.apache.org/repos/asf/superset.git

commit e352871a996bbb4258914e846eac75daa215f47d
Author: lilykuang <ji...@gmail.com>
AuthorDate: Tue Mar 26 09:38:12 2024 -0700

    update type
---
 .../plugin-chart-table/src/controlPanel.tsx        |  5 +-
 .../plugin-chart-table/src/transformProps.ts       | 74 +++++++++++-----------
 .../plugins/plugin-chart-table/src/types.ts        |  7 ++
 3 files changed, 45 insertions(+), 41 deletions(-)

diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
index 6fcdcd825d..641445913b 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx
@@ -665,9 +665,8 @@ const config: ControlPanelConfig = {
                         }))
                     : [];
 
-                const columnOptions = Boolean(
-                  explore?.controls?.enable_time_comparison?.value,
-                )
+                const columnOptions = explore?.controls?.enable_time_comparison
+                  ?.value
                   ? processComparisonColumns(numericColumns || [])
                   : numericColumns;
 
diff --git a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
index 8a39f4b4dd..924357653f 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
@@ -379,12 +379,12 @@ const transformProps = (
     comparison_color_scheme: comparisonColorScheme = ColorSchemeEnum.Green,
   } = formData;
 
-  const calculateColorAndArrow = (percentDifferenceNum: number) => {
+  const calculateBasicStyle = (percentDifferenceNum: number) => {
     if (percentDifferenceNum === 0) {
       return {
         arrow: '',
         arrowColor: '',
-        basicBackgroundColor: 'rgba(255, 191, 161, 0.2)',
+        backgroundColor: '#FFBFA133',
       };
     }
     const isPositive = percentDifferenceNum > 0;
@@ -397,51 +397,49 @@ const transformProps = (
         : isPositive
           ? ColorSchemeEnum.Red
           : ColorSchemeEnum.Green;
-    const basicBackgroundColor =
+    const backgroundColor =
       comparisonColorScheme === ColorSchemeEnum.Green
         ? `rgba(${isPositive ? '0,150,0' : '150,0,0'},0.2)`
         : `rgba(${isPositive ? '150,0,0' : '0,150,0'},0.2)`;
 
-    return { arrow, arrowColor, basicBackgroundColor };
+    return { arrow, arrowColor, backgroundColor };
   };
 
-  const getBasicColorFormatter = memoizeOne(
-    function processComparisonDataRecords(
-      originalData: DataRecord[] | undefined,
-      originalColumns: DataColumnMeta[],
-    ) {
-      // Transform data
-      return originalData?.map(originalItem => {
-        const item: any = {};
-        originalColumns.forEach(origCol => {
-          if (
-            (origCol.isMetric || origCol.isPercentMetric) &&
-            !origCol.key.includes(COMPARISON_PREFIX) &&
-            origCol.isNumeric
-          ) {
-            const originalValue = originalItem[origCol.key] || 0;
-            const comparisonValue = origCol.isMetric
-              ? originalItem?.[`${COMPARISON_PREFIX}${origCol.key}`] || 0
-              : originalItem[`%${COMPARISON_PREFIX}${origCol.key.slice(1)}`] ||
-                0;
-            const { percentDifferenceNum } = calculateDifferences(
-              originalValue as number,
-              comparisonValue as number,
-            );
+  const getBasicColorFormatter = memoizeOne(function getBasicColorFormatter(
+    originalData: DataRecord[] | undefined,
+    originalColumns: DataColumnMeta[],
+  ) {
+    // Transform data
+    return originalData?.map(originalItem => {
+      const item: any = {};
+      originalColumns.forEach(origCol => {
+        if (
+          (origCol.isMetric || origCol.isPercentMetric) &&
+          !origCol.key.includes(COMPARISON_PREFIX) &&
+          origCol.isNumeric
+        ) {
+          const originalValue = originalItem[origCol.key] || 0;
+          const comparisonValue = origCol.isMetric
+            ? originalItem?.[`${COMPARISON_PREFIX}${origCol.key}`] || 0
+            : originalItem[`%${COMPARISON_PREFIX}${origCol.key.slice(1)}`] || 0;
+          const { percentDifferenceNum } = calculateDifferences(
+            originalValue as number,
+            comparisonValue as number,
+          );
 
-            const { arrow, arrowColor, basicBackgroundColor } =
-              calculateColorAndArrow(percentDifferenceNum);
+          const { arrow, arrowColor, backgroundColor } =
+            calculateBasicStyle(percentDifferenceNum);
 
-            item[`${origCol.key}`] = {};
-            item[`${origCol.key}`].mainArrow = arrow;
-            item[`${origCol.key}`].arrowColor = arrowColor;
-            item[`${origCol.key}`].backgroundColor = basicBackgroundColor;
-          }
-        });
-        return item;
+          item[`${origCol.key}`] = {
+            mainArrow: arrow,
+            arrowColor: arrowColor,
+            backgroundColor: backgroundColor,
+          };
+        }
       });
-    },
-  );
+      return item;
+    });
+  });
 
   const canUseTimeComparison =
     enableTimeComparison &&
diff --git a/superset-frontend/plugins/plugin-chart-table/src/types.ts b/superset-frontend/plugins/plugin-chart-table/src/types.ts
index f4ca8473f1..8393bb23cc 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/types.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/types.ts
@@ -145,4 +145,11 @@ export enum ColorSchemeEnum {
   'Red' = 'Red',
 }
 
+export type BasicColorFormatterType {
+  backgroundColor: string;
+  arrowColor: string;
+  mainArrow: string;
+}
+
+
 export default {};


(superset) 04/04: multi select for conditional color formatter

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lilykuang pushed a commit to branch table-time-comparison-color
in repository https://gitbox.apache.org/repos/asf/superset.git

commit f92eff21c0474dd3db8450a35cb8615322faeaaf
Author: lilykuang <ji...@gmail.com>
AuthorDate: Mon Mar 25 09:41:14 2024 -0700

    multi select for conditional color formatter
---
 .../superset-ui-chart-controls/src/types.ts        |  4 ++--
 .../src/utils/getColorFormatters.ts                | 23 ++++++++++++++--------
 .../plugin-chart-table/src/transformProps.ts       |  1 +
 .../plugins/plugin-chart-table/src/types.ts        |  5 +++++
 .../ConditionalFormattingControl.tsx               |  8 +++++++-
 .../FormattingPopover.tsx                          |  2 ++
 .../FormattingPopoverContent.tsx                   |  8 +++++++-
 .../controls/ConditionalFormattingControl/types.ts |  4 +++-
 8 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
index 3d149b1299..3243f22c60 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
+++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
@@ -446,7 +446,7 @@ export type ConditionalFormattingConfig = {
   targetValue?: number;
   targetValueLeft?: number;
   targetValueRight?: number;
-  column?: string;
+  column?: string | string[];
   colorScheme?: string;
 };
 
@@ -519,7 +519,7 @@ export type ControlFormItemSpec<T extends ControlType = ControlType> = {
   ? {
       allowNewOptions?: boolean;
       options: any;
-      value?: string;
+      value?: string | string[];
       defaultValue?: string;
       creatable?: boolean;
       minWidth?: number | string;
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 4e5e89fe41..3b493281b3 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
@@ -195,8 +195,13 @@ export const getColorFormatters = memoizeOne(
   ) =>
     columnConfig?.reduce(
       (acc: ColorFormatters, config: ConditionalFormattingConfig) => {
+        const columns = Array.isArray(config?.column)
+          ? config?.column
+          : config?.column
+            ? [config?.column]
+            : undefined;
         if (
-          config?.column !== undefined &&
+          columns !== undefined &&
           (config?.operator === Comparator.None ||
             (config?.operator !== undefined &&
               (MultipleValueComparators.includes(config?.operator)
@@ -204,13 +209,15 @@ export const getColorFormatters = memoizeOne(
                   config?.targetValueRight !== undefined
                 : config?.targetValue !== undefined)))
         ) {
-          acc.push({
-            column: config?.column,
-            getColorFromValue: getColorFunction(
-              config,
-              data.map(row => row[config.column!] as number),
-              alpha,
-            ),
+          columns.forEach((column: string) => {
+            acc.push({
+              column,
+              getColorFromValue: getColorFunction(
+                config,
+                data.map(row => row[column!] as number),
+                alpha,
+              ),
+            });
           });
         }
         return acc;
diff --git a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
index 924357653f..abc3c51914 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/transformProps.ts
@@ -481,6 +481,7 @@ const transformProps = (
 
   const basicColorFormatter =
     comparisonColorEnabled && getBasicColorFormatter(baseQuery?.data, columns);
+
   const columnColorFormatters =
     getColorFormatters(conditionalFormatting, passedData) ??
     defaultColorFormatters;
diff --git a/superset-frontend/plugins/plugin-chart-table/src/types.ts b/superset-frontend/plugins/plugin-chart-table/src/types.ts
index 8393bb23cc..ddb31b460a 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/types.ts
+++ b/superset-frontend/plugins/plugin-chart-table/src/types.ts
@@ -103,6 +103,11 @@ export interface TableChartProps extends ChartProps {
   queriesData: ChartDataResponseResult[];
 }
 
+export enum ColorSchemeEnum {
+  Green = 'Green',
+  Red = 'Red',
+}
+
 export interface TableChartTransformedProps<D extends DataRecord = DataRecord> {
   timeGrain?: TimeGranularity;
   height: number;
diff --git a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx
index 6c4ae9f412..5c35d652bf 100644
--- a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx
+++ b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/ConditionalFormattingControl.tsx
@@ -71,6 +71,7 @@ const ConditionalFormattingControl = ({
   columnOptions,
   verboseMap,
   removeIrrelevantConditions,
+  multi = false,
   ...props
 }: ConditionalFormattingControlProps) => {
   const theme = useTheme();
@@ -121,7 +122,10 @@ const ConditionalFormattingControl = ({
     targetValueLeft,
     targetValueRight,
   }: ConditionalFormattingConfig) => {
-    const columnName = (column && verboseMap?.[column]) ?? column;
+    const cols = Array.isArray(column) ? column : [column];
+    const columnName = cols
+      .map(col => (col && verboseMap?.[col]) ?? col)
+      .join(', ');
     switch (operator) {
       case Comparator.None:
         return `${columnName}`;
@@ -154,6 +158,7 @@ const ConditionalFormattingControl = ({
               onChange={(newConfig: ConditionalFormattingConfig) =>
                 onEdit(newConfig, index)
               }
+              multi={multi}
               destroyTooltipOnHide
             >
               <OptionControlContainer withCaret>
@@ -170,6 +175,7 @@ const ConditionalFormattingControl = ({
           columns={columnOptions}
           onChange={onSave}
           destroyTooltipOnHide
+          multi={multi}
         >
           <AddControlLabel>
             <Icons.PlusSmall iconColor={theme.colors.grayscale.light1} />
diff --git a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopover.tsx b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopover.tsx
index c44ca76235..87dddc43d0 100644
--- a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopover.tsx
+++ b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopover.tsx
@@ -27,6 +27,7 @@ export const FormattingPopover = ({
   onChange,
   config,
   children,
+  multi = false,
   ...props
 }: FormattingPopoverProps) => {
   const [visible, setVisible] = useState(false);
@@ -47,6 +48,7 @@ export const FormattingPopover = ({
           onChange={handleSave}
           config={config}
           columns={columns}
+          multi={multi}
         />
       }
       visible={visible}
diff --git a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
index 533e185475..86b1e56330 100644
--- a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
+++ b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx
@@ -186,10 +186,12 @@ export const FormattingPopoverContent = ({
   config,
   onChange,
   columns = [],
+  multi = false,
 }: {
   config?: ConditionalFormattingConfig;
   onChange: (config: ConditionalFormattingConfig) => void;
   columns: { label: string; value: string }[];
+  multi?: boolean;
 }) => {
   const theme = useTheme();
   const colorScheme = colorSchemeOptions(theme);
@@ -208,7 +210,11 @@ export const FormattingPopoverContent = ({
             rules={rulesRequired}
             initialValue={columns[0]?.value}
           >
-            <Select ariaLabel={t('Select column')} options={columns} />
+            <Select
+              mode={multi ? 'multiple' : undefined}
+              ariaLabel={t('Select column')}
+              options={columns}
+            />
           </FormItem>
         </Col>
         <Col span={12}>
diff --git a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/types.ts b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/types.ts
index 4edadf99b4..44d7fbd602 100644
--- a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/types.ts
+++ b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/types.ts
@@ -26,7 +26,7 @@ export type ConditionalFormattingConfig = {
   targetValue?: number;
   targetValueLeft?: number;
   targetValueRight?: number;
-  column?: string;
+  column?: string | string[];
   colorScheme?: string;
 };
 
@@ -38,6 +38,7 @@ export type ConditionalFormattingControlProps = ControlComponentProps<
   verboseMap: Record<string, string>;
   label: string;
   description: string;
+  multi?: boolean;
 };
 
 export type FormattingPopoverProps = PopoverProps & {
@@ -46,4 +47,5 @@ export type FormattingPopoverProps = PopoverProps & {
   config?: ConditionalFormattingConfig;
   title: string;
   children: ReactNode;
+  multi?: boolean;
 };