Skip to content

Display massive user statistic numbers more compactly#845

Merged
bradchoate merged 5 commits intoMLTSHP:xxl-stats-formattingfrom
smallsaucepan:xxl-stats-formatting
Sep 1, 2025
Merged

Display massive user statistic numbers more compactly#845
bradchoate merged 5 commits intoMLTSHP:xxl-stats-formattingfrom
smallsaucepan:xxl-stats-formatting

Conversation

@smallsaucepan
Copy link
Contributor

Changed user statistic presentation to format larger numbers in abbreviated formats to avoid overflowing the allocated screen space.

*slaps roof of car* this bad boy can display from 0 to 999 trillion without breaking a sweat.

Before and afters:

xxl-stats-1 xxl-stats-2

Exact value displayed as tooltip:

xxl-stats-3

Fixes #223

Will add a task in patterns to tidy up the layout.

…viated formats to avoid overflowing the allocated screen space.
@bradchoate
Copy link
Collaborator

Assigned @spaceninja for design related review.

It's an interesting problem to tackle. I like the approach and clean nature of the succinct numbers but I'm a long way from those metrics. Those with > 1 million on a given stat are going to see that same number for a while before it advances, which is a little undesirable.

Another possibility is to display more significant digits. If we have 6 digits available, instead of cutting off to "1M", it could be "123,456K" (I think anyone at this scale wouldn't miss the last 3 digits that much; and would still be visible via tooltip). Using Art Wells as a reference:

image

Another possibility for power MLTSHPers is to display their big numbers in rows instead of columns.

image

But whichever approach we take, I'd prefer to leave the Python side alone; it's returning the raw numbers. The front-end can reshape those as needed for the client display (that is, in Javascript). That also allows us to use things like number.toLocaleString() for locale-appropriate formatting suited for the reader.

@spaceninja
Copy link
Member

spaceninja commented Aug 22, 2025

I'm quite happy with the design change, but @bradchoate makes some excellent points. I'll post this PR on Slack to get some community insight into the change.

Also, I have no problem with the idea that we should do this on the front-end, rather than in Python. In general, I try to avoid burdening MLTSHP with much JS, but this feels like a reasonable and small-scoped change that shouldn't hurt performance.

Once we have a sense of community feeling around the design change, we can take it to the pattern library. Leaving this ticket open until then, as a focal point for the discussion.

@jessamynwest
Copy link
Contributor

I'm fine with any idea honestly but I do like how some social media sites handle this where they show the abbreviated number in the display BUT you can get the full number by hovering. So on Mastodon, it shows I have 9.2K followers but hovering shows the exact number. I'm not savvy enough to get a screenshot but you get the idea.

@foofoo
Copy link

foofoo commented Aug 22, 2025

If it is decided to implement, don't mess with the python, I agree with @bradchoate that this should be handled in the front end.

…ing in the browser instead.

This reverts commit 1331d72.
…priovide more precision. Also took the opportunity to leverage built in toLocaleString for tooltip display value.
@bradchoate
Copy link
Collaborator

Here are some test cases (input, expected output):

[
  ["0", "0"],
  ["1", "1"],
  ["12", "12"],
  ["123", "123"],
  ["1234", "1,234"],
  ["1235", "1,235"],
  ["1239", "1,239"],
  ["10004", "10K"],
  ["10500", "10.5K"],
  ["10580", "10.58K"],
  ["10588", "10.58K"],
  ["10030", "10.03K"],
  ["12341", "12.34K"],
  ["12345", "12.34K"],
  ["12348", "12.34K"],
  ["123000", "123K"],
  ["123456", "123.4K"],
  ["1234000", "1.234M"],
  ["1234567", "1.234M"],
  ["12345678", "12.34M"],
  ["123456789", "123.4M"],
  ["1234267890", "1.234B"],
  ["1234567891", "1.234B"],
  ["12342678901", "12.34B"],
  ["12349678901", "12.34B"],
  ["123426789012", "123.4B"],
  ["123496789012", "123.4B"],
  ["1234267890123", "1.234T"],
  ["1234967890123", "1.234T"],
  ["12342678901234", "12.34T"],
  ["12349678901234", "12.34T"],
  ["123426789012345", "123.4T"],
  ["123496789012345", "123.4T"]
]

From this set, there are failures for "0", "1234", "1235", "1239", and "10030".

For those middle cases, I think "1,234" reads better than "1.234K". The function should try to squeeze the number into a six character string, and "1,234" doesn't need to be reduced... adding the suffix makes it longer and less readable.

You might consider conditioning the abbreviation logic for cases where the number is only >= 10_000.

I would also suggest deriving magnitude based on the input string length which is always going to be a base-10 unsigned integer.

@bradchoate
Copy link
Collaborator

You might even limit abbreviation for views in particular where n >= 100_000 since we have a wider space for view count. We have space to show "100,000" there instead of shortening it to "100K". This would just be a variation for views... saves and likes should probably be shortened for n >= 10_000 since the space for those is smaller.

Also, @spaceninja suggests that we keep to integers since it's cleaner and we are showing full numbers via tooltip. If you want to target that approach, here's a new test suite, expectations:

[
  ["0", "0"],
  ["1", "1"],
  ["12", "12"],
  ["123", "123"],
  ["1234", "1,234"],
  ["1235", "1,235"],
  ["1239", "1,239"],
  ["10004", "10K"],
  ["10500", "10K"],
  ["10580", "10K"],
  ["10588", "10K"],
  ["10030", "10K"],
  ["12341", "12K"],
  ["12345", "12K"],
  ["12348", "12K"],
  ["123000", "123K"],
  ["123456", "123K"],
  ["1234000", "1M"],
  ["1234567", "1M"],
  ["12345678", "12M"],
  ["123456789", "123M"],
  ["1234267890", "1B"],
  ["1234567891", "1B"],
  ["12342678901", "12B"],
  ["12349678901", "12B"],
  ["123426789012", "123B"],
  ["123496789012", "123B"],
  ["1234267890123", "1T"],
  ["1234967890123", "1T"],
  ["12342678901234", "12T"],
  ["12349678901234", "12T"],
  ["123426789012345", "123T"],
  ["123496789012345", "123T"]
]

...if we do want to preserve full numbers for views below 1 million, the "K" expected results would instead be the input number passed through toLocaleString (ie, "123456" => "123,456").

@jessamynwest
Copy link
Contributor

I like the idea of abbreviation logic only for a set of large numbers whether it's six characters or five.

@smallsaucepan
Copy link
Contributor Author

Have proposed a simple 1 decimal place approach for numbers larger than 9,999 to Slack. Will wait to see what the response to that is, and go from there.

Thanks for the test cases @bradchoate

…suffixes and truncated to 1 decimal place max. Anything below 10,000 is returned verbatim as a localised string.
@smallsaucepan
Copy link
Contributor Author

Have updated as discussed (truncate to 1 decimal place once past 9,999). Stuck with a maths-y suffix determination, rather than string length just in case one day we accidentally feed it "undefined" or "SQL error 654321".

Not sure extra space / different rules for "views" is something we should accomodate. A consistent layout and approach likely to be more parseable.

@spaceninja
Copy link
Member

Not sure extra space / different rules for "views" is something we should accomodate. A consistent layout and approach likely to be more parseable.

Once this is merged, we won't need the views box to be larger anymore. There's a pattern library issue to fix the spacing.

Copy link
Member

@spaceninja spaceninja left a comment

Choose a reason for hiding this comment

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

This looks good to me — I'll defer final approval to @bradchoate

Copy link
Collaborator

@bradchoate bradchoate left a comment

Choose a reason for hiding this comment

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

Looks good and best performance so far!

@bradchoate bradchoate changed the base branch from master to xxl-stats-formatting September 1, 2025 15:58
@bradchoate bradchoate merged commit 6759489 into MLTSHP:xxl-stats-formatting Sep 1, 2025
5 checks passed
bradchoate added a commit that referenced this pull request Sep 1, 2025
* Changed user statistic presentation to format larger numbers in abbreviated formats to avoid overflowing the allocated screen space.

* Revert server side approach, and perform any calculations and formatting in the browser instead.

This reverts commit 1331d72.

* Implemented formatting on the client, incorporating user feedback to priovide more precision. Also took the opportunity to leverage built in toLocaleString for tooltip display value.

* Based on feedback, have adjusted to display anything >= 10,000 using suffixes and truncated to 1 decimal place max. Anything below 10,000 is returned verbatim as a localised string.

Co-authored-by: James Beard <james@smallsaucepan.com>
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.

Stats panel should accommodate large numbers better

5 participants