mikemazara opened a new issue, #43258:
URL: https://github.com/apache/superset/issues/43258

   ### Bug
   
   When a Matrixify axis is in `dimensions` mode, the member list is resolved 
in Explore and frozen into `form_data`. It is never re-resolved at dashboard 
render, so it cannot respond to native filters, cross-filters, or time range. 
Combined with a hardcoded 25-member cap in `all` mode, a matrixified chart can 
**silently omit dimension members that do have data under the viewer's active 
filters**, with no indication that anything is missing.
   
   The cell *contents* are filter-aware but the cell *membership* is not, which 
is what makes this a data-correctness problem rather than a cosmetic one.
   
   #### The asymmetry
   
   `generateCellFormData` copies the base `form_data` — including 
`extra_form_data` merged from dashboard filters — and appends a filter pinning 
that cell's value:
   
   ```js
   const cellFormData: any = { ...baseFormData };
   // ...
   additionalFilters.push(createDimensionFilter(rowConfig.dimension.dimension, 
value));
   ```
   
   So members excluded by the active filters render a "No data" panel instead 
of disappearing, and members outside the frozen list never render at all.
   
   #### Where membership is decided
   
   
`superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts`
 — one cell per member, created before any query runs:
   
   ```js
   rowCount = config.rows.dimension.values.length;
   ```
   
   
`superset-frontend/src/explore/components/controls/MatrixifyDimensionControl.tsx`
 — the list is fetched by an **Explore control**, which never mounts on a 
dashboard:
   
   - `members` / `all` — `GET 
/api/v1/datasource/{type}/{id}/column/{column}/values/`, with no filters and no 
time range, then truncated:
     ```js
     const MAX_ALL_DIMENSION_VALUES = 25;
     const allValues = selectionMode === 'all'
         ? values.slice(0, MAX_ALL_DIMENSION_VALUES)
         : value.values || [];
     ```
   - `topn`, and `all` + metric sort — `fetchTopNValues({ filters: 
formData?.adhoc_filters, timeRange: formData?.time_range, limit })`
   
   In every mode the result is written into `form_data` via `onChange`, so it 
is identical for all viewers.
   
   #### Top N is not a workaround
   
   This is worth stating explicitly, since it is the obvious first suggestion. 
Top N does pass filters, but:
   
   1. it runs at **config time**, before the render path, so dashboard filters 
have not been applied yet; and
   2. it therefore ranks members by the metric computed over the **whole 
dataset** (or at most the chart author's own adhoc filters), not per viewer.
   
   The consequence is that "top" does not mean "relevant to this viewer". The 
globally-largest member gets a panel for a viewer who has no rows for it at all 
— a guaranteed "No data" cell — while that viewer's own most-active members may 
be missing from the list entirely. Ranking globally and rendering per-viewer 
cannot be reconciled.
   
   ### How to reproduce
   
   1. Enable `MATRIXIFY`.
   2. Create a dataset where one dimension has more than 25 distinct values (69 
in our case) and a second dimension partitions the rows so that each value of 
the second only touches a small subset of the first (here: projects vs. 
employees).
   3. Build a chart matrixified by rows on the high-cardinality dimension, `All 
dimensions` selection mode, sorted by metric.
   4. Put it on a dashboard with a single-select native filter on the second 
dimension.
   5. Switch the filter between values.
   
   ### Actual results
   
   Measured on 6.1.0 with 69 members and a 25 cap:
   
   | viewer | panels populated | members **with data** that were omitted 
entirely |
   |---|---|---|
   | Employee A | 8 / 25 | 6 |
   | Employee B | 4 / 25 | 1 |
   
   Employee A has data for 14 members; the chart rendered 8 and gave no 
indication the other 6 existed. Alphabetical sorting fails the same way on a 
different arbitrary subset. Because the member count exceeds the cap, **no 
configuration of this chart is correct for all viewers.**
   
   ### Expected results
   
   The member list should be resolved against the chart's *effective* filters 
(`form_data` + `extra_form_data`) at render time, so that panels correspond to 
what the viewer is actually looking at — and in particular so that a member 
with data under the active filters is never dropped.
   
   ### Suggested fixes, in order of value
   
   1. **Resolve members in the render path** rather than in the Explore 
control, using effective filters. This is the real fix and is what makes the 
feature correct on dashboards.
   2. **Add a "hide empty cells" option.** Useful, but insufficient alone — the 
cap already excludes members before any query runs, so omissions persist.
   3. **Make `MAX_ALL_DIMENSION_VALUES` configurable.** It is hardcoded at 25, 
while `members` mode is uncapped, so the limit is inconsistent between modes.
   4. **Surface truncation in the UI** when `totalValueCount` exceeds the cap. 
Today it is entirely silent.
   
   ### Environment
   
   - Superset 6.1.0
   - Postgres metadata + Postgres analytics database
   - Feature flags: `MATRIXIFY`, `ENABLE_TEMPLATE_PROCESSING`, `DASHBOARD_RBAC`
   - `echarts_timeseries_bar` with two saved metrics, matrixified by rows
   
   ### Related
   
   #39007, #39008 — other 6.1 Matrixify defects. No existing issue covers 
member resolution.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to