Climate Biomes Map Generator

Climate & Biomes Map Generator

Map Configuration

Filter Options

Map View & Download

Selection Summary

No selections made yet.

Legend

No active legend.

Region Focus (Conceptual): ${countryData[regionFocus]?.name || regionFocus}

`; } let legendHTML = `

Legend

`; let highlightedCountriesCount = 0; if (selectedFilters.length > 0) { summaryText += `

Selected ${mapType === 'climate' ? 'Zones' : 'Biomes'}: ${selectedFilters.join(', ')}

`; selectedFilters.forEach(filter => { legendHTML += `
${filter}: ${mapType === 'climate' ? climateClassifications[filter] : biomeTypes[filter]}
`; }); Object.keys(countryData).forEach(countryCode => { const countryInfo = countryData[countryCode]; let matchesFilter = false; if (mapType === 'climate') { matchesFilter = countryInfo.climate && countryInfo.climate.some(cz => selectedFilters.includes(cz)); } else { matchesFilter = countryInfo.biome && countryInfo.biome.some(b => selectedFilters.includes(b)); } // Conceptual region focus filter let matchesRegionFocus = (regionFocus === 'world' || regionFocus === countryCode); const pathElement = svgMap.getElementById(countryCode); if (pathElement && matchesFilter && matchesRegionFocus) { pathElement.style.fill = highlightColor; highlightedCountriesCount++; } else if (pathElement && !matchesRegionFocus && regionFocus !== 'world') { // If focused on a specific region, others go to default or slightly dimmed pathElement.style.fill = '#e0e0e0'; // Dimmed fill for non-focused } }); summaryText += `

Matching Countries Highlighted: ${highlightedCountriesCount}

`; } else { summaryText += `

No filters selected. Displaying default map.

`; legendHTML += `

No active filters to display in legend.

`; } summaryDiv.innerHTML = summaryText; legendDiv.innerHTML = legendHTML; if (highlightedCountriesCount === 0 && selectedFilters.length > 0) { summaryText += `

No countries match the selected criteria ${regionFocus !== 'world' ? 'in the focused region' : ''}.

`; summaryDiv.innerHTML = summaryText; // Update summary if no matches } } document.getElementById('cb-download-pdf').addEventListener('click', async function() { const loader = document.getElementById('cb-loader'); loader.style.display = 'flex'; const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a4' }); // Prepare content for PDF const pdfContentElement = document.createElement('div'); pdfContentElement.className = 'cb-pdf-output-content'; // Apply PDF-specific styles const title = document.createElement('h3'); title.textContent = 'Climate & Biomes Map Report'; pdfContentElement.appendChild(title); pdfContentElement.appendChild(document.createElement('hr')); // Clone summary and legend const summaryClone = document.getElementById('cb-selection-summary').cloneNode(true); const legendClone = document.getElementById('cb-map-legend').cloneNode(true); pdfContentElement.appendChild(summaryClone); pdfContentElement.appendChild(legendClone); // Add current date and time to PDF const dateTime = document.createElement('p'); dateTime.textContent = `Report generated on: ${new Date().toLocaleString('en-US', { dateStyle: 'full', timeStyle: 'medium'})}`; dateTime.style.fontSize = '10px'; dateTime.style.marginTop = '20px'; pdfContentElement.appendChild(dateTime); // Temporarily append to body to render for html2canvas if needed for complex text styling // document.body.appendChild(pdfContentElement); // Add text content first // Using html method of jsPDF for better text rendering from HTML structure await pdf.html(pdfContentElement, { callback: function(pdfInstance) { // Get the map display area const mapDisplayArea = document.getElementById('cb-map-display'); // Use html2canvas to capture the SVG map area as an image html2canvas(mapDisplayArea, { scale: 2, // Increase scale for better quality useCORS: true, // If map had external images backgroundColor: null, // Preserve transparency if any, or set explicit logging: false, onclone: (clonedDoc) => { // Ensure styles are applied in cloned document const svgInClone = clonedDoc.getElementById('cb-world-map-svg'); if (svgInClone) { // Ensure all paths in the cloned SVG have their current fill and stroke visible for PDF const originalSvgPaths = document.getElementById('cb-world-map-svg').querySelectorAll('path.country'); const clonedSvgPaths = svgInClone.querySelectorAll('path.country'); clonedSvgPaths.forEach((clonedPath, index) => { if (originalSvgPaths[index]) { clonedPath.style.fill = originalSvgPaths[index].style.fill || '#ccc'; clonedPath.style.stroke = 'black'; // Ensure borders are visible in PDF clonedPath.style.strokeWidth = '0.5px'; } }); } } }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const imgProps = pdfInstance.getImageProperties(imgData); const pdfWidth = pdfInstance.internal.pageSize.getWidth() - 40; // margins const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width; const availableHeight = pdfInstance.internal.pageSize.getHeight() - pdfInstance.autoTable.previous.finalY - 40; // Space left after text let finalImgHeight = pdfHeight; let finalImgWidth = pdfWidth; if (pdfHeight > availableHeight * 0.8) { // If image too tall for remaining space (leave some margin) finalImgHeight = availableHeight * 0.8; finalImgWidth = (imgProps.width * finalImgHeight) / imgProps.height; } // Check if there is enough space on the current page, otherwise add new page if (pdfInstance.autoTable.previous.finalY + finalImgHeight + 20 > pdfInstance.internal.pageSize.getHeight() - 40 ) { pdfInstance.addPage(); pdfInstance.text("Generated Map:", 20, 30); // Title for map on new page pdfInstance.addImage(imgData, 'PNG', 20, 50, finalImgWidth, finalImgHeight); } else { pdfInstance.addImage(imgData, 'PNG', 20, pdfInstance.autoTable.previous.finalY + 20, finalImgWidth, finalImgHeight); } pdfInstance.save('climate_biomes_map_report.pdf'); loader.style.display = 'none'; // document.body.removeChild(pdfContentElement); // Clean up }).catch(err => { console.error("Error capturing map with html2canvas:", err); alert("Error generating PDF: Could not capture map image."); loader.style.display = 'none'; // document.body.removeChild(pdfContentElement); // Clean up }); }, x: 20, y: 20, width: pdf.internal.pageSize.getWidth() - 40, // Fit content within margins windowWidth: pdfContentElement.scrollWidth // ensure full width is captured }); }); // Initialize document.addEventListener('DOMContentLoaded', () => { openCbTab({currentTarget: cbTabButtons[0]}, 'cb-tab-config'); // Open first tab by default updateFilterOptions(); // Populate initial filter options updateMapView(); // Initial map view });
Scroll to Top