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