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(); });