Property Valuation Tool

Property Valuation Tool

Estimate property value using comparable sales and income analysis.

Valuation Summary

Price per Square Foot Comparison

Property & Financial Inputs

Subject Property

Income Approach

Comparable Sales (Comps)

${value}

`; function renderChart(chartData) { if (compsChart) compsChart.destroy(); compsChart = new Chart(document.getElementById('comps-chart'), { type: 'bar', data: { labels: chartData.labels, datasets: [{ label: 'Price per Sq. Ft.', data: chartData.values, backgroundColor: chartData.labels.map((_, i) => i === 0 ? '#0f766e' : '#99f6e4') }] } }); } // --- PDF GENERATION --- async function generatePdfReport() { if (!state.analysisResult) return alert("Please run an analysis first."); downloadPdfBtn.disabled = true; downloadPdfBtn.textContent = 'Generating...'; const chartImg = compsChart.toBase64Image(); const { kpis, incomeDetails, compsDetails } = state.analysisResult; const format = (val) => val.toLocaleString('en-US', {maximumFractionDigits: 2}); const compsRows = compsDetails.map(c => `${c.name}$${format(c.price)}${format(c.size)}$${format(c.price / c.size)}`).join(''); const incomeRows = ` Gross Annual Income$${format(incomeDetails.annualIncome)} Total Annual Expenses-$${format(incomeDetails.annualExpenses)} Net Operating Income (NOI)$${format(incomeDetails.noi)} `; const reportHtml = `

Rental Property Analysis

${state.property.name}

Valuation Summary

Estimated Market Value
$${format(kpis.finalValue)}
Price per Sq. Ft.
$${format(kpis.pricePerSqFt)}

Analysis Approaches

Value from Comps
$${format(kpis.compsValue)}
Value from Income
$${format(kpis.incomeValue)}

Price / Sq. Ft. Comparison

Income Analysis

${incomeRows}

Comparable Properties

${compsRows}
PropertySale PriceSize (Sq. Ft.)Price / Sq. Ft.
`; const pdfTemplate = document.getElementById('pdf-template'); pdfTemplate.innerHTML = reportHtml; pdfTemplate.classList.remove('invisible'); try { const { jsPDF } = window.jspdf; const canvas = await html2canvas(pdfTemplate.querySelector('.pdf-report-container'), { scale: 2 }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); pdf.addImage(imgData, 'PNG', 0, 0, pdf.internal.pageSize.getWidth(), (canvas.height * pdf.internal.pageSize.getWidth()) / canvas.width); pdf.save(`Valuation_${state.property.name.replace(/\s+/g, '_')}.pdf`); } catch(e) { console.error('PDF Generation Error:', e); } finally { downloadPdfBtn.disabled = false; downloadPdfBtn.textContent = 'Download Property Analysis'; pdfTemplate.classList.add('invisible'); } } downloadPdfBtn.addEventListener('click', generatePdfReport); // --- INITIALIZATION --- populateInputs(); renderComps(); attachDataListeners(); runAnalysis(); switchTab(0); });
Scroll to Top