UNPKG

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
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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