From 3688720f1b3dafef1f06add549c8562a39f88861 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 16 Jul 2025 15:15:34 +0200 Subject: [PATCH] better cope with big numbers --- .../calculator/csp_roi_calculator.html | 68 +++++++++++++++---- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/hub/services/templates/calculator/csp_roi_calculator.html b/hub/services/templates/calculator/csp_roi_calculator.html index c05152a..1b8bfc1 100644 --- a/hub/services/templates/calculator/csp_roi_calculator.html +++ b/hub/services/templates/calculator/csp_roi_calculator.html @@ -83,9 +83,12 @@ } .metric-value { - font-size: 2rem; + font-size: 1.6rem; font-weight: bold; color: #007bff; + line-height: 1.2; + word-break: break-word; + overflow-wrap: break-word; } .metric-label { @@ -93,6 +96,7 @@ font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.5px; + margin-top: 0.5rem; } .chart-container { @@ -166,7 +170,22 @@ } .metric-value { - font-size: 1.5rem; + font-size: 1.4rem; + } + + .metric-card { + padding: 1rem; + } +} + +@media (max-width: 576px) { + .metric-value { + font-size: 1.2rem; + } + + .metric-card { + padding: 0.75rem; + margin-bottom: 0.75rem; } } @@ -843,9 +862,9 @@ class ROICalculator { row.innerHTML = ` ${result.scenario} ${result.finalInstances.toLocaleString()} - ${this.formatCurrency(result.totalRevenue)} - ${this.formatCurrency(result.cspRevenue)} - ${this.formatCurrency(result.servalaRevenue)} + ${this.formatCurrencyDetailed(result.totalRevenue)} + ${this.formatCurrencyDetailed(result.cspRevenue)} + ${this.formatCurrencyDetailed(result.servalaRevenue)} ${this.formatPercentage(result.roi)} ${result.breakEvenMonth ? result.breakEvenMonth + ' months' : 'N/A'} ${result.npvBreakEvenMonth ? result.npvBreakEvenMonth + ' months' : 'N/A'} @@ -875,15 +894,36 @@ class ROICalculator { ${data.newInstances} ${data.churnedInstances} ${data.totalInstances.toLocaleString()} - ${this.formatCurrency(data.monthlyRevenue)} - ${this.formatCurrency(data.cspRevenue)} - ${this.formatCurrency(data.servalaRevenue)} - ${this.formatCurrency(data.cumulativeCSPRevenue)} + ${this.formatCurrencyDetailed(data.monthlyRevenue)} + ${this.formatCurrencyDetailed(data.cspRevenue)} + ${this.formatCurrencyDetailed(data.servalaRevenue)} + ${this.formatCurrencyDetailed(data.cumulativeCSPRevenue)} `; }); } formatCurrency(amount) { + // Use compact notation for large numbers in metric cards + if (amount >= 1000000) { + return new Intl.NumberFormat('de-CH', { + style: 'currency', + currency: 'CHF', + notation: 'compact', + minimumFractionDigits: 0, + maximumFractionDigits: 1 + }).format(amount); + } else { + return new Intl.NumberFormat('de-CH', { + style: 'currency', + currency: 'CHF', + minimumFractionDigits: 0, + maximumFractionDigits: 0 + }).format(amount); + } + } + + formatCurrencyDetailed(amount) { + // Use full formatting for detailed views (tables, exports) return new Intl.NumberFormat('de-CH', { style: 'currency', currency: 'CHF', @@ -1037,10 +1077,10 @@ function exportToPDF() { doc.setFontSize(11); const params = [ - ['Investment Amount:', calculator.formatCurrency(inputs.investmentAmount)], + ['Investment Amount:', calculator.formatCurrencyDetailed(inputs.investmentAmount)], ['Investment Timeframe:', `${inputs.timeframe} years`], ['Discount Rate:', `${(inputs.discountRate * 100).toFixed(1)}%`], - ['Revenue per Instance:', calculator.formatCurrency(inputs.revenuePerInstance)], + ['Revenue per Instance:', calculator.formatCurrencyDetailed(inputs.revenuePerInstance)], ['Servala Revenue Share:', `${(inputs.servalaShare * 100).toFixed(0)}%`], ['Grace Period:', `${inputs.gracePeriod} months`] ]; @@ -1075,9 +1115,9 @@ function exportToPDF() { const resultData = [ ['Final Instances:', result.finalInstances.toLocaleString()], - ['Total Revenue:', calculator.formatCurrency(result.totalRevenue)], - ['CSP Revenue:', calculator.formatCurrency(result.cspRevenue)], - ['Servala Revenue:', calculator.formatCurrency(result.servalaRevenue)], + ['Total Revenue:', calculator.formatCurrencyDetailed(result.totalRevenue)], + ['CSP Revenue:', calculator.formatCurrencyDetailed(result.cspRevenue)], + ['Servala Revenue:', calculator.formatCurrencyDetailed(result.servalaRevenue)], ['ROI:', calculator.formatPercentage(result.roi)], ['Break-even:', result.breakEvenMonth ? `${result.breakEvenMonth} months` : 'Not achieved'], ['NPV Break-even:', result.npvBreakEvenMonth ? `${result.npvBreakEvenMonth} months` : 'Not achieved']