Skip to content

Commit 1ab32c8

Browse files
Display massive user statistic numbers more compactly (#845) (#853)
* 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>
1 parent a2fc240 commit 1ab32c8

File tree

1 file changed

+55
-11
lines changed

1 file changed

+55
-11
lines changed

static/js/main.js

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,23 +1876,67 @@ $(document).ready(function () {
18761876
display_results: function (result) {
18771877
if ("views" in result) {
18781878
$root
1879-
.find(".views .num")
1880-
.html(UserCounts.format(result["views"]));
1879+
.find(".views")
1880+
.attr("title", UserCounts.format(result["views"]) + " views")
1881+
.find(".num")
1882+
.html(UserCounts.formatBrief(result["views"]));
18811883
$root
1882-
.find(".saves .num")
1883-
.html(UserCounts.format(result["saves"]));
1884+
.find(".saves")
1885+
.attr("title", UserCounts.format(result["saves"]) + " saves")
1886+
.find(".num")
1887+
.html(UserCounts.formatBrief(result["saves"]));
18841888
$root
1885-
.find(".likes .num")
1886-
.html(UserCounts.format(result["likes"]));
1889+
.find(".likes")
1890+
.attr("title", UserCounts.format(result["likes"]) + " likes")
1891+
.find(".num")
1892+
.html(UserCounts.formatBrief(result["likes"]));
18871893
}
18881894
},
18891895
format: function (str_num) {
1890-
var rgx = /(\d+)(\d{3})/;
1891-
str_num = "" + str_num;
1892-
while (rgx.test(str_num)) {
1893-
str_num = str_num.replace(rgx, "$1" + "," + "$2");
1896+
return Number.parseInt(str_num).toLocaleString();
1897+
},
1898+
formatBrief: function (str_num) {
1899+
// Format number in a way that won't need excessive space to
1900+
// display. Abbreviate with suffixes and limit to one
1901+
// decimal place.
1902+
1903+
const n = parseInt(str_num, 10);
1904+
1905+
// Handle garbage input (somewhat) gracefully.
1906+
if (Number.isNaN(n)) {
1907+
return '0';
1908+
}
1909+
1910+
// Anything up to and including 9,999 return verbatim as
1911+
// we've got four characters minimum to play with.
1912+
if (n < 10000) {
1913+
return n.toLocaleString();
1914+
}
1915+
1916+
const suffixes = [
1917+
{ threshold: 1e12, suffix: 'T' },
1918+
{ threshold: 1e9, suffix: 'B' },
1919+
{ threshold: 1e6, suffix: 'M' },
1920+
{ threshold: 1e3, suffix: 'K' }
1921+
];
1922+
1923+
for (const { threshold, suffix } of suffixes) {
1924+
// Iterate until we find a suffix that can handle this
1925+
// value.
1926+
if (n >= threshold) {
1927+
// Truncate to 1 decimal place.
1928+
const truncated = Math.floor((n / threshold) * 10) / 10;
1929+
1930+
// If the decimal part is 0 trim it.
1931+
if (truncated % 1 === 0) {
1932+
return truncated.toFixed(0) + suffix;
1933+
} else {
1934+
return truncated.toFixed(1) + suffix;
1935+
}
1936+
}
18941937
}
1895-
return str_num;
1938+
1939+
return n.toLocaleString();
18961940
},
18971941
};
18981942
})();

0 commit comments

Comments
 (0)