better cope with big numbers

This commit is contained in:
Tobias Brunner 2025-07-16 15:15:34 +02:00
parent 545b49ecd2
commit 3688720f1b
Signed by: tobru
SSH key fingerprint: SHA256:kOXg1R6c11XW3/Pt9dbLdQvOJGFAy+B2K6v6PtRWBGQ

View file

@ -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;
}
}
</style>
@ -843,9 +862,9 @@ class ROICalculator {
row.innerHTML = `
<td><strong>${result.scenario}</strong></td>
<td>${result.finalInstances.toLocaleString()}</td>
<td>${this.formatCurrency(result.totalRevenue)}</td>
<td>${this.formatCurrency(result.cspRevenue)}</td>
<td>${this.formatCurrency(result.servalaRevenue)}</td>
<td>${this.formatCurrencyDetailed(result.totalRevenue)}</td>
<td>${this.formatCurrencyDetailed(result.cspRevenue)}</td>
<td>${this.formatCurrencyDetailed(result.servalaRevenue)}</td>
<td class="${result.roi >= 0 ? 'text-success' : 'text-danger'}">${this.formatPercentage(result.roi)}</td>
<td>${result.breakEvenMonth ? result.breakEvenMonth + ' months' : 'N/A'}</td>
<td>${result.npvBreakEvenMonth ? result.npvBreakEvenMonth + ' months' : 'N/A'}</td>
@ -875,15 +894,36 @@ class ROICalculator {
<td>${data.newInstances}</td>
<td>${data.churnedInstances}</td>
<td>${data.totalInstances.toLocaleString()}</td>
<td>${this.formatCurrency(data.monthlyRevenue)}</td>
<td>${this.formatCurrency(data.cspRevenue)}</td>
<td>${this.formatCurrency(data.servalaRevenue)}</td>
<td>${this.formatCurrency(data.cumulativeCSPRevenue)}</td>
<td>${this.formatCurrencyDetailed(data.monthlyRevenue)}</td>
<td>${this.formatCurrencyDetailed(data.cspRevenue)}</td>
<td>${this.formatCurrencyDetailed(data.servalaRevenue)}</td>
<td>${this.formatCurrencyDetailed(data.cumulativeCSPRevenue)}</td>
`;
});
}
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']