diff --git a/app.js b/app.js index 4846d1f..ce8f01b 100644 --- a/app.js +++ b/app.js @@ -1,3 +1,10 @@ +// Format RUB amount: no decimals, thin space (U+2009) as thousands separator +function formatRUB(amount) { + return Math.round(amount) + .toLocaleString('ru-RU') + .replace(/\u00a0/g, '\u202F'); +} + // Initialize the chart const chartDom = document.getElementById('chart-container'); const myChart = echarts.init(chartDom); @@ -44,9 +51,9 @@ function navigateToHistoryState(state) { option.series.data = state.data; if (state.contextName) { - option.graphic.elements[0].style.text = `${russianMonth}\n${state.contextName}\n${state.total.toFixed(0).toLocaleString()} ₽`; + option.graphic.elements[0].style.text = `${russianMonth}\n${state.contextName}\n${formatRUB(state.total)}\u202F₽`; } else { - option.graphic.elements[0].style.text = russianMonth + '\n' + state.total.toFixed(0).toLocaleString() + ' ₽'; + option.graphic.elements[0].style.text = russianMonth + '\n' + formatRUB(state.total) + '\u202F₽'; } myChart.setOption(option, { replaceMerge: ['series'] }); @@ -687,13 +694,13 @@ function renderChart(data) { tooltip: { trigger: 'item', formatter: function(info) { - const value = info.value.toLocaleString(); + const value = formatRUB(info.value); const name = info.name; - + // Calculate percentage of total const percentage = ((info.value / sunburstData.total) * 100).toFixed(1); - - return `${name}
Amount: ${value} RUB
Percentage: ${percentage}%`; + + return `${name}
Amount: ${value}\u202F₽
Percentage: ${percentage}%`; } } }, @@ -705,7 +712,7 @@ function renderChart(data) { top: 'middle', z: 100, style: { - text: russianMonth + '\n' + sunburstData.total.toFixed(0).toLocaleString() + ' ₽', + text: russianMonth + '\n' + formatRUB(sunburstData.total) + '\u202F₽', fontFamily: '-apple-system, BlinkMacSystemFont, "SF Pro", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif', fontWeight: 'bold', fontSize: 18, @@ -907,7 +914,7 @@ function renderChart(data) { // Update the center text to show the drilled-down category const russianMonth = getRussianMonthName(document.getElementById('month-select').value); - option.graphic.elements[0].style.text = `${russianMonth}\n${params.name}\n${params.value.toFixed(0).toLocaleString()} ₽`; + option.graphic.elements[0].style.text = `${russianMonth}\n${params.name}\n${formatRUB(params.value)}\u202F₽`; myChart.setOption(option, { replaceMerge: ['series'] }); @@ -1679,9 +1686,9 @@ async function selectMonth(index) { // Update the total amount in the center text const russianMonth = getRussianMonthName(month); if (targetName) { - option.graphic.elements[0].style.text = `${russianMonth}\n${targetName}\n${targetTotal.toFixed(0).toLocaleString()} ₽`; + option.graphic.elements[0].style.text = `${russianMonth}\n${targetName}\n${formatRUB(targetTotal)}\u202F₽`; } else { - option.graphic.elements[0].style.text = russianMonth + '\n' + targetTotal.toFixed(0).toLocaleString() + ' ₽'; + option.graphic.elements[0].style.text = russianMonth + '\n' + formatRUB(targetTotal) + '\u202F₽'; } myChart.setOption({ @@ -2098,7 +2105,7 @@ function setupHoverEvents(sunburstData, contextName = null) { const amountSpan = document.createElement('span'); amountSpan.className = 'top-item-amount'; - amountSpan.textContent = item.value.toLocaleString() + ' ₽'; + amountSpan.textContent = formatRUB(item.value) + '\u202F₽'; itemDiv.appendChild(amountSpan); topItemsElement.appendChild(itemDiv); }); @@ -2125,7 +2132,7 @@ function setupHoverEvents(sunburstData, contextName = null) { - ${value.toLocaleString()} ₽ + ${formatRUB(value)}\u202F₽ `; // Add click handler to header eye button const headerEyeBtn = detailsHeader.querySelector('.header-eye-btn'); @@ -2166,7 +2173,7 @@ function setupHoverEvents(sunburstData, contextName = null) { - ${sunburstData.total.toLocaleString()} ₽ + ${formatRUB(sunburstData.total)}\u202F₽ `; // Add click handler to header eye button @@ -2518,7 +2525,7 @@ function renderTransactionTable() { let value = transaction.originalRow[col]; if ((col === 'amount_rub' || col === 'amount_original') && typeof value === 'number') { - value = value.toLocaleString(); + value = formatRUB(value); } td.textContent = value !== undefined && value !== null ? value : '';