Electric Vehicle (EV) Battery Health Dashboard
An interactive tool to monitor and analyze your EV's battery performance.
State of Health (SoH)
The overall health and capacity of your battery compared to new.
State of Charge (SoC)
The current charge level of your battery.
Estimated Range
-- miles
Battery Temperature
-- °F
Charge Cycles
--
Capacity Degradation Over Cycles
Battery Health Analysis
Tips for Longevity
-
Avoid regular charging to 100%. Aim for 80-90% for daily use to reduce battery strain.
-
Limit DC Fast Charging. While convenient, frequent fast charging can accelerate degradation. Prioritize Level 2 AC charging.
-
Minimize exposure to extreme temperatures. Park in the shade or a garage when possible, especially in hot or cold climates.
-
Avoid deep discharges. Try not to let the battery level drop below 20% regularly.
Configure Your Vehicle's Data
Enter your EV's current metrics to update the dashboard. Sample data for a typical US model is pre-filled.
At its current charge level, you have an estimated range of ${range.toFixed(0)} miles.
The battery has undergone approximately ${cycles} charge cycles.
Recommendation: ${advice}
`; } // --- TAB & NAVIGATION LOGIC --- // window.changeTab = (tabId) => { // Hide all content document.querySelectorAll('.tab-content').forEach(content => content.classList.add('hidden')); // Deactivate all buttons document.querySelectorAll('.tab-btn').forEach(btn => { btn.classList.remove('tab-active'); btn.classList.add('tab-inactive'); }); // Show selected content const contentToShow = getElement(`tab-content-${tabId}`); if (contentToShow) contentToShow.classList.remove('hidden'); // Activate selected button const btnToActivate = getElement(`tab-btn-${tabId}`); if(btnToActivate) { btnToActivate.classList.remove('tab-inactive'); btnToActivate.classList.add('tab-active'); } currentTabIndex = tabOrder.indexOf(tabId); updateNavButtons(); }; function updateNavButtons() { if (prevBtn) prevBtn.disabled = (currentTabIndex === 0); if (nextBtn) nextBtn.disabled = (currentTabIndex === tabOrder.length - 1); if (prevBtn) prevBtn.classList.toggle('opacity-50', prevBtn.disabled); if (nextBtn) nextBtn.classList.toggle('opacity-50', nextBtn.disabled); } // --- EVENT LISTENERS --- // if (socSlider && socSliderValue) { socSlider.addEventListener('input', (e) => { socSliderValue.textContent = `${e.target.value}%`; }); } if (updateBtn) { updateBtn.addEventListener('click', () => { updateDashboard(); changeTab('dashboard'); // Switch to dashboard after update }); } if (nextBtn) { nextBtn.addEventListener('click', () => { if (currentTabIndex < tabOrder.length - 1) { changeTab(tabOrder[currentTabIndex + 1]); } }); } if (prevBtn) { prevBtn.addEventListener('click', () => { if (currentTabIndex > 0) { changeTab(tabOrder[currentTabIndex - 1]); } }); } if (pdfBtn) { pdfBtn.addEventListener('click', () => { const { jsPDF } = window.jspdf; const content = getElement('pdf-content-area'); if (!content) return; // Show both dashboard and report temporarily for capture const dashboardContent = getElement('tab-content-dashboard'); const reportContent = getElement('tab-content-report'); dashboardContent.classList.remove('hidden'); reportContent.classList.remove('hidden'); const originalTab = tabOrder[currentTabIndex]; // Add a loading indicator to the button pdfBtn.textContent = 'Generating...'; pdfBtn.disabled = true; html2canvas(content, { scale: 2, // Higher scale for better quality useCORS: true, onclone: (document) => { // Ensure charts are rendered properly in the clone } }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const ratio = canvasWidth / canvasHeight; const imgWidth = pdfWidth - 20; // with margin const imgHeight = imgWidth / ratio; let heightLeft = imgHeight; let position = 10; // top margin pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= (pdfHeight - 20); while (heightLeft > 0) { position = -heightLeft + 10; pdf.addPage(); pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= (pdfHeight - 20); } pdf.save('EV_Battery_Health_Report.pdf'); // Restore UI pdfBtn.textContent = 'Download Report as PDF'; pdfBtn.disabled = false; changeTab(originalTab); // Go back to the tab the user was on }).catch(err => { console.error("PDF generation failed:", err); // Restore UI in case of error pdfBtn.textContent = 'Download Report as PDF'; pdfBtn.disabled = false; changeTab(originalTab); }); }); } // --- INITIALIZATION CALL --- // // Initial setup on page load createSoHChart(); createSoCChart(); createDegradationChart(); updateDashboard(); // Populate with default data changeTab('dashboard'); // Start on the dashboard tab });