Skip to content

fix(pivot-table): include aggregation type in subtotal labels#41957

Open
RehanIslam09 wants to merge 1 commit into
apache:masterfrom
RehanIslam09:fix-pivot-subvalue-label
Open

fix(pivot-table): include aggregation type in subtotal labels#41957
RehanIslam09 wants to merge 1 commit into
apache:masterfrom
RehanIslam09:fix-pivot-subvalue-label

Conversation

@RehanIslam09

Copy link
Copy Markdown

SUMMARY

This PR updates the Pivot Table subtotal labels to include the selected aggregation function.

Previously, subtotal rows and columns always displayed the generic label "Subtotal", regardless of the selected aggregation function.

This change updates the subtotal labels to display the selected aggregation function, making them consistent with the existing total labels.

Examples:

  • Before: Subtotal
  • After:
    • Subvalue (Sum)
    • Subvalue (Average)
    • Subvalue (Count)

Fixes #35089.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

After

The Pivot Table subtotal labels now include the aggregation type.

Example:

  • Subvalue (Sum)
image
  • Subvalue (Average)
image

TESTING INSTRUCTIONS

  1. Open Explore.
  2. Select the Pivot Table visualization.
  3. Add at least one row and one metric.
  4. Enable row or column subtotals.
  5. Change the aggregation function (for example, Sum, Average, or Count).
  6. Verify that the subtotal labels display the selected aggregation function.

ADDITIONAL INFORMATION

@dosubot dosubot Bot added explore:design Related to the Explore UI/UX viz:charts:pivot Related to the Pivot Table charts labels Jul 11, 2026
@bito-code-review

bito-code-review Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #58a382

Actionable Suggestions - 0
Review Details
  • Files reviewed - 1 · Commit Range: b068321..b068321
    • superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment on lines +1076 to +1078
{t('Subvalue (%(aggregatorName)s)', {
aggregatorName: t(aggregatorName),
})}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The new label text uses Subvalue, which contradicts the subtotal terminology used by the surrounding code (pvtSubtotalLabel) and the feature intent (subtotal labels). This introduces incorrect user-facing wording; use Subtotal (%(aggregatorName)s) instead. [inconsistent naming]

Severity Level: Minor 🧹
- ⚠️ Suggestion targets wording choice, not functional bug.
- ⚠️ Pivot table behavior unaffected; labels already consistent.
- ⚠️ CSS class name needn’t match human-readable text.
Steps of Reproduction ✅
1. The column subtotal header cell is rendered in `renderColHeaderRow` at
`TableRenderers.tsx:860-1112`; when `attrIdx === colKey.length`, the code at `1060-1080`
creates a `<th>` with class `pvtSubtotalLabel` and the label `{t('Subvalue
(%(aggregatorName)s)', { aggregatorName: t(aggregatorName) })}` (lines `1076-1078`).

2. The same `Subvalue` label pattern is used for row subtotals in `renderTableRow` at
`TableRenderers.tsx:1322-1342`, so subtotal labels are consistent between row and column
headers within this component.

3. A repository-wide search for `"Subtotal"` in the frontend (`Grep` over
`superset-frontend/**/*.ts*`) shows no other user-facing strings like `"Subtotal
(%(aggregatorName)s)"`; the only uses ofsubtotalare internal types and flags such as
`SubtotalOptions` and style selectors `.pvtSubtotalLabel` in `Styles.ts:69-107`, which
just control visual formatting, not text.

4. Given there is no conflicting `"Subtotal"` label elsewhere in this visualization and
the PR descriptions examples explicitly use `Subvalue (Sum)` / `Subvalue (Average)` as
the intended copy, this wording appears deliberate rather than a bug; changing it to
`"Subtotal"` is a product copy decision, not a functional defect.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.tsx
**Line:** 1076:1078
**Comment:**
	*Inconsistent Naming: The new label text uses `Subvalue`, which contradicts the subtotal terminology used by the surrounding code (`pvtSubtotalLabel`) and the feature intent (subtotal labels). This introduces incorrect user-facing wording; use `Subtotal (%(aggregatorName)s)` instead.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +1338 to +1340
{t('Subvalue (%(aggregatorName)s)', {
aggregatorName: t(aggregatorName),
})}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This new use of aggregatorName is inside a memoized row-render callback, but that callback’s dependency list does not include aggregatorName. When users switch aggregation (Sum/Average/Count), this label can keep showing the previous aggregator due to a stale closure. Add aggregatorName to that useCallback dependency array so subtotal labels update correctly. [stale reference]

Severity Level: Major ⚠️
- ⚠️ Row subtotal headers show outdated aggregation name after change.
- ⚠️ Users can misread subtotals when aggregator changes.
- ⚠️ Any UI tests on subtotal labels may become flaky.
Steps of Reproduction ✅
1. In `TableRenderers.tsx:327-341`, `TableRenderer` destructures `aggregatorName` from
props and passes it into several memoized callbacks; row rendering is handled by
`renderTableRow` defined at `TableRenderers.tsx:1207-1410`.

2. Inside `renderTableRow`, the row subtotal header cell is rendered when `rowKey.length <
settingsRowAttrs.length` at `TableRenderers.tsx:1322-1342`; the label uses the new code at
`1338-1340`: `t('Subvalue (%(aggregatorName)s)', { aggregatorName: t(aggregatorName) })`,
so this callback closes over `aggregatorName`.

3. The `renderTableRow` function itself is memoized with `useCallback` at
`TableRenderers.tsx:1207-1418`, but its dependency array at `1410-1417` is `[tableOptions,
onContextMenu, toggleRowKey, clickHeaderHandler, rows, collapsedRows]` and does not
include `aggregatorName`, meaning the callback instance (and its closed-over
`aggregatorName` value) is reused across renders as long as those dependencies do not
change.

4. When the aggregator is changed from, for example, `"Count"` to `"Sum"` (as exercised in
tests by `aggregatorName: 'Count'` and `aggregatorName: 'Sum'` in `buildDefaultProps` at
`test/react-pivottable/tableRenders.test.tsx:62-73` and `211-215`, or via the
`aggregateFunction` control in Storybook at `src/stories/PivotTable.stories.tsx:31-51`),
`TableRenderer` re-renders with a new `aggregatorName` prop but `renderTableRow` is not
recreated (its deps are unchanged), so row subtotal header cells still display the stale
label like `Subvalue (Count)` instead of the updated `Subvalue (Sum)`.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.tsx
**Line:** 1338:1340
**Comment:**
	*Stale Reference: This new use of `aggregatorName` is inside a memoized row-render callback, but that callback’s dependency list does not include `aggregatorName`. When users switch aggregation (Sum/Average/Count), this label can keep showing the previous aggregator due to a stale closure. Add `aggregatorName` to that `useCallback` dependency array so subtotal labels update correctly.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.77%. Comparing base (a6ce2fd) to head (79c8ec6).
⚠️ Report is 23 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #41957      +/-   ##
==========================================
- Coverage   64.78%   64.77%   -0.01%     
==========================================
  Files        2739     2739              
  Lines      152981   152980       -1     
  Branches    35058    35058              
==========================================
- Hits        99107    99100       -7     
- Misses      51974    51980       +6     
  Partials     1900     1900              
Flag Coverage Δ
javascript 69.78% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment on lines 88 to 94
const { value, errorMsg } = calculateCellValue(
valueField,
columnConfig,
reversedEntries,
);

if (columnConfig.colType === 'spark') {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: calculateCellValue is executed for every column before checking colType, so sparkline columns do unnecessary value computation that is immediately discarded; this adds avoidable per-row/per-column work in a hot render path. Move the calculation into the non-spark branch to avoid wasted processing. [performance]

Severity Level: Major ⚠️
- ⚠️ TimeTable sparkline columns perform redundant value calculations per render.
- ⚠️ Large tables with many spark columns render more slowly.
Steps of Reproduction ✅
1. In the TimeTable component, inspect the memoizedRows computation at
superset-frontend/src/visualizations/TimeTable/TimeTable.tsx:81-126. For each row,
columnConfigs.reduce is used to build cellValues; within the reducer, calculateCellValue
is called unconditionally at lines 88-92 to derive { value, errorMsg } for the current
column.

2. Immediately after that call, the code branches on columnConfig.colType at lines 94-105.
If colType is 'spark', the reducer returns a Sparkline component: <Sparkline
valueField={valueField} column={columnConfig} entries={entries} /> (lines 98-102), and the
previously computed value and errorMsg are not referenced anywhere in the spark branch.

3. Review calculateCellValue in
superset-frontend/src/visualizations/TimeTable/utils/valueCalculations/valueCalculations.ts:142-160.
This helper performs non-trivial work per cell: it reads reversedEntries, derives the
“recent” value, and may call calculateTimeValue, calculateContribution, or
calculateAverage (lines 151-158), which themselves iterate over reversedEntries and
perform numeric computations.

4. Because calculateCellValue is invoked for every column, including spark columns whose
rendered cells never use its result, every TimeTable render with spark columns performs
unnecessary per-row/per-column value computation that is immediately discarded. This
wasted work sits on the core render path for TimeTable, so any dataset with many rows and
spark columns will pay extra CPU cost without functional benefit.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/visualizations/TimeTable/TimeTable.tsx
**Line:** 88:94
**Comment:**
	*Performance: `calculateCellValue` is executed for every column before checking `colType`, so sparkline columns do unnecessary value computation that is immediately discarded; this adds avoidable per-row/per-column work in a hot render path. Move the calculation into the non-spark branch to avoid wasted processing.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines 110 to 114
<ValueCell
valueField={valueField}
value={value}
errorMsg={errorMsg}
column={columnConfig}
reversedEntries={reversedEntries}
/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The new ValueCell props no longer include the metadata that the existing sortNumberWithMixedTypes comparator depends on (valueField/reversedEntries), so non-spark columns now sort as equal and user sorting/default sort behavior silently breaks. Preserve the previous sort contract (pass required props) or update the sorter to read the precomputed value prop. [api mismatch]

Severity Level: Critical 🚨
- ❌ TimeTable visualization columns cannot be sorted by value.
- ❌ Default descending sort by latest metric no longer applies.
- ⚠️ Users see inconsistent ordering across reloads and aggregations.
Steps of Reproduction ✅
1. Open the Explore page and select the TimeTable visualization type, which is wired
through VizType.TimeTable (see
superset-frontend/src/explore/components/ControlPanelsContainer.tsx:13-20 where TimeTable
is listed in MATRIXIFY_INCOMPATIBLE_CHARTS, and
superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx:72
where TimeTableChartPlugin is configured with key VizType.TimeTable).

2. Run a query that produces multiple rows and at least one non-spark metric column, so
TimeTable renders; the TimeTable component builds columns with sortType set to
sortNumberWithMixedTypes at
superset-frontend/src/visualizations/TimeTable/TimeTable.tsx:50-76, and memoizedRows at
lines 81-126, where each non-spark column cell is rendered as <ValueCell value={value}
errorMsg={errorMsg} column={columnConfig} /> (lines 107-115).

3. Note that ValueCell’s props, defined in
superset-frontend/src/visualizations/TimeTable/components/ValueCell/ValueCell.tsx:24-28,
only include value, errorMsg, and column; they do not include valueField or
reversedEntries. However, the shared comparator sortNumberWithMixedTypes in
superset-frontend/src/visualizations/TimeTable/utils/sortUtils/sortUtils.ts:57-106
directly inspects cellA.props and cellB.props and expects props with shape { valueField,
column, reversedEntries?, entries? } (see the comments at lines 65-68 and the typed casts
at lines 69-84).

4. When the user clicks a non-spark column header to sort, or when the initialSortBy
default sort is applied (TimeTable.tsx:128-135), react-table calls
sortNumberWithMixedTypes. Because the ValueCell elements in row.values[columnId] lack
valueField and reversedEntries, reversedEntriesA and reversedEntriesB resolve to undefined
(lines 86-89 in sortUtils.ts), triggering the guard at lines 91-93 that returns 0 for any
row pair, so all comparisons areequaland sorting for non-spark columns silently fails
(no change in order despite sort gestures or default sort configuration).

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/visualizations/TimeTable/TimeTable.tsx
**Line:** 110:114
**Comment:**
	*Api Mismatch: The new `ValueCell` props no longer include the metadata that the existing `sortNumberWithMixedTypes` comparator depends on (`valueField`/`reversedEntries`), so non-spark columns now sort as equal and user sorting/default sort behavior silently breaks. Preserve the previous sort contract (pass required props) or update the sorter to read the precomputed `value` prop.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@bito-code-review

bito-code-review Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #a9723b

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: b068321..bbf29f0
    • superset-frontend/src/visualizations/TimeTable/TimeTable.tsx
    • superset-frontend/src/visualizations/TimeTable/components/ValueCell/ValueCell.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@pull-request-size pull-request-size Bot added size/L and removed size/M labels Jul 12, 2026
@RehanIslam09 RehanIslam09 force-pushed the fix-pivot-subvalue-label branch from 79c8ec6 to b068321 Compare July 12, 2026 15:16
@bito-code-review

bito-code-review Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #8fd9f2

Actionable Suggestions - 0
Review Details
  • Files reviewed - 1 · Commit Range: b068321..b068321
    • superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/TableRenderers.tsx
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

explore:design Related to the Explore UI/UX plugins size/XS viz:charts:pivot Related to the Pivot Table charts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rename "Subtotal" to "Subvalue" in Pivot Tables

1 participant