datastake-daf 0.6.99 → 0.6.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.vscode/settings.json +13 -0
  2. package/dist/components/index.js +114 -54
  3. package/dist/style/datastake/_index.css +5 -0
  4. package/dist/style/datastake/datastake.css +5081 -0
  5. package/dist/style/datastake/fonts/Outfit-Black.ttf +0 -0
  6. package/dist/style/datastake/fonts/Outfit-Bold.ttf +0 -0
  7. package/dist/style/datastake/fonts/Outfit-ExtraBold.ttf +0 -0
  8. package/dist/style/datastake/fonts/Outfit-ExtraLight.ttf +0 -0
  9. package/dist/style/datastake/fonts/Outfit-Light.ttf +0 -0
  10. package/dist/style/datastake/fonts/Outfit-Medium.ttf +0 -0
  11. package/dist/style/datastake/fonts/Outfit-Regular.ttf +0 -0
  12. package/dist/style/datastake/fonts/Outfit-SemiBold.ttf +0 -0
  13. package/dist/style/datastake/fonts/Outfit-Thin.ttf +0 -0
  14. package/dist/style/datastake/fonts/outfit.css +62 -0
  15. package/dist/style/datastake/fonts/sf-ui-display-black-58646a6b80d5a.woff +0 -0
  16. package/dist/style/datastake/fonts/sf-ui-display-bold-58646a511e3d9.woff +0 -0
  17. package/dist/style/datastake/fonts/sf-ui-display-heavy-586470160b9e5.woff +0 -0
  18. package/dist/style/datastake/fonts/sf-ui-display-light-58646b33e0551.woff +0 -0
  19. package/dist/style/datastake/fonts/sf-ui-display-medium-58646be638f96.woff +0 -0
  20. package/dist/style/datastake/fonts/sf-ui-display-semibold-58646eddcae92.woff +0 -0
  21. package/dist/style/datastake/fonts/sf-ui-display-thin-58646e9b26e8b.woff +0 -0
  22. package/dist/style/datastake/fonts/sf-ui-display-ultralight-58646b19bf205.woff +0 -0
  23. package/dist/style/datastake/fonts/sfDisplay.css +59 -0
  24. package/dist/style/datastake/leaflet.css +671 -0
  25. package/dist/style/datastake/leaflet.markercluster.css +60 -0
  26. package/dist/style/style.css +1 -0
  27. package/package.json +1 -1
  28. package/rollup.config.js +83 -41
  29. package/src/@daf/core/components/Dashboard/Map/helper.js +439 -434
  30. package/src/@daf/core/components/Dashboard/Map/storyConfig1.js +233 -230
  31. package/src/helpers/Map.js +82 -6
  32. package/src/styles/_index.scss +1 -1
  33. package/src/styles/datastake/_index.css +5 -0
  34. package/src/styles/datastake/datastake.css +5081 -0
  35. package/src/styles/datastake/fonts/Outfit-Black.ttf +0 -0
  36. package/src/styles/datastake/fonts/Outfit-Bold.ttf +0 -0
  37. package/src/styles/datastake/fonts/Outfit-ExtraBold.ttf +0 -0
  38. package/src/styles/datastake/fonts/Outfit-ExtraLight.ttf +0 -0
  39. package/src/styles/datastake/fonts/Outfit-Light.ttf +0 -0
  40. package/src/styles/datastake/fonts/Outfit-Medium.ttf +0 -0
  41. package/src/styles/datastake/fonts/Outfit-Regular.ttf +0 -0
  42. package/src/styles/datastake/fonts/Outfit-SemiBold.ttf +0 -0
  43. package/src/styles/datastake/fonts/Outfit-Thin.ttf +0 -0
  44. package/src/styles/datastake/fonts/outfit.css +62 -0
  45. package/src/styles/datastake/fonts/sf-ui-display-black-58646a6b80d5a.woff +0 -0
  46. package/src/styles/datastake/fonts/sf-ui-display-bold-58646a511e3d9.woff +0 -0
  47. package/src/styles/datastake/fonts/sf-ui-display-heavy-586470160b9e5.woff +0 -0
  48. package/src/styles/datastake/fonts/sf-ui-display-light-58646b33e0551.woff +0 -0
  49. package/src/styles/datastake/fonts/sf-ui-display-medium-58646be638f96.woff +0 -0
  50. package/src/styles/datastake/fonts/sf-ui-display-semibold-58646eddcae92.woff +0 -0
  51. package/src/styles/datastake/fonts/sf-ui-display-thin-58646e9b26e8b.woff +0 -0
  52. package/src/styles/datastake/fonts/sf-ui-display-ultralight-58646b19bf205.woff +0 -0
  53. package/src/styles/datastake/fonts/sfDisplay.css +59 -0
  54. package/src/styles/datastake/leaflet.css +671 -0
  55. package/src/styles/datastake/leaflet.markercluster.css +60 -0
  56. package/src/styles/datastake.scss +1 -4454
@@ -1,13 +1,14 @@
1
1
  import {
2
- AimOutlined,
3
- DownOutlined,
4
- MinusOutlined,
5
- PlusOutlined,
6
- UpOutlined,
2
+ AimOutlined,
3
+ DownOutlined,
4
+ MinusOutlined,
5
+ PlusOutlined,
6
+ UpOutlined,
7
7
  } from "@ant-design/icons";
8
8
  import L from "leaflet";
9
9
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
10
10
  import { createRoot } from "react-dom/client";
11
+ import { getEventMarkerStyle } from "../../../../../helpers/Map";
11
12
  import { SET_VIEW_DEFAULT_ZOOM } from "../../../../hooks/useMapHelper";
12
13
  import { renderTooltipJsx as renderTooltipHtml } from "../../../../utils/tooltip";
13
14
  import ChainIcon from "./ChainIcon";
@@ -15,147 +16,144 @@ import { isExtraSmallMarker, isSmallMarker } from "./ChainIcon/utils";
15
16
  import StakeholderIcon from "./StakeholderIcon";
16
17
 
17
18
  // Event type color constants
18
- const EVENT_COLORS = {
19
- MAJOR: "#cf1322", // Red for major incidents
20
- MODERATE: "#fa8c16", // Orange for moderate incidents
21
- MINOR: "#fadb14", // Yellow for minor incidents
22
- CORRECTIVE: "#12b76a", // Green for corrective actions
23
- };
19
+ // const EVENT_COLORS = {
20
+ // MAJOR: "#cf1322", // Red for major incidents
21
+ // MODERATE: "#fa8c16", // Orange for moderate incidents
22
+ // MINOR: "#fadb14", // Yellow for minor incidents
23
+ // CORRECTIVE: "#12b76a", // Green for corrective actions
24
+ // };
24
25
 
25
26
  export function useMapHelper({
26
- type,
27
- mapRef,
28
- mapCenter,
29
- allData,
30
- renderTooltip,
31
- onClickLink,
32
- link,
33
- tooltipAsText,
34
- renderMarker,
35
- zoom,
36
- selectedMarkersId,
37
- handleSelectMarker,
38
- openPopupIdRef,
27
+ type,
28
+ mapRef,
29
+ mapCenter,
30
+ allData,
31
+ renderTooltip,
32
+ onClickLink,
33
+ link,
34
+ tooltipAsText,
35
+ renderMarker,
36
+ zoom,
37
+ selectedMarkersId,
38
+ handleSelectMarker,
39
+ openPopupIdRef,
39
40
  }) {
40
- const [mapMarkers, setMapMarkers] = useState([]);
41
- const [activeMarker, setActiveMarker] = useState(null);
42
- const getZoom = useCallback(
43
- (mapRef) =>
44
- mapRef.getZoom() > SET_VIEW_DEFAULT_ZOOM ? mapRef.getZoom() : SET_VIEW_DEFAULT_ZOOM,
45
- [],
46
- );
47
- const roots = useRef([]);
48
- const polylinesRef = useRef([]);
49
- const mappedActiveMarker = useMemo(
50
- () => mapMarkers.find((m) => m.id === activeMarker),
51
- [mapMarkers, activeMarker],
52
- );
53
- const [activeStakeholder, setActiveStakeholder] = useState(null);
54
-
55
- // Recenter Map
56
- const recenterMap = useCallback(() => {
57
- if (mapRef) {
58
- if (allData && allData.length) {
59
- const pos = allData.map((m) =>
60
- Array.isArray(m.area)
61
- ? m.area
62
- : [Number(m.marker?.lat ?? 0), Number(m.marker?.lng ?? 0)],
63
- );
64
- const bounds = new L.LatLngBounds(pos);
65
- mapRef.fitBounds(bounds);
66
- } else {
67
- mapRef.setView(mapCenter, SET_VIEW_DEFAULT_ZOOM);
68
- }
69
- }
70
- }, [mapRef, mapCenter, allData]);
71
-
72
- // Actions to do when active marker is changed
73
- useEffect(() => {
74
- if (mapRef) {
75
- if (activeMarker) {
76
- mapRef.eachLayer((layer) => {
77
- if (layer.options.icon) {
78
- if (layer._leaflet_id === activeMarker) {
79
- layer.openPopup();
80
- layer.off("popupclose");
81
- layer.on("popupclose", () => {
82
- setActiveMarker(null);
83
- });
84
- } else {
85
- layer.off("click");
86
- layer.on("click", () => {
87
- setActiveMarker(layer._leaflet_id);
88
- });
89
- }
90
- }
91
- });
92
- } else {
93
- mapRef.eachLayer((layer) => {
94
- if (layer.options.icon) {
95
- const icon = layer.options.icon;
96
- layer.off("click");
97
- layer.on("click", () => {
98
- setActiveMarker(layer._leaflet_id);
99
- });
100
- layer.setIcon(icon);
101
-
102
- if (layer.getPopup() && layer.getPopup().isOpen()) {
103
- layer.closePopup();
104
- }
105
- }
106
- });
107
- }
108
- }
109
- }, [activeMarker, mapRef]);
110
-
111
- // Draws the marker in the map
112
- const addIconToMap = useCallback(
113
- (coordinates, className, data, name, iconSize, html) => {
114
- if (mapRef) {
115
- const marker =
116
- typeof renderMarker === "function"
117
- ? renderMarker(L, coordinates, data).addTo(mapRef)
118
- : L.marker(coordinates, {
119
- icon: L.divIcon({
120
- html,
121
- className: `map-marker ${className}`,
122
- iconSize,
123
- }),
124
- zIndexOffset: parseInt(iconSize[0]),
125
- }).addTo(mapRef);
126
-
127
- if (name) {
128
- marker.bindPopup(name);
129
- }
130
-
131
- marker.on("click", () => {
132
- setActiveMarker(marker._leaflet_id);
133
- });
134
- return marker;
135
- }
136
- return null;
137
- },
138
- [mapRef, renderMarker],
139
- );
140
-
141
- // console.log({
142
- // activeMarker,
143
- // mapMarkers,
144
- // });
145
-
146
- // Draws the marker in the map and saves it in mapMarkers state
147
- const addIconToMapInitialy = useCallback(
148
- (coordinates, groupName, markerName, data, maxTotal = 0, i = 0) => {
149
- if (mapRef) {
150
- let marker;
151
- let iconClassName = "";
152
- let innerHtml = "";
153
- let iconSize = [25, 25];
154
-
155
- if (type === "event") {
156
- iconClassName = "incident rounded";
157
-
158
- const incidents = data?.data || [];
41
+ const [mapMarkers, setMapMarkers] = useState([]);
42
+ const [activeMarker, setActiveMarker] = useState(null);
43
+ const getZoom = useCallback(
44
+ (mapRef) =>
45
+ mapRef.getZoom() > SET_VIEW_DEFAULT_ZOOM
46
+ ? mapRef.getZoom()
47
+ : SET_VIEW_DEFAULT_ZOOM,
48
+ []
49
+ );
50
+ const roots = useRef([]);
51
+ const polylinesRef = useRef([]);
52
+ const mappedActiveMarker = useMemo(
53
+ () => mapMarkers.find((m) => m.id === activeMarker),
54
+ [mapMarkers, activeMarker]
55
+ );
56
+ const [activeStakeholder, setActiveStakeholder] = useState(null);
57
+
58
+ // Recenter Map
59
+ const recenterMap = useCallback(() => {
60
+ if (mapRef) {
61
+ if (allData && allData.length) {
62
+ const pos = allData.map((m) =>
63
+ Array.isArray(m.area)
64
+ ? m.area
65
+ : [Number(m.marker?.lat ?? 0), Number(m.marker?.lng ?? 0)]
66
+ );
67
+ const bounds = new L.LatLngBounds(pos);
68
+ mapRef.fitBounds(bounds);
69
+ } else {
70
+ mapRef.setView(mapCenter, SET_VIEW_DEFAULT_ZOOM);
71
+ }
72
+ }
73
+ }, [mapRef, mapCenter, allData]);
74
+
75
+ // Actions to do when active marker is changed
76
+ useEffect(() => {
77
+ if (mapRef) {
78
+ if (activeMarker) {
79
+ mapRef.eachLayer((layer) => {
80
+ if (layer.options.icon) {
81
+ if (layer._leaflet_id === activeMarker) {
82
+ layer.openPopup();
83
+ layer.off("popupclose");
84
+ layer.on("popupclose", () => {
85
+ setActiveMarker(null);
86
+ });
87
+ } else {
88
+ layer.off("click");
89
+ layer.on("click", () => {
90
+ setActiveMarker(layer._leaflet_id);
91
+ });
92
+ }
93
+ }
94
+ });
95
+ } else {
96
+ mapRef.eachLayer((layer) => {
97
+ if (layer.options.icon) {
98
+ const icon = layer.options.icon;
99
+ layer.off("click");
100
+ layer.on("click", () => {
101
+ setActiveMarker(layer._leaflet_id);
102
+ });
103
+ layer.setIcon(icon);
104
+
105
+ if (layer.getPopup() && layer.getPopup().isOpen()) {
106
+ layer.closePopup();
107
+ }
108
+ }
109
+ });
110
+ }
111
+ }
112
+ }, [activeMarker, mapRef]);
113
+
114
+ // Draws the marker in the map
115
+ const addIconToMap = useCallback(
116
+ (coordinates, className, data, name, iconSize, html) => {
117
+ if (mapRef) {
118
+ const marker =
119
+ typeof renderMarker === "function"
120
+ ? renderMarker(L, coordinates, data).addTo(mapRef)
121
+ : L.marker(coordinates, {
122
+ icon: L.divIcon({
123
+ html,
124
+ className: `map-marker ${className}`,
125
+ iconSize,
126
+ }),
127
+ zIndexOffset: parseInt(iconSize[0]),
128
+ }).addTo(mapRef);
129
+
130
+ if (name) {
131
+ marker.bindPopup(name);
132
+ }
133
+
134
+ marker.on("click", () => {
135
+ setActiveMarker(marker._leaflet_id);
136
+ });
137
+ return marker;
138
+ }
139
+ return null;
140
+ },
141
+ [mapRef, renderMarker]
142
+ );
143
+
144
+ // Draws the marker in the map and saves it in mapMarkers state
145
+ const addIconToMapInitialy = useCallback(
146
+ (coordinates, groupName, markerName, data, maxTotal = 0, i = 0) => {
147
+ if (mapRef) {
148
+ let marker;
149
+ let iconClassName = "";
150
+ let innerHtml = "";
151
+ let iconSize = [25, 25];
152
+
153
+ if (type === "event") {
154
+ iconClassName = "incident rounded";
155
+
156
+ /* const incidents = data?.data || [];
159
157
  const totals = {
160
158
  major: incidents.filter((d) => d.type === "major_incident").length,
161
159
  minor: incidents.filter((d) => d.type === "minor_incident").length,
@@ -168,7 +166,6 @@ export function useMapHelper({
168
166
  let background = "#f1f1f1";
169
167
 
170
168
  if (total > 0) {
171
- // Build a dynamic array of categories with colors & percentages
172
169
  const categories = [
173
170
  { key: "major", value: totals.major, color: EVENT_COLORS.MAJOR },
174
171
  {
@@ -211,104 +208,106 @@ export function useMapHelper({
211
208
  } else {
212
209
  radius = 40;
213
210
  }
211
+ */
214
212
 
215
- innerHtml = `
213
+ const { background, radius, totals } = getEventMarkerStyle(data);
214
+ innerHtml = `
216
215
  <div class="main" style="background: ${background}; border: 2px solid white; width: ${radius}px; height: ${radius}px;">
217
216
  <span>${data.total || 0}</span>
218
217
  </div>`;
219
218
 
220
- const div = document.createElement("div");
221
- const root = createRoot(div);
222
-
223
- root.render(
224
- <>
225
- {renderTooltipHtml({
226
- title: data.name,
227
- subTitle: data.type,
228
- items: renderTooltip({ ...data, totals }),
229
- link,
230
- total: data.sources,
231
- onClickLink: () => onClickLink(data),
232
- })}
233
- </>,
234
- );
235
-
236
- roots.current.push(root);
237
-
238
- const base = 30;
239
- const mp = 1.3;
240
- const perc = (data.total / (maxTotal || 1)) * mp;
241
- const size = 50 * perc;
242
- iconSize = size > base ? [size, size] : [base, base];
243
-
244
- marker = addIconToMap(
245
- coordinates,
246
- iconClassName,
247
- data,
248
- tooltipAsText ? data.name : div,
249
- iconSize,
250
- innerHtml,
251
- );
252
- } else if (type === "territory") {
253
- marker = L.polygon(data.area, {
254
- color: data.color,
255
- opacity: 0.4,
256
- }).addTo(mapRef);
257
- const div = document.createElement("div");
258
- const root = createRoot(div);
259
-
260
- root.render(
261
- <>
262
- {renderTooltipHtml({
263
- title: data.name,
264
- items: renderTooltip(data),
265
- link,
266
- total: data.sources,
267
- onClickLink: () => onClickLink(data),
268
- })}
269
- </>,
270
- );
271
-
272
- roots.current.push(root);
273
-
274
- marker.bindPopup(div);
275
-
276
- marker.on("popupopen", function () {
277
- this.setStyle({ fillOpacity: 0.7 });
278
- });
279
-
280
- marker.on("popupclose", function () {
281
- this.setStyle({ fillOpacity: 0.4 });
282
- });
283
- } else if (type === "stakeholder") {
284
- marker = L.marker(coordinates, {
285
- icon: L.divIcon({
286
- html: `<div id="${i}"></div>`,
287
- className: "marker-stakeholder",
288
- iconSize,
289
- }),
290
- zIndexOffset: parseInt(iconSize[0]),
291
- }).addTo(mapRef);
292
-
293
- const div = document.getElementById(i);
294
- const root = createRoot(div);
295
-
296
- root.render(
297
- <StakeholderIcon
298
- data={data}
299
- title={data.name}
300
- renderTooltip={renderTooltip}
301
- link={link}
302
- onClickLink={onClickLink}
303
- activeStakeholder={activeStakeholder}
304
- setActiveStakeholder={setActiveStakeholder}
305
- />,
306
- );
307
-
308
- roots.current.push(root);
309
- } else if (type === "location") {
310
- iconClassName = "";
311
- innerHtml = `
219
+ const div = document.createElement("div");
220
+ const root = createRoot(div);
221
+
222
+ root.render(
223
+ <>
224
+ {renderTooltipHtml({
225
+ title: data.name,
226
+ subTitle: data.type,
227
+ items: renderTooltip({ ...data, totals }),
228
+ link,
229
+ total: data.sources,
230
+ onClickLink: () => onClickLink(data),
231
+ })}
232
+ </>
233
+ );
234
+
235
+ roots.current.push(root);
236
+
237
+ const base = 30;
238
+ const mp = 1.3;
239
+ const perc = (data.total / (maxTotal || 1)) * mp;
240
+ const size = 50 * perc;
241
+ iconSize = size > base ? [size, size] : [base, base];
242
+
243
+ marker = addIconToMap(
244
+ coordinates,
245
+ iconClassName,
246
+ data,
247
+ tooltipAsText ? data.name : div,
248
+ iconSize,
249
+ innerHtml
250
+ );
251
+ } else if (type === "territory") {
252
+ marker = L.polygon(data.area, {
253
+ color: data.color,
254
+ opacity: 0.4,
255
+ }).addTo(mapRef);
256
+ const div = document.createElement("div");
257
+ const root = createRoot(div);
258
+
259
+ root.render(
260
+ <>
261
+ {renderTooltipHtml({
262
+ title: data.name,
263
+ items: renderTooltip(data),
264
+ link,
265
+ total: data.sources,
266
+ onClickLink: () => onClickLink(data),
267
+ })}
268
+ </>
269
+ );
270
+
271
+ roots.current.push(root);
272
+
273
+ marker.bindPopup(div);
274
+
275
+ marker.on("popupopen", function () {
276
+ this.setStyle({ fillOpacity: 0.7 });
277
+ });
278
+
279
+ marker.on("popupclose", function () {
280
+ this.setStyle({ fillOpacity: 0.4 });
281
+ });
282
+ } else if (type === "stakeholder") {
283
+ marker = L.marker(coordinates, {
284
+ icon: L.divIcon({
285
+ html: `<div id="${i}"></div>`,
286
+ className: "marker-stakeholder",
287
+ iconSize,
288
+ }),
289
+ zIndexOffset: parseInt(iconSize[0]),
290
+ }).addTo(mapRef);
291
+
292
+ const div = document.getElementById(i);
293
+ const root = createRoot(div);
294
+
295
+ root.render(
296
+ <StakeholderIcon
297
+ data={data}
298
+ title={data.name}
299
+ renderTooltip={renderTooltip}
300
+ link={link}
301
+ onClickLink={onClickLink}
302
+ activeStakeholder={activeStakeholder}
303
+ setActiveStakeholder={setActiveStakeholder}
304
+ />
305
+ );
306
+
307
+ roots.current.push(root);
308
+ } else if (type === "location") {
309
+ iconClassName = "";
310
+ innerHtml = `
312
311
 
313
312
  <svg
314
313
  width="28"
@@ -326,201 +325,207 @@ export function useMapHelper({
326
325
 
327
326
  `;
328
327
 
329
- const svg = document.createElement("svg");
330
- const root = createRoot(svg);
331
-
332
- root.render(
333
- <>
334
- {renderTooltipHtml({
335
- title: data.name,
336
- subTitle: data?.subTitle,
337
- total: data.sources,
338
- link,
339
- onClickLink: () => onClickLink(data),
340
- items: renderTooltip(data),
341
- })}
342
- </>,
343
- );
344
-
345
- roots.current.push(root);
346
-
347
- marker = addIconToMap(
348
- coordinates,
349
- iconClassName,
350
- data,
351
- tooltipAsText ? data.name : svg,
352
- iconSize,
353
- innerHtml,
354
- );
355
- } else if (type === "chain") {
356
- marker = L.marker(coordinates, {
357
- icon: L.divIcon({
358
- html: `<div id="${i}"></div>`,
359
- className: "marker-chain",
360
- iconSize:
361
- isSmallMarker(zoom) || isExtraSmallMarker(zoom)
362
- ? [10.5, 12.6]
363
- : [25, 25],
364
- }),
365
- }).addTo(mapRef);
366
-
367
- const div = document.getElementById(i);
368
- const root = createRoot(div);
369
-
370
- root.render(
371
- <ChainIcon
372
- data={data}
373
- zoom={zoom}
374
- allData={allData}
375
- link={link}
376
- renderTooltip={renderTooltip}
377
- onClickLink={onClickLink}
378
- selectedMarkersId={selectedMarkersId}
379
- handleSelectMarker={handleSelectMarker}
380
- mapRef={mapRef}
381
- activeMarker={activeMarker}
382
- setActiveMarker={setActiveMarker}
383
- setMapMarkers={setMapMarkers}
384
- addIconToMap={addIconToMap}
385
- openPopupIdRef={openPopupIdRef}
386
- polylinesRef={polylinesRef}
387
- />,
388
- );
389
-
390
- roots.current.push(root);
391
- } else {
392
- iconClassName = "marker";
393
- innerHtml = '<div class="main"></div>';
394
- const div = document.createElement("div");
395
- const root = createRoot(div);
396
-
397
- root.render(
398
- <>
399
- {renderTooltipHtml({
400
- title: data.name,
401
- subTitle: data?.subTitle,
402
- total: data.sources,
403
- link,
404
- onClickLink: () => onClickLink(data),
405
- items: renderTooltip(data),
406
- })}
407
- </>,
408
- );
409
-
410
- roots.current.push(root);
411
-
412
- marker = addIconToMap(
413
- coordinates,
414
- iconClassName,
415
- data,
416
- tooltipAsText ? data.name : div,
417
- iconSize,
418
- innerHtml,
419
- );
420
- }
421
-
422
- if (marker) {
423
- setMapMarkers((prevMapMarkers) => [
424
- ...prevMapMarkers,
425
- {
426
- id: marker._leaflet_id,
427
- coordinates,
428
- groupName,
429
- markerName,
430
- iconClassName,
431
- data,
432
- },
433
- ]);
434
- }
435
- }
436
- },
437
- [
438
- mapRef,
439
- renderTooltip,
440
- tooltipAsText,
441
- onClickLink,
442
- zoom,
443
- selectedMarkersId,
444
- openPopupIdRef.current,
445
- handleSelectMarker,
446
- activeStakeholder,
447
- setActiveStakeholder,
448
- ],
449
- );
450
-
451
- // Map control handlers
452
- const zoomHandler = useCallback(() => mapRef.setZoom(mapRef.getZoom() + 1), [mapRef]);
453
- const zoomOutHandler = useCallback(() => mapRef.setZoom(mapRef.getZoom() - 1), [mapRef]);
454
-
455
- const moveUpHandler = useCallback(() => {
456
- const center = mapRef.getCenter();
457
- const value = 30 / mapRef.getZoom();
458
- mapRef.panTo(new L.LatLng(center.lat + value, center.lng));
459
- }, [mapRef]);
460
-
461
- const moveDownHandler = useCallback(() => {
462
- const center = mapRef.getCenter();
463
- const value = 30 / mapRef.getZoom();
464
- mapRef.panTo(new L.LatLng(center.lat - value, center.lng));
465
- }, [mapRef]);
466
-
467
- const clearMapMarkers = useCallback(() => {
468
- if (mapRef) {
469
- roots.current.forEach((root) => {
470
- setTimeout(() => {
471
- try {
472
- root.unmount();
473
- } catch (err) {
474
- console.log(err);
475
- }
476
- });
477
- });
478
- roots.current = [];
479
-
480
- mapRef.eachLayer((layer) => {
481
- if (!layer._url) {
482
- mapRef.removeLayer(layer);
483
- }
484
- });
485
- setMapMarkers([]);
486
- }
487
- }, [mapRef]);
488
-
489
- const mapOptionsButtonsConfig = useMemo(
490
- () => [
491
- {
492
- icon: <PlusOutlined style={{ color: "#727272" }} />,
493
- handler: zoomHandler,
494
- },
495
- {
496
- icon: <MinusOutlined style={{ color: "#727272" }} />,
497
- handler: zoomOutHandler,
498
- },
499
- {
500
- icon: <AimOutlined style={{ color: "#727272" }} />,
501
- handler: recenterMap,
502
- },
503
- {
504
- icon: <UpOutlined style={{ color: "#727272" }} />,
505
- handler: moveUpHandler,
506
- },
507
- {
508
- icon: <DownOutlined style={{ color: "#727272" }} />,
509
- handler: moveDownHandler,
510
- },
511
- ],
512
- [zoomHandler, moveUpHandler, moveDownHandler, zoomOutHandler, recenterMap],
513
- );
514
-
515
- return {
516
- addIconToMapInitialy,
517
- activeMarker: mappedActiveMarker,
518
- mapOptionsButtonsConfig,
519
- setActiveMarker,
520
- mapMarkers,
521
- clearMapMarkers,
522
- getZoom,
523
- polylinesRef,
524
- activeStakeholder,
525
- };
328
+ const svg = document.createElement("svg");
329
+ const root = createRoot(svg);
330
+
331
+ root.render(
332
+ <>
333
+ {renderTooltipHtml({
334
+ title: data.name,
335
+ subTitle: data?.subTitle,
336
+ total: data.sources,
337
+ link,
338
+ onClickLink: () => onClickLink(data),
339
+ items: renderTooltip(data),
340
+ })}
341
+ </>
342
+ );
343
+
344
+ roots.current.push(root);
345
+
346
+ marker = addIconToMap(
347
+ coordinates,
348
+ iconClassName,
349
+ data,
350
+ tooltipAsText ? data.name : svg,
351
+ iconSize,
352
+ innerHtml
353
+ );
354
+ } else if (type === "chain") {
355
+ marker = L.marker(coordinates, {
356
+ icon: L.divIcon({
357
+ html: `<div id="${i}"></div>`,
358
+ className: "marker-chain",
359
+ iconSize:
360
+ isSmallMarker(zoom) || isExtraSmallMarker(zoom)
361
+ ? [10.5, 12.6]
362
+ : [25, 25],
363
+ }),
364
+ }).addTo(mapRef);
365
+
366
+ const div = document.getElementById(i);
367
+ const root = createRoot(div);
368
+
369
+ root.render(
370
+ <ChainIcon
371
+ data={data}
372
+ zoom={zoom}
373
+ allData={allData}
374
+ link={link}
375
+ renderTooltip={renderTooltip}
376
+ onClickLink={onClickLink}
377
+ selectedMarkersId={selectedMarkersId}
378
+ handleSelectMarker={handleSelectMarker}
379
+ mapRef={mapRef}
380
+ activeMarker={activeMarker}
381
+ setActiveMarker={setActiveMarker}
382
+ setMapMarkers={setMapMarkers}
383
+ addIconToMap={addIconToMap}
384
+ openPopupIdRef={openPopupIdRef}
385
+ polylinesRef={polylinesRef}
386
+ />
387
+ );
388
+
389
+ roots.current.push(root);
390
+ } else {
391
+ iconClassName = "marker";
392
+ innerHtml = '<div class="main"></div>';
393
+ const div = document.createElement("div");
394
+ const root = createRoot(div);
395
+
396
+ root.render(
397
+ <>
398
+ {renderTooltipHtml({
399
+ title: data.name,
400
+ subTitle: data?.subTitle,
401
+ total: data.sources,
402
+ link,
403
+ onClickLink: () => onClickLink(data),
404
+ items: renderTooltip(data),
405
+ })}
406
+ </>
407
+ );
408
+
409
+ roots.current.push(root);
410
+
411
+ marker = addIconToMap(
412
+ coordinates,
413
+ iconClassName,
414
+ data,
415
+ tooltipAsText ? data.name : div,
416
+ iconSize,
417
+ innerHtml
418
+ );
419
+ }
420
+
421
+ if (marker) {
422
+ setMapMarkers((prevMapMarkers) => [
423
+ ...prevMapMarkers,
424
+ {
425
+ id: marker._leaflet_id,
426
+ coordinates,
427
+ groupName,
428
+ markerName,
429
+ iconClassName,
430
+ data,
431
+ },
432
+ ]);
433
+ }
434
+ }
435
+ },
436
+ [
437
+ mapRef,
438
+ renderTooltip,
439
+ tooltipAsText,
440
+ onClickLink,
441
+ zoom,
442
+ selectedMarkersId,
443
+ openPopupIdRef.current,
444
+ handleSelectMarker,
445
+ activeStakeholder,
446
+ setActiveStakeholder,
447
+ ]
448
+ );
449
+
450
+ // Map control handlers
451
+ const zoomHandler = useCallback(
452
+ () => mapRef.setZoom(mapRef.getZoom() + 1),
453
+ [mapRef]
454
+ );
455
+ const zoomOutHandler = useCallback(
456
+ () => mapRef.setZoom(mapRef.getZoom() - 1),
457
+ [mapRef]
458
+ );
459
+
460
+ const moveUpHandler = useCallback(() => {
461
+ const center = mapRef.getCenter();
462
+ const value = 30 / mapRef.getZoom();
463
+ mapRef.panTo(new L.LatLng(center.lat + value, center.lng));
464
+ }, [mapRef]);
465
+
466
+ const moveDownHandler = useCallback(() => {
467
+ const center = mapRef.getCenter();
468
+ const value = 30 / mapRef.getZoom();
469
+ mapRef.panTo(new L.LatLng(center.lat - value, center.lng));
470
+ }, [mapRef]);
471
+
472
+ const clearMapMarkers = useCallback(() => {
473
+ if (mapRef) {
474
+ roots.current.forEach((root) => {
475
+ setTimeout(() => {
476
+ try {
477
+ root.unmount();
478
+ } catch (err) {
479
+ console.log(err);
480
+ }
481
+ });
482
+ });
483
+ roots.current = [];
484
+
485
+ mapRef.eachLayer((layer) => {
486
+ if (!layer._url) {
487
+ mapRef.removeLayer(layer);
488
+ }
489
+ });
490
+ setMapMarkers([]);
491
+ }
492
+ }, [mapRef]);
493
+
494
+ const mapOptionsButtonsConfig = useMemo(
495
+ () => [
496
+ {
497
+ icon: <PlusOutlined style={{ color: "#727272" }} />,
498
+ handler: zoomHandler,
499
+ },
500
+ {
501
+ icon: <MinusOutlined style={{ color: "#727272" }} />,
502
+ handler: zoomOutHandler,
503
+ },
504
+ {
505
+ icon: <AimOutlined style={{ color: "#727272" }} />,
506
+ handler: recenterMap,
507
+ },
508
+ {
509
+ icon: <UpOutlined style={{ color: "#727272" }} />,
510
+ handler: moveUpHandler,
511
+ },
512
+ {
513
+ icon: <DownOutlined style={{ color: "#727272" }} />,
514
+ handler: moveDownHandler,
515
+ },
516
+ ],
517
+ [zoomHandler, moveUpHandler, moveDownHandler, zoomOutHandler, recenterMap]
518
+ );
519
+
520
+ return {
521
+ addIconToMapInitialy,
522
+ activeMarker: mappedActiveMarker,
523
+ mapOptionsButtonsConfig,
524
+ setActiveMarker,
525
+ mapMarkers,
526
+ clearMapMarkers,
527
+ getZoom,
528
+ polylinesRef,
529
+ activeStakeholder,
530
+ };
526
531
  }