format numbers

by lovinglobo

JavaScript

/**
For which minimum delta do we choose what adjusment?
An adjustment is basically dividing the to be formatted value by the adjustment
value and adding the suffix, e.g. 1000 becomes 1k.
*/
const BIG_NUMBER_ADJUSTMENT_TABLE =[
	{ suffix: 'm', adjustment: 1000000 },
	{ suffix: 'k', adjustment: 1000 },
];


/*
Formats numbers in such a way as to keep them within `max_size` characters, by:
 - shrinking big numbers using suffixes with no loss of precision
 - otherwise using scientific notation
 	- scientifific notation loses precision when the size of scinotation exceeds `max_size`
*/
function formatNumber(max_size, value) {
	const adjustment_row = BIG_NUMBER_ADJUSTMENT_TABLE.find(a => value >= a.adjustment);
  const adjusted_value = adjustment_row ? value / adjustment_row.adjustment : value;
  const suffix = adjustment_row ? adjustment_row.suffix : '';

	const str_value = adjusted_value.toString();
  if (str_value.length + suffix.length > max_size) {
  	const exp_str_value = value.toExponential();
    if (exp_str_value.length > max_size) {
    	const dot_len = exp_str_value.indexOf('.') >=0 ? 1 : 0;
      const numlen_after_e = exp_str_value.length - exp_str_value.indexOf('e') + 1;
      const scientific_overhead = dot_len + numlen_after_e;
    	return value.toExponential(Math.max(0, max_size-scientific_overhead));
    } else {
    	return exp_str_value;
    }
  } else {
  	return str_value + suffix;
  }
}

//////////////////
//// TESTING /////
//////////////////


const testValues = [
	{ min: 0, max: 100000000, values: [0, 50000000, 912463000, 91246300023421111823897383573892]},
	{ min: 0, max: 10000000, values: [0, 5000000, 14646000]},
	{ min: 0, max: 100000, values: [0, 50000, 500, 5000, 9999, 10000]},
	{ min: 0, max: 10000, values: [0, 5, 500, 5000, 9999, 10000]},
	{ min: 0, max: 100, values: [0, 25.535, 60.52312412412, 100]},
	{ min: 0, max: 10, values: [0, 1, 5.5, 7]},
	{ min: 0, max: 1, values: [0, 0.25, 0.001, 1]},
  { min: 0, max: 0.1, values: [0, 0.0005,...