feat(stats): try collapsed rendering of large integers (1,123M)#319
Open
Amund211 wants to merge 2 commits into
Open
feat(stats): try collapsed rendering of large integers (1,123M)#319Amund211 wants to merge 2 commits into
Amund211 wants to merge 2 commits into
Conversation
Large integer stats — chiefly `index` (FKDR^2 * stars), but also
`experience` and lifetime kill/win counts — render as long digit strings
like "1.123.123" that are hard to scan at a glance.
Add a `notation: "standard" | "collapsed"` option to `formatStatValue`
(default "standard", so every existing call is byte-for-byte unchanged).
In "collapsed" notation a magnitude at or above 1,000 is shortened to a
mantissa plus a single-letter tier suffix (K/M/B/T), keeping the locale's
own decimal separator:
1_123_123 -> "1,123M" (nb-NO) / "1.123M" (en-US)
45_000 -> "45K"
2_500_000_000 -> "2,5B"
The suffix is kept Latin rather than the locale-spelled form ("mill.")
that `Intl` compact notation emits, so the shape is stable across locales.
Fraction digits follow the existing `precision` option (2 compact / 3
detailed) with trailing zeros trimmed, so an exact tier reads as "2M".
Values below 1,000 — and percentage-kind stats, which never grow large —
fall through to the unchanged per-kind formatting.
Covered by a new locale-robust `format.unit.test.ts`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Opt every single-stat scalar render site into `notation: "collapsed"` so large values (index above all) stop overflowing as long digit strings: - session detail: the stat-card value, its start->end tooltip and diff, the sessions table cells, and the progression value + milestone - history charts: both the multi-line and simple-chart tooltips Each of these renders one known stat, so the collapse is unambiguous. The shared multi-line Y-axis is left untouched -- it can plot several stats at once, so there is no single format kind to collapse against. Small stats are unaffected (collapsing only kicks in at >= 1,000), and percentage stats never collapse. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying rainbow with
|
| Latest commit: |
4f23e6d
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://712e8a14.rainbow-ctx.pages.dev |
| Branch Preview URL: | https://collapsed-large-integers.rainbow-ctx.pages.dev |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an optional “collapsed” rendering mode to the central stat formatter so large magnitudes can be displayed as a locale-aware mantissa plus a stable Latin suffix (K/M/B/T) (e.g. 1,123M / 1.123M), and opts key single-stat UI surfaces into using it.
Changes:
- Extended
formatStatValuewithnotation: "standard" | "collapsed"and implemented tier-based collapsing for values ≥ 1,000 (excluding percentage-kind stats). - Added unit coverage for collapsed tiering, precision differences, sign handling, and “standard” notation invariants.
- Updated session and history chart tooltip/value rendering call sites to request
notation: "collapsed".
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/stats/format.ts | Implements collapsed K/M/B/T notation as a new formatStatValue option and gates it by magnitude/kind. |
| src/stats/format.unit.test.ts | Adds unit tests covering collapsed formatting behavior and ensures standard formatting remains unchanged. |
| src/routes/session/$uuid.tsx | Switches several session-page stat renders (cards/tooltips/table/progression value) to collapsed notation. |
| src/charts/history/chart.tsx | Switches history chart tooltip value formatting to collapsed notation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| { threshold: 1e3, suffix: "K" }, | ||
| ] as const; | ||
|
|
||
| const SMALLEST_COLLAPSE_TIER = 1e3; |
Comment on lines
+6
to
+10
| // is environment-dependent (a comma in nb-NO, a dot in en-US). Assertions that | ||
| // span the separator therefore accept either character instead of hard-coding | ||
| // one, while the collapse logic under test (tier selection, suffix, threshold | ||
| // gating, sign handling) is locale-independent. | ||
| const sep = "[.,]"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Tries out "collapsed" rendering of large integers: instead of a long digit string like
1.123.123(theindexstat, in a comma-grouping locale), large stat values render as a mantissa + a single-letter magnitude suffix —1,123M(nb-NO) /1.123M(en-US).Built as an extension to the central
formatStatValue(the formatter introduced in #316), so it slots in as a new option rather than a new code path per call site.How it works
formatStatValuegains anotation: "standard" | "collapsed"option (default"standard", so every existing call is byte-for-byte unchanged). In"collapsed"notation, a magnitude at or above1,000is shortened to a mantissa + tier suffix (K/M/B/T), keeping the locale's own decimal separator:999999(below the smallest tier — unchanged)1_0001K45_00045K1_123_1231,123M(nb) /1.123M(en)2_500_0002,5M2_500_000_0002,5B12_000_000_000_00012T-1_200_000-1,2MDesign notes:
Intl's own compact notation emits1,1 mill.innb-NO; we keep a stableK/M/B/Tacross locales (matching the1,123Min the ask) while still formatting the mantissa locale-aware.precisionoption — 2 (compact) / 3 (detailed) — with trailing zeros trimmed, so an exact tier reads as2M, not2,00M.1,000, and for percentage-kind stats (a winrate never leaves[0, 1]), the value falls through to the unchanged per-kind formatting — so42 winsstays42.Commits
feat(stats): add collapsed notation to formatStatValue— thenotationoption +formatCollapsedtier logic, plus a locale-robustformat.unit.test.ts.feat(session,charts): render large stat values in collapsed notation— opts every single-stat scalar render site intonotation: "collapsed": the session-detail stat-card value / start→end tooltip / diff, the sessions table, the progression value + milestone, and both history-chart tooltips. The shared multi-line Y-axis is left untouched (it can plot several stats at once, so there is no single format kind to collapse against).Known rough edge
At
compactprecision (2dp), a value like999_999rounds its mantissa up to1,000Krather than promoting to1M. It's a narrow band just under each tier boundary and only at 2dp; left as-is for this "try it out" pass.Preview
Search a player with a big Index (
FKDR² × stars), then compare against production. The collapse shows up on the stat-card value, the sessions table, the progression row, and chart tooltips.Staging is the Cloudflare Pages branch preview for
collapsed-large-integers(tracks the branch head).Test plan
pnpm tsc(app) +pnpm tsc:node(tests) — clean.pnpm lint:check— clean (oxfmt + oxlint).pnpm test:unit— 790 pass (incl. the new collapsed-notation cases: tier selection, threshold gating, sign/negatives, precision fraction digits, percentage never collapsing, and standard notation unchanged).pnpm test:ui— 201 pass (session detail + history explore render sites unaffected).🤖 Generated with Claude Code