Skip to content

fix(dashboards): Support multiple aggregates and equations in categorical bar charts#108071

Merged
gggritso merged 21 commits intomasterfrom
georgegritsouk/dain-1201-fix-equation-support-in-categorical-bar-charts
Feb 25, 2026
Merged

fix(dashboards): Support multiple aggregates and equations in categorical bar charts#108071
gggritso merged 21 commits intomasterfrom
georgegritsouk/dain-1201-fix-equation-support-in-categorical-bar-charts

Conversation

@gggritso
Copy link
Member

@gggritso gggritso commented Feb 11, 2026

Categorical bar charts previously limited users to a single aggregate, which made equations impossible on the Errors dataset (where equations require their underlying aggregate to be selected and the equation). Also, switching to a categorical bar from a time series chart would silently drop all but the first aggregate, which is annoying.

This PR adopts the Big Number pattern: users can add multiple aggregates and equations, then select which one to plot via radio buttons. When only one aggregate exists, no radio buttons appear. This way, when users change back/forth between datasets and widget types, we don't drop any data.

There is added complexity now though, because the different actions might invalidate state (e.g., changing the selected aggregate might have to force change the sort). There were some stale closure issues in the reduces, so I ended up adding a new action dispatch for deleting an aggregate, which will now fall back to the correct aggregate where needed.

Screenshot 2026-02-13 at 12 05 07 PM

Fixes DAIN-1201

Categorical bar charts did not properly handle equations (e.g.,
`count(span.duration) / 5`). Equations were filtered out of the
Visualize section, sort used the wrong format (`equation|...` instead
of `equation[0]`), and changing the X-axis dropped equations from
state causing server errors.

- Include FieldValueKind.EQUATION in the Visualize section filter
- Use equation[0] alias format for sort (matching getTableSortOptions)
- Preserve equations in SET_CATEGORICAL_X_AXIS aggregate filter
- Validate equation alias sorts when X-axis changes

Refs DAIN-1201
Co-Authored-By: Claude <noreply@anthropic.com>
@linear
Copy link

linear bot commented Feb 11, 2026

@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Feb 11, 2026
@gggritso gggritso changed the title Add equation support to categorical bar charts fix(dashboards): Add equation support to categorical bar charts Feb 11, 2026
@gggritso gggritso marked this pull request as ready for review February 11, 2026 21:23
@gggritso gggritso requested a review from a team as a code owner February 11, 2026 21:23
…ical bar charts

Categorical bar charts previously limited users to a single aggregate,
which made equations impossible on the Errors dataset (where equations
require their underlying aggregate to coexist). This adopts the Big
Number pattern: users can add multiple aggregates/equations and select
which one to plot via radio buttons. The chart, sort, and display type
switching all respect the selection.

Fixes DAIN-1201
@gggritso gggritso changed the title fix(dashboards): Add equation support to categorical bar charts fix(dashboards): Support multiple aggregates and equations in categorical bar charts Feb 12, 2026
… aggregates

When deleting an aggregate before the selected one, the index now
decrements to keep pointing at the same aggregate. When deleting the
selected item itself, the index resets to undefined (defaults to last).
Previously only the last-item deletion was handled, leaving a stale
index that could go out of bounds.
…elete index check

Two fixes from automated review:

1. convertBuilderStateToWidget: The defaultSort fallback for categorical
   bar used the raw equation|... string format. The API expects the
   equation[N] alias format. Now computes the correct alias index.

2. visualize/index: The delete handler used >= which also caught
   deletions after the selected aggregate, incorrectly resetting the
   radio. Changed to === so only deleting the selected item resets it.
…ional

SET_CATEGORICAL_AGGREGATE previously recomputed sort unconditionally
using selectedAggregate from the closure, which could be stale during
deletions (dispatch order: SET_CATEGORICAL_AGGREGATE runs before
SET_SELECTED_AGGREGATE updates the index).

Now only recomputes sort when the current sort field is no longer
present in the new aggregates, matching how SET_FIELDS works for
tables. This avoids the stale-index problem entirely.
…ata lookup

Two fixes:

1. Sort validation now checks the specific equation[N] index against
   the equation count, not just whether any equation exists. Prevents
   stale equation[1] sort when only equation[0] remains after deletion.
   Applies to both SET_CATEGORICAL_AGGREGATE and SET_CATEGORICAL_X_AXIS.

2. Chart rendering now converts raw equation|... aggregates to their
   equation[N] alias before passing to transformTableToCategoricalSeries,
   since the events API returns data under alias keys.
…ge cases

Document the equation alias index computation pattern, stale closure
avoidance in SET_CATEGORICAL_AGGREGATE, equation index bounds validation,
and the three-way delete handler logic.
…ton visibility

When switching the categorical bar radio selection, update the sort to
match so bars are ordered by the displayed metric. Also remove the
enableEquations gate from the delete button for categorical bar, since
multiple aggregates can come from display type switching even when
equations are disabled for the dataset.
If the selectedAggregate URL param is stale (e.g. from a bookmark after
aggregates were removed), clamp it to the valid range so the chart
renders the last aggregate instead of falling back to showing all.
…GATE

The time series branch of DELETE_AGGREGATE was missing sort-fixup
logic that SET_Y_AXIS applies: clearing sort when no grouping fields
exist, and resetting stale TraceMetrics sort targets.
Copy link
Member

@narsaynorath narsaynorath left a comment

Choose a reason for hiding this comment

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

Just pointed out two things I think we should consider changing (the stuff around valid sorts and resetting), and some clarification things around text copy (low priority) and possibly moving off equation[X] in the future. Otherwise the code looks good, thanks for naming some of the operations like fixing the sort for tables and categorical charts

We also talked about the behaviour when adding an equation causes the chart to not show data. Likely caused by some of the filtering that we do by filtering out an empty equation from our query, so the selected aggregate look up returns nothing for the chart to plot, throwing the error

@narsaynorath
Copy link
Member

Oh, one more thing, I noticed that the tooltip label for categorical bar charts renders the series name with the equation| prefix, I suppose we can fix that by using a formatter for dashboards, or possibly baking common prefix prettifying operations like this into base chart tooltips

Screenshot 2026-02-20 at 2 37 05 PM

- Move categorical bar sort sync from radio onChange into
  SET_SELECTED_AGGREGATE reducer (eliminates two-dispatch pattern)
- Refactor fixupCategoricalBarSort and fixupTableSortOnRemoval to
  return Sort[] | null instead of calling setSort internally
- Accept xAxisFields in fixupCategoricalBarSort so sorting by the
  X-axis column is treated as valid
- Pass old sort index as fallbackIndex in SET_CATEGORICAL_AGGREGATE
  so sort follows in-place aggregate edits
- Filter empty equations from aggregates in convertBuilderStateToWidget
  to prevent "no plottable values" error when adding a new equation
…egate index

- Include DisplayType.TOP_N in DELETE_AGGREGATE time-series branch
  so it correctly deletes from yAxis instead of falling through to
  the table branch
- Clamp getSelectedAggregateIndex to aggregateCount-1 to prevent
  out-of-bounds access when empty equations are filtered from aggregates
Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

…branch

Clamp fallbackIndex once at the top of fixupCategoricalBarSort so both
the invalid-sort and no-sort branches use a safe index. Previously the
no-sort branch passed fallbackIndex directly to generateSortField,
which could crash on out-of-bounds access with a stale selectedAggregate.
@gggritso
Copy link
Member Author

@narsaynorath thanks for taking a look! I ended up asking Claude to make a detailed test plan, and went through it. I think we should be good to go!

categorical-bar-test-plan.md

…display

The raw `equation|` prefix was showing in chart tooltips and legends
for categorical bar widgets using equations. Strip it in
formatCategoricalSeriesLabel, the latest display-only formatting point.
@gggritso
Copy link
Member Author

@narsaynorath right on thanks! I fixed the equation| prefix, and I think we got all the edge cases you found. I'm going to leave the "metrics" tooltip string for now since I don't think there's a much better alternative! equation[0] would be a nice fix in a follow-up too 👍🏻

@gggritso gggritso merged commit 4199c6a into master Feb 25, 2026
63 checks passed
@gggritso gggritso deleted the georgegritsouk/dain-1201-fix-equation-support-in-categorical-bar-charts branch February 25, 2026 17:15
@github-actions github-actions bot locked and limited conversation to collaborators Mar 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants