xref: /webtrees/resources/views/modules/pedigree-map/chart.phtml (revision b2e5f20ea75b7378d8949eac2d8ec43fb9552b6f)
1<?php
2
3declare(strict_types=1);
4
5use Fisharebest\Webtrees\I18N;
6use Fisharebest\Webtrees\View;
7
8/**
9 * @var array<mixed> $data
10 * @var object       $leaflet_config
11 */
12?>
13
14<div class="row my-4 gchart wt-pedigree-map-wrapper">
15    <div id="wt-map" class="col-sm-9 wt-ajax-load wt-map wt-pedigree-map-map" dir="ltr"></div>
16    <ul class="col-sm-3 wt-pedigree-map-sidebar wt-page-options-value list-unstyled px-1"></ul>
17</div>
18
19<?php View::push('javascript') ?>
20<script>
21  'use strict';
22
23  (function () {
24    const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>;
25    const sidebar = document.querySelector('.wt-pedigree-map-sidebar');
26
27    const scrollOptions = {
28      behavior: "smooth",
29      block: "start",
30      inline: "start"
31    };
32
33    let map = null;
34
35    // Map components
36    let markers = L.markerClusterGroup({
37      showCoverageOnHover: false,
38    });
39
40    /**
41     * Passed to resetControl to
42     * perform necessary reset actions on map
43     *
44     * @param {Event} event
45     */
46    let resetCallback = function (event) {
47       event.preventDefault();
48      map.flyToBounds(markers.getBounds(), {padding: [50, 30], maxZoom: 15 });
49      sidebar.firstElementChild.scrollIntoView(scrollOptions);
50    }
51
52    /**
53     *
54     * @private
55     */
56    let _drawMap = function () {
57      map = webtrees.buildLeafletJsMap('wt-map', config, resetCallback);
58    };
59
60    /**
61     *
62     * @private
63     */
64    let _buildMapData = function () {
65      let geoJson_data = <?= json_encode($data, JSON_THROW_ON_ERROR) ?>;
66
67      if (geoJson_data.features.length === 0) {
68        map.fitWorld();
69        sidebar.innerHTML = '<div class="bg-info text-white text-center">' + <?= json_encode(I18N::translate('Nothing to show'), JSON_THROW_ON_ERROR) ?> + '</div>';
70      } else {
71        sidebar.innerHTML = '';
72        let geoJsonLayer = L.geoJson(geoJson_data, {
73          pointToLayer: function (feature, latlng) {
74            return new L.Marker(latlng, {
75              icon: L.BeautifyIcon.icon({
76                icon: 'bullseye fas',
77                borderColor: 'transparent',
78                backgroundColor: feature.properties.iconcolor,
79                iconShape: 'marker',
80                textColor: 'white',
81              }),
82              title: feature.properties.tooltip,
83              id: feature.id,
84            })
85              .on('popupopen', function (e) {
86                let item = document.querySelector('[data-wt-feature-id="' + e.target.feature.id + '"]');
87                item.classList.add('messagebox');
88                item.scrollIntoView(scrollOptions);
89              })
90              .on('popupclose', function () {
91                sidebar.childNodes.forEach(e => e.classList.remove('messagebox'));
92                sidebar.firstElementChild.scrollIntoView(scrollOptions);
93              });
94          },
95          onEachFeature: function (feature, layer) {
96            if (feature.properties.polyline) {
97              let pline = L.polyline(feature.properties.polyline.points, feature.properties.polyline.options);
98              markers.addLayer(pline);
99            }
100
101            layer.bindPopup(feature.properties.summary);
102            sidebar.innerHTML += `<li class="gchart my-1" data-wt-feature-id=${feature.id}>${feature.properties.summary}</li>`;
103          },
104        });
105        markers.addLayer(geoJsonLayer);
106        map.addLayer(markers);
107        map.fitBounds(markers.getBounds(), { padding: [50, 30], maxZoom: 15 });
108      }
109    };
110
111    window.onload = function() {
112      // Activate marker popup when sidebar entry clicked
113      sidebar.addEventListener('click', (e) => {
114        if (e.target.matches('[data-wt-sosa]')) {
115          map.closePopup();
116
117          let marker = markers.getLayers().filter(function (v) {
118            return v.feature !== undefined && v.feature.id === parseInt(e.target.dataset.wtSosa);
119          }).pop();
120
121          markers.zoomToShowLayer(marker, () => marker.openPopup());
122
123          return false;
124        }
125      });
126    }
127
128    _drawMap();
129    _buildMapData();
130  })();
131</script>
132<?php View::endpush() ?>
133