Customer Demand Heatmap Generator

Customer Demand Heatmap Generator

Enter Demand Data

Add locations and their corresponding demand value (e.g., sales, units sold). Latitude and Longitude are required for mapping.

Location Name Latitude Longitude Demand Value ($) Actions

Configure Heatmap Appearance

Demand Visualization

Could not load the map. Please check your internet connection and try again.

'; } } else { map.invalidateSize(); // Recalculate map size if it was hidden } } window.generateHeatmap = function() { validationMessage.classList.add('hidden'); if (demandData.length === 0) { validationMessage.textContent = 'Please add at least one data row before generating the heatmap.'; validationMessage.classList.remove('hidden'); changeTab(1); return; } let dataValid = true; const heatmapData = demandData.map(row => { const lat = parseFloat(row.lat); const lng = parseFloat(row.lng); const value = parseFloat(row.value); if (isNaN(lat) || isNaN(lng) || isNaN(value)) { dataValid = false; } return { lat, lon: lng, value }; }); if (!dataValid) { validationMessage.textContent = 'Please ensure all Latitude, Longitude, and Demand Value fields are valid numbers.'; validationMessage.classList.remove('hidden'); changeTab(1); return; } changeTab(3); setTimeout(() => { // Allow time for map container to become visible const radius = document.getElementById('heatmapRadius').value; const blur = document.getElementById('heatmapBlur').value; const opacity = document.getElementById('heatmapOpacity').value; const maxDemand = Math.max(...demandData.map(d => d.value), 0); const cfg = { "radius": radius / 100, "maxOpacity": opacity, "scaleRadius": true, "useLocalExtrema": false, latField: 'lat', lngField: 'lon', valueField: 'value' }; if (heatmapLayer) { map.removeLayer(heatmapLayer); } heatmapLayer = new HeatmapOverlay(cfg); heatmapLayer.setData({ max: maxDemand, data: heatmapData }); map.addLayer(heatmapLayer); }, 100); }; window.downloadPDF = function() { const mapElement = document.getElementById('map'); if (!mapElement) return; const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'landscape', unit: 'mm', format: 'a4' }); // Show loading state const downloadBtn = document.getElementById('pdfDownloadBtn'); const originalText = downloadBtn.innerHTML; downloadBtn.innerHTML = 'Generating...'; downloadBtn.disabled = true; html2canvas(mapElement, { useCORS: true, logging: false }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const imgWidth = 277; // A4 landscape width - margins const pageHeight = 210; const imgHeight = canvas.height * imgWidth / canvas.width; doc.setFontSize(20); doc.text('Customer Demand Heatmap Report', 15, 20); doc.addImage(imgData, 'PNG', 10, 30, imgWidth, imgHeight); doc.addPage(); doc.setFontSize(20); doc.text('Data Summary', 15, 20); doc.autoTable({ startY: 30, head: [['Location', 'Latitude', 'Longitude', 'Demand Value ($)']], body: demandData.map(d => [d.name, d.lat, d.lng, d.value.toLocaleString('en-US')]), theme: 'grid' }); doc.save('Customer_Demand_Heatmap_Report.pdf'); // Restore button state downloadBtn.innerHTML = originalText; downloadBtn.disabled = false; }).catch(err => { console.error("PDF generation failed:", err); alert("Sorry, there was an error generating the PDF."); // Restore button state downloadBtn.innerHTML = originalText; downloadBtn.disabled = false; }); }; // Initial setup changeTab(1); loadSampleData(); });
Scroll to Top