Add scaled number formatter for K/M/B values
This commit is contained in:
@@ -7,6 +7,63 @@ export function asNumber(value: string | number | null | undefined) {
|
||||
return Number.isFinite(parsed) ? parsed : 0;
|
||||
}
|
||||
|
||||
type NumberScale = {
|
||||
divisor: number;
|
||||
suffix: string;
|
||||
};
|
||||
|
||||
const NUMBER_SCALES: NumberScale[] = [
|
||||
{ divisor: 1, suffix: '' },
|
||||
{ divisor: 1_000, suffix: 'K' },
|
||||
{ divisor: 1_000_000, suffix: 'M' },
|
||||
{ divisor: 1_000_000_000, suffix: 'B' }
|
||||
];
|
||||
|
||||
type FormatScaledNumberOptions = {
|
||||
minimumFractionDigits?: number;
|
||||
maximumFractionDigits?: number;
|
||||
};
|
||||
|
||||
export function formatScaledNumber(
|
||||
value: string | number | null | undefined,
|
||||
options: FormatScaledNumberOptions = {}
|
||||
) {
|
||||
const {
|
||||
minimumFractionDigits = 0,
|
||||
maximumFractionDigits = 1
|
||||
} = options;
|
||||
|
||||
const numeric = asNumber(value);
|
||||
const absolute = Math.abs(numeric);
|
||||
|
||||
let scaleIndex = 0;
|
||||
if (absolute >= 1_000_000_000) {
|
||||
scaleIndex = 3;
|
||||
} else if (absolute >= 1_000_000) {
|
||||
scaleIndex = 2;
|
||||
} else if (absolute >= 1_000) {
|
||||
scaleIndex = 1;
|
||||
}
|
||||
|
||||
let scaledAbsolute = absolute / NUMBER_SCALES[scaleIndex].divisor;
|
||||
|
||||
if (
|
||||
Number(scaledAbsolute.toFixed(maximumFractionDigits)) >= 1_000
|
||||
&& scaleIndex < NUMBER_SCALES.length - 1
|
||||
) {
|
||||
scaleIndex += 1;
|
||||
scaledAbsolute = absolute / NUMBER_SCALES[scaleIndex].divisor;
|
||||
}
|
||||
|
||||
const scaled = numeric < 0 ? -scaledAbsolute : scaledAbsolute;
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
minimumFractionDigits,
|
||||
maximumFractionDigits
|
||||
}).format(scaled);
|
||||
|
||||
return `${formatted}${NUMBER_SCALES[scaleIndex].suffix}`;
|
||||
}
|
||||
|
||||
export function formatCurrency(value: string | number | null | undefined) {
|
||||
return new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
|
||||
Reference in New Issue
Block a user