import { state } from '../core/state.js'; import { getToday } from '../services/ebbinghaus.js'; import { getErrorTopWords, getLast30DaysData, getStats, getStreak } from '../services/stats.js'; import { escapeHtml } from '../ui/dom.js'; let studyChart = null; // ==================== Page: Stats ==================== export function renderStats(el) { destroyStudyChart(); if (state.records.length === 0 && state.words.length === 0) { el.innerHTML = `

暂无数据

开始学习后这里会显示你的统计数据

`; return; } const s = getStats(); const streak = getStreak(); const todayRecords = state.records.filter(r => r.date === getToday()); const todayCorrect = todayRecords.filter(r => r.isCorrect).length; const todayTotal = todayRecords.length; const todayRate = todayTotal > 0 ? Math.round(todayCorrect / todayTotal * 100) : 0; const allCorrect = state.records.filter(r => r.isCorrect).length; const allTotal = state.records.length; const allRate = allTotal > 0 ? Math.round(allCorrect / allTotal * 100) : 0; const dailyData = getLast30DaysData(); const errorTop = getErrorTopWords(10); el.innerHTML = `
${s.total}
总单词
${s.mastered}
已掌握
${streak}
连续天数
${allRate}%
总正确率
${todayTotal}
今日练习次数
${todayRate}%
今日正确率

近30天学习量

最容易出错的单词 Top 10

${errorTop.length > 0 ? `
${errorTop.map(w => { const color = w.rate < 40 ? 'var(--error)' : w.rate < 70 ? 'var(--warning)' : 'var(--success)'; return ` `; }).join('')}
单词释义正确率次数
${escapeHtml(w.english)} ${escapeHtml(w.chinese)} ${w.rate}%
${w.total}
` : '

暂无测试数据

完成 AI 测试后,错误统计将在此展示

'}

掌握程度分布

已掌握${s.mastered}
学习中${s.learning}
新词${s.newCount}
`; renderStudyChart(dailyData); } export function destroyStudyChart() { if (!studyChart) return; studyChart.destroy(); studyChart = null; } export function refreshStudyChart() { if (!document.getElementById('study-chart')) return; renderStudyChart(getLast30DaysData()); } export function renderStudyChart(dailyData) { const ctx = document.getElementById('study-chart'); if (!ctx || typeof globalThis.Chart === 'undefined') return; destroyStudyChart(); const isDark = document.documentElement.getAttribute('data-theme') === 'dark'; const gridColor = isDark ? 'rgba(148, 163, 184, 0.1)' : 'rgba(148, 163, 184, 0.15)'; const textColor = isDark ? '#94a3b8' : '#64748b'; studyChart = new globalThis.Chart(ctx, { type: 'bar', data: { labels: dailyData.map(d => d.label), datasets: [{ label: '每日学习量', data: dailyData.map(d => d.count), backgroundColor: 'rgba(99, 102, 241, 0.7)', hoverBackgroundColor: 'rgba(99, 102, 241, 0.9)', borderRadius: 4, borderSkipped: false }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { backgroundColor: isDark ? '#334155' : '#1e293b', titleFont: { size: 12 }, bodyFont: { size: 13 }, padding: 10, cornerRadius: 8 } }, scales: { y: { beginAtZero: true, grid: { color: gridColor }, ticks: { color: textColor, font: { size: 11 } } }, x: { grid: { display: false }, ticks: { color: textColor, font: { size: 10 }, maxRotation: 45 } } } } }); }