';
const dashboardDisplayEl = document.getElementById('pwct-dashboard-display');
const insightsListEl = document.getElementById('pwct-insights-list');
const avgSummaryEl = document.getElementById('pwct-average-summary-list');
Object.values(pwctChartInstances).forEach(chart => { if (chart) chart.destroy(); });
pwctChartInstances = {};
if (pwctSessionLogs.length === 0 && pwctCurrentTabIndex === 1) {
if(dashboardDisplayEl) dashboardDisplayEl.innerHTML = noDataMsg;
if(insightsListEl) insightsListEl.innerHTML = '
No data to analyze.';
if(avgSummaryEl) avgSummaryEl.innerHTML = '
No data for averages.';
return;
}
const startDateStr = document.getElementById('pwct-analysis-start-date').value;
const endDateStr = document.getElementById('pwct-analysis-end-date').value;
if(!startDateStr || !endDateStr) return;
const startDate = new Date(startDateStr + "T00:00:00");
const endDate = new Date(endDateStr + "T23:59:59");
const filteredLogs = pwctSessionLogs.filter(log => log.date >= startDate && log.date <= endDate);
if (filteredLogs.length === 0 && pwctCurrentTabIndex === 1) {
if(dashboardDisplayEl) dashboardDisplayEl.innerHTML = noDataMsg;
if(insightsListEl) insightsListEl.innerHTML = '
No data in selected range for insights.';
if(avgSummaryEl) avgSummaryEl.innerHTML = '
No data in range for averages.';
return;
}
if(avgSummaryEl){
if(filteredLogs.length > 0){
const calcAvg = (key) => filteredLogs.reduce((s,l)=>s+l[key],0)/filteredLogs.length;
avgSummaryEl.innerHTML = `
Avg. Sleep: ${calcAvg('sleepHours').toFixed(1)}h (Quality: ${calcAvg('sleepQuality').toFixed(1)}/5)
Avg. Mood: ${calcAvg('mood').toFixed(1)}/5 | Avg. Stress: ${calcAvg('stressLevel').toFixed(1)}/5 | Avg. Energy: ${calcAvg('energyLevel').toFixed(1)}/5
Avg. Tasks Completed: ${calcAvg('tasksCompleted').toFixed(1)} | Avg. Productivity: ${calcAvg('productivity').toFixed(1)}/5 | Avg. Focus: ${calcAvg('focus').toFixed(1)}/5
`;
} else { avgSummaryEl.innerHTML = '
No data in range for averages.'; }
}
const chartData = (key) => filteredLogs.map(log => ({x: log.date, y: log[key]}));
// Predefined Correlation Spotlights
if(dashboardDisplayEl) {
dashboardDisplayEl.innerHTML = `
Sleep Hours vs Focus Level
Stress Level vs Productivity
Physical Activity vs Mood
Sleep Quality vs Mood
`; // Trend charts removed for now to focus on correlations
}
// Render Predefined Correlation Charts (using scatter for clearer correlation)
pwctRenderCorrelationChart('pwct-corr-sleep-focus', filteredLogs, 'sleepHours', 'focus', 'Sleep Hours', 'Focus Level (1-5)');
pwctRenderCorrelationChart('pwct-corr-stress-prod', filteredLogs, 'stressLevel', 'productivity', 'Stress Level (1-5)', 'Productivity (1-5)');
pwctRenderCorrelationChart('pwct-corr-activity-mood', filteredLogs, 'physicalActivity', 'mood', 'Physical Activity (min)', 'Mood (1-5)');
pwctRenderCorrelationChart('pwct-corr-sleepq-mood', filteredLogs, 'sleepQuality', 'mood', 'Sleep Quality (1-5)', 'Mood (1-5)');
// Plot User-Selected Correlation (initially based on defaults)
pwctPlotCustomCorrelation();
// Generate Insights
if(insightsListEl){
insightsListEl.innerHTML = ''; let insightsGeneratedCount = 0;
if (filteredLogs.length >= 5) {
// Simple insight example: If avg sleep < 6.5 and avg productivity < 3
const avgSleep = filteredLogs.reduce((s,l)=>s+l.sleepHours,0)/filteredLogs.length;
const avgProd = filteredLogs.reduce((s,l)=>s+l.productivity,0)/filteredLogs.length;
if(avgSleep < 6.5 && avgProd < 3) { insightsListEl.innerHTML += `
Your average sleep of ${avgSleep.toFixed(1)}h appears to be correlated with lower average productivity (${avgProd.toFixed(1)}/5). Consider aiming for more consistent, quality sleep.`; insightsGeneratedCount++;}
const highStressDays = filteredLogs.filter(l => l.stressLevel >= 4);
if(highStressDays.length > filteredLogs.length * 0.4) { // If more than 40% of days are high stress
const avgFocusOnHighStress = highStressDays.reduce((s,l)=>s+l.focus,0) / (highStressDays.length || 1);
insightsListEl.innerHTML += `
High stress is reported on many days. On these days, average focus is ${avgFocusOnHighStress.toFixed(1)}/5. Managing stress could boost focus.`; insightsGeneratedCount++;
}
// Find days with good sleep quality (>3) and good mood (>3)
const goodSleepAndMoodDays = filteredLogs.filter(l => l.sleepQuality > 3 && l.mood > 3).length;
if (goodSleepAndMoodDays > filteredLogs.length / 2) {
insightsListEl.innerHTML += `
Positive Correlation Noted: Good sleep quality frequently aligns with a positive mood the next day in your logs.`; insightsGeneratedCount++;
}
}
if(insightsGeneratedCount === 0 && filteredLogs.length > 0) insightsListEl.innerHTML += `
Explore different metric correlations in the 'Correlation Explorer' to find personal patterns! Consistent logging provides richer insights.`;
else if (filteredLogs.length === 0) insightsListEl.innerHTML += `
No data in selected range for insights.`;
}
}
function pwctPlotCustomCorrelation(){
const metric1Key = document.getElementById('pwct-metric1-select').value;
const metric2Key = document.getElementById('pwct-metric2-select').value;
if(!metric1Key || !metric2Key) return;
const metric1Def = PWCT_METRIC_DEFINITIONS.find(m => m.key === metric1Key);
const metric2Def = PWCT_METRIC_DEFINITIONS.find(m => m.key === metric2Key);
const startDateStr = document.getElementById('pwct-analysis-start-date').value;
const endDateStr = document.getElementById('pwct-analysis-end-date').value;
const startDate = new Date(startDateStr + "T00:00:00");
const endDate = new Date(endDateStr + "T23:59:59");
const filteredLogs = pwctSessionLogs.filter(log => log.date >= startDate && log.date <= endDate);
if(filteredLogs.length < 2) {
document.getElementById('pwct-custom-correlation-insight').textContent = "Not enough data points in the selected range to plot this correlation.";
if(pwctChartInstances['pwct-custom-correlation-chart']) {pwctChartInstances['pwct-custom-correlation-chart'].destroy(); delete pwctChartInstances['pwct-custom-correlation-chart'];}
const canvas = document.getElementById('pwct-custom-correlation-chart');
if(canvas) { const ctx = canvas.getContext('2d'); ctx.clearRect(0,0,canvas.width,canvas.height);}
return;
}
pwctRenderCorrelationChart('pwct-custom-correlation-chart', filteredLogs, metric1Key, metric2Key, metric1Def.name, metric2Def.name);
// Basic textual insight for custom correlation
// This would require actual correlation coefficient calculation or more complex quartile analysis,
// For V1, the visual plot is the main insight.
document.getElementById('pwct-custom-correlation-insight').textContent = `Showing correlation between ${metric1Def.name} and ${metric2Def.name}. Look for patterns in the scatter plot.`;
}
function pwctRenderCorrelationChart(canvasId, logs, keyX, keyY, labelX, labelY) {
const ctx = document.getElementById(canvasId);
if (!ctx) return;
if (pwctChartInstances[canvasId]) pwctChartInstances[canvasId].destroy();
const dataPoints = logs.map(log => ({x: log[keyX], y: log[keyY]}));
const metricXDef = PWCT_METRIC_DEFINITIONS.find(m => m.key === keyX);
const metricYDef = PWCT_METRIC_DEFINITIONS.find(m => m.key === keyY);
pwctChartInstances[canvasId] = new Chart(ctx.getContext('2d'), {
type: 'scatter',
data: {
datasets: [{
label: `${labelX} vs ${labelY}`,
data: dataPoints,
backgroundColor: 'var(--primary-color)',
borderColor: 'var(--dark-color)',
borderWidth: 1,
pointRadius: 4,
pointHoverRadius: 6
}]
},
options: {
responsive: true, maintainAspectRatio: false,
scales: {
x: { title: { display: true, text: labelX }, min: metricXDef.scaleMin, suggestedMax: metricXDef.scaleMax },
y: { title: { display: true, text: labelY }, min: metricYDef.scaleMin, suggestedMax: metricYDef.scaleMax }
},
plugins: { legend: { display: false }}
}
});
}
// PDF Download
function pwctDownloadPDF() {
const dashboardDisplayEl = document.getElementById('shpi-dashboard-display'); // Check generic display area
if (!dashboardDisplayEl || dashboardDisplayEl.innerHTML.includes("Log daily data") || shpiSessionLogs.length === 0) {
alert("Please log some data and view the dashboard first."); return;
}
const analysisStartDate = document.getElementById('shpi-analysis-start-date').value;
const analysisEndDate = document.getElementById('shpi-analysis-end-date').value;
let pdfHTML = `
Healthy Productivity Insights Report
`;
pdfHTML += `
Analysis Period: ${analysisStartDate} to ${analysisEndDate}
`;
const avgSummaryContent = document.getElementById('shpi-average-summary-list').outerHTML;
if(avgSummaryContent) pdfHTML += `
Overall Averages (Selected Period)
${avgSummaryContent}`;
const chartsToInclude = [ // Predefined correlation charts + custom one if plotted
{instanceKey: 'pwct-corr-sleep-focus', title: "Sleep Hours vs Focus Level"},
{instanceKey: 'pwct-corr-stress-prod', title: "Stress Level vs Productivity"},
{instanceKey: 'pwct-corr-activity-mood', title: "Physical Activity vs Mood"},
{instanceKey: 'pwct-corr-sleepq-mood', title: "Sleep Quality vs Mood"},
{instanceKey: 'pwct-custom-correlation-chart', title: "Custom Correlation Explorer"}
];
chartsToInclude.forEach(chartInfo => {
const chartInstance = pwctChartInstances[chartInfo.instanceKey];
if(chartInstance){
try {
pdfHTML += `
${chartInfo.title}
`;
} catch (e) { console.error("Error converting chart to image for PDF: ", chartInfo.title, e); }
}
});
const insightsContent = document.getElementById('shpi-insights-list').outerHTML;
if(insightsContent) pdfHTML += `
"Smart" Insights & Recommendations
${insightsContent}`;
const filteredLogsForPDF = shpiSessionLogs.filter(log => {
const logDateOnly = log.date.toISOString().split('T')[0];
return logDateOnly >= analysisStartDate && logDateOnly <= analysisEndDate;
});
if (filteredLogsForPDF.length > 0 && confirm("Include detailed daily logs in PDF? (Can be long)")) {
pdfHTML += `
Detailed Logs (${analysisStartDate} to ${analysisEndDate})
`;
pdfHTML += `
| Date | Slp(H) | Slp(Q) | Stress | Mood | Energy | Activ(m) | Tasks | Prod | Focus | Notes |
`;
filteredLogsForPDF.forEach(log => {
pdfHTML += `
| ${log.date.toLocaleDateString()} | ${log.sleepHours.toFixed(1)} | ${log.sleepQuality} |
${log.stressLevel} | ${log.mood} | ${log.energyLevel} | ${log.physicalActivity} |
${log.tasksCompleted} | ${log.productivity} | ${log.focus} |
${log.notes.substring(0,30)}${log.notes.length > 30 ? '...' : ''} |
`;
});
pdfHTML += `
`;
}
const pdfContainer = document.getElementById('shpi-report-content-for-pdf');
pdfContainer.innerHTML = pdfHTML;
const opt = {
margin: [0.5, 0.3, 0.5, 0.3], filename: `Productivity_Wellness_Correlation_${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.");
});
}