1import { Controller } from "@hotwired/stimulus" 2import mapboxgl from "mapbox-gl" 3import supportsInteractionObserver from "utils/supports_interaction_observer" 4 5// Connects to data-controller="numiko--single-point-map" 6export default class extends Controller { 7 static targets = ['mapWrapper'] 8 static values = { token: String, style: String } 9 10 connect () { 11 if (supportsInteractionObserver()) { 12 this.#setupObserver(); 13 } else { 14 this.#loadMapbox(); 15 } 16 } 17 18 disconnect () { 19 if (this.intersectionObserver) { 20 this.intersectionObserver.disconnect(); 21 } 22 } 23 24 #setupObserver () { 25 this.intersectionObserver = new window.IntersectionObserver(([entry]) => { 26 if (entry.isIntersecting) { 27 this.#loadMapbox(); 28 return; 29 } 30 }, { root: null, threshold: 0.1 }) 31 32 this.intersectionObserver.observe(this.element); 33 } 34 35 #loadMapbox () { 36 /* Should make file .js.erb and interpolate via ENV key */ 37 mapboxgl.accessToken = this.tokenValue; 38 let mapElem = this.mapWrapperTarget; 39 let marker = JSON.parse(mapElem.dataset.mapMarker); 40 let map_center = JSON.parse(mapElem.dataset.mapCenter); 41 let zoom_level = JSON.parse(mapElem.dataset.mapZoom); 42 let map = new mapboxgl.Map({ 43 container: 'single-point-map', 44 style: this.styleValue, 45 center: map_center, 46 maxBounds: [[map_center[0] - 20, map_center[1] - 20], [map_center[0] + 20, map_center[1] + 20]], 47 zoom: zoom_level, 48 minZoom: 1, 49 scrollZoom: false, 50 dragRotate: false, 51 renderWorldCopies: false 52 }); 53 let nav = new mapboxgl.NavigationControl(); 54 map.addControl(nav, 'top-right'); 55 return map.on('load', function() { 56 map.addSource('globalimpact', { 57 type: 'geojson', 58 data: { 59 "type": "FeatureCollection", 60 "features": marker 61 }, 62 cluster: false, 63 clusterMaxZoom: 14, 64 clusterRadius: 50 65 }); 66 map.addLayer({ 67 id: 'clusters', 68 type: 'circle', 69 source: 'globalimpact', 70 filter: ['has', 'point_count'], 71 paint: { 72 'circle-color': ['step', ['get', 'point_count'], '#B33D26', 100, '#B33D26', 750, '#B33D26'], 73 'circle-radius': ['step', ['get', 'point_count'], 20, 10, 30, 20, 40, 30, 60] 74 } 75 }); 76 return map.addLayer({ 77 id: 'unclustered-point', 78 type: 'circle', 79 source: 'globalimpact', 80 filter: ['!', ['has', 'point_count']], 81 paint: { 82 'circle-color': '#B33D26', 83 'circle-radius': 8, 84 'circle-stroke-width': 1, 85 'circle-stroke-color': '#fff' 86 } 87 }); 88 }); 89 } 90}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.