| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- const Stats = (() => {
- async function init() {
- await loadStats();
- }
- async function loadStats() {
- const content = document.getElementById('stats-content');
- content.innerHTML = '<div class="loading">Loading stats...</div>';
- try {
- const stats = await API.getStats();
- renderStats(stats);
- } catch (e) {
- content.innerHTML = '<div class="error-msg">Error loading stats: ' + escHtml(e.message) + '</div>';
- }
- }
- function renderStats(stats) {
- const content = document.getElementById('stats-content');
- let html = '';
- // Summary totals
- if (stats.total !== undefined || stats.totalDistance !== undefined) {
- const totalDist = stats.total?.distance || stats.totalDistance || 0;
- const totalTracks = stats.total?.count || stats.trackCount || 0;
- html += `<div class="stats-section">
- <h3>Total</h3>
- <div class="stat-row">
- <span class="stat-label">Tracks</span>
- <div class="stat-bar-wrap"><div class="stat-bar" style="width:100%"></div></div>
- <span class="stat-value">${totalTracks}</span>
- </div>
- <div class="stat-row">
- <span class="stat-label">Distance</span>
- <div class="stat-bar-wrap"><div class="stat-bar" style="width:100%"></div></div>
- <span class="stat-value">${formatDistance(totalDist)}</span>
- </div>
- </div>`;
- }
- // By year
- if (stats.byYear && stats.byYear.length > 0) {
- const maxDist = Math.max(...stats.byYear.map(s => s.distance || 0));
- html += '<div class="stats-section"><h3>By Year</h3>';
- for (const s of stats.byYear) {
- const pct = maxDist > 0 ? ((s.distance || 0) / maxDist * 100) : 0;
- html += `<div class="stat-row">
- <span class="stat-label">${s.year}</span>
- <div class="stat-bar-wrap"><div class="stat-bar" style="width:${pct.toFixed(1)}%"></div></div>
- <span class="stat-value">${formatDistance(s.distance)}</span>
- </div>`;
- }
- html += '</div>';
- }
- // By month (last 24 months)
- if (stats.byMonth && stats.byMonth.length > 0) {
- const recent = stats.byMonth.slice(-24);
- const maxDist = Math.max(...recent.map(s => s.distance || 0));
- html += '<div class="stats-section"><h3>By Month (last 24)</h3>';
- for (const s of recent) {
- const pct = maxDist > 0 ? ((s.distance || 0) / maxDist * 100) : 0;
- const label = `${s.year}-${String(s.month).padStart(2, '0')}`;
- html += `<div class="stat-row">
- <span class="stat-label">${label}</span>
- <div class="stat-bar-wrap"><div class="stat-bar" style="width:${pct.toFixed(1)}%"></div></div>
- <span class="stat-value">${formatDistance(s.distance)}</span>
- </div>`;
- }
- html += '</div>';
- }
- // By week (last 52 weeks)
- if (stats.byWeek && stats.byWeek.length > 0) {
- const recent = stats.byWeek.slice(-52);
- const maxDist = Math.max(...recent.map(s => s.distance || 0));
- html += '<div class="stats-section"><h3>By Week (last 52)</h3>';
- for (const s of recent) {
- const pct = maxDist > 0 ? ((s.distance || 0) / maxDist * 100) : 0;
- const label = `${s.year}-W${String(s.week).padStart(2, '0')}`;
- html += `<div class="stat-row">
- <span class="stat-label">${label}</span>
- <div class="stat-bar-wrap"><div class="stat-bar" style="width:${pct.toFixed(1)}%"></div></div>
- <span class="stat-value">${formatDistance(s.distance)}</span>
- </div>`;
- }
- html += '</div>';
- }
- if (!html) {
- html = '<div class="empty-list">No tracks yet. Upload some GPX files to see stats.</div>';
- }
- content.innerHTML = html;
- }
- return { init, loadStats };
- })();
|