diff --git a/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.tsx b/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.tsx index 9bf5cd67da8..dd7489cdfc5 100644 --- a/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.tsx +++ b/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.tsx @@ -28,18 +28,20 @@ import { } from 'react'; import { safeHtmlSpan } from '@superset-ui/core'; import { t } from '@apache-superset/core/translation'; +import { supersetTheme } from '@apache-superset/core/theme'; import PropTypes from 'prop-types'; import { FaSort } from 'react-icons/fa'; import { FaSortDown as FaSortDesc } from 'react-icons/fa'; import { FaSortUp as FaSortAsc } from 'react-icons/fa'; +import { + ColorFormatters, + getTextColorForBackground, + ObjectFormattingEnum, + ResolvedColorFormatterResult, +} from '@superset-ui/chart-controls'; import { PivotData, flatKey } from './utilities'; import { Styles } from './Styles'; -interface CellColorFormatter { - column: string; - getColorFromValue(value: unknown): string | undefined; -} - type ClickCallback = ( e: MouseEvent, value: unknown, @@ -67,8 +69,11 @@ interface TableOptions { highlightHeaderCellsOnHover?: boolean; omittedHighlightHeaderGroups?: string[]; highlightedHeaderCells?: Record; - cellColorFormatters?: Record; + cellColorFormatters?: Record; dateFormatters?: Record string) | undefined>; + cellBackgroundColor?: string; + cellTextColor?: string; + activeHeaderBackgroundColor?: string; } interface SubtotalDisplay { @@ -175,6 +180,50 @@ function displayHeaderCell( ); } +export function getCellColor( + keys: string[], + aggValue: string | number | null, + cellColorFormatters: Record | undefined, + cellBackgroundColor = supersetTheme.colorBgBase, +): ResolvedColorFormatterResult { + if (!cellColorFormatters) return { backgroundColor: undefined }; + + let backgroundColor: string | undefined; + let color: string | undefined; + const isTextColorFormatter = (formatter: ColorFormatters[number]) => + formatter.objectFormatting === ObjectFormattingEnum.TEXT_COLOR || + formatter.toTextColor; + + for (const cellColorFormatter of Object.values(cellColorFormatters)) { + if (!Array.isArray(cellColorFormatter)) continue; + + for (const key of keys) { + for (const formatter of cellColorFormatter) { + if (formatter.column === key) { + const result = formatter.getColorFromValue(aggValue); + if (result) { + if (isTextColorFormatter(formatter)) { + color = result; + } else if ( + formatter.objectFormatting !== ObjectFormattingEnum.CELL_BAR + ) { + backgroundColor = result; + } + } + } + } + } + } + + return { + backgroundColor, + color: getTextColorForBackground( + { backgroundColor, color }, + cellBackgroundColor, + ), + }; +} + interface HierarchicalNode { currentVal?: number; [key: string]: HierarchicalNode | number | undefined; @@ -840,7 +889,10 @@ export function TableRenderer({ highlightHeaderCellsOnHover, omittedHighlightHeaderGroups = [], highlightedHeaderCells, + cellColorFormatters, dateFormatters, + cellBackgroundColor = supersetTheme.colorBgBase, + activeHeaderBackgroundColor = supersetTheme.colorPrimaryBg, } = tableOptions; if (!settingsVisibleColKeys || !colAttrSpans) { @@ -950,10 +1002,22 @@ export function TableRenderer({ }; const headerCellFormattedValue = dateFormatters?.[attrName]?.(colKey[attrIdx]) ?? colKey[attrIdx]; + const isActiveHeader = colLabelClass.includes('active'); + const { backgroundColor, color } = getCellColor( + [attrName], + headerCellFormattedValue, + cellColorFormatters, + isActiveHeader ? activeHeaderBackgroundColor : cellBackgroundColor, + ); + const colHeaderStyle = { + backgroundColor, + ...(color ? { color } : {}), + }; attrValueCells.push( { - if (Array.isArray(cellColorFormatter)) { - keys.forEach(key => { - if (backgroundColor) { - return; - } - cellColorFormatter - .filter(formatter => formatter.column === key) - .forEach(formatter => { - const formatterResult = - formatter.getColorFromValue(aggValue); - if (formatterResult) { - backgroundColor = formatterResult; - } - }); - }); - } - }); - } + const { backgroundColor, color } = getCellColor( + keys, + aggValue, + cellColorFormatters, + cellBackgroundColor, + ); const style = agg.isSubtotal - ? { fontWeight: 'bold' } - : { backgroundColor }; + ? { + backgroundColor, + fontWeight: 'bold', + color: color ?? cellTextColor, + } + : { backgroundColor, color: color ?? cellTextColor }; return (