feat: implement number precision parameter for stats card (#4514)

* Update short number format 

Update short number format by adding 2 decimal places instead of 1 for numbers between 1,000 and 9,999

* review

* Update src/common/utils.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* dev

* dev

---------

Co-authored-by: Alexandr <qwerty541zxc@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Lucas
2025-10-13 20:21:28 +03:00
committed by GitHub
co-authored by Copilot Alexandr
parent 7caaa21e73
commit 4143c6dec3
7 changed files with 85 additions and 11 deletions
+19 -5
View File
@@ -33,7 +33,8 @@ const RANK_ONLY_CARD_DEFAULT_WIDTH = 290;
* @param {boolean} params.showIcons Whether to show icons.
* @param {number} params.shiftValuePos Number of pixels the value has to be shifted to the right.
* @param {boolean} params.bold Whether to bold the label.
* @param {string} params.number_format The format of numbers on card.
* @param {string} params.numberFormat The format of numbers on card.
* @param {number=} params.numberPrecision The precision of numbers on card.
* @returns {string} The stats card text item SVG object.
*/
const createTextNode = ({
@@ -46,10 +47,17 @@ const createTextNode = ({
showIcons,
shiftValuePos,
bold,
number_format,
numberFormat,
numberPrecision,
}) => {
const precision =
typeof numberPrecision === "number" && !isNaN(numberPrecision)
? clampValue(numberPrecision, 0, 2)
: undefined;
const kValue =
number_format.toLowerCase() === "long" ? value : kFormatter(value);
numberFormat.toLowerCase() === "long" || id === "prs_merged_percentage"
? value
: kFormatter(value, precision);
const staggerDelay = (index + 3) * 150;
const labelOffset = showIcons ? `x="25"` : "";
@@ -251,6 +259,7 @@ const renderStatsCard = (stats, options = {}) => {
border_radius,
border_color,
number_format = "short",
number_precision,
locale,
disable_animations = false,
rank_icon = "default",
@@ -319,7 +328,11 @@ const renderStatsCard = (stats, options = {}) => {
STATS.prs_merged_percentage = {
icon: icons.prs_merged_percentage,
label: i18n.t("statcard.prs-merged-percentage"),
value: mergedPRsPercentage.toFixed(2),
value: mergedPRsPercentage.toFixed(
typeof number_precision === "number" && !isNaN(number_precision)
? clampValue(number_precision, 0, 2)
: 2,
),
id: "prs_merged_percentage",
unitSymbol: "%",
};
@@ -408,7 +421,8 @@ const renderStatsCard = (stats, options = {}) => {
showIcons: show_icons,
shiftValuePos: 79.01 + (isLongLocale ? 50 : 0),
bold: text_bold,
number_format,
numberFormat: number_format,
numberPrecision: number_precision,
});
});
+1
View File
@@ -25,6 +25,7 @@ export type StatCardOptions = CommonOptions & {
custom_title: string;
disable_animations: boolean;
number_format: string;
number_precision: number;
ring_color: string;
text_bold: boolean;
rank_icon: RankIcon;
+15 -5
View File
@@ -77,15 +77,25 @@ const iconWithLabel = (icon, label, testid, iconSize) => {
};
/**
* Retrieves num with suffix k(thousands) precise to 1 decimal if greater than 999.
* Retrieves num with suffix k(thousands) precise to given decimal places.
*
* @param {number} num The number to format.
* @param {number=} precision The number of decimal places to include.
* @returns {string|number} The formatted number.
*/
const kFormatter = (num) => {
return Math.abs(num) > 999
? Math.sign(num) * parseFloat((Math.abs(num) / 1000).toFixed(1)) + "k"
: Math.sign(num) * Math.abs(num);
const kFormatter = (num, precision) => {
const abs = Math.abs(num);
const sign = Math.sign(num);
if (typeof precision === "number" && !isNaN(precision)) {
return (sign * (abs / 1000)).toFixed(precision) + "k";
}
if (abs < 1000) {
return sign * abs;
}
return sign * parseFloat((abs / 1000).toFixed(1)) + "k";
};
/**