Fix: Group By on ratio charts#2538
Conversation
🦋 Changeset detectedLatest commit: ae5cd2e The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🟡 Tier 3 — StandardIntroduces new logic, modifies core functionality, or touches areas with non-trivial risk. Why this tier:
Review process: Full human review — logic, architecture, edge cases. Stats
|
Greptile SummaryThis PR fixes Group By support for ratio charts and metric autocomplete. The main changes are:
Confidence Score: 5/5This looks safe to merge.
Important Files Changed
Reviews (9): Last reviewed commit: "Merge branch 'main' into jordansimonovsk..." | Re-trigger Greptile |
E2E Test Results✅ All tests passed • 222 passed • 3 skipped • 1516s
Tests ran across 4 shards in parallel. |
Deep Review✅ No critical issues found. The grouped-ratio fix is well-constructed and the core correctness risk is contained. The merge now keys grouped rows by 🟡 P2 -- recommended
🔵 P3 nitpicks (4)
Reviewers (7): correctness, adversarial, testing, maintainability, kieran-typescript, performance, project-standards. Testing gaps: hook-level coverage for the |
|
Closes HDX-2555 |
| const _meta = resultSet.meta; | ||
| export const computeResultSetRatio = ( | ||
| resultSet: ResponseJSON<any>, | ||
| operands?: { numeratorName: string; denominatorName: string }, |
There was a problem hiding this comment.
Do we need the optional here if the only caller is always passing the operator? Or is there an expected use-case in the near future which needs the inference behavior?
| // Share-of-total semantics: each group's denominator is the total of the | ||
| // denominator column across ALL groups in the same time bucket. So a grouped | ||
| // ratio shows each group's contribution to the overall ratio (the lines sum | ||
| // to the ungrouped value) rather than each group's own in-group rate. With no | ||
| // grouping there's one row per bucket, so the bucket total equals that row's | ||
| // denominator and the result is unchanged. |
There was a problem hiding this comment.
I'm curious why these semantics were chosen. My initial instinct would have been to apply the ratio within-group, for use-cases where for example you want a per-service error %. What is the motivation for this behavior instead?
There was a problem hiding this comment.
For some of the use cases I was testing, I kind of wanted to determine a share of total, though you make a good point about something like error rate per service. That's an oversight by me! I'm going to toggle this behaviour
There was a problem hiding this comment.
Added a ratioMode config field with two values:
per_group (default):each group divided by its own denominator. A per-service error %, which is what you'd expect. service: errors / totalshare_of_total (opt-in):each group's numerator over the per-bucket total across all groups, so the lines decompose the blended rate and sum to the ungrouped value. I find this particularly useful to see how much of a total error rate would be comprised by which service.
The default is per_group, so we're not imposing the share of total interpretation. In the editor it surfaces as a "Share of total" switch that only appears when you have a ratio and a Group By.
… ratios Grouped ratios had a single baked-in interpretation (share-of-total). Add a `ratioMode` config field so users pick the semantic: - per_group (default): each group divided by its own denominator (per-service error %), the intuitive "group by a ratio" meaning - share_of_total: each group's numerator over the per-bucket total across all groups, so the lines decompose the blended rate and sum to the ungrouped value Surfaces as a "Share of total" switch in the chart editor, shown only for a grouped ratio (no-op otherwise). Ungrouped ratios are identical under both modes, so no behavior change for existing charts. Also make `computeResultSetRatio`'s `operands` required and drop the numeric- column inference fallback — the only caller always passes operands explicitly; tests updated to match.
| {fields.length === 2 && | ||
| seriesReturnType === 'ratio' && | ||
| hasGroupBy && ( | ||
| <Switch |
There was a problem hiding this comment.
Having the option is nice, but this seems to have no effect for non-metric type sources (since for those sources, we calculate the ratio within-group only, in the database, see renderSelectList in renderChartConfig)
Problem
Ratio charts (As Ratio) couldn't be meaningfully grouped:
Root cause
Ratio runs the numerator and denominator as two separate queries and merges them. Two bugs:
Separately, metric sources have no single from.tableName (they fan out to per-type tables),input had no table to fetch attribute keys from.
Changes
packages/common-utils/src/clickhouse/index.ts
packages/app/src/components/DBEditTimeChartForm/ChartEditorControls.tsx
typing on metric ratio/multi-series charts — matching the per-series inputs. Non-metric sou
Why share-of-total
"Group by" applied to a ratio has two plausible meanings: each group's own rate (per-group)n to the overall rate (share-of-total). We chose share-of-total so a grouped error-rate
decomposes the blended rate — the lines add up to the number you see ungrouped — which matcdown the 22% by tenant" chart. (Per-group rates are still available by not using ratio mode,or via a future toggle if needed.)
Testing
Scope
Only affects metric ratio charts — the only config path that splits into the merge/ratio coatio or non-metric charts.