Skip to content

Instantly share code, notes, and snippets.

@eliseumds
Last active August 29, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eliseumds/45d0fa0b0b96f1d3eb84 to your computer and use it in GitHub Desktop.
Save eliseumds/45d0fa0b0b96f1d3eb84 to your computer and use it in GitHub Desktop.
Number formatter

Number Formatter: how to use

// some pre-made formatters
var myFormatFn = NumberFormatter.PERCENT; // check NumberFormatter.js for more
myFormatFn(0.54122); // '54.1%'
myFormatFn('0.54122'); // '54.1%'

var formatter = new NumberFormatter();

var myStr = formatter.format('0.0', 12.23); // '12.2'

// callbacks?
var myChartSettings = {
    yAxisFormatter: formatter.createCallback('0.0')
};

// with a custom strategy
var myStr = formatter.formatUsing(new CustomStrategy(), 12.984);

CustomNumberFormatter

This subclass gives you more flexibility with pre and post process functions.

Example: let's say you have an API that returns wind speed in meters/second and you want to format it as km/h with one decimal place:

var formatter = new CustomNumberFormatter(
	'0.0',
	value => value * 3.6, // Pre: value here is still the number
	value => value + ' km/h' // Post: value here is already the formatter str
);

var myStr = formatter.format(10); // '36 km/h'
import numeral from 'numeral';
import NumberFormattingStrategy from './strategies/NumberFormattingStrategy';
class NumberFormatter {
static PLAIN = new NumeraljsFormatFormattingStrategy('0,0');
static AVG = new NumeraljsFormatFormattingStrategy('0,0.00');
static PERCENT = new NumeraljsFormatFormattingStrategy('0.0 %');
static AVG_PERCENT = new NumeraljsFormatFormattingStrategy('0.00 %');
/**
* @param {number|string} value
* @return {string}
*/
_parseValue(value) {
NumberFormattingStrategy._assertValidValue(value);
return numeral(value);
}
/**
* @param {string} format
* @return {function}
*/
createCallback(format) {
return this.format.bind(this, format);
}
/**
* @param {NumberFormattingStrategy} strategy
* @return {function}
*/
createCallbackUsing(strategy) {
return this.formatUsing.bind(this, strategy);
}
/**
* @param {string} formatString
* @param {Date|string|moment} value
* @return {string}
*/
format(formatString, value) {
return this._parseValue(value).format(formatString);
}
/**
* @param {NumberFormattingStrategy} strategy
* @param {number|string} value
* @return {string}
* @throws {TypeError}
*/
formatUsing(strategy, value) {
if (strategy instanceof NumberFormattingStrategy) {
return strategy.format(this._parseValue(value));
}
throw new TypeError(
'`strategy` must be an instance of NumberFormattingStrategy'
);
}
}
class NumberFormattingStrategy {
// TODO move to a helper
static _assertValidValue(value) {
if (typeof value !== 'number' && typeof value !== 'string') {
throw new TypeError('`value` must be a number or string');
}
value = Number(value);
if (isNaN(value)) {
throw new TypeError('`value` must be a valid number');
}
return true;
}
format() {
throw 'MethodNotImplementedException';
}
}
import numeral from 'numeral';
import NumberFormattingStrategy from './NumberFormattingStrategy';
class NumeraljsFormatFormattingStrategy extends NumberFormattingStrategy {
constructor(formatString) {
super();
this.formatString = formatString;
}
format(value) {
NumberFormattingStrategy._assertValidValue(value);
return numeral(value).format(this.formatString);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment