export const PropagationMap = { mounted() { this.map = L.map(this.el, { center: [38.0, -96.0], zoom: 5, minZoom: 4, maxZoom: 10 }) L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { attribution: "© OpenStreetMap contributors", maxZoom: 19 }).addTo(this.map) this.scoreLayer = L.layerGroup().addTo(this.map) this.colorScale = [ { min: 80, color: "#00ffa3" }, { min: 65, color: "#7dffd4" }, { min: 50, color: "#ffe566" }, { min: 33, color: "#ff9044" }, { min: 0, color: "#ff4f4f" } ] const initialScores = JSON.parse(this.el.dataset.scores || "[]") this.renderScores(initialScores) this.handleEvent("update_scores", ({ scores }) => { this.renderScores(scores) }) const legend = L.control({ position: "bottomright" }) legend.onAdd = () => { const div = L.DomUtil.create("div", "leaflet-legend") div.innerHTML = `
Propagation
Excellent (80-100)
Good (65-79)
Marginal (50-64)
Poor (33-49)
Negligible (0-32)
` return div } legend.addTo(this.map) }, renderScores(scores) { this.scoreLayer.clearLayers() scores.forEach(({ lat, lon, score }) => { const color = this.scoreColor(score) const circle = L.circleMarker([lat, lon], { radius: 6, fillColor: color, fillOpacity: 0.7, color: color, weight: 0 }) circle.bindPopup( `Score: ${score}/100
${this.scoreTier(score)}
` + `${lat.toFixed(3)}\u00b0N, ${Math.abs(lon).toFixed(3)}\u00b0W` ) this.scoreLayer.addLayer(circle) }) }, scoreColor(score) { for (const tier of this.colorScale) { if (score >= tier.min) return tier.color } return "#ff4f4f" }, scoreTier(score) { if (score >= 80) return "EXCELLENT" if (score >= 65) return "GOOD" if (score >= 50) return "MARGINAL" if (score >= 33) return "POOR" return "NEGLIGIBLE" }, destroyed() { if (this.map) this.map.remove() } }