Permalink
Browse files

Number: Add support for compact option (short/long) (2/2)

  • Loading branch information...
rxaviers committed Jul 21, 2017
1 parent e4e1276 commit a975fd72430c9589701428b6b8be4b85d7e1488f
@@ -20,6 +20,8 @@ Number to be formatted, eg. `9.99`.
### Example
#### Static Formatter
Prior to using any currency methods, you must load `cldr/main/{locale}/currencies.json`, `cldr/supplemental/currencyData.json`, and the CLDR content required by the number module. If using plural messages, you also must load the CLDR content required by the plural module. Read [CLDR content][] if you need more information.
[CLDR content]: ../../../README.md#2-cldr-content
@@ -37,6 +39,8 @@ formatter( 9.99 );
```
#### Instance Formatter
You can use the instance method `.currencyFormatter()`, which uses the instance locale.
```javascript
@@ -62,6 +66,8 @@ For comparison, follow the formatting output of different symbols in different l
| `.currencyFormatter( "GBP" )( 1 )` | `£1.00` | `1,00 £` | `£ 1.00` |
| `.currencyFormatter( "BRL" )( 1 )` | `R$1.00` | `1,00 R$` | `R$ 1.00` |
#### Configuring style
For the accounting variation of the symbol format, use `style: "accounting"`.
```javascript
@@ -109,6 +115,8 @@ formatter( 9.99 );
// > "9.99 USD"
```
#### Configuring inherited number options
Override the number of digits, grouping separators, rounding function or any other [`.numberFormatter()` options](../number/number-formatter.md).
```javascript
@@ -129,16 +137,39 @@ formatter = Globalize.currencyFormatter( "USD", {
formatter( 1.491 );
// > "$1.50"
```
formatter = Globalize.currencyFormatter( "USD", {
maximumFractionDigits: 0,
#### Formatting Compact Currencies
```js
var shortFormatter = Globalize( "en" ).currencyFormatter( "USD", {
compact: "short"
});
formatter( 12830000000 );
var longFormatter = Globalize( "en" ).currencyFormatter( "USD", {
compact: "long"
});
shortFormatter( 12830000000 );
// > "$13B"
longFormatter( 12830000000 );
// > "$13 billion"
```
The minimumSignificantDigits and maximumSignificantDigits options are specially useful to control the number of digits to display.
```js
Globalize( "en" ).formatCurrency( 12830000000, "USD", {
compact: "short",
minimumSignificantDigits: 3,
maximumSignificantDigits: 3
});
// > "$12.8B"
```
#### Performance Suggestion
For improved performance on iterations, first create the formatter. Then, reuse it on each loop.
```javascript
@@ -149,15 +149,11 @@ Long numbers can be represented in a compact format, with `short` using abbrevia
```javascript
var shortFormatter = Globalize( "en" ).numberFormatter({
compact: "short",
maximumFractionDigits: 0,
style: "decimal"
compact: "short"
});
var longFormatter = Globalize( "en" ).numberFormatter({
compact: "long",
maximumFractionDigits: 0,
style: "decimal"
compact: "long"
});
shortFormatter( 27588910 );
@@ -167,6 +163,17 @@ longFormatter( 27588910 );
// > "28 million"
```
The minimumSignificantDigits and maximumSignificantDigits options are specially useful to control the number of digits to display.
```js
Globalize( "en" ).formatNumber( 27588910, {
compact: "short",
minimumSignificantDigits: 3,
maximumSignificantDigits: 3
});
// > "27.6M"
```
#### Configuring Rounding
Numbers with a decreased amount of decimal places can be rounded up, rounded down, rounded arithmetically, or truncated by setting the `round` option to `ceil`, `floor`, `round` (default), or `truncate`.
@@ -0,0 +1,21 @@
define(function() {
/**
* EBNF representation:
*
* compact_pattern_re = prefix?
* number_pattern_re
* suffix?
*
* number_pattern_re = 0+
*
* Regexp groups:
*
* 0: compact_pattern_re
* 1: prefix
* 2: number_pattern_re (the number pattern to use in compact mode)
* 3: suffix
*/
return ( /^([^0]*)(0+)([^0]*)$/ );
});
View
@@ -1,5 +1,5 @@
define([
"./numbering-system"
"./numbering-system"
], function( numberNumberingSystem ) {
/**
@@ -12,11 +12,26 @@ define([
* Return the localized compact map for the given compact mode.
*/
return function( compactType, cldr ) {
return cldr.main([
"numbers/decimalFormats-numberSystem-" + numberNumberingSystem( cldr ),
compactType,
"decimalFormat"
]);
var maxExponent = 0;
var object = cldr.main([
"numbers/decimalFormats-numberSystem-" + numberNumberingSystem( cldr ),
compactType,
"decimalFormat"
]);
object = Object.keys( object ).reduce(function( newObject, compactKey ) {
var numberExponent = compactKey.split( "0" ).length - 1;
var pluralForm = compactKey.split( "-" )[ 2 ];
newObject[ numberExponent ] = newObject[ numberExponent ] || {};
newObject[ numberExponent ][ pluralForm ] = object[ compactKey ];
maxExponent = Math.max( numberExponent, maxExponent );
return newObject;
}, {});
object.maxExponent = maxExponent;
return object;
};
});
@@ -65,6 +65,18 @@ return function( pattern, cldr, options ) {
]);
if ( options.compact ) {
// The compact digits number pattern is always `0+`, so override the following properties.
// Note: minimumIntegerDigits would actually range from `0` to `000` based on the scale of
// the value to be formatted, though we're always using 1 as a simplification, because the
// number won't be zero-padded since we chose the right format based on the scale, i.e.,
// we'd never see something like `003M` anyway.
properties[ 2 ] = negativeSuffix[ 2 ] = 1; // minimumIntegerDigits
properties[ 3 ] = negativeSuffix[ 3 ] = 0; // minimumFractionDigits
properties[ 4 ] = negativeSuffix[ 4 ] = 0; // maximumFractionDigits
properties[ 5 ] = negativeSuffix[ 5 ] = // minimumSignificantDigits &
properties[ 6 ] = negativeSuffix[ 6 ] = undefined ; // maximumSignificantDigits
properties[20] = numberCompact( options.compact, cldr );
}
View
@@ -1,11 +1,13 @@
define([
"./compact-pattern-re",
"./format/grouping-separator",
"./format/integer-fraction-digits",
"./format/significant-digits",
"./pattern-re",
"../util/remove-literal-quotes"
], function( numberFormatGroupingSeparator, numberFormatIntegerFractionDigits,
numberFormatSignificantDigits, numberPatternRe, removeLiteralQuotes ) {
], function( numberCompactPatternRe, numberFormatGroupingSeparator,
numberFormatIntegerFractionDigits, numberFormatSignificantDigits, numberPatternRe,
removeLiteralQuotes ) {
/**
* format( number, properties )
@@ -68,29 +70,24 @@ return function( number, properties, pluralGenerator ) {
number *= 1000;
}
var compactPattern, compactDigits, compactProperties, divisor, pluralForm, zeroes,
originalNumber;
var compactPattern, compactDigits, compactProperties, divisor, numberExponent, pluralForm;
// Compact mode: initial number digit processing
if ( compactMap ) {
originalNumber = number;
zeroes = Array( Math.floor( number ).toString().length ).join( "0" );
if ( zeroes.length >= 3 ) {
// use default plural form to perform initial decimal shift
compactPattern = compactMap[ "1" + zeroes + "-count-other" ];
if ( compactPattern ) {
compactDigits = compactPattern.split( "0" ).length - 1;
divisor = zeroes.length - ( compactDigits - 1 );
number = number / Math.pow( 10, divisor );
// Some languages specify no pattern for certain digit lengths, represented as "0".
// If no pattern, original number should remain uncompacted.
if ( compactPattern === "0" ) {
number = originalNumber;
}
}
numberExponent = Math.floor( number ).toString().length - 1;
numberExponent = Math.min( numberExponent, compactMap.maxExponent );
// Use default plural form to perform initial decimal shift
if ( numberExponent >= 3 ) {
compactPattern = compactMap[ numberExponent ] && compactMap[ numberExponent ].other;
}
if ( compactPattern === "0" ) {
compactPattern = null;
} else if ( compactPattern ) {
compactDigits = compactPattern.split( "0" ).length - 1;
divisor = numberExponent - ( compactDigits - 1 );
number = number / Math.pow( 10, divisor );
}
}
@@ -107,18 +104,16 @@ return function( number, properties, pluralGenerator ) {
// Compact mode: apply formatting
if ( compactMap && compactPattern ) {
pluralForm = pluralGenerator ? pluralGenerator( number ) : "other";
compactPattern = compactMap[ "1" + zeroes + "-count-" + pluralForm ] || compactPattern;
// Some languages specify no pattern for certain digit lengths, represented as "0".
// Only apply compact pattern if one is specified.
if ( compactPattern !== "0" ) {
compactProperties = compactPattern.match( numberPatternRe );
// Get plural form after possible roundings
pluralForm = pluralGenerator ? pluralGenerator( +number ) : "other";
// update prefix/suffix with compact prefix/suffix
prefix += compactProperties[ 1 ];
suffix = compactProperties[ 11 ] + suffix;
}
compactPattern = compactMap[ numberExponent ][ pluralForm ] || compactPattern;
compactProperties = compactPattern.match( numberCompactPatternRe );
// update prefix/suffix with compact prefix/suffix
prefix += compactProperties[ 1 ];
suffix = compactProperties[ 3 ] + suffix;
}
// Remove the possible number minus sign
View
@@ -26,7 +26,7 @@ define(function() {
*
* suffix = non_number_stuff
*
* non_number_stuff = regexp(.*?)
* non_number_stuff = regexp(('[^']+'|''|[^*#@0,.E])*)
*
*
* Regexp groups:
@@ -45,6 +45,6 @@ define(function() {
* 11: suffix
* 12: -
*/
return ( /^(('([^']|'')*'|[^*#@0,.E])*)(\*.)?((([#,]*[0,]*0+)(\.0*[0-9]*#*)?)|([#,]*@+#*))(E\+?0+)?(.*?)$/ );
return ( /^(('([^']|'')*'|[^*#@0,.E])*)(\*.)?((([#,]*[0,]*0+)(\.0*[0-9]*#*)?)|([#,]*@+#*))(E\+?0+)?(('[^']+'|''|[^*#@0,.E])*)$/ );
});
Oops, something went wrong.

0 comments on commit a975fd7

Please sign in to comment.