Animal Behavior Ethogram Builder

Animal Behavior Ethogram Builder

EthoMapper

Animal Behavior Ethogram Builder
Study Metadata
Behavior Definitions

Define all observable behaviors for consistent data collection.

Code (e.g., GRM)
Behavior Name
Operational Definition (The "How")
Type
Remove

Target Species: ${meta.species} | Researcher: ${meta.researcher}

`; // 2. Log Table if (logData.length === 0) { html += '

No behaviors defined yet. Use the builder tab to define the ethogram.

'; } else { html += `

I. Behavior Catalog (Definitions)

`; logData.forEach(item => { const typeColor = item.type === 'Event' ? '#1e88e5' : (item.type === 'State' ? '#ffc107' : '#999'); html += ``; }); html += `
Code Behavior Name Operational Definition Type
${item.code} ${item.name} ${item.def} ${item.type}
`; html += `

*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`); }
Scroll to Top