let currentQuestionnaire = null; let questionnaireAnswers = []; function formatDate(timestamp) { if (!timestamp) return '-'; const date = new Date(timestamp); return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; } function renderPieChart(containerId, labels, data) { const ctx = document.getElementById(containerId).getContext('2d'); return new Chart(ctx, { type: 'pie', data: { labels: labels, datasets: [{ data: data, backgroundColor: [ '#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF', '#FF9F40' ] }] }, options: { responsive: true, maintainAspectRatio: false } }); } function renderBarChart(containerId, validCount, invalidCount) { const ctx = document.getElementById(containerId).getContext('2d'); return new Chart(ctx, { type: 'bar', data: { labels: ['有效回答', '无效回答'], datasets: [{ data: [validCount, invalidCount], backgroundColor: ['#36A2EB', '#FF6384'] }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, ticks: { stepSize: 1 } } }, plugins: { legend: { display: false } } } }); } function analyzeAnswers(question) { const answers = questionnaireAnswers.map(response => response.answers.find(a => a.questionId === question.id) ); if (question.type === 'text') { const validCount = answers.filter(a => a && a.answer && a.answer.trim()).length; const invalidCount = answers.length - validCount; return { validCount, invalidCount }; } else { const optionCounts = {}; question.options.forEach(opt => optionCounts[opt.id] = 0); answers.forEach(answer => { if (answer && answer.answer) { const selectedOptions = Array.isArray(answer.answer) ? answer.answer : [answer.answer]; selectedOptions.forEach(optId => { if (optionCounts[optId] !== undefined) { optionCounts[optId]++; } }); } }); return optionCounts; } } function renderQuestion(question, index) { const analysis = analyzeAnswers(question); const chartId = `chart_${question.id}`; let questionHtml = `