1a634ddebSGreg Roach<?php 2a634ddebSGreg Roach 3a634ddebSGreg Roachuse Fisharebest\Webtrees\View; 4a634ddebSGreg Roach 57c2c99faSGreg Roach/** 67c2c99faSGreg Roach * @var array<mixed> $data 7c9c6f2ecSGreg Roach * @var object $leaflet_config 87c2c99faSGreg Roach */ 97c2c99faSGreg Roach 10a634ddebSGreg Roach?> 11a634ddebSGreg Roach 1284df6051SGreg Roach<div class="row gchart wt-place-hierarchy-wrapper"> 1384df6051SGreg Roach <div id="wt-map" class="col-sm-9 wt-ajax-load wt-map wt-place-hierarchy-map" dir="ltr"></div> 1484df6051SGreg Roach <ul class="col-sm-3 wt-place-hierarchy-sidebar wt-page-options-value list-unstyled px-md-1"></ul> 15a634ddebSGreg Roach</div> 16a634ddebSGreg Roach 17a634ddebSGreg Roach<?php View::push('javascript') ?> 1874b9ba3fSGreg Roach<script> 19c68bbde3SGreg Roach 'use strict'; 20a634ddebSGreg Roach 21bd6ca2dbSDavid Drury (function () { 22728c8c27SGreg Roach const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>; 23a634ddebSGreg Roach 24a634ddebSGreg Roach let map = null; 2584df6051SGreg Roach const sidebar = document.querySelector('.wt-place-hierarchy-sidebar'); 26bd6ca2dbSDavid Drury 27bd6ca2dbSDavid Drury const scrollOptions = { 28bd6ca2dbSDavid Drury behavior: "smooth", 29bd6ca2dbSDavid Drury block: "start", 30bd6ca2dbSDavid Drury inline: "start" 31bd6ca2dbSDavid Drury }; 32ab039d30SDavid Drury 33ab039d30SDavid Drury // Map components 34a634ddebSGreg Roach let markers = L.markerClusterGroup({ 35a634ddebSGreg Roach showCoverageOnHover: false, 36a634ddebSGreg Roach }); 37a634ddebSGreg Roach 38f352d954SDavid Drury /** 39f352d954SDavid Drury * Passed to resetControl to 40f352d954SDavid Drury * perform necessary reset actions on map 41f352d954SDavid Drury */ 42*b7b71725SGreg Roach let resetCallback = function () { 43c68bbde3SGreg Roach map.flyToBounds(markers.getBounds(), {padding: [50, 30], maxZoom: 15 }); 44bd6ca2dbSDavid Drury sidebar.firstElementChild.scrollIntoView(scrollOptions); 45f352d954SDavid Drury } 46a634ddebSGreg Roach 47ab039d30SDavid Drury /** 48ab039d30SDavid Drury * @private 49ab039d30SDavid Drury */ 50ab039d30SDavid Drury let _drawMap = function () { 51*b7b71725SGreg Roach map = webtrees.buildLeafletJsMap('wt-map', config, resetCallback); 52a634ddebSGreg Roach }; 53a634ddebSGreg Roach 54ab039d30SDavid Drury /** 55ab039d30SDavid Drury * @private 56ab039d30SDavid Drury */ 57ab039d30SDavid Drury let _buildMapData = function () { 58728c8c27SGreg Roach let data = <?= json_encode($data['markers'], JSON_THROW_ON_ERROR) ?>; 59a634ddebSGreg Roach 60ab039d30SDavid Drury let geoJsonLayer = L.geoJson(data, { 61a634ddebSGreg Roach pointToLayer: function (feature, latlng) { 62a634ddebSGreg Roach return new L.Marker(latlng, { 63a634ddebSGreg Roach icon: L.BeautifyIcon.icon({ 64a634ddebSGreg Roach icon: 'bullseye fas', 65c68bbde3SGreg Roach borderColor: 'transparent', 66a634ddebSGreg Roach backgroundColor: '#1e90ff', 67c68bbde3SGreg Roach iconShape: 'marker', 68c68bbde3SGreg Roach textColor: 'white', 69a634ddebSGreg Roach }), 70a634ddebSGreg Roach title: feature.properties.tooltip, 71a634ddebSGreg Roach alt: feature.properties.tooltip, 72a634ddebSGreg Roach id: feature.id, 73a634ddebSGreg Roach }) 74c68bbde3SGreg Roach .on('popupopen', function (e) { 75bd6ca2dbSDavid Drury let item = document.querySelector('.mapped[data-wt-feature-id="' + e.target.feature.id + '"]'); 76bd6ca2dbSDavid Drury item.classList.add('messagebox'); 77bd6ca2dbSDavid Drury item.scrollIntoView(scrollOptions); 78a634ddebSGreg Roach }) 79c68bbde3SGreg Roach .on('popupclose', function () { 80bd6ca2dbSDavid Drury sidebar.querySelectorAll('.mapped').forEach(e => e.classList.remove('messagebox')); 81bd6ca2dbSDavid Drury sidebar.firstElementChild.scrollIntoView(scrollOptions); 82a634ddebSGreg Roach }); 83a634ddebSGreg Roach }, 84a634ddebSGreg Roach onEachFeature: function (feature, layer) { 85a634ddebSGreg Roach layer.bindPopup(feature.properties.popup); 86a634ddebSGreg Roach }, 87a634ddebSGreg Roach }); 88a634ddebSGreg Roach 89a634ddebSGreg Roach if (data.features.length > 0) { 90a634ddebSGreg Roach markers.addLayer(geoJsonLayer); 91c68bbde3SGreg Roach map.addLayer(markers); 9279de923dSGreg Roach } 93ab039d30SDavid Drury 94728c8c27SGreg Roach map.fitBounds(<?= json_encode($data['bounds'], JSON_THROW_ON_ERROR) ?>, { padding: [50, 30] }); 95bd6ca2dbSDavid Drury sidebar.innerHTML = <?= json_encode($data['sidebar'], JSON_THROW_ON_ERROR) ?>; 96a634ddebSGreg Roach }; 97a634ddebSGreg Roach 98bd6ca2dbSDavid Drury window.onload = function() { 99a634ddebSGreg Roach // Activate marker popup when sidebar entry clicked 100bd6ca2dbSDavid Drury sidebar.querySelectorAll('.mapped').forEach((element) => { 101bd6ca2dbSDavid Drury var eventId = parseInt(element.dataset.wtFeatureId); 102bd6ca2dbSDavid Drury 103bd6ca2dbSDavid Drury element.addEventListener('click', () => { 104a634ddebSGreg Roach // first close any existing 105a634ddebSGreg Roach map.closePopup(); 106a634ddebSGreg Roach //find the marker corresponding to the clicked event 107a634ddebSGreg Roach let mkrLayer = markers.getLayers().filter(function (v) { 108bd6ca2dbSDavid Drury return v.feature !== undefined && v.feature.id === eventId; 109a634ddebSGreg Roach }); 110bd6ca2dbSDavid Drury 111a634ddebSGreg Roach let mkr = mkrLayer.pop(); 112bd6ca2dbSDavid Drury 113a634ddebSGreg Roach markers.zoomToShowLayer(mkr, function (e) { 114a634ddebSGreg Roach mkr.openPopup(); 115a634ddebSGreg Roach }); 116bd6ca2dbSDavid Drury 117a634ddebSGreg Roach return false; 118bd6ca2dbSDavid Drury }); 119bd6ca2dbSDavid Drury 120bd6ca2dbSDavid Drury // stop clicking on a person also opening the popup 121bd6ca2dbSDavid Drury element.querySelectorAll('a').forEach((el) => { 122bd6ca2dbSDavid Drury el.addEventListener('click', (e) => { 123a634ddebSGreg Roach e.stopPropagation(); 124a634ddebSGreg Roach }); 125a634ddebSGreg Roach }); 126bd6ca2dbSDavid Drury }); 127bd6ca2dbSDavid Drury } 128a634ddebSGreg Roach 129a634ddebSGreg Roach _drawMap(); 130ab039d30SDavid Drury _buildMapData(); 131a634ddebSGreg Roach })(); 132a634ddebSGreg Roach</script> 133a634ddebSGreg Roach<?php View::endpush() ?> 134