This is an automated email from the ASF dual-hosted git repository.
sadpandajoe 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 51378f529d8 fix(matrixify): fan metrics-axis selection into
multi-query fields (#44629)
51378f529d8 is described below
commit 51378f529d8707a7962c7bb315103bf9e8e5237e
Author: Joe Li <[email protected]>
AuthorDate: Wed Sep 30 14:53:33 2026 -0700
fix(matrixify): fan metrics-axis selection into multi-query fields (#44629)
Co-authored-by: Claude Sonnet 5 <[email protected]>
---
.../Matrixify/MatrixifyGridGenerator.test.ts | 63 ++++++++++++++++++++++
.../components/Matrixify/MatrixifyGridGenerator.ts | 34 ++++++++++--
2 files changed, 92 insertions(+), 5 deletions(-)
diff --git
a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts
b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts
index 2ba91742291..61d28c9723b 100644
---
a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts
+++
b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts
@@ -206,6 +206,69 @@ test('should add dimension filters to every query-specific
adhoc filter collecti
);
});
+test('should apply a metrics-axis selection to every query-specific metrics
collection', () => {
+ // Multi-query charts (e.g. Mixed Chart) read each query's metrics from a
+ // separate collection. When the matrix axis is in "metrics" mode, the
+ // metric chosen for a cell must reach all of them, not just the primary
+ // `metrics` field, or the secondary query renders identically in every
+ // cell of the grid.
+ const mixedChartFormData: TestFormData = {
+ viz_type: 'mixed_timeseries',
+ datasource: '1__table',
+ matrixify_enable: true,
+ matrixify_mode_rows: 'metrics',
+ matrixify_mode_columns: 'disabled',
+ matrixify_rows: [createAdhocMetric('Revenue'),
createAdhocMetric('Profit')],
+ metrics: [createAdhocMetric('Original Primary')],
+ metrics_b: [createAdhocMetric('Original Secondary')],
+ };
+
+ const grid = generateMatrixifyGrid(mixedChartFormData);
+
+ expect(grid).not.toBeNull();
+ const revenueCell = grid!.cells[0][0]!;
+ const profitCell = grid!.cells[1][0]!;
+
+ expect(revenueCell.formData.metrics).toEqual([createAdhocMetric('Revenue')]);
+ expect(revenueCell.formData.metrics_b).toEqual([
+ createAdhocMetric('Revenue'),
+ ]);
+ expect(revenueCell.formData.metric).toEqual(createAdhocMetric('Revenue'));
+
+ expect(profitCell.formData.metrics).toEqual([createAdhocMetric('Profit')]);
+ expect(profitCell.formData.metrics_b).toEqual([createAdhocMetric('Profit')]);
+ expect(profitCell.formData.metric).toEqual(createAdhocMetric('Profit'));
+
+ // The base formData's collection is untouched by either cell's override.
+ expect(mixedChartFormData.metrics_b).toEqual([
+ createAdhocMetric('Original Secondary'),
+ ]);
+});
+
+test('should store independent metrics array references per query-specific
field', () => {
+ // Each query-specific metrics collection must be its own array, not the
+ // same reference reused across keys, or mutating one (e.g. via push/sort)
+ // would silently mutate the others too.
+ const mixedChartFormData: TestFormData = {
+ viz_type: 'mixed_timeseries',
+ datasource: '1__table',
+ matrixify_enable: true,
+ matrixify_mode_rows: 'metrics',
+ matrixify_mode_columns: 'disabled',
+ matrixify_rows: [createAdhocMetric('Revenue')],
+ metrics: [createAdhocMetric('Original Primary')],
+ metrics_b: [createAdhocMetric('Original Secondary')],
+ };
+
+ const grid = generateMatrixifyGrid(mixedChartFormData);
+ const cellFormData = grid!.cells[0][0]!.formData;
+
+ expect(cellFormData.metrics).not.toBe(cellFormData.metrics_b);
+
+ cellFormData.metrics.push(createAdhocMetric('Mutation'));
+ expect(cellFormData.metrics_b).toEqual([createAdhocMetric('Revenue')]);
+});
+
test('should generate grid for mixed mode (metrics rows, dimensions columns)',
() => {
const mixedFormData: TestFormData = {
viz_type: 'table',
diff --git
a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts
b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts
index 900a3160deb..99fe167428a 100644
---
a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts
+++
b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts
@@ -18,7 +18,7 @@
*/
import Handlebars from 'handlebars';
-import type { QueryFormData } from '../../../query';
+import type { AdhocMetric, QueryFormData } from '../../../query';
import type {
AdhocFilter,
BinaryAdhocFilter,
@@ -134,6 +134,30 @@ function appendMatrixifyFilters(
});
}
+/**
+ * Apply the matrix's chosen metrics to the primary `metrics` collection as
well
+ * as every query-specific `metrics_*` collection present on the formData (plus
+ * the singular `metric` field used by single-metric viz types). Charts with
+ * more than one query (e.g. Mixed Chart) read each query's metrics from a
+ * separate collection (`metrics_b`, `metrics_c`, ...), so a cell's chosen
+ * metrics must overwrite all of them, not just the primary query's.
+ */
+function overrideMatrixifyMetrics(
+ formData: QueryFormData & MatrixifyFormData,
+ metrics: AdhocMetric[],
+): void {
+ const metricsFields: Record<string, unknown> = formData;
+ const metricsKeys = [
+ 'metrics',
+ ...Object.keys(metricsFields).filter(key => /^metrics_.+$/u.test(key)),
+ ];
+
+ metricsKeys.forEach(key => {
+ metricsFields[key] = [...metrics];
+ });
+ metricsFields.metric = metrics[0];
+}
+
/**
* Generate form data for a specific grid cell
*/
@@ -205,7 +229,7 @@ function generateCellFormData(
}
// Set metrics based on row/column configuration
- const metrics = [];
+ const metrics: AdhocMetric[] = [];
if (rowConfig && rowIndex !== null && rowConfig.mode === 'metrics') {
const metric = rowConfig.metrics?.[rowIndex];
@@ -221,10 +245,10 @@ function generateCellFormData(
}
}
- // If we have metrics from the matrix, use them; otherwise keep original
+ // If we have metrics from the matrix, apply them to the primary and every
+ // query-specific metrics collection; otherwise keep each query's original.
if (metrics.length > 0) {
- cellFormData.metrics = metrics;
- cellFormData.metric = metrics[0];
+ overrideMatrixifyMetrics(cellFormData, metrics);
}
return cellFormData;