import L from 'leaflet' import './leaflet.bezier' const arcStyles = { edu: { color: 'rgb(245, 246, 150)', fillColor: 'rgb(245, 246, 150)', opacity: 0.5, weight: '1', }, company: { color: 'rgb(50, 100, 246)', fillColor: 'rgb(50, 100, 246)', opacity: 1.0, weight: '2', }, gov: { color: 'rgb(245, 150, 100)', fillColor: 'rgb(245, 150, 150)', opacity: 1.0, weight: '2', }, mil: { color: 'rgb(245, 0, 0)', fillColor: 'rgb(245, 0, 0)', opacity: 1.0, weight: '2', }, } const sortOrder = ['edu', 'company', 'gov', 'mil'] const redDot = L.icon({ iconUrl: '/assets/img/reddot.png', iconSize: [17, 17], // size of the icon iconAnchor: [8, 8], // point of the icon which will correspond to marker's location popupAnchor: [0, -5] // point from which the popup should open relative to the iconAnchor }) function addMarker(map, latlng, title, subtext, year, pdf) { const marker = L.marker(latlng, { icon: redDot }).addTo(map) let message = [ "", title, "", ] if (pdf && pdf.length) { message.unshift("") message.push("") } message = message.concat([ "
", subtext, ]) if (year) { message.push(" (" + year + ")") } marker.bindPopup(message.join('')) return marker } function addArc(map, src, dest, arcStyle) { L.bezier({ path: [ [ { lat: src[0], lng: src[1] }, { lat: dest[0], lng: dest[1] }, ], ] }, arcStyle).addTo(map) } export default function append(el, payload) { const { data } = payload if (!data) return let { paper, address, citations } = data let source = [0, 0] let map = L.map(el).setView([25, 0], 2) L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', { attribution: 'Map data © OpenStreetMap contributors, ' + 'CC-BY-SA, ' + 'Imagery © Mapbox', maxZoom: 18, id: 'mapbox.dark', style: 'mapbox://styles/mapbox/dark-v9', accessToken: 'pk.eyJ1IjoiZmFuc2FsY3kiLCJhIjoiY2pvN3I1czJwMHF5NDNrbWRoMWpteHlrdCJ9.kMpM5syQUhVjKkn1iVx9fg' }).addTo(map) if (address) { source = [address.lat, address.lng].map(n => parseFloat(n)) } else { console.error("No address found for root paper") // console.log(data) } citations.forEach(citation => { console.log(citation) if (!citation.addresses) { console.log(citation) return } const citationAddress = citation.addresses[0] const latlng = [citationAddress.lat, citationAddress.lng].map(n => parseFloat(n)) if (Number.isNaN(latlng[0]) || Number.isNaN(latlng[1])) return addMarker(map, latlng, citation.title, citationAddress.name, citation.year, citation.pdf) addArc(map, source, latlng, arcStyles[citationAddress.type]) }) console.log(paper) const rootMarker = addMarker(map, source, paper.title, address.name, paper.year) rootMarker.openPopup() // a transparent div to cover the map, so normal scroll events will not be eaten by leaflet const mapCover = document.createElement("div") mapCover.classList.add("map_cover") mapCover.innerHTML = "
Click here to explore the map
" mapCover.querySelector('div').addEventListener('click', () => { map.scrollWheelZoom.enable() if (mapCover.parentNode === el) { el.removeChild(mapCover) } }) function stopPropagation(e) { e.stopPropagation() } mapCover.addEventListener('mousewheel', stopPropagation, true) mapCover.addEventListener('DOMMouseScroll', stopPropagation, true) map.scrollWheelZoom.disable() map.on('focus', () => { map.scrollWheelZoom.enable() if (mapCover.parentNode === el) { el.removeChild(mapCover) } }) map.on('blur', () => { map.scrollWheelZoom.disable() // el.appendChild(mapCover) }) el.appendChild(mapCover) }