Skip to content

feat(stats): try collapsed rendering of large integers (1,123M)#319

Open
Amund211 wants to merge 2 commits into
mainfrom
collapsed-large-integers
Open

feat(stats): try collapsed rendering of large integers (1,123M)#319
Amund211 wants to merge 2 commits into
mainfrom
collapsed-large-integers

Conversation

@Amund211

@Amund211 Amund211 commented Jul 9, 2026

Copy link
Copy Markdown
Owner

What

Tries out "collapsed" rendering of large integers: instead of a long digit string like 1.123.123 (the index stat, 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

formatStatValue gains a notation: "standard" | "collapsed" option (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 + tier suffix (K/M/B/T), keeping the locale's own decimal separator:

value collapsed (detailed / 3dp)
999 999 (below the smallest tier — unchanged)
1_000 1K
45_000 45K
1_123_123 1,123M (nb) / 1.123M (en)
2_500_000 2,5M
2_500_000_000 2,5B
12_000_000_000_000 12T
-1_200_000 -1,2M

Design notes:

  • Latin suffix, not the locale-spelled form. Intl's own compact notation emits 1,1 mill. in nb-NO; we keep a stable K/M/B/T across locales (matching the 1,123M in the ask) while still formatting the mantissa locale-aware.
  • Fraction digits reuse the existing precision option — 2 (compact) / 3 (detailed) — with trailing zeros trimmed, so an exact tier reads as 2M, not 2,00M.
  • Only large magnitudes collapse. Below 1,000, and for percentage-kind stats (a winrate never leaves [0, 1]), the value falls through to the unchanged per-kind formatting — so 42 wins stays 42.

Commits

  1. feat(stats): add collapsed notation to formatStatValue — the notation option + formatCollapsed tier logic, plus a locale-robust format.unit.test.ts.
  2. feat(session,charts): render large stat values in collapsed notation — opts every single-stat scalar render site into notation: "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 compact precision (2dp), a value like 999_999 rounds its mantissa up to 1,000K rather than promoting to 1M. 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.

Page Current (production) Staging (this PR)
Session https://prismoverlay.com/session https://collapsed-large-integers.rainbow-ctx.pages.dev/session
History explorer https://prismoverlay.com/history/explore https://collapsed-large-integers.rainbow-ctx.pages.dev/history/explore

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

Amund211 and others added 2 commits July 9, 2026 19:54
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>
Copilot AI review requested due to automatic review settings July 9, 2026 18:16
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying rainbow with  Cloudflare Pages  Cloudflare Pages

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

View logs

Copilot AI left a comment

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.

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 formatStatValue with notation: "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.

Comment thread src/stats/format.ts
{ 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 = "[.,]";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants