UNPKG

ng-number-formatter

Version:

Angular Number Formatter - formats the number into human readable format when in Thousands, Millions and Billions.

223 lines (217 loc) 20.1 kB
import { Component, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var NgNumberFormatterComponent = /** @class */ (function () { function NgNumberFormatterComponent() { } /** * @return {?} */ NgNumberFormatterComponent.prototype.ngOnInit = /** * @return {?} */ function () { /** @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 {?} */ NgNumberFormatterComponent.prototype.emojifyNumber = /** * @param {?} num * @return {?} */ function (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 {?} */ NgNumberFormatterComponent.prototype.beautifyNumber = /** * @param {?} num * @return {?} */ function (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 {?} */ NgNumberFormatterComponent.prototype.numberWithCommas = /** * @param {?} num * @return {?} */ function (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 {?} */ NgNumberFormatterComponent.prototype.numberWithMetricsName = /** * @param {?} num * @param {?=} digits * @return {?} */ function (num, digits) { if (digits === void 0) { 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 {?} */ NgNumberFormatterComponent.prototype.numberWithMetricsSymbol = /** * @param {?} num * @param {?=} digits * @return {?} */ function (num, digits) { if (digits === void 0) { 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 = function () { return []; }; return NgNumberFormatterComponent; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var NgNumberFormatterModule = /** @class */ (function () { function NgNumberFormatterModule() { } NgNumberFormatterModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule ], declarations: [ NgNumberFormatterComponent ], exports: [ NgNumberFormatterComponent ] },] }, ]; return NgNumberFormatterModule; }()); /** * @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/IG51bVN0cmluZy5jaGFyQXQoaSkgOiBlbW9qaUFycmF5W251bVN0cmluZy5jaGFyQXQoaSldO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBlbW9qaWZpZWRTdHJpbmc7XG4gIH1cblxuICBiZWF1dGlmeU51bWJlcihudW0pIHtcbiAgICB2YXIgbnVtU3RyaW5nID0gbnVtO1xuICAgIGlmIChudW0gPiAwKSB7XG4gICAgICBpZiAobnVtICUgMTAgPT0gMSAmJiBudW0gIT0gMTEpIG51bVN0cmluZyA9IGAke251bX1zdGA7XG4gICAgICBpZiAobnVtICUgMTAgPT0gMiAmJiBudW0gIT0gMTIpIG51bVN0cmluZyA9IGAke251bX1uZGA7XG4gICAgICBpZiAobnVtICUgMTAgPT0gMyAmJiBudW0gIT0gMTMpIG51bVN0cmluZyA9IGAke251bX1yZGA7XG4gICAgICBpZiAoKG51bSAlIDEwICE9IDEgJiYgbnVtICUgMTAgIT0gMiAmJiBudW0gJSAxMCAhPSAzKSB8fCAobnVtID09IDExIHx8IG51bSA9PSAxMiB8fCBudW0gPT0gMTMpKSBudW1TdHJpbmcgPSBgJHtudW19dGhgO1xuICAgIH1cbiAgICByZXR1cm4gbnVtU3RyaW5nO1xuICB9XG5cbiAgbnVtYmVyV2l0aENvbW1hcyhudW0pIHtcbiAgICAvLyBzZXR0aW5nIG1heGltdW0gdG8gMTUsIHNvIHRoYXQgaXRzIHRoZSBtYXhpbXVtIHZhbHVlIHBvc3NpYmxlIGZvciBKU1xuICAgIHJldHVybiBudW0udG9Mb2NhbGVTdHJpbmcoJ2VuLVVTJywgeyBtYXhpbXVtRnJhY3Rpb25EaWdpdHM6IDE1IH0pO1xuICB9XG5cbiAgbnVtYmVyV2l0aE1ldHJpY3NOYW1lKG51bSwgZGlnaXRzID0gMSkge1xuICAgIC8vIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BldGEtXG4gICAgdmFyIHNpID0gW1xuICAgICAgeyB2YWx1ZTogMUUyNCwgc3ltYm9sOiBcIiBzZXB0aWxsaW9uXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMjEsIHN5bWJvbDogXCIgc2V4dGlsbGlvblwiIH0sXG4gICAgICB7IHZhbHVlOiAxRTE4LCBzeW1ib2w6IFwiIHF1aW50aWxsaW9uXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMTUsIHN5bWJvbDogXCIgcXVhZHJpbGxpb25cIiB9LFxuICAgICAgeyB2YWx1ZTogMUUxMiwgc3ltYm9sOiBcIiB0cmlsbGlvblwiIH0sXG4gICAgICB7IHZhbHVlOiAxRTksIHN5bWJvbDogXCIgYmlsbGlvblwiIH0sXG4gICAgICB7IHZhbHVlOiAxRTYsIHN5bWJvbDogXCIgbWlsbGlvblwiIH0sXG4gICAgICB7IHZhbHVlOiAxRTMsIHN5bWJvbDogXCIgdGhvdXNhbmRcIiB9XG4gICAgXSwgcnggPSAvXFwuMCskfChcXC5bMC05XSpbMS05XSkwKyQvO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2kubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChudW0gPj0gc2lbaV0udmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIChudW0gLyBzaVtpXS52YWx1ZSkudG9GaXhlZChkaWdpdHMpLnJlcGxhY2UocngsIFwiJDFcIikgKyBzaVtpXS5zeW1ib2w7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudW0udG9GaXhlZChkaWdpdHMpLnJlcGxhY2UocngsIFwiJDFcIik7XG4gIH1cblxuICBudW1iZXJXaXRoTWV0cmljc1N5bWJvbChudW0sIGRpZ2l0cyA9IDEpIHtcbiAgICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QZXRhLVxuICAgIHZhciBzaSA9IFtcbiAgICAgIHsgdmFsdWU6IDFFMjQsIHN5bWJvbDogXCJZXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMjEsIHN5bWJvbDogXCJaXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMTgsIHN5bWJvbDogXCJFXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMTUsIHN5bWJvbDogXCJQXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFMTIsIHN5bWJvbDogXCJUXCIgfSxcbiAgICAgIHsgdmFsdWU6IDFFOSwgc3ltYm9sOiBcIkJcIiB9LFxuICAgICAgeyB2YWx1ZTogMUU2LCBzeW1ib2w6IFwiTVwiIH0sXG4gICAgICB7IHZhbHVlOiAxRTMsIHN5bWJvbDogXCJLXCIgfVxuICAgIF0sIHJ4ID0gL1xcLjArJHwoXFwuWzAtOV0qWzEtOV0pMCskLztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAobnVtID49IHNpW2ldLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiAobnVtIC8gc2lbaV0udmFsdWUpLnRvRml4ZWQoZGlnaXRzKS5yZXBsYWNlKHJ4LCBcIiQxXCIpICsgc2lbaV0uc3ltYm9sO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVtLnRvRml4ZWQoZGlnaXRzKS5yZXBsYWNlKHJ4LCBcIiQxXCIpO1xuICB9XG59IiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBOZ051bWJlckZvcm1hdHRlckNvbXBvbmVudCB9IGZyb20gJy4vbmctbnVtYmVyLWZvcm1hdHRlci5jb21wb25lbnQnO1xuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW1xuICAgIE5nTnVtYmVyRm9ybWF0dGVyQ29tcG9uZW50XG4gIF0sXG4gIGV4cG9ydHM6IFtcbiAgICBOZ051bWJlckZvcm1hdHRlckNvbXBvbmVudFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIE5nTnVtYmVyRm9ybWF0dGVyTW9kdWxlIHsgfVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtJQWFFO0tBQWlCOzs7O0lBRWpCLDZDQUFROzs7SUFBUjs7UUFFRSxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDOztRQUM5QyxJQUFJLGNBQWMsR0FBRyxVQUFVLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDaEQsSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLEVBQUU7O1lBRXpCLElBQUksQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO1NBQ3RDO2FBQU07O1lBRUwsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLGNBQWMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLEdB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