';
document.getElementById('pwbt-insights-list').innerHTML = '
No data to analyze.';
Object.values(pwbtChartInstances).forEach(chart => chart ? chart.destroy() : null);
return;
}
// Calculate Averages
const avgSummaryContainer = document.getElementById('pwbt-average-summary-cards');
if (filteredLogs.length > 0) {
const avgMood = filteredLogs.reduce((sum,l)=>sum+l.mood,0)/filteredLogs.length;
const avgStress = filteredLogs.reduce((sum,l)=>sum+l.stressLevel,0)/filteredLogs.length;
const avgEnergy = filteredLogs.reduce((sum,l)=>sum+l.energyLevel,0)/filteredLogs.length;
const avgSleepHours = filteredLogs.reduce((sum,l)=>sum+l.sleepHours,0)/filteredLogs.length;
const avgSleepQuality = filteredLogs.reduce((sum,l)=>sum+l.sleepQuality,0)/filteredLogs.length;
avgSummaryContainer.innerHTML = `
Avg Mood: ${avgMood.toFixed(1)}/5
Avg Stress: ${avgStress.toFixed(1)}/5
Avg Energy: ${avgEnergy.toFixed(1)}/5
Avg Sleep: ${avgSleepHours.toFixed(1)}hrs (Quality: ${avgSleepQuality.toFixed(1)}/5)
`;
} else {
avgSummaryContainer.innerHTML = '
No data in selected range to calculate averages.
';
}
// Prepare chart data
const moodData = filteredLogs.map(log => ({x: log.datetime, y: log.mood}));
const stressData = filteredLogs.map(log => ({x: log.datetime, y: log.stressLevel}));
const energyData = filteredLogs.map(log => ({x: log.datetime, y: log.energyLevel}));
const sleepHoursData = filteredLogs.map(log => ({x: log.datetime, y: log.sleepHours}));
const sleepQualityData = filteredLogs.map(log => ({x: log.datetime, y: log.sleepQuality}));
const physActivityData = filteredLogs.map(log => ({x: log.datetime, y: log.physActivityDuration}));
const mindfulnessData = filteredLogs.map(log => ({x: log.datetime, y: log.mindfulnessDuration}));
document.getElementById('pwbt-dashboard-display').innerHTML = `
Mood Over Time
Stress Level Over Time
Energy Level Over Time
Sleep (Hours & Quality)
Physical Activity Duration (min)
Mindfulness/Relaxation Duration (min)
`;
// Render Charts
pwbtRenderLineChart('pwbt-mood-chart', moodData, 'Mood (1-5)', 'var(--success-color)');
pwbtRenderLineChart('pwbt-stress-chart', stressData, 'Stress (1-5)', 'var(--danger-color)');
pwbtRenderLineChart('pwbt-energy-chart', energyData, 'Energy (1-5)', 'var(--info-color)');
pwbtRenderDualLineChart('pwbt-sleep-chart', sleepHoursData, 'Hours Slept', sleepQualityData, 'Sleep Quality (1-5)');
pwbtRenderBarChart('pwbt-phys-activity-chart', physActivityData, 'Physical Activity (min)', 'var(--accent-color)');
pwbtRenderBarChart('pwbt-mindfulness-chart', mindfulnessData, 'Mindfulness/Relaxation (min)', 'var(--primary-color)');
// Generate Insights
const insightsListEl = document.getElementById('pwbt-insights-list');
insightsListEl.innerHTML = ''; let insightsGenerated = 0;
if (filteredLogs.length >= 3) { // Need some data for meaningful insights
const avgStress = filteredLogs.reduce((sum,l)=>sum+l.stressLevel,0)/filteredLogs.length;
const avgSleepQ = filteredLogs.reduce((sum,l)=>sum+l.sleepQuality,0)/filteredLogs.length;
const avgSleepHours = filteredLogs.reduce((sum,l)=>sum+l.sleepHours,0)/filteredLogs.length;
const avgEnergy = filteredLogs.reduce((sum,l)=>sum+l.energyLevel,0)/filteredLogs.length;
const physActivityDays = filteredLogs.filter(l => l.physActivityDuration > 15).length;
if(avgStress > 3.5) { insightsListEl.innerHTML += `
Your average stress level (${avgStress.toFixed(1)}/5) is on the higher side. Consider incorporating more stress-reducing activities like mindfulness or ensuring adequate breaks.`; insightsGenerated++;}
if(avgSleepQ < 2.5 || avgSleepHours < 6.5) { insightsListEl.innerHTML += `
Average sleep quality (${avgSleepQ.toFixed(1)}/5) or duration (${avgSleepHours.toFixed(1)}hrs) appears low. Aim for 7-9 hours of quality sleep, as it significantly impacts mood and energy.`; insightsGenerated++;}
if(avgEnergy < 2.5) { insightsListEl.innerHTML += `
Low average energy (${avgEnergy.toFixed(1)}/5) can be linked to sleep, stress, or diet. Review these areas.`; insightsGenerated++;}
if(physActivityDays < filteredLogs.length / 2 && filteredLogs.length >= 5) { insightsListEl.innerHTML += `
Physical activity was logged on less than half the days in this period. Even short bursts of activity (15-30 min) can boost mood and energy.`; insightsGenerated++;}
// Simple trend check: compare first third to last third of data for mood
const third = Math.floor(filteredLogs.length / 3);
if (third >= 1) {
const firstThirdMoodAvg = filteredLogs.slice(0, third).reduce((s, l) => s + l.mood, 0) / third;
const lastThirdMoodAvg = filteredLogs.slice(-third).reduce((s, l) => s + l.mood, 0) / third;
if (lastThirdMoodAvg > firstThirdMoodAvg + 0.5) { insightsListEl.innerHTML += `
Positive trend noted: Your mood seems to be improving over this period!`; insightsGenerated++;}
else if (lastThirdMoodAvg < firstThirdMoodAvg - 0.5) { insightsListEl.innerHTML += `
Observation: Your mood shows a declining trend in this period. Reflect on potential contributing factors.`; insightsGenerated++;}
}
}
if(insightsGenerated === 0 && filteredLogs.length > 0) insightsListEl.innerHTML += `
Consistent logging helps identify personal well-being patterns. Keep tracking to see what works for you!`;
else if (filteredLogs.length === 0) insightsListEl.innerHTML += `
No data in the selected range to provide insights.`;
}
function pwbtRenderLineChart(canvasId, dataPoints, label, color) { /* ... (Same as sptaRenderLineChart, using pwbtChartInstances) ... */
const ctx = document.getElementById(canvasId);
if (!ctx) return;
if (pwbtChartInstances[canvasId]) pwbtChartInstances[canvasId].destroy();
pwbtChartInstances[canvasId] = new Chart(ctx.getContext('2d'), {
type: 'line',
data: { datasets: [{ label: label, data: dataPoints, borderColor: color, tension: 0.1, fill: false, pointRadius: 2, pointHoverRadius: 5 }] },
options: { responsive: true, maintainAspectRatio: false,
scales: { x: { type: 'time', time: { unit: 'day', tooltipFormat: 'MMM dd, yy', displayFormats: {'day': 'MMM dd'} } },
y: { beginAtZero: false, suggestedMin: 1, suggestedMax: (label.includes('(1-5)')) ? 5 : (label.includes('(1-10)') ? 10 : undefined), title: {display:true, text:label.split('(')[0].trim()} }
}
}
});
}
function pwbtRenderDualLineChart(canvasId, data1, label1, data2, label2) {
const ctx = document.getElementById(canvasId);
if (!ctx) return;
if (pwbtChartInstances[canvasId]) pwbtChartInstances[canvasId].destroy();
pwbtChartInstances[canvasId] = new Chart(ctx.getContext('2d'), {
type: 'line',
data: {
datasets: [
{ label: label1, data: data1, borderColor: 'var(--primary-color)', yAxisID: 'yHours', tension: 0.1, fill:false, pointRadius: 2 },
{ label: label2, data: data2, borderColor: 'var(--accent-color)', yAxisID: 'yQuality', tension: 0.1, fill:false, pointRadius: 2 }
]
},
options: { responsive: true, maintainAspectRatio: false,
scales: {
x: { type: 'time', time: { unit: 'day', tooltipFormat: 'MMM dd, yy' } },
yHours: { type: 'linear', position: 'left', title: {display:true, text:'Hours Slept'}, suggestedMin:0, suggestedMax:12},
yQuality: { type: 'linear', position: 'right', title: {display:true, text:'Quality (1-5)'}, min:1, max:5, grid:{drawOnChartArea:false} }
}
}
});
}
function pwbtRenderBarChart(canvasId, dataPoints, label, color) { // dataPoints = [{x: Date, y: value}]
const ctx = document.getElementById(canvasId);
if (!ctx) return;
if (pwbtChartInstances[canvasId]) pwbtChartInstances[canvasId].destroy();
pwbtChartInstances[canvasId] = new Chart(ctx.getContext('2d'), {
type: 'bar',
data: { datasets: [{ label: label, data: dataPoints, backgroundColor: color }] },
options: { responsive: true, maintainAspectRatio: false,
scales: { x: { type: 'time', time: { unit: 'day' } },
y: { beginAtZero: true, title: {display:true, text:"Duration (min)"}} } }
});
}
// PDF Download
function pwbtDownloadPDF() { /* ... (Similar to sptaDownloadPDF, adapt for well-being data and charts) ... */
if (pwbtWellBeingLogs.length === 0 || !document.getElementById('pwbt-mood-chart')) { // Check if dashboard has been rendered
alert("Please log some data and view the dashboard first."); return;
}
const analysisStartDate = document.getElementById('pwbt-analysis-start-date').value;
const analysisEndDate = document.getElementById('pwbt-analysis-end-date').value;
let pdfHTML = `
Personal Well-Being Report
`;
pdfHTML += `
Analysis Period: ${analysisStartDate} to ${analysisEndDate}
`;
const avgSummaryHTML = document.getElementById('pwbt-average-summary-cards').innerHTML;
if(avgSummaryHTML && !avgSummaryHTML.includes("No data")) pdfHTML += `
Well-Being Averages
${avgSummaryHTML}`;
const chartsToInclude = [
{instance: pwbtChartInstances['pwbt-mood-chart'], title: "Mood Over Time"},
{instance: pwbtChartInstances['pwbt-stress-chart'], title: "Stress Level Over Time"},
{instance: pwbtChartInstances['pwbt-energy-chart'], title: "Energy Level Over Time"},
{instance: pwbtChartInstances['pwbt-sleep-chart'], title: "Sleep (Hours & Quality)"},
{instance: pwbtChartInstances['pwbt-phys-activity-chart'], title: "Physical Activity Duration"},
{instance: pwbtChartInstances['pwbt-mindfulness-chart'], title: "Mindfulness/Relaxation Duration"}
];
chartsToInclude.forEach(chartInfo => {
if(chartInfo.instance){
pdfHTML += `
`;
}
});
const insightsContent = document.getElementById('pwbt-insights-list').outerHTML;
if(insightsContent && !insightsContent.includes("No data")) pdfHTML += `
Key Insights & Gentle Reminders
${insightsContent}`;
const filteredLogsForPDF = pwbtWellBeingLogs.filter(log => {
const logDateOnly = log.datetime.toISOString().split('T')[0];
return logDateOnly >= analysisStartDate && logDateOnly <= analysisEndDate;
});
if (filteredLogsForPDF.length > 0) {
pdfHTML += `
Detailed Log (${analysisStartDate} to ${analysisEndDate})
`;
pdfHTML += `
| Date | Mood | Stress | Energy | Sleep(H) | Sleep(Q) | Phys.Act(m) | Mindful(m) | Hydration | Positive |
`;
filteredLogsForPDF.forEach(log => {
pdfHTML += `
| ${log.datetime.toLocaleDateString()} | ${log.mood} | ${log.stressLevel} | ${log.energyLevel} |
${log.sleepHours.toFixed(1)} | ${log.sleepQuality} | ${log.physActivityDuration} | ${log.mindfulnessDuration} |
${log.hydration} | ${log.positiveMoment.substring(0,30)}${log.positiveMoment.length > 30 ? '...' : ''} |
`;
});
pdfHTML += `
`;
}
const pdfContainer = document.getElementById('pwbt-report-content-for-pdf');
pdfContainer.innerHTML = pdfHTML;
const opt = {
margin: [0.5, 0.3, 0.5, 0.3], filename: `WellBeing_Report_${analysisStartDate}_to_${analysisEndDate}.pdf`,
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, useCORS: true, logging: false, scrollX:0, scrollY: -window.scrollY, windowWidth: pdfContainer.scrollWidth + 100 },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' },
pagebreak: { mode: ['avoid-all', 'css', 'legacy'] }
};
html2pdf().from(pdfContainer).set(opt).save().then(() => {
pdfContainer.innerHTML = '';
}).catch(err => {
console.error("Error generating PDF:", err);
pdfContainer.innerHTML = '';
alert("An error occurred while generating the PDF. Check console for details.");
});
}