`;
// 2. Log Table
if (logData.length === 0) {
html += '
`;
html += `
No behaviors defined yet. Use the builder tab to define the ethogram.
'; } else { html += `I. Behavior Catalog (Definitions)
| Code | Behavior Name | Operational Definition | Type |
|---|---|---|---|
| ${item.code} | ${item.name} | ${item.def} | ${item.type} |
*Type Note: State (Duration/Time Sampling); Event (Frequency/Count); Context (Situation).
`; } container.innerHTML = html; } function ebbSwitchTab(tabId) { document.querySelectorAll('.ebb-tab-btn').forEach(b => b.classList.remove('active')); document.querySelectorAll('.ebb-content').forEach(c => c.classList.remove('active')); const idx = tabId === 'builder' ? 0 : 1; document.querySelectorAll('.ebb-tab-btn')[idx].classList.add('active'); document.getElementById('ebb-' + tabId).classList.add('active'); if (tabId === 'report') { ebbRenderReport(); } } function ebbLoadExample() { if(!confirm("Overwrite current data and load example primate behavior ethogram?")) return; document.getElementById('inp-species').value = "Macaca mulatta (Rhesus Macaque)"; document.getElementById('inp-researcher').value = "B. Smith / Primate Lab Study"; // Clear and fill log entries document.getElementById('ebb-behavior-rows-container').innerHTML = ''; ebbAddBehaviorRow("SIT", "Sitting", "Stationary, hindquarters in contact with substrate, not moving extremities.", "State"); ebbAddBehaviorRow("FGT", "Fighting", "Rapid approach, physical contact, chasing, or screaming directed at another individual.", "Event"); ebbAddBehaviorRow("TRV", "Travel", "Locomotion (walking, running, climbing) for more than 3 body lengths.", "State"); ebbAddBehaviorRow("AUT", "Auto-Grooming", "Licking or picking own fur or skin.", "State"); ebbAddBehaviorRow("ALF", "Affiliative", "Mutual grooming, close proximity (within 10 cm), non-aggressive touch.", "Event"); ebbRenderReport(); ebbSwitchTab('report'); } /* --- PDF Generation --- */ async function ebbGeneratePDF() { ebbRenderReport(); // Final render check const logData = ebbGetBehaviorData(); if (logData.length === 0) { alert("Please add behavior definitions before generating the PDF."); return; } const meta = { species: document.getElementById('inp-species').value || "Target Species", researcher: document.getElementById('inp-researcher').value || "Researcher/Study ID" }; const { jsPDF } = window.jspdf; const doc = new jsPDF('l', 'mm', 'a4'); // Landscape for wide table const green = [5, 150, 105]; let y = 20; // Header doc.setFillColor(...green); doc.rect(0, 0, 297, 20, 'F'); doc.setTextColor(255, 255, 255); doc.setFontSize(16); doc.text(`Ethogram for: ${meta.species}`, 14, 13); // Meta Data doc.setTextColor(0, 0, 0); doc.setFontSize(10); doc.setFont("helvetica", "normal"); doc.text(`Researcher/Study ID: ${meta.researcher}`, 14, y + 10); doc.text(`Date Generated: ${new Date().toLocaleDateString()}`, 250, y + 10); y += 20; // Log Table doc.setFontSize(14); doc.setFont("helvetica", "bold"); doc.setTextColor(...green); doc.text("Behavior Catalog (Operational Definitions)", 14, y); y += 5; const tableBody = logData.map(item => [ item.code, item.name, item.type, item.def ]); doc.autoTable({ startY: y, head: [['Code', 'Behavior Name', 'Type', 'Operational Definition']], body: tableBody, theme: 'grid', headStyles: { fillColor: green, fontSize: 10 }, styles: { fontSize: 8.5 }, columnStyles: { 0: { cellWidth: 20, fontStyle: 'bold', halign: 'center' }, 1: { cellWidth: 40, fontStyle: 'bold' }, 2: { cellWidth: 25, halign: 'center' }, 3: { cellWidth: 'auto', overflow: 'linebreak' } }, didParseCell: function(data) { if (data.section === 'body' && data.column.index === 2) { // Type column coloring const val = data.cell.raw; if (val === 'Event') data.cell.styles.textColor = [30, 144, 255]; else if (val === 'State') data.cell.styles.textColor = [255, 165, 0]; } } }); // Signature Block let finalY = doc.lastAutoTable.finalY + 15; if (finalY > 180) { doc.addPage(); finalY = 30; } doc.setFontSize(10); doc.text("Ethogram Approved By: ___________________________", 14, finalY); doc.save(`Ethogram_${meta.species.replace(/\s/g, '_')}.pdf`); }