xref: /webtrees/resources/views/modules/pedigree-map/chart.phtml (revision 75f2a4831adecfe14c5b50312beb437d05654f96)
19ec21bfdSGreg Roach<?php
2d70512abSGreg Roach
310e06497SGreg Roachdeclare(strict_types=1);
410e06497SGreg Roach
59ec21bfdSGreg Roachuse Fisharebest\Webtrees\I18N;
69ec21bfdSGreg Roachuse Fisharebest\Webtrees\View;
79ec21bfdSGreg Roach
89ec21bfdSGreg Roach/**
9dc270d8cSGreg Roach * @var array<mixed> $data
10c9c6f2ecSGreg Roach * @var object       $leaflet_config
119ec21bfdSGreg Roach */
129ec21bfdSGreg Roach?>
139ec21bfdSGreg Roach
1455ea0389SGreg Roach<div class="row my-4 gchart wt-pedigree-map-wrapper wt-fullscreen-container">
15*75f2a483SDavid Drury    <div id="wt-map" class="col-sm-9 wt-ajax-load wt-map" dir="ltr"></div>
16*75f2a483SDavid Drury    <ul class="col-sm-3 wt-map-sidebar wt-page-options-value list-unstyled px-1 mb-0"></ul>
173dcc812bSGreg Roach</div>
183dcc812bSGreg Roach
193dcc812bSGreg Roach<?php View::push('javascript') ?>
2029eb5762SGreg Roach<script>
2129eb5762SGreg Roach  'use strict';
223dcc812bSGreg Roach
2345be2995SDavid Drury  (function () {
24728c8c27SGreg Roach    const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>;
25*75f2a483SDavid Drury    const sidebar = document.querySelector('.wt-map-sidebar');
2645be2995SDavid Drury
2745be2995SDavid Drury    const scrollOptions = {
2845be2995SDavid Drury      behavior: "smooth",
29aeea31bdSGreg Roach      block: "nearest",
3045be2995SDavid Drury      inline: "start"
3145be2995SDavid Drury    };
3245be2995SDavid Drury
333dcc812bSGreg Roach    let map = null;
3498579324SDavid Drury
3598579324SDavid Drury    // Map components
363dcc812bSGreg Roach    let markers = L.markerClusterGroup({
3729eb5762SGreg Roach      showCoverageOnHover: false,
383dcc812bSGreg Roach    });
393dcc812bSGreg Roach
40f352d954SDavid Drury    /**
41f352d954SDavid Drury     * Passed to resetControl to
42f352d954SDavid Drury     * perform necessary reset actions on map
43b2e5f20eSGreg Roach     *
44b2e5f20eSGreg Roach     * @param {Event} event
45f352d954SDavid Drury     */
46b2e5f20eSGreg Roach    let resetCallback = function (event) {
47b2e5f20eSGreg Roach       event.preventDefault();
48c68bbde3SGreg Roach      map.flyToBounds(markers.getBounds(), {padding: [50, 30], maxZoom: 15 });
49f352d954SDavid Drury    }
5098579324SDavid Drury
513dcc812bSGreg Roach    /**
5245be2995SDavid Drury     *
533dcc812bSGreg Roach     * @private
543dcc812bSGreg Roach     */
553dcc812bSGreg Roach    let _drawMap = function () {
56b7b71725SGreg Roach      map = webtrees.buildLeafletJsMap('wt-map', config, resetCallback);
573dcc812bSGreg Roach    };
583dcc812bSGreg Roach
593dcc812bSGreg Roach    /**
6045be2995SDavid Drury     *
613dcc812bSGreg Roach     * @private
623dcc812bSGreg Roach     */
6398579324SDavid Drury    let _buildMapData = function () {
64728c8c27SGreg Roach      let geoJson_data = <?= json_encode($data, JSON_THROW_ON_ERROR) ?>;
653dcc812bSGreg Roach
6698579324SDavid Drury      if (geoJson_data.features.length === 0) {
6798579324SDavid Drury        map.fitWorld();
6845be2995SDavid Drury        sidebar.innerHTML = '<div class="bg-info text-white text-center">' + <?= json_encode(I18N::translate('Nothing to show'), JSON_THROW_ON_ERROR) ?> + '</div>';
6998579324SDavid Drury      } else {
7045be2995SDavid Drury        sidebar.innerHTML = '';
7198579324SDavid Drury        let geoJsonLayer = L.geoJson(geoJson_data, {
723dcc812bSGreg Roach          pointToLayer: function (feature, latlng) {
733dcc812bSGreg Roach            return new L.Marker(latlng, {
743dcc812bSGreg Roach              icon: L.BeautifyIcon.icon({
753130efd4SGreg Roach                icon: 'bullseye fas',
763dcc812bSGreg Roach                borderColor: 'transparent',
773130efd4SGreg Roach                backgroundColor: feature.properties.iconcolor,
783dcc812bSGreg Roach                iconShape: 'marker',
793130efd4SGreg Roach                textColor: 'white',
803dcc812bSGreg Roach              }),
813dcc812bSGreg Roach              title: feature.properties.tooltip,
8229eb5762SGreg Roach              id: feature.id,
833dcc812bSGreg Roach            })
843dcc812bSGreg Roach              .on('popupopen', function (e) {
854c6304d3SGreg Roach                let item = document.querySelector('[data-wt-feature-id="' + e.target.feature.id + '"]');
8645be2995SDavid Drury                item.classList.add('messagebox');
8745be2995SDavid Drury                item.scrollIntoView(scrollOptions);
883dcc812bSGreg Roach              })
893dcc812bSGreg Roach              .on('popupclose', function () {
9045be2995SDavid Drury                sidebar.childNodes.forEach(e => e.classList.remove('messagebox'));
913dcc812bSGreg Roach              });
923dcc812bSGreg Roach          },
933dcc812bSGreg Roach          onEachFeature: function (feature, layer) {
943dcc812bSGreg Roach            if (feature.properties.polyline) {
953dcc812bSGreg Roach              let pline = L.polyline(feature.properties.polyline.points, feature.properties.polyline.options);
963dcc812bSGreg Roach              markers.addLayer(pline);
973dcc812bSGreg Roach            }
9817c5ea9eSGreg Roach
993dcc812bSGreg Roach            layer.bindPopup(feature.properties.summary);
1002210ec83SDavid Drury            sidebar.innerHTML += `<li class="gchart p-1 mb-1" data-wt-feature-id=${feature.id}>${feature.properties.summary}</li>`;
10129eb5762SGreg Roach          },
1023dcc812bSGreg Roach        });
1033dcc812bSGreg Roach        markers.addLayer(geoJsonLayer);
10498579324SDavid Drury        map.addLayer(markers);
105ce283fd9SGreg Roach        map.fitBounds(markers.getBounds(), { padding: [50, 30], maxZoom: 15 });
1063dcc812bSGreg Roach      }
1073dcc812bSGreg Roach    };
1083dcc812bSGreg Roach
10945be2995SDavid Drury    window.onload = function() {
1103dcc812bSGreg Roach      // Activate marker popup when sidebar entry clicked
11117c5ea9eSGreg Roach      sidebar.addEventListener('click', (e) => {
11217c5ea9eSGreg Roach        if (e.target.matches('[data-wt-sosa]')) {
113aeaf8337SGreg Roach          e.preventDefault();
1143dcc812bSGreg Roach          map.closePopup();
11545be2995SDavid Drury
11617c5ea9eSGreg Roach          let marker = markers.getLayers().filter(function (v) {
11717c5ea9eSGreg Roach            return v.feature !== undefined && v.feature.id === parseInt(e.target.dataset.wtSosa);
11817c5ea9eSGreg Roach          }).pop();
11945be2995SDavid Drury
12017c5ea9eSGreg Roach          markers.zoomToShowLayer(marker, () => marker.openPopup());
12198579324SDavid Drury
1223dcc812bSGreg Roach          return false;
12317c5ea9eSGreg Roach        }
12445be2995SDavid Drury      });
12545be2995SDavid Drury    }
1263dcc812bSGreg Roach
1273dcc812bSGreg Roach    _drawMap();
12898579324SDavid Drury    _buildMapData();
1293dcc812bSGreg Roach  })();
1303dcc812bSGreg Roach</script>
1313dcc812bSGreg Roach<?php View::endpush() ?>
132