github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/ui/dashboard/src/components/IntegerDisplay/index.tsx (about) 1 import isNil from "lodash/isNil"; 2 import isObject from "lodash/isObject"; 3 4 type IntegerDisplayProps = { 5 num: number | null; 6 className?: string; 7 startAt?: "k" | "100k" | "m"; 8 withTitle?: boolean; 9 }; 10 11 // Adapted from https://stackoverflow.com/questions/42658221/vanilla-javascript-function-to-round-to-nearest-hundred-or-100k-plus-symbol 12 // const truncate = (num: number) => { 13 // const p = Math.floor(Math.log(num) / Math.LN10); 14 // const l = Math.min(2, Math.ceil(p / 3)); 15 // return ( 16 // Math.pow(10, p - l * 3) * +(num / Math.pow(10, p)).toFixed(1) + 17 // ["", "k", "M"][l] 18 // ); 19 // }; 20 21 const ten_million = 10000000; 22 const one_million = 1000000; 23 const one_hundred_thousand = 100000; 24 const one_thousand = 1000; 25 26 const roundToThousands = (num) => { 27 return (num / 1000).toFixed(1).replace(/\.0$/, "") + "k"; 28 }; 29 30 const roundToNearestThousand = (num) => { 31 const toNearest1k = Math.round(num / one_thousand) * one_thousand; 32 if (toNearest1k >= one_million) { 33 return roundToMillions(num); 34 } 35 return roundToThousands(toNearest1k); 36 }; 37 38 const roundToMillions = (num, fixedDigits = 2) => { 39 return (num / one_million).toFixed(fixedDigits).replace(/\.0+$/, "") + "M"; 40 }; 41 42 const IntegerDisplay = ({ 43 num, 44 className, 45 startAt = "m", 46 withTitle = true, 47 }: IntegerDisplayProps) => { 48 const levels = { 49 k: one_thousand, 50 "100k": one_hundred_thousand, 51 m: one_million, 52 }; 53 const numberFormatter = (num) => { 54 if (isNil(num) || isObject(num)) { 55 return; 56 } 57 58 const threshold = levels[startAt]; 59 60 if (threshold <= one_million && num >= ten_million) { 61 return roundToMillions(num, 1); 62 } 63 if (threshold <= one_million && num >= one_million) { 64 return roundToMillions(num); 65 } 66 if (threshold <= one_hundred_thousand && num >= one_hundred_thousand) { 67 return roundToNearestThousand(num); 68 } 69 if (threshold <= one_thousand) { 70 if (num >= one_million) { 71 return roundToMillions(num); 72 } 73 if (num >= one_hundred_thousand) { 74 return roundToNearestThousand(num); 75 } 76 if (num >= one_thousand) { 77 return roundToThousands(num); 78 } 79 } 80 // display number as-is but separated with commas 81 return num.toLocaleString(); 82 }; 83 return ( 84 <span 85 className={className} 86 title={withTitle && num ? num.toLocaleString() : undefined} 87 > 88 {numberFormatter(num)} 89 </span> 90 ); 91 }; 92 93 export default IntegerDisplay;