This is an automated email from the ASF dual-hosted git repository.
msyavuz 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 c31224c891 fix(TableChart): render cell bars for columns with NULL
values (#36819)
c31224c891 is described below
commit c31224c891d3269893d3724c62777ab6557d598d
Author: Luis Sánchez <[email protected]>
AuthorDate: Wed Dec 31 11:51:35 2025 -0300
fix(TableChart): render cell bars for columns with NULL values (#36819)
---
.../src/utils/useColDefs.ts | 21 +++++--
.../plugins/plugin-chart-table/src/TableChart.tsx | 3 +-
.../plugin-chart-table/test/TableChart.test.tsx | 72 ++++++++++++++++++++++
3 files changed, 90 insertions(+), 6 deletions(-)
diff --git
a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useColDefs.ts
b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useColDefs.ts
index f9f28ace11..89f652b1cf 100644
---
a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useColDefs.ts
+++
b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/utils/useColDefs.ts
@@ -67,11 +67,22 @@ function getValueRange(
alignPositiveNegative: boolean,
data: InputData[],
) {
- if (typeof data?.[0]?.[key] === 'number') {
- const nums = data.map(row => row[key]) as number[];
- return (
- alignPositiveNegative ? [0, d3Max(nums.map(Math.abs))] : d3Extent(nums)
- ) as ValueRange;
+ const nums = data
+ .map(row => {
+ const raw = row[key];
+ return raw instanceof Number ? raw.valueOf() : raw;
+ })
+ .filter(
+ (value): value is number =>
+ typeof value === 'number' && Number.isFinite(value),
+ ) as number[];
+ if (nums.length > 0) {
+ const maxAbs = d3Max(nums.map(Math.abs));
+ if (alignPositiveNegative) {
+ return [0, maxAbs ?? 0] as ValueRange;
+ }
+ const extent = d3Extent(nums) as ValueRange | undefined;
+ return extent ?? [0, 0];
}
return null;
}
diff --git a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
index e901f7103a..964ab72d47 100644
--- a/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx
@@ -385,7 +385,7 @@ export default function TableChart<D extends DataRecord =
DataRecord>(
const nums = data
?.map(row => row?.[key])
.filter(value => typeof value === 'number') as number[];
- if (data && nums.length === data.length) {
+ if (nums.length > 0) {
return (
alignPositiveNegative
? [0, d3Max(nums.map(Math.abs))]
@@ -958,6 +958,7 @@ export default function TableChart<D extends DataRecord =
DataRecord>(
display: block;
top: 0;
${valueRange &&
+ typeof value === 'number' &&
`
width: ${`${cellWidth({
value: value as number,
diff --git
a/superset-frontend/plugins/plugin-chart-table/test/TableChart.test.tsx
b/superset-frontend/plugins/plugin-chart-table/test/TableChart.test.tsx
index fd5b8f68df..ceb254822c 100644
--- a/superset-frontend/plugins/plugin-chart-table/test/TableChart.test.tsx
+++ b/superset-frontend/plugins/plugin-chart-table/test/TableChart.test.tsx
@@ -26,6 +26,7 @@ import {
} from '@superset-ui/core/spec';
import { cloneDeep } from 'lodash';
import TableChart, { sanitizeHeaderId } from '../src/TableChart';
+import { GenericDataType } from '@apache-superset/core/api/core';
import transformProps from '../src/transformProps';
import DateWithFormatter from '../src/utils/DateWithFormatter';
import testData from './testData';
@@ -803,6 +804,77 @@ describe('plugin-chart-table', () => {
cells = document.querySelectorAll('td');
});
+ test('render cell bars even when column contains NULL values', () => {
+ const props = transformProps({
+ ...testData.raw,
+ queriesData: [
+ {
+ ...testData.raw.queriesData[0],
+ colnames: ['category', 'value1', 'value2', 'value3', 'value4'],
+ coltypes: [
+ GenericDataType.String,
+ GenericDataType.Numeric,
+ GenericDataType.Numeric,
+ GenericDataType.Numeric,
+ GenericDataType.Numeric,
+ ],
+ data: [
+ {
+ category: 'Category A',
+ value1: 10,
+ value2: 20,
+ value3: 30,
+ value4: null,
+ },
+ {
+ category: 'Category B',
+ value1: 15,
+ value2: 25,
+ value3: 35,
+ value4: 100,
+ },
+ {
+ category: 'Category C',
+ value1: 18,
+ value2: 28,
+ value3: 38,
+ value4: null,
+ },
+ ],
+ },
+ ],
+ rawFormData: {
+ ...testData.raw.rawFormData,
+ show_cell_bars: true,
+ metrics: ['value1', 'value2', 'value3', 'value4'],
+ },
+ });
+
+ const { container } = render(
+ ProviderWrapper({
+ children: <TableChart {...props} sticky={false} />,
+ }),
+ );
+
+ // Get all cell bars - should exist for both columns with and without
NULL values
+ const cellBars = container.querySelectorAll('div.cell-bar');
+
+ // Should have cell bars in all numeric columns, even those with NULL
values
+ // value1, value2, value3 all have 3 values, value4 has 1 non-NULL
value
+ // Total: 3 + 3 + 3 + 1 = 10 cell bars
+ expect(cellBars.length).toBeGreaterThan(0);
+
+ // Specifically check that value4 column (which has NULLs) still
renders bars for non-NULL cells
+ const rows = container.querySelectorAll('tbody tr');
+ expect(rows.length).toBe(3);
+
+ // Row 2 should have a cell bar in value4 column (value: 100)
+ const row2Cells = rows[1].querySelectorAll('td');
+ const value4Cell = row2Cells[4]; // 5th column (0-indexed)
+ const value4Bar = value4Cell.querySelector('div.cell-bar');
+ expect(value4Bar).toBeTruthy();
+ });
+
test('render color with string column color formatter(operator begins
with)', () => {
render(
ProviderWrapper({