No lifts logged yet.
`;
return;
}
let tableHTML = `
| Date |
Exercise |
Type |
Weight (lbs) |
Reps x Sets |
`;
liftLog.forEach(lift => {
tableHTML += `
| ${lift.date} |
${lift.exercise} |
${lift.type} |
${lift.weight} |
${lift.reps} x ${lift.sets} |
`;
});
tableHTML += `
`;
logTableContainer.innerHTML = tableHTML;
};
const renderChart = () => {
const selectedExercise = chartExerciseSelect.value;
const filteredData = liftLog
.filter(lift => lift.exercise === selectedExercise)
.sort((a, b) => new Date(a.date) - new Date(b.date));
const barbellData = filteredData.filter(lift => lift.type === 'Barbell');
const dumbbellData = filteredData.filter(lift => lift.type === 'Dumbbell');
const labels = [...new Set(filteredData.map(lift => lift.date))].sort();
const chartData = {
labels: labels,
datasets: [
{
label: 'Barbell Weight (lbs)',
data: barbellData.map(lift => ({ x: lift.date, y: lift.weight })),
borderColor: 'rgb(59, 130, 246)',
backgroundColor: 'rgba(59, 130, 246, 0.5)',
tension: 0.1
},
{
label: 'Dumbbell Weight (lbs, per hand)',
data: dumbbellData.map(lift => ({ x: lift.date, y: lift.weight })),
borderColor: 'rgb(239, 68, 68)',
backgroundColor: 'rgba(239, 68, 68, 0.5)',
tension: 0.1
}
]
};
const ctx = document.getElementById('progress-chart').getContext('2d');
if (progressChart) {
progressChart.destroy();
}
progressChart = new Chart(ctx, {
type: 'line',
data: chartData,
options: {
responsive: true,
plugins: {
legend: { position: 'top' },
title: { display: true, text: `Weight Progression for ${selectedExercise}` }
},
scales: {
x: { title: { display: true, text: 'Date' } },
y: { title: { display: true, text: 'Weight (lbs)' } }
}
}
});
};
// --- PDF Generation ---
const generatePdf = () => {
const { jsPDF } = window.jspdf;
if (typeof jsPDF === 'undefined' || typeof jsPDF.API.autoTable !== 'function') {
console.error("jsPDF or autoTable library not loaded correctly.");
return;
}
if (liftLog.length === 0) {
alert("No data to generate a report.");
return;
}
const doc = new jsPDF();
const pageWidth = doc.internal.pageSize.width;
let yPos = 20;
// Header
doc.setFont('helvetica', 'bold');
doc.setFontSize(20);
doc.setTextColor(44, 62, 80);
doc.text('Strength Progress Report', pageWidth / 2, yPos, { align: 'center' });
yPos += 10;
// Chart Image
const chartImage = progressChart.toBase64Image();
doc.setFont('helvetica', 'bold');
doc.setFontSize(14);
doc.text(`Progress Chart: ${chartExerciseSelect.value}`, 14, yPos);
yPos += 5;
doc.addImage(chartImage, 'PNG', 14, yPos, pageWidth - 28, (pageWidth - 28) * 0.5);
yPos += (pageWidth - 28) * 0.5 + 10;
// Full Log Table
doc.setFont('helvetica', 'bold');
doc.setFontSize(14);
doc.text('Full Lift History', 14, yPos);
yPos += 5;
const tableData = liftLog.map(lift => [
lift.date,
lift.exercise,
lift.type,
lift.weight,
`${lift.reps} x ${lift.sets}`
]);
doc.autoTable({
startY: yPos,
head: [['Date', 'Exercise', 'Type', 'Weight (lbs)', 'Reps x Sets']],
body: tableData,
theme: 'grid',
headStyles: { fillColor: [44, 62, 80] }
});
doc.save('Strength_Progress_Report.pdf');
};
init();
});