ng-number-formatter
Version:
Angular Number Formatter - formats the number into human readable format when in Thousands, Millions and Billions.
191 lines (185 loc) • 19 kB
JavaScript
import { Component, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class NgNumberFormatterComponent {
constructor() { }
/**
* @return {?}
*/
ngOnInit() {
/** @type {?} */
var incomingString = this.ngNumber.toString();
/** @type {?} */
var incomingNumber = parseFloat(incomingString);
if (isNaN(incomingNumber)) {
// if its not a number then return as it is!
this.ngOutputNumber = incomingString;
}
else {
// handling minus sign for negative numbers
this.ngOutputNumber = (incomingNumber > 0) ? '' : '-';
incomingNumber = Math.abs(incomingNumber);
switch (this.ngFormat) {
case 'emoji':
this.ngOutputNumber += this.emojifyNumber(incomingNumber);
break;
case 'comma':
this.ngOutputNumber += this.numberWithCommas(incomingNumber);
break;
case 'metrics-name':
this.ngOutputNumber += this.numberWithMetricsName(incomingNumber);
break;
case 'metrics-symbol':
this.ngOutputNumber += this.numberWithMetricsSymbol(incomingNumber);
break;
default:
// metrics symbol based (K thousand, M million, B billion)
this.ngOutputNumber += this.numberWithMetricsSymbol(incomingNumber);
// if someone sets the ngFormat value not as string or other than the expexted formats
// console.log(`Ng-Number-Formatter: String value is requried for the property ngFormat ['', 'metrics-symbol', 'metrics-name', 'comma', 'emoji']`);
break;
}
}
}
/**
* @param {?} num
* @return {?}
*/
emojifyNumber(num) {
/** @type {?} */
var emojifiedString = '';
/** @type {?} */
var emojiArray = ['0️⃣', '1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟'];
if (num <= 10) {
emojifiedString = emojiArray[num];
}
else {
/** @type {?} */
var numString = num.toString();
for (var i = 0; i < numString.length; i++) {
emojifiedString += isNaN(numString.charAt(i)) ? numString.charAt(i) : emojiArray[numString.charAt(i)];
}
}
return emojifiedString;
}
/**
* @param {?} num
* @return {?}
*/
beautifyNumber(num) {
/** @type {?} */
var numString = num;
if (num > 0) {
if (num % 10 == 1 && num != 11)
numString = `${num}st`;
if (num % 10 == 2 && num != 12)
numString = `${num}nd`;
if (num % 10 == 3 && num != 13)
numString = `${num}rd`;
if ((num % 10 != 1 && num % 10 != 2 && num % 10 != 3) || (num == 11 || num == 12 || num == 13))
numString = `${num}th`;
}
return numString;
}
/**
* @param {?} num
* @return {?}
*/
numberWithCommas(num) {
// setting maximum to 15, so that its the maximum value possible for JS
return num.toLocaleString('en-US', { maximumFractionDigits: 15 });
}
/**
* @param {?} num
* @param {?=} digits
* @return {?}
*/
numberWithMetricsName(num, digits = 1) {
/** @type {?} */
var si = [
{ value: 1E24, symbol: " septillion" },
{ value: 1E21, symbol: " sextillion" },
{ value: 1E18, symbol: " quintillion" },
{ value: 1E15, symbol: " quadrillion" },
{ value: 1E12, symbol: " trillion" },
{ value: 1E9, symbol: " billion" },
{ value: 1E6, symbol: " million" },
{ value: 1E3, symbol: " thousand" }
];
/** @type {?} */
var rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
for (var i = 0; i < si.length; i++) {
if (num >= si[i].value) {
return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol;
}
}
return num.toFixed(digits).replace(rx, "$1");
}
/**
* @param {?} num
* @param {?=} digits
* @return {?}
*/
numberWithMetricsSymbol(num, digits = 1) {
/** @type {?} */
var si = [
{ value: 1E24, symbol: "Y" },
{ value: 1E21, symbol: "Z" },
{ value: 1E18, symbol: "E" },
{ value: 1E15, symbol: "P" },
{ value: 1E12, symbol: "T" },
{ value: 1E9, symbol: "B" },
{ value: 1E6, symbol: "M" },
{ value: 1E3, symbol: "K" }
];
/** @type {?} */
var rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
for (var i = 0; i < si.length; i++) {
if (num >= si[i].value) {
return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol;
}
}
return num.toFixed(digits).replace(rx, "$1");
}
}
NgNumberFormatterComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-number-formatter',
inputs: ['ngNumber', 'ngFormat'],
template: '<span>{{ngOutputNumber}}</span>',
},] },
];
/** @nocollapse */
NgNumberFormatterComponent.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class NgNumberFormatterModule {
}
NgNumberFormatterModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule
],
declarations: [
NgNumberFormatterComponent
],
exports: [
NgNumberFormatterComponent
]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
export { NgNumberFormatterModule, NgNumberFormatterComponent as ɵa };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctbnVtYmVyLWZvcm1hdHRlci5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbmctbnVtYmVyLWZvcm1hdHRlci9zcmMvYXBwL21vZHVsZXMvbmctbnVtYmVyLWZvcm1hdHRlci9uZy1udW1iZXItZm9ybWF0dGVyLmNvbXBvbmVudC50cyIsIm5nOi8vbmctbnVtYmVyLWZvcm1hdHRlci9zcmMvYXBwL21vZHVsZXMvbmctbnVtYmVyLWZvcm1hdHRlci9uZy1udW1iZXItZm9ybWF0dGVyLm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZy1udW1iZXItZm9ybWF0dGVyJyxcbiAgaW5wdXRzOiBbJ25nTnVtYmVyJywgJ25nRm9ybWF0J10sXG4gIHRlbXBsYXRlOiAnPHNwYW4+e3tuZ091dHB1dE51bWJlcn19PC9zcGFuPicsXG59KVxuXG5leHBvcnQgY2xhc3MgTmdOdW1iZXJGb3JtYXR0ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBuZ051bWJlcjogbnVtYmVyIHwgc3RyaW5nO1xuICBuZ0Zvcm1hdDogc3RyaW5nO1xuICBuZ091dHB1dE51bWJlcjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKCkgeyB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgLy8gdG8gcHJvY2VzcyBib3RoIG51bWJlcnMgYW5kIHN0cmluZ3NcbiAgICB2YXIgaW5jb21pbmdTdHJpbmcgPSB0aGlzLm5nTnVtYmVyLnRvU3RyaW5nKCk7XG4gICAgdmFyIGluY29taW5nTnVtYmVyID0gcGFyc2VGbG9hdChpbmNvbWluZ1N0cmluZyk7XG4gICAgaWYgKGlzTmFOKGluY29taW5nTnVtYmVyKSkge1xuICAgICAgLy8gaWYgaXRzIG5vdCBhIG51bWJlciB0aGVuIHJldHVybiBhcyBpdCBpcyFcbiAgICAgIHRoaXMubmdPdXRwdXROdW1iZXIgPSBpbmNvbWluZ1N0cmluZztcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaGFuZGxpbmcgbWludXMgc2lnbiBmb3IgbmVnYXRpdmUgbnVtYmVyc1xuICAgICAgdGhpcy5uZ091dHB1dE51bWJlciA9IChpbmNvbWluZ051bWJlciA+IDApID8gJycgOiAnLSc7XG4gICAgICBpbmNvbWluZ051bWJlciA9IE1hdGguYWJzKGluY29taW5nTnVtYmVyKTtcbiAgICAgIHN3aXRjaCAodGhpcy5uZ0Zvcm1hdCkge1xuICAgICAgICBjYXNlICdlbW9qaSc6XG4gICAgICAgICAgdGhpcy5uZ091dHB1dE51bWJlciArPSB0aGlzLmVtb2ppZnlOdW1iZXIoaW5jb21pbmdOdW1iZXIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdjb21tYSc6XG4gICAgICAgICAgdGhpcy5uZ091dHB1dE51bWJlciArPSB0aGlzLm51bWJlcldpdGhDb21tYXMoaW5jb21pbmdOdW1iZXIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdtZXRyaWNzLW5hbWUnOlxuICAgICAgICAgIHRoaXMubmdPdXRwdXROdW1iZXIgKz0gdGhpcy5udW1iZXJXaXRoTWV0cmljc05hbWUoaW5jb21pbmdOdW1iZXIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdtZXRyaWNzLXN5bWJvbCc6XG4gICAgICAgICAgdGhpcy5uZ091dHB1dE51bWJlciArPSB0aGlzLm51bWJlcldpdGhNZXRyaWNzU3ltYm9sKGluY29taW5nTnVtYmVyKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvLyBtZXRyaWNzIHN5bWJvbCBiYXNlZCAoSyB0aG91c2FuZCwgTSBtaWxsaW9uLCBCIGJpbGxpb24pXG4gICAgICAgICAgdGhpcy5uZ091dHB1dE51bWJlciArPSB0aGlzLm51bWJlcldpdGhNZXRyaWNzU3ltYm9sKGluY29taW5nTnVtYmVyKTtcbiAgICAgICAgICAvLyBpZiBzb21lb25lIHNldHMgdGhlIG5nRm9ybWF0IHZhbHVlIG5vdCBhcyBzdHJpbmcgb3Igb3RoZXIgdGhhbiB0aGUgZXhwZXh0ZWQgZm9ybWF0c1xuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBOZy1OdW1iZXItRm9ybWF0dGVyOiBTdHJpbmcgdmFsdWUgaXMgcmVxdXJpZWTCoGZvciB0aGUgcHJvcGVydHkgbmdGb3JtYXQgWycnLCAnbWV0cmljcy1zeW1ib2wnLCAnbWV0cmljcy1uYW1lJywgJ2NvbW1hJywgJ2Vtb2ppJ11gKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBlbW9qaWZ5TnVtYmVyKG51bSkge1xuICAgIHZhciBlbW9qaWZpZWRTdHJpbmcgPSAnJztcbiAgICB2YXIgZW1vamlBcnJheSA9IFsnMO+4j+KDoycsICcx77iP4oOjJywgJzLvuI/ig6MnLCAnM++4j+KDoycsICc077iP4oOjJywgJzXvuI/ig6MnLCAnNu+4j+KDoycsICc377iP4oOjJywgJzjvuI/ig6MnLCAnOe+4j+KDoycsICfvv73vv73vv73vv73vv73vv70nXTtcbiAgICBpZiAobnVtIDw9IDEwKSB7XG4gICAgICBlbW9qaWZpZWRTdHJpbmcgPSBlbW9qaUFycmF5W251bV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBudW1TdHJpbmcgPSBudW0udG9TdHJpbmcoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtU3RyaW5nLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGVtb2ppZmllZFN0cmluZyArPSBpc05hTihudW1TdHJpbmcuY2hhckF0KGkpKSA/IG51bVN0cmluZy5jaGFyQXQoaSkgOiBlbW9qaUFycmF5W251bVN0cmluZy5jaGFyQXQoaSldO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBlbW9qaWZpZWRTdHJpbmc7XG4gIH1cblxuICBiZWF1dGlmeU51bWJlcihudW0pIHtcbiAgICB2YXIgbnVtU3RyaW5nID0gbnVtO1xuICAgIGlmIChudW0gPiAwKSB7XG4gICAgICBpZiAobnVtICUgMTAgPT0gMSAmJiBudW0gIT0gMTEpIG51bVN0cmluZyA9IGAke251bX1zdGA7XG4gICAgICBpZiAobnVtICUgMTAgPT0gMiAmJiBudW0gIT0gMTIpIG51bVN0cmluZyA9IGAke251bX1uZGA7XG4gICAgICBpZiAobnVtICUgMTAgPT0gMyAmJiBudW0gIT0gMTMpIG51bVN0cmluZyA9IGAke251bX1yZGA7XG4gICAgICBpZiAoKG51bSAlIDEwICE9IDEgJiYgbnVtICUgMTAgIT0gMiAmJiBudW0gJSAxMCAhPSAzKSB8fCAobnVtID09IDExIHx8IG51bSA9PSAxMiB8fCBudW0gPT0gMTMpKSBudW1TdHJpbmcgPSBgJHtudW19dGhgO1xuICAgIH1cbiAgICByZXR1cm4gbnVtU3RyaW5nO1xuICB9XG5cbiAgbnVtYmVyV2l0aENvbW1hcyhudW0pIHtcbiAgICAvLyBzZXR0aW5nIG1heGltdW0gdG8gMTUsIHNvIHRoYXQgaXRzIHRoZSBtYXhpbXVtIHZhbHVlIHBvc3NpYmxlIGZvciBKU1xuICAgIHJldHVybiBudW0udG9Mb2NhbGVTdHJpbmcoJ2VuLVVTJywgeyBtYXhpbXVtRnJhY3Rpb25EaWdpdHM6IDE1IH0pO1xuICB9XG5cbiAgbnVtYmVyV2l0aE1ldHJpY3NOYW1lKG51bSwgZGlnaXRzID0gMSkge1xuICAgIC8vIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BldGEtXG4gICAgdmFyIHNpID0gW1xuICAgICAgeyB2YWx1ZTogMUUyNCwgc3ltYm9sOiBcIiBzZXB0aWxsaW9uXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMjEsIHN5bWJvbDogXCIgc2V4dGlsbGlvblwiIH0sXG4gICAgICB7IHZhbHVlOiAxRTE4LCBzeW1ib2w6IFwiIHF1aW50aWxsaW9uXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMTUsIHN5bWJvbDogXCIgcXVhZHJpbGxpb25cIiB9LFxuICAgICAgeyB2YWx1ZTogMUUxMiwgc3ltYm9sOiBcIiB0cmlsbGlvblwiIH0sXG4gICAgICB7IHZhbHVlOiAxRTksIHN5bWJvbDogXCIgYmlsbGlvblwiIH0sXG4gICAgICB7IHZhbHVlOiAxRTYsIHN5bWJvbDogXCIgbWlsbGlvblwiIH0sXG4gICAgICB7IHZhbHVlOiAxRTMsIHN5bWJvbDogXCIgdGhvdXNhbmRcIiB9XG4gICAgXSwgcnggPSAvXFwuMCskfChcXC5bMC05XSpbMS05XSkwKyQvO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2kubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChudW0gPj0gc2lbaV0udmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIChudW0gLyBzaVtpXS52YWx1ZSkudG9GaXhlZChkaWdpdHMpLnJlcGxhY2UocngsIFwiJDFcIikgKyBzaVtpXS5zeW1ib2w7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudW0udG9GaXhlZChkaWdpdHMpLnJlcGxhY2UocngsIFwiJDFcIik7XG4gIH1cblxuICBudW1iZXJXaXRoTWV0cmljc1N5bWJvbChudW0sIGRpZ2l0cyA9IDEpIHtcbiAgICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QZXRhLVxuICAgIHZhciBzaSA9IFtcbiAgICAgIHsgdmFsdWU6IDFFMjQsIHN5bWJvbDogXCJZXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMjEsIHN5bWJvbDogXCJaXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMTgsIHN5bWJvbDogXCJFXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMTUsIHN5bWJvbDogXCJQXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMTIsIHN5bWJvbDogXCJUXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFOSwgc3ltYm9sOiBcIkJcIiB9LFxuICAgICAgeyB2YWx1ZTogMUU2LCBzeW1ib2w6IFwiTVwiIH0sXG4gICAgICB7IHZhbHVlOiAxRTMsIHN5bWJvbDogXCJLXCIgfVxuICAgIF0sIHJ4ID0gL1xcLjArJHwoXFwuWzAtOV0qWzEtOV0pMCskLztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAobnVtID49IHNpW2ldLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiAobnVtIC8gc2lbaV0udmFsdWUpLnRvRml4ZWQoZGlnaXRzKS5yZXBsYWNlKHJ4LCBcIiQxXCIpICsgc2lbaV0uc3ltYm9sO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVtLnRvRml4ZWQoZGlnaXRzKS5yZXBsYWNlKHJ4LCBcIiQxXCIpO1xuICB9XG59IiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBOZ051bWJlckZvcm1hdHRlckNvbXBvbmVudCB9IGZyb20gJy4vbmctbnVtYmVyLWZvcm1hdHRlci5jb21wb25lbnQnO1xuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW1xuICAgIE5nTnVtYmVyRm9ybWF0dGVyQ29tcG9uZW50XG4gIF0sXG4gIGV4cG9ydHM6IFtcbiAgICBOZ051bWJlckZvcm1hdHRlckNvbXBvbmVudFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIE5nTnVtYmVyRm9ybWF0dGVyTW9kdWxlIHsgfVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtJQWFFLGlCQUFpQjs7OztJQUVqQixRQUFROztRQUVOLElBQUksY0FBYyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7O1FBQzlDLElBQUksY0FBYyxHQUFHLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNoRCxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsRUFBRTs7WUFFekIsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7U0FDdEM7YUFBTTs7WUFFTCxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsY0FBYyxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsR0FBRyxDQUFD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