Animal Growth Rate Calculator & Visualizer

Please select an animal to begin.

'; if (growthChart) growthChart.destroy(); dataTable.innerHTML = ''; return; } renderMetrics(); renderChart(); renderDataTable(); } function renderMetrics() { const selectedAnimals = getSelectedAnimals(); const unit = getCurrentUnit(); metricsContainer.innerHTML = selectedAnimals.map(animalName => { const animal = growthData[animalName]; const data = animal.data; if (data.length < 2) return ''; const start = data[0]; const end = data[data.length - 1]; const weightGain = end.weightKg - start.weightKg; const timeSpan = end.age - start.age; const daysInUnit = animal.timeUnit === 'Weeks' ? 7 : 30.4; const adg = weightGain / (timeSpan * daysInUnit); return `

${animalName} - ADG

${convertWeight(adg, unit).toFixed(3)} ${unit}/day
`; }).join(''); } function renderChart() { const selectedAnimals = getSelectedAnimals(); const unit = getCurrentUnit(); const ctx = document.getElementById('growth-chart').getContext('2d'); const chartColors = ['#65a30d', '#f97316', '#2563eb', '#dc2626']; const datasets = selectedAnimals.map((animalName, index) => { const animal = growthData[animalName]; return { label: `${animalName} (${unit})`, data: animal.data.map(p => ({ x: p.age, y: convertWeight(p.weightKg, unit) })), borderColor: chartColors[index % chartColors.length], backgroundColor: chartColors[index % chartColors.length], tension: 0.1, fill: false }; }); // Determine a common time unit for the x-axis label const commonTimeUnit = selectedAnimals.length > 0 ? growthData[selectedAnimals[0]].timeUnit : 'Time'; if (growthChart) { growthChart.destroy(); } growthChart = new Chart(ctx, { type: 'line', data: { datasets }, options: { responsive: true, maintainAspectRatio: false, scales: { x: { type: 'linear', title: { display: true, text: `Age in ${commonTimeUnit}` }, beginAtZero: true }, y: { title: { display: true, text: `Weight (${unit})` }, beginAtZero: true } } } }); } function renderDataTable() { const selectedAnimals = getSelectedAnimals(); const unit = getCurrentUnit(); if (selectedAnimals.length === 0) { dataTable.innerHTML = ''; return; } // Unify data points by age const allAges = new Set(); selectedAnimals.forEach(name => growthData[name].data.forEach(p => allAges.add(p.age))); const sortedAges = Array.from(allAges).sort((a, b) => a - b); const headerTimeUnit = growthData[selectedAnimals[0]].timeUnit; let tableHTML = ` Age (${headerTimeUnit}) ${selectedAnimals.map(name => `${name} (${unit})`).join('')} `; sortedAges.forEach(age => { tableHTML += `${age}`; selectedAnimals.forEach(name => { const dataPoint = growthData[name].data.find(p => p.age === age); const value = dataPoint ? convertWeight(dataPoint.weightKg, unit).toFixed(2) : 'N/A'; const editable = dataPoint ? `contenteditable="true" onblur="agr_updateDataPoint('${name}', ${age}, this.innerText)"` : ''; tableHTML += `${value}`; }); tableHTML += ``; }); tableHTML += ``; dataTable.innerHTML = tableHTML; } window.agr_updateDataPoint = (animalName, age, newValue) => { const unit = getCurrentUnit(); const numericValue = parseFloat(newValue); if (isNaN(numericValue)) { renderAll(); // Revert if input is not a number return; } const weightInKg = unit === 'lbs' ? numericValue / KG_TO_LBS : numericValue; const dataPoint = growthData[animalName].data.find(p => p.age === age); if (dataPoint) { dataPoint.weightKg = weightInKg; } renderAll(); // Re-render everything to reflect the change }; // --- EVENT LISTENERS & INITIALIZATION --- function initialize() { animalSelect.innerHTML = Object.keys(growthData).map(name => ``).join(''); animalSelect.addEventListener('change', renderAll); unitSelect.addEventListener('change', renderAll); const downloadBtn = document.getElementById('agr-download-pdf-btn'); if(downloadBtn) { downloadBtn.addEventListener('click', () => { const visualizer = document.getElementById('agr-tab-0'); if (!visualizer) return; html2canvas(visualizer, { scale: 2, useCORS: true }).then(canvas => { const { jsPDF } = window.jspdf; const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'l', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const ratio = canvas.width / canvas.height; let imgWidth = pdfWidth - 20; let imgHeight = imgWidth / ratio; if (imgHeight > pdfHeight - 20) { imgHeight = pdfHeight - 20; imgWidth = imgHeight * ratio; } pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight); pdf.save('Animal-Growth-Visualizer.pdf'); }); }); } renderAll(); } initialize(); });
Scroll to Top