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;

Reply via email to