Telehealth ROI Dashboard

Telehealth ROI Dashboard

Calculate and visualize the return on investment for your telehealth implementation.

Annual Cost Savings Breakdown

Cumulative ROI Over 3 Years

Detailed ROI Calculation (Annual)

${isFinite(results.paybackPeriodMonths) ? results.paybackPeriodMonths.toFixed(1) + ' mo' : 'N/A'}

`; }; const renderSavingsBreakdownChart = (results) => { const ctx = document.getElementById('savingsBreakdownChart').getContext('2d'); if (savingsBreakdownChart) savingsBreakdownChart.destroy(); savingsBreakdownChart = new Chart(ctx, { type: 'pie', data: { labels: ['Patient Travel', 'Reduced No-Shows', 'Admin Efficiency'], datasets: [{ data: [results.patientTravelSavings, results.noShowSavings, results.adminEfficiencySavings], backgroundColor: ['#3b82f6', '#10b981', '#f59e0b'], }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'bottom' } } } }); }; const renderCumulativeRoiChart = (results) => { const ctx = document.getElementById('cumulativeRoiChart').getContext('2d'); const year1Cum = results.year1Net; const year2Cum = year1Cum + results.netAnnualSavings; const year3Cum = year2Cum + results.netAnnualSavings; if (cumulativeRoiChart) cumulativeRoiChart.destroy(); cumulativeRoiChart = new Chart(ctx, { type: 'line', data: { labels: ['Year 1', 'Year 2', 'Year 3'], datasets: [{ label: 'Cumulative Net Savings ($)', data: [year1Cum, year2Cum, year3Cum], borderColor: '#2563eb', backgroundColor: 'rgba(37, 99, 235, 0.1)', fill: true, tension: 0.1 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { ticks: { callback: value => formatCurrency(value) } } } } }); }; const renderRoiTable = (results) => { const container = document.getElementById('roi-table-container'); const tableData = [ { category: 'Savings', item: 'Patient Travel Savings', value: formatCurrency(results.patientTravelSavings) }, { category: 'Savings', item: 'Reduced No-Show Savings', value: formatCurrency(results.noShowSavings) }, { category: 'Savings', item: 'Admin Efficiency Savings', value: formatCurrency(results.adminEfficiencySavings) }, { category: 'Savings', item: 'Total Annual Savings', value: `${formatCurrency(results.totalAnnualSavings)}` }, { category: 'Costs', item: 'One-Time Implementation Costs', value: formatCurrency(roiInputs.oneTimeCosts) }, { category: 'Costs', item: 'Annual Operating Costs', value: formatCurrency(results.totalAnnualOperatingCosts) }, { category: 'Costs', item: 'Total Year 1 Costs', value: `${formatCurrency(results.totalYear1Costs)}` }, { category: 'Results', item: 'Net Annual Savings (Year 2+)', value: formatCurrency(results.netAnnualSavings) }, { category: 'Results', item: 'Net Year 1 Result', value: `${formatCurrency(results.year1Net)}` }, ]; let tableHtml = ``; tableData.forEach(row => { tableHtml += ``; }); tableHtml += `
Category Line Item Annual Value
${row.category} ${row.item} ${row.value}
`; container.innerHTML = tableHtml; }; // --- EVENT HANDLERS --- document.getElementById('recalculate-btn').addEventListener('click', () => { renderAll(); switchTab('dashboard'); }); document.getElementById('download-pdf-btn').addEventListener('click', () => { const exportArea = document.getElementById('dashboard-export-area'); const mainTitleEl = document.querySelector('#roi-tool-container h1'); if (!exportArea || !mainTitleEl) return; const btn = document.getElementById('download-pdf-btn'); const originalBtnText = btn.innerHTML; btn.disabled = true; btn.innerHTML = `Processing...`; html2canvas(exportArea, { scale: 2, useCORS: true, windowWidth: exportArea.scrollWidth, windowHeight: exportArea.scrollHeight }) .then(canvas => { const { jsPDF } = window.jspdf; const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'landscape', unit: 'mm', format: 'a4' }); const pageMargin = 15; const pdfPageWidth = pdf.internal.pageSize.getWidth(); const pdfPageHeight = pdf.internal.pageSize.getHeight(); const pdfContentWidth = pdfPageWidth - (2 * pageMargin); const canvasAspectRatio = canvas.width / canvas.height; const pdfImgHeight = pdfContentWidth / canvasAspectRatio; let yPos = pageMargin; pdf.setFontSize(18).setFont('helvetica', 'bold'); pdf.text(mainTitleEl.innerText, pdfPageWidth / 2, yPos, { align: 'center' }); yPos += 12; let heightLeft = pdfImgHeight; let positionOnCanvas = 0; pdf.addImage(imgData, 'PNG', pageMargin, yPos, pdfContentWidth, pdfImgHeight); heightLeft -= (pdfPageHeight - yPos - pageMargin); while (heightLeft > 0) { positionOnCanvas -= (pdfPageHeight - (2 * pageMargin)); pdf.addPage(); pdf.addImage(imgData, 'PNG', pageMargin, positionOnCanvas + pageMargin, pdfContentWidth, pdfImgHeight); heightLeft -= (pdfPageHeight - (2 * pageMargin)); } pdf.save(`telehealth-roi-dashboard-${new Date().toISOString().slice(0,10)}.pdf`); }) .catch(err => { console.error("PDF generation failed:", err); alert("Error generating PDF."); }) .finally(() => { btn.disabled = false; btn.innerHTML = originalBtnText; }); }); // --- INITIALIZATION --- const switchTab = (tabName) => { const tabDashboardBtn = document.getElementById('tab-dashboard-btn'); const tabConfigBtn = document.getElementById('tab-config-btn'); const tabDashboardContent = document.getElementById('tab-dashboard-content'); const tabConfigContent = document.getElementById('tab-config-content'); const prevTabBtn = document.getElementById('prev-tab-btn'); const nextTabBtn = document.getElementById('next-tab-btn'); if (tabName === 'dashboard') { tabDashboardBtn.classList.add('active'); tabConfigBtn.classList.remove('active'); tabDashboardContent.classList.remove('hidden'); tabConfigContent.classList.add('hidden'); prevTabBtn.disabled = true; nextTabBtn.disabled = false; } else { tabDashboardBtn.classList.remove('active'); tabConfigBtn.classList.add('active'); tabDashboardContent.classList.add('hidden'); tabConfigContent.classList.remove('hidden'); prevTabBtn.disabled = false; nextTabBtn.disabled = true; } }; document.getElementById('tab-dashboard-btn').addEventListener('click', () => switchTab('dashboard')); document.getElementById('tab-config-btn').addEventListener('click', () => switchTab('config')); document.getElementById('prev-tab-btn').addEventListener('click', () => switchTab('dashboard')); document.getElementById('next-tab-btn').addEventListener('click', () => switchTab('config')); switchTab('dashboard'); renderAll(); });
Scroll to Top