const UNITS = ['', 'K', 'M', 'G', 'T', 'P']; const FRACTIONAL = ['', 'm', 'u', 'n', 'p', 'f']; // milli micro nano pico femto export function formatSi(inValue, increment = 1000, suffix = null, firstSuffix = null, startingExponent = 0, minExponent = 0, maxPrecision = 2) { var val = inValue; var exp = startingExponent; while ( val >= increment && exp + 1 < UNITS.length || exp < minExponent ) { val = val / increment; exp++; } var out = ''; if ( val < 10 && maxPrecision >= 2 ) { out = Math.round(val * 100) / 100; } else if ( val < 100 && maxPrecision >= 1) { out = Math.round(val * 10) / 10; } else { out = Math.round(val); } if ( exp === 0 && firstSuffix !== null) { out += ` ${ firstSuffix }`; } else { out += ` ${ UNITS[exp] }${ suffix }` || ''; } return out; } export function exponentNeeded(val, increment = 1000) { let exp = 0; while ( val >= increment ) { val = val / increment; exp++; } return exp; } export function parseSi(inValue, increment = null, allowFractional = true) { if ( !inValue || typeof inValue !== 'string' || !inValue.length ) { return NaN; } inValue = inValue.replace(/,/g, '') let [, valStr, unit, incStr] = inValue.match(/^([0-9.-]+)\s*([^0-9.-]?)([^0-9.-]?)/) || []; const val = parseFloat(valStr); if ( !unit ) { return val; } // micro "mu" symbol -> u if ( unit.charCodeAt(0) === 181 ) { unit = 'u'; } const divide = FRACTIONAL.includes(unit); const multiply = UNITS.includes(unit.toUpperCase()); if ( increment === null ) { // Automatically handle 1 KB = 1000B, 1 KiB = 1024B if no increment set if ( (multiply || divide) && incStr === 'i' ) { increment = 1024; } else { increment = 1000; } } if ( divide && allowFractional ) { const exp = FRACTIONAL.indexOf(unit); return val / Math.pow(increment, exp); } if ( multiply ) { const exp = UNITS.indexOf(unit.toUpperCase()); return val * Math.pow(increment, exp); } // Unrecognized unit character return val; }