Skip to content

fix(dashboards): match the number-tile background sparkline to the displayed value#2501

Merged
kodiakhq[bot] merged 2 commits into
mainfrom
alex/HDX-1360-number-tile-sparkline-groupby
Jun 24, 2026
Merged

fix(dashboards): match the number-tile background sparkline to the displayed value#2501
kodiakhq[bot] merged 2 commits into
mainfrom
alex/HDX-1360-number-tile-sparkline-groupby

Conversation

@alex-fedotyev

Copy link
Copy Markdown
Contributor

Follow-up to #2489. The background trend sparkline that #2489 added to number tiles can plot the wrong data when a tile carries a leftover groupBy.

Summary

The big number on a number tile is a single aggregate: convertToNumberChartConfig strips groupBy from its query. The background sparkline builds its own query from the tile config but kept groupBy, so a tile that still carried one queried multiple series and the renderer plotted only the first. The faint trend behind the value then belonged to a single group while the value itself aggregated every group.

A residual groupBy is reachable in normal use: switching a grouped Line chart to the Number display type only hides the group-by input, it does not clear the value, so a saved Number tile can still carry it.

The fix extracts the sparkline's query derivation into a small pure helper, buildSparklineTimeConfig, and drops groupBy there, mirroring the value query's strip. granularity is still kept (defaulting to auto) so the trend stays bucketed. There is no visual or layout change: the sparkline renders exactly as before, it just plots the same single series as the value it sits behind.

Changes

  • Extract buildSparklineTimeConfig(config) from the inline useMemo in NumberTileBackgroundChart and strip groupBy alongside the existing display-only fields.
  • Add a render test that asserts the issued query has no groupBy, plus unit tests for the helper.
  • Patch changeset.

Test plan

  • nx run @hyperdx/app:ci:lint (lint + tsc)
  • nx run @hyperdx/app:ci:unit (2069 passed, 0 failures)
  • New render test mounts NumberTileBackgroundChart with a tile that has a residual groupBy and asserts the config passed to useQueriedChartConfig drops it, exercising the real buildSparklineTimeConfig then convertToTimeChartConfig path rather than the helper in isolation.

[ui-check: allow] Data-correctness fix: it changes which series the sparkline queries, not how anything is drawn. There is no visual, layout, color, or state surface to capture, and the new render test proves the issued query is correct.
[viewport: allow] No layout change.

…query

The big number on a number tile is a single aggregate
(`convertToNumberChartConfig` drops `groupBy`), but the background
sparkline kept any `groupBy` the tile carried over from a prior Line
display type. It then plotted only the first group's trend behind a
value that aggregates every group.

Extract the sparkline's query derivation into a pure
`buildSparklineTimeConfig` helper and drop `groupBy` there, mirroring
the value query's strip, so the trend reflects the same single series
as the value it sits behind.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 281e7d2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@hyperdx/app Patch
@hyperdx/api Patch
@hyperdx/otel-collector Patch

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

@vercel

vercel Bot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview, Comment Jun 24, 2026 5:42pm
hyperdx-storybook Ready Ready Preview, Comment Jun 24, 2026 5:42pm

Request Review

@github-actions github-actions Bot added the review/tier-2 Low risk — AI review + quick human skim label Jun 23, 2026
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

🔵 Tier 2 — Low Risk

Small, isolated change with no API route or data model modifications.

Why this tier:

  • Standard feature/fix — introduces new logic or modifies core functionality

Review process: AI review + quick human skim (target: 5–15 min). Reviewer validates AI assessment and checks for domain-specific concerns.
SLA: Resolve within 4 business hours.

Stats
  • Production files changed: 1
  • Production lines changed: 61 (+ 97 in test files, excluded from tier calculation)
  • Branch: alex/HDX-1360-number-tile-sparkline-groupby
  • Author: alex-fedotyev

To override this classification, remove the review/tier-2 label and apply a different review/tier-* label. Manual overrides are preserved on subsequent pushes.

@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a data-correctness bug in the NumberTileBackgroundChart sparkline: when a number tile carried a residual groupBy (left over from a prior Line display), the sparkline queried multiple series and plotted only the first, while the displayed aggregate value covered all groups. The fix extracts a buildSparklineTimeConfig helper that mirrors what convertToNumberChartConfig already does — stripping groupBy — so the sparkline always plots the same single series as the number it sits behind.

  • Extracts buildSparklineTimeConfig from the inline useMemo in NumberTileBackgroundChartInner, adding delete timeConfig.groupBy guarded by isBuilderChartConfig, while keeping granularity so the trend remains time-bucketed.
  • Adds unit tests for the helper (drop of groupBy, display-only fields, and granularity defaulting) plus a render test that mounts the component with a residual groupBy and asserts the issued query (useQueriedChartConfig call) has no groupBy, exercising the full buildSparklineTimeConfig → convertToTimeChartConfig pipeline.

Confidence Score: 5/5

Safe to merge — the change is a targeted query-shape correction with no effect on rendering, layout, or other tile types.

The fix is minimal and surgical: one new helper function, a one-line replacement of the existing useMemo body, and tests that exercise both the helper in isolation and the full component pipeline. The isBuilderChartConfig guard correctly limits the delete to configs that actually carry groupBy, and the outer component already gates on the same guard so the inner path will always be a builder config in practice. No regressions to other tile types are possible.

No files require special attention.

Important Files Changed

Filename Overview
packages/app/src/components/NumberTileBackgroundChart.tsx Extracts buildSparklineTimeConfig helper that correctly strips groupBy (and display-only fields) before building the sparkline query; the useMemo is reduced to a one-liner delegating to the helper. Logic is sound and mirrors the existing number-value query path.
packages/app/src/components/tests/NumberTileBackgroundChart.test.tsx Adds unit tests for buildSparklineTimeConfig covering the groupBy drop, display-field strip, granularity default, and a render-level integration test verifying the full pipeline issues a query without groupBy. Test coverage is thorough and appropriate.
.changeset/number-tile-sparkline-groupby.md Patch-level changeset for @hyperdx/app; description accurately reflects the bug and fix.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[NumberTileBackgroundChart\nreceives config with possible residual groupBy] -->|isBuilderChartConfig check| B[NumberTileBackgroundChartInner]
    B --> C["buildSparklineTimeConfig(config)"]
    C --> D[Strip display-only fields\nbackgroundChart / color / colorRules / numberFormat]
    D --> E[Set displayType = Line\ngranularity = config.granularity ?? 'auto']
    E --> F{isBuilderChartConfig?}
    F -->|yes| G[delete timeConfig.groupBy]
    F -->|no| H[no groupBy to remove]
    G --> I[timeConfig: single-series query shape]
    H --> I
    I --> J["convertToTimeChartConfig(timeConfig)"]
    J --> K["useQueriedChartConfig(queriedConfig)"]
    K --> L[Single-series data matches\nnumber tile aggregate value]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[NumberTileBackgroundChart\nreceives config with possible residual groupBy] -->|isBuilderChartConfig check| B[NumberTileBackgroundChartInner]
    B --> C["buildSparklineTimeConfig(config)"]
    C --> D[Strip display-only fields\nbackgroundChart / color / colorRules / numberFormat]
    D --> E[Set displayType = Line\ngranularity = config.granularity ?? 'auto']
    E --> F{isBuilderChartConfig?}
    F -->|yes| G[delete timeConfig.groupBy]
    F -->|no| H[no groupBy to remove]
    G --> I[timeConfig: single-series query shape]
    H --> I
    I --> J["convertToTimeChartConfig(timeConfig)"]
    J --> K["useQueriedChartConfig(queriedConfig)"]
    K --> L[Single-series data matches\nnumber tile aggregate value]
Loading

Reviews (2): Last reviewed commit: "Merge branch 'main' into alex/HDX-1360-n..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

E2E Test Results

All tests passed • 216 passed • 3 skipped • 1544s

Status Count
✅ Passed 216
❌ Failed 0
⚠️ Flaky 6
⏭️ Skipped 3

Tests ran across 4 shards in parallel.

View full report →

@alex-fedotyev alex-fedotyev self-assigned this Jun 23, 2026
@alex-fedotyev alex-fedotyev requested review from a team and teeohhem and removed request for a team June 23, 2026 03:15
@kodiakhq

kodiakhq Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

This PR currently has a merge conflict. Please resolve this and then re-add the automerge label.

@kodiakhq kodiakhq Bot removed the automerge label Jun 24, 2026
@teeohhem

Copy link
Copy Markdown
Contributor

@alex-fedotyev mind resolving the merge conflict please? Thanks!

Resolve conflict in NumberTileBackgroundChart.test.tsx: keep the
expanded import set the render and helper tests need, and adopt the
path-alias import (@/components/...) that #2506 now requires in place
of the relative path.
@alex-fedotyev

Copy link
Copy Markdown
Contributor Author

@teeohhem done, merged main in. The only conflict was the sparkline test's import block: #2506 moved the repo onto path aliases, so I kept the imports the new tests need and switched them to @/components/NumberTileBackgroundChart. Lint and unit pass locally.

@kodiakhq kodiakhq Bot merged commit a258fcf into main Jun 24, 2026
20 checks passed
@kodiakhq kodiakhq Bot deleted the alex/HDX-1360-number-tile-sparkline-groupby branch June 24, 2026 21:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automerge review/tier-2 Low risk — AI review + quick human skim

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants