@opengeoweb/time-slider 13.0.0

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 (83) hide show
  1. package/README.md +11 -0
  2. package/index.d.ts +1 -0
  3. package/index.esm.js +3941 -0
  4. package/package.json +34 -0
  5. package/src/index.d.ts +5 -0
  6. package/src/lib/Providers/Providers.d.ts +8 -0
  7. package/src/lib/Providers/index.d.ts +1 -0
  8. package/src/lib/components/TimeSlider/TimeSlider.d.ts +16 -0
  9. package/src/lib/components/TimeSlider/TimeSlider.spec.d.ts +1 -0
  10. package/src/lib/components/TimeSlider/TimeSlider.stories.d.ts +7 -0
  11. package/src/lib/components/TimeSlider/changeTimeFunctions.d.ts +14 -0
  12. package/src/lib/components/TimeSlider/changeTimeFunctions.spec.d.ts +1 -0
  13. package/src/lib/components/TimeSlider/index.d.ts +4 -0
  14. package/src/lib/components/TimeSlider/timeSliderEffects.d.ts +2 -0
  15. package/src/lib/components/TimeSlider/timeSliderUtils.d.ts +138 -0
  16. package/src/lib/components/TimeSlider/timeSliderUtils.spec.d.ts +1 -0
  17. package/src/lib/components/TimeSliderButtons/AnimationLengthButton/AnimationLengthButton.d.ts +12 -0
  18. package/src/lib/components/TimeSliderButtons/AnimationLengthButton/AnimationLengthButton.spec.d.ts +1 -0
  19. package/src/lib/components/TimeSliderButtons/AutoUpdateButton/AutoUpdateButton.d.ts +8 -0
  20. package/src/lib/components/TimeSliderButtons/AutoUpdateButton/AutoUpdateButton.spec.d.ts +1 -0
  21. package/src/lib/components/TimeSliderButtons/BackwardForwardStepButton/BackwardForwardStepButton.d.ts +7 -0
  22. package/src/lib/components/TimeSliderButtons/BackwardForwardStepButton/BackwardForwardStepButton.spec.d.ts +1 -0
  23. package/src/lib/components/TimeSliderButtons/ControlButtons/ControlButtons.d.ts +8 -0
  24. package/src/lib/components/TimeSliderButtons/HideSliderButton/HideSliderButton.d.ts +6 -0
  25. package/src/lib/components/TimeSliderButtons/HideSliderButton/HideSliderButton.spec.d.ts +1 -0
  26. package/src/lib/components/TimeSliderButtons/NowButton/NowButton.d.ts +7 -0
  27. package/src/lib/components/TimeSliderButtons/NowButton/NowButton.spec.d.ts +1 -0
  28. package/src/lib/components/TimeSliderButtons/OptionsMenuButton/OptionsMenu.d.ts +7 -0
  29. package/src/lib/components/TimeSliderButtons/OptionsMenuButton/OptionsMenuButton.d.ts +10 -0
  30. package/src/lib/components/TimeSliderButtons/OptionsMenuButton/OptionsMenuButton.spec.d.ts +1 -0
  31. package/src/lib/components/TimeSliderButtons/OptionsMenuButton/index.d.ts +2 -0
  32. package/src/lib/components/TimeSliderButtons/PlayButton/PlayButton.d.ts +7 -0
  33. package/src/lib/components/TimeSliderButtons/PlayButton/PlayButton.spec.d.ts +1 -0
  34. package/src/lib/components/TimeSliderButtons/SpeedButton/SpeedButton.d.ts +6 -0
  35. package/src/lib/components/TimeSliderButtons/SpeedButton/SpeedButton.spec.d.ts +1 -0
  36. package/src/lib/components/TimeSliderButtons/TimeSliderButtons.d.ts +10 -0
  37. package/src/lib/components/TimeSliderButtons/TimeSliderButtons.spec.d.ts +1 -0
  38. package/src/lib/components/TimeSliderButtons/TimeSliderButtons.stories.d.ts +8 -0
  39. package/src/lib/components/TimeSliderButtons/TimeSliderMenu/TimeSliderMenu.d.ts +24 -0
  40. package/src/lib/components/TimeSliderButtons/TimeSliderMenu/TimeSliderMenu.spec.d.ts +1 -0
  41. package/src/lib/components/TimeSliderButtons/TimeSpanButton/TimeSpanButton.d.ts +17 -0
  42. package/src/lib/components/TimeSliderButtons/TimeSpanButton/TimeSpanButton.spec.d.ts +1 -0
  43. package/src/lib/components/TimeSliderButtons/TimeSpanButton/TimeSpanButton.stories.d.ts +9 -0
  44. package/src/lib/components/TimeSliderButtons/TimeSpanButton/TimeSpanButtonCustomSelect.d.ts +7 -0
  45. package/src/lib/components/TimeSliderButtons/TimeSpanButton/TimeSpanButtonCustomSelect.spec.d.ts +1 -0
  46. package/src/lib/components/TimeSliderButtons/TimeStepButton/TimeStepButton.d.ts +11 -0
  47. package/src/lib/components/TimeSliderButtons/TimeStepButton/TimeStepButton.spec.d.ts +1 -0
  48. package/src/lib/components/TimeSliderButtons/TimeStepButton/TimeStepButton.stories.d.ts +9 -0
  49. package/src/lib/components/TimeSliderButtons/index.d.ts +13 -0
  50. package/src/lib/components/TimeSliderClock/ClockContainer.d.ts +18 -0
  51. package/src/lib/components/TimeSliderClock/PopperMenu.d.ts +9 -0
  52. package/src/lib/components/TimeSliderClock/TimeSliderClock.d.ts +9 -0
  53. package/src/lib/components/TimeSliderClock/TimeSliderClock.spec.d.ts +1 -0
  54. package/src/lib/components/TimeSliderClock/TimeSliderClock.stories.d.ts +11 -0
  55. package/src/lib/components/TimeSliderClock/clockContainerUtils.d.ts +1 -0
  56. package/src/lib/components/TimeSliderClock/clockContainerUtils.spec.d.ts +1 -0
  57. package/src/lib/components/TimeSliderClock/index.d.ts +1 -0
  58. package/src/lib/components/TimeSliderCurrentTimeBox/CalendarButton/CalendarButton.d.ts +10 -0
  59. package/src/lib/components/TimeSliderCurrentTimeBox/CalendarButton/CalendarButton.spec.d.ts +1 -0
  60. package/src/lib/components/TimeSliderCurrentTimeBox/MarkerTimeSelector/MarkerTimeSelector.d.ts +24 -0
  61. package/src/lib/components/TimeSliderCurrentTimeBox/MarkerTimeSelector/MarkerTimeSelector.spec.d.ts +1 -0
  62. package/src/lib/components/TimeSliderCurrentTimeBox/TimeSliderCurrentTimeBox.d.ts +16 -0
  63. package/src/lib/components/TimeSliderCurrentTimeBox/TimeSliderCurrentTimeBox.spec.d.ts +1 -0
  64. package/src/lib/components/TimeSliderCurrentTimeBox/TimeSliderCurrentTimeBoxMouseEvents.d.ts +2 -0
  65. package/src/lib/components/TimeSliderCurrentTimeBox/TimeSliderCurrentTimeBoxMouseEvents.spec.d.ts +1 -0
  66. package/src/lib/components/TimeSliderCurrentTimeBox/TimeSliderCurrentTimeBoxRenderFunctions.d.ts +3 -0
  67. package/src/lib/components/TimeSliderCurrentTimeBox/index.d.ts +1 -0
  68. package/src/lib/components/TimeSliderLegend/TimeSliderLegend.d.ts +35 -0
  69. package/src/lib/components/TimeSliderLegend/TimeSliderLegend.spec.d.ts +1 -0
  70. package/src/lib/components/TimeSliderLegend/TimeSliderLegend.stories.d.ts +9 -0
  71. package/src/lib/components/TimeSliderLegend/drawFunctions/drawBackground.d.ts +4 -0
  72. package/src/lib/components/TimeSliderLegend/drawFunctions/drawBackground.spec.d.ts +1 -0
  73. package/src/lib/components/TimeSliderLegend/drawFunctions/drawCurrentTime.d.ts +2 -0
  74. package/src/lib/components/TimeSliderLegend/drawFunctions/drawNeedle.d.ts +2 -0
  75. package/src/lib/components/TimeSliderLegend/drawFunctions/drawTimeScale.d.ts +7 -0
  76. package/src/lib/components/TimeSliderLegend/drawFunctions/drawTimeScale.spec.d.ts +1 -0
  77. package/src/lib/components/TimeSliderLegend/drawFunctions/drawTimeSliderLegend.d.ts +2 -0
  78. package/src/lib/components/TimeSliderLegend/drawFunctions/index.d.ts +1 -0
  79. package/src/lib/components/TimeSliderLegend/index.d.ts +1 -0
  80. package/src/lib/components/TimeSliderLegend/timeSliderLegendUtils.d.ts +37 -0
  81. package/src/lib/components/TimeSliderLegend/timeSliderLegenedUtils.spec.d.ts +1 -0
  82. package/src/lib/index.d.ts +6 -0
  83. package/src/lib/utils/i18n.d.ts +6 -0
package/index.esm.js ADDED
@@ -0,0 +1,3941 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { Grid, Typography, Box, Menu, MenuItem, CardHeader, FormControl, TextField, Select, Popper, Paper, useTheme, Stack, InputAdornment, ClickAwayListener } from '@mui/material';
3
+ import { safelyInitI18nForTestsAndStories, CustomIconButton, dateUtils, CustomTooltip, renderCounter, useMakeSureContainerStaysInsideWindow, CanvasComponent, CustomToggleButton } from '@opengeoweb/shared';
4
+ import { ChevronDown, ChevronUp, ChevronRight, ChevronLeft, Edit, Speed, FastForward, Clock, Animation, Pause, Play, StepForward, StepBackward, Now, AutoUpdateActive, AutoUpdateInActive, Resize, dragHandlePath, Options, CalendarToday, ThemeWrapper, lightTheme, darkTheme } from '@opengeoweb/theme';
5
+ import * as React from 'react';
6
+ import React__default, { useState, useRef, useEffect, createElement } from 'react';
7
+ import i18n from 'i18next';
8
+ import { useTranslation, I18nextProvider } from 'react-i18next';
9
+ import { debounce, throttle } from 'lodash';
10
+ import Draggable from 'react-draggable';
11
+ import { Resizable } from 're-resizable';
12
+ import { Box as Box$1 } from '@mui/system';
13
+ import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
14
+ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
15
+ import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
16
+ import { PickersDay } from '@mui/x-date-pickers/PickersDay';
17
+
18
+ var en = {
19
+ "timeslider-auto": "Auto",
20
+ "timeslider-length": "length",
21
+ "timeslider-animation": "Animation",
22
+ "timeslider-auto-update-on": "Auto update on",
23
+ "timeslider-auto-update-off": "Auto update off",
24
+ "timeslider-backward": "Backward",
25
+ "timeslider-forward": "Forward",
26
+ "timeslider-hide": "Hide timeslider",
27
+ "timeslider-show": "Show timeslider",
28
+ "timeslider-now": "Now",
29
+ "timeslider-animation-options": "Animation options",
30
+ "timeslider-play": "Play",
31
+ "timeslider-pause": "Pause",
32
+ "timeslider-speed": "Speed",
33
+ "timeslider-min": "min",
34
+ "timeslider-hour": "h",
35
+ "timeslider-day": "d",
36
+ "timeslider-week": "week",
37
+ "timeslider-weeks": "weeks",
38
+ "timeslider-month": "month",
39
+ "timeslider-months": "months",
40
+ "timeslider-year": "year",
41
+ "timeslider-years": "years",
42
+ "timeslider-time-step": "Time step",
43
+ "timeslider-time-span": "Time span",
44
+ "timeslider-january": "Jan",
45
+ "timeslider-february": "Feb",
46
+ "timeslider-march": "Mar",
47
+ "timeslider-april": "Apr",
48
+ "timeslider-may": "May",
49
+ "timeslider-june": "Jun",
50
+ "timeslider-july": "Jul",
51
+ "timeslider-august": "Aug",
52
+ "timeslider-september": "Sep",
53
+ "timeslider-october": "Oct",
54
+ "timeslider-november": "Nov",
55
+ "timeslider-december": "Dec",
56
+ "timeslider-sunday": "Sun",
57
+ "timeslider-monday": "Mon",
58
+ "timeslider-tuesday": "Tue",
59
+ "timeslider-wednesday": "Wed",
60
+ "timeslider-thursday": "Thu",
61
+ "timeslider-friday": "Fri",
62
+ "timeslider-saturday": "Sat",
63
+ "timeslider-edit": "Edit",
64
+ "timeslider-span": "Span",
65
+ "timeslider-marker": "Marker",
66
+ "timeslider-marker-placement": "Marker placement",
67
+ "timeslider-marker-label": "Select date and time"
68
+ };
69
+ var fi = {
70
+ "timeslider-auto": "Auto",
71
+ "timeslider-length": "pituus",
72
+ "timeslider-animation": "Animaatio",
73
+ "timeslider-auto-update-on": "Auto update päällä",
74
+ "timeslider-auto-update-off": "Auto update pois päältä",
75
+ "timeslider-backward": "Taaksepäin",
76
+ "timeslider-forward": "Eteenpäin",
77
+ "timeslider-hide": "Piilota Timeslider",
78
+ "timeslider-show": "Näytä Timeslider",
79
+ "timeslider-now": "Nyt",
80
+ "timeslider-animation-options": "Animoinnin asetukset",
81
+ "timeslider-play": "Toista",
82
+ "timeslider-pause": "Tauko",
83
+ "timeslider-speed": "Nopeus",
84
+ "timeslider-min": "min",
85
+ "timeslider-hour": "t",
86
+ "timeslider-week": "viikko",
87
+ "timeslider-weeks": "viikkoa",
88
+ "timeslider-month": "kuukausi",
89
+ "timeslider-months": "kuukautta",
90
+ "timeslider-year": "vuosi",
91
+ "timeslider-years": "vuotta",
92
+ "timeslider-time-step": "Aika-askel",
93
+ "timeslider-time-span": "Aikaväli",
94
+ "timeslider-january": "Tammmi",
95
+ "timeslider-february": "Helmi",
96
+ "timeslider-march": "Maalis",
97
+ "timeslider-april": "Huhti",
98
+ "timeslider-may": "Touko",
99
+ "timeslider-june": "Kesä",
100
+ "timeslider-july": "Heinä",
101
+ "timeslider-august": "Elo",
102
+ "timeslider-september": "Syys",
103
+ "timeslider-october": "Loka",
104
+ "timeslider-november": "Marras",
105
+ "timeslider-december": "Joulu",
106
+ "timeslider-sunday": "Su",
107
+ "timeslider-monday": "Ma",
108
+ "timeslider-tuesday": "Ti",
109
+ "timeslider-wednesday": "Ke",
110
+ "timeslider-thursday": "To",
111
+ "timeslider-friday": "Pe",
112
+ "timeslider-saturday": "La",
113
+ "timeslider-edit": "missing-translation",
114
+ "timeslider-span": "missing-translation",
115
+ "timeslider-marker": "Aikamerkki",
116
+ "timeslider-marker-placement": "Aikamerkin siirto",
117
+ "timeslider-marker-label": "Valitse päivämäärä ja kellonaika"
118
+ };
119
+ var no = {
120
+ "timeslider-auto": "Auto",
121
+ "timeslider-length": "lengde",
122
+ "timeslider-animation": "Animasjon",
123
+ "timeslider-auto-update-on": "Autooppdatering på",
124
+ "timeslider-auto-update-off": "Autooppdatering av",
125
+ "timeslider-backward": "Bakover",
126
+ "timeslider-forward": "Forover",
127
+ "timeslider-hide": "Skjul",
128
+ "timeslider-show": "Vis",
129
+ "timeslider-now": "Nå",
130
+ "timeslider-animation-options": "Animasjonsinnstillinger",
131
+ "timeslider-play": "Spill",
132
+ "timeslider-pause": "Pause",
133
+ "timeslider-speed": "Hurtighet",
134
+ "timeslider-min": "min",
135
+ "timeslider-hour": "t",
136
+ "timeslider-week": "uke",
137
+ "timeslider-weeks": "uker",
138
+ "timeslider-month": "måned",
139
+ "timeslider-months": "måneder",
140
+ "timeslider-year": "år",
141
+ "timeslider-years": "år",
142
+ "timeslider-time-step": "Tidsintervall",
143
+ "timeslider-time-span": "Tidsperiode",
144
+ "timeslider-january": "Jan",
145
+ "timeslider-february": "Feb",
146
+ "timeslider-march": "Mar",
147
+ "timeslider-april": "Apr",
148
+ "timeslider-may": "Mai",
149
+ "timeslider-june": "Jun",
150
+ "timeslider-july": "Jul",
151
+ "timeslider-august": "Aug",
152
+ "timeslider-september": "Sep",
153
+ "timeslider-october": "Okt",
154
+ "timeslider-november": "Nov",
155
+ "timeslider-december": "Des",
156
+ "timeslider-sunday": "Søn",
157
+ "timeslider-monday": "Man",
158
+ "timeslider-tuesday": "Tir",
159
+ "timeslider-wednesday": "Ons",
160
+ "timeslider-thursday": "Tor",
161
+ "timeslider-friday": "Fre",
162
+ "timeslider-saturday": "Lør",
163
+ "timeslider-edit": "Editer",
164
+ "timeslider-span": "Periode",
165
+ "timeslider-marker": "missing translation",
166
+ "timeslider-marker-placement": "missing translation",
167
+ "timeslider-marker-label": "missing translation"
168
+ };
169
+ var nl = {
170
+ "timeslider-auto": "Auto",
171
+ "timeslider-length": "lengte",
172
+ "timeslider-animation": "Animatie",
173
+ "timeslider-auto-update-on": "Auto update aan",
174
+ "timeslider-auto-update-off": "Auto update uit",
175
+ "timeslider-backward": "Achteruit",
176
+ "timeslider-forward": "Vooruit",
177
+ "timeslider-hide": "Timeslider verbergen",
178
+ "timeslider-show": "Timeslider tonen",
179
+ "timeslider-now": "Nu",
180
+ "timeslider-animation-options": "Animatie opties",
181
+ "timeslider-play": "Afspelen",
182
+ "timeslider-pause": "Pauze",
183
+ "timeslider-speed": "Snelheid",
184
+ "timeslider-min": "min",
185
+ "timeslider-hour": "u",
186
+ "timeslider-week": "week",
187
+ "timeslider-weeks": "weken",
188
+ "timeslider-month": "maand",
189
+ "timeslider-months": "maanden",
190
+ "timeslider-year": "jaar",
191
+ "timeslider-years": "jaren",
192
+ "timeslider-time-step": "Tijdsinterval",
193
+ "timeslider-time-span": "Tijdsperiode",
194
+ "timeslider-january": "Jan",
195
+ "timeslider-february": "Feb",
196
+ "timeslider-march": "Maa",
197
+ "timeslider-april": "Apr",
198
+ "timeslider-may": "Mei",
199
+ "timeslider-june": "Jun",
200
+ "timeslider-july": "Jul",
201
+ "timeslider-august": "Aug",
202
+ "timeslider-september": "Sep",
203
+ "timeslider-october": "Okt",
204
+ "timeslider-november": "Nov",
205
+ "timeslider-december": "Dec",
206
+ "timeslider-sunday": "Zon",
207
+ "timeslider-monday": "Maa",
208
+ "timeslider-tuesday": "Din",
209
+ "timeslider-wednesday": "Woe",
210
+ "timeslider-thursday": "Don",
211
+ "timeslider-friday": "Vri",
212
+ "timeslider-saturday": "Zat",
213
+ "timeslider-edit": "Bewerken",
214
+ "timeslider-span": "Tijdsperiode",
215
+ "timeslider-marker": "Kies tijdstip",
216
+ "timeslider-marker-placement": "Tijd kiezen",
217
+ "timeslider-marker-label": "Selecteer datum en tijd"
218
+ };
219
+ var timesliderTranslations = {
220
+ en: en,
221
+ fi: fi,
222
+ no: no,
223
+ nl: nl
224
+ };
225
+
226
+ /* *
227
+ * Licensed under the Apache License, Version 2.0 (the "License");
228
+ * you may not use this file except in compliance with the License.
229
+ * You may obtain a copy of the License at
230
+ *
231
+ * http://www.apache.org/licenses/LICENSE-2.0
232
+ *
233
+ * Unless required by applicable law or agreed to in writing, software
234
+ * distributed under the License is distributed on an "AS IS" BASIS,
235
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
236
+ * See the License for the specific language governing permissions and
237
+ * limitations under the License.
238
+ *
239
+ * Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
240
+ * Copyright 2023 - Finnish Meteorological Institute (FMI)
241
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
242
+ * */
243
+ var TIME_SLIDER_NAMESPACE = 'timeslider';
244
+ var initTimesliderI18n = function initTimesliderI18n() {
245
+ safelyInitI18nForTestsAndStories(i18n, TIME_SLIDER_NAMESPACE, [{
246
+ ns: TIME_SLIDER_NAMESPACE,
247
+ translations: timesliderTranslations
248
+ }]);
249
+ };
250
+ var useTimesliderTranslation = function useTimesliderTranslation() {
251
+ return useTranslation(TIME_SLIDER_NAMESPACE);
252
+ };
253
+
254
+ var HideSliderButtonComponent = function HideSliderButtonComponent(_ref) {
255
+ var isVisible = _ref.isVisible,
256
+ toggleTimeSliderIsVisible = _ref.toggleTimeSliderIsVisible;
257
+ var _useTimesliderTransla = useTimesliderTranslation(),
258
+ t = _useTimesliderTransla.t;
259
+ return jsx(CustomIconButton, {
260
+ variant: "tool",
261
+ onClick: function onClick() {
262
+ toggleTimeSliderIsVisible(!isVisible);
263
+ },
264
+ "data-testid": "hideTimeSliderButton",
265
+ tooltipTitle: isVisible ? t('timeslider-hide') : t('timeslider-show'),
266
+ children: isVisible ? jsx(ChevronDown, {}) : jsx(ChevronUp, {})
267
+ });
268
+ };
269
+ var HideSliderButton = /*#__PURE__*/React__default.memo(HideSliderButtonComponent);
270
+
271
+ function _arrayLikeToArray(r, a) {
272
+ (null == a || a > r.length) && (a = r.length);
273
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
274
+ return n;
275
+ }
276
+ function _createForOfIteratorHelperLoose(r, e) {
277
+ var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
278
+ if (t) return (t = t.call(r)).next.bind(t);
279
+ if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) {
280
+ t && (r = t);
281
+ var o = 0;
282
+ return function () {
283
+ return o >= r.length ? {
284
+ done: true
285
+ } : {
286
+ done: false,
287
+ value: r[o++]
288
+ };
289
+ };
290
+ }
291
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
292
+ }
293
+ function _objectWithoutPropertiesLoose(r, e) {
294
+ if (null == r) return {};
295
+ var t = {};
296
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
297
+ if (-1 !== e.indexOf(n)) continue;
298
+ t[n] = r[n];
299
+ }
300
+ return t;
301
+ }
302
+ function _unsupportedIterableToArray(r, a) {
303
+ if (r) {
304
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
305
+ var t = {}.toString.call(r).slice(8, -1);
306
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
307
+ }
308
+ }
309
+
310
+ var Scale;
311
+ (function (Scale) {
312
+ Scale[Scale["Minutes5"] = 0] = "Minutes5";
313
+ Scale[Scale["Hour"] = 1] = "Hour";
314
+ Scale[Scale["Hours3"] = 2] = "Hours3";
315
+ Scale[Scale["Hours6"] = 3] = "Hours6";
316
+ Scale[Scale["Day"] = 4] = "Day";
317
+ Scale[Scale["Week"] = 5] = "Week";
318
+ Scale[Scale["Weeks2"] = 6] = "Weeks2";
319
+ Scale[Scale["Month"] = 7] = "Month";
320
+ Scale[Scale["Months3"] = 8] = "Months3";
321
+ Scale[Scale["Year"] = 9] = "Year";
322
+ })(Scale || (Scale = {}));
323
+ var AnimationLength;
324
+ (function (AnimationLength) {
325
+ AnimationLength[AnimationLength["Minutes15"] = 15] = "Minutes15";
326
+ AnimationLength[AnimationLength["Minutes30"] = 30] = "Minutes30";
327
+ AnimationLength[AnimationLength["Hours1"] = 60] = "Hours1";
328
+ AnimationLength[AnimationLength["Hours2"] = 120] = "Hours2";
329
+ AnimationLength[AnimationLength["Hours3"] = 180] = "Hours3";
330
+ AnimationLength[AnimationLength["Hours6"] = 360] = "Hours6";
331
+ AnimationLength[AnimationLength["Hours12"] = 720] = "Hours12";
332
+ AnimationLength[AnimationLength["Hours24"] = 1440] = "Hours24";
333
+ })(AnimationLength || (AnimationLength = {}));
334
+ /**
335
+ * In this Map collection all fundamental scales
336
+ * (Scale.Minutes5 ... Scale.Year) are mapped with their corresponding
337
+ * secondsPerPx numbers.
338
+ * @returns a Map including information explained above
339
+ */
340
+ var secondsPerPxToScale = new Map([[2.5, Scale.Minutes5], [30, Scale.Hour], [3 * 30, Scale.Hours3], [6 * 30, Scale.Hours6], [24 * 30, Scale.Day], [7 * 24 * 30, Scale.Week], [14 * 24 * 30, Scale.Weeks2], [30 * 24 * 30, Scale.Month], [90 * 24 * 30, Scale.Months3], [365 * 24 * 30, Scale.Year]]);
341
+ var spanToScale = new Map([[5 * 60, Scale.Minutes5], [60 * 60, Scale.Hour], [3 * 60 * 60, Scale.Hours3], [6 * 60 * 60, Scale.Hours6], [24 * 60 * 60, Scale.Day], [7 * 24 * 60 * 60, Scale.Week], [14 * 24 * 60 * 60, Scale.Weeks2], [30 * 24 * 60 * 60, Scale.Month], [90 * 24 * 60 * 60, Scale.Months3], [365 * 24 * 60 * 60, Scale.Year]]);
342
+ /**
343
+ * Creates a reverse mapping of scales to their corresponding secondsPerPx
344
+ * values to make it easier in some parts GeoWeb to fetch a secondsPerpx for
345
+ * a certain fundamental scale (Scale.Minutes5 ... Scale.year)
346
+ * @returns an Object, where names are fundamental scale values (0 - 7) and
347
+ * values are their corresponding secondsPerPx numbers.
348
+ */
349
+ var scaleToSecondsPerPx = Object.fromEntries(Array.from(secondsPerPxToScale.entries()).map(function (_ref) {
350
+ var key = _ref[0],
351
+ value = _ref[1];
352
+ return [value, key];
353
+ }));
354
+ var scalingCoefficient = function scalingCoefficient(end, start, width) {
355
+ return width / (end - start);
356
+ };
357
+ var timestampToPixelEdges = function timestampToPixelEdges(timestamp, start, end, width) {
358
+ return (timestamp - start) * scalingCoefficient(end, start, width);
359
+ };
360
+ var timestampToPixel = function timestampToPixel(timestamp, centerTime, widthPx, secondsPerPx) {
361
+ return widthPx / 2 - (centerTime - timestamp) / secondsPerPx;
362
+ };
363
+ var pixelToTimestamp = function pixelToTimestamp(timePx, centerTime, widthPx, secondsPerPx) {
364
+ return centerTime - (widthPx / 2 - timePx) * secondsPerPx;
365
+ };
366
+ /**
367
+ * This function creates and returns an array where there is secondsPerPx
368
+ * number of the data set added for a data scale (secondsPerPx)
369
+ * to secondsPerPxToScale.
370
+ * @param secondsPerPx
371
+ * @returns an array containing secondsPerPx numbers.
372
+ * The secondsPerPx number for a data scale is included
373
+ * contrary to secondsPerPxToScale.
374
+ */
375
+ var secondsPerPxValues = function secondsPerPxValues(secondsPerPx) {
376
+ var sortedSecondsPerPx = [].concat(secondsPerPxToScale).map(function (value) {
377
+ return Number(value[0]);
378
+ });
379
+ var full = [].concat(sortedSecondsPerPx, [secondsPerPx]);
380
+ return full;
381
+ };
382
+ var secondsPerPxFromCanvasWidth = function secondsPerPxFromCanvasWidth(canvasWidth, spanInSeconds) {
383
+ if (canvasWidth <= 0 || spanInSeconds <= 0) {
384
+ return undefined;
385
+ }
386
+ return spanInSeconds / canvasWidth;
387
+ };
388
+ var getNewCenterOfFixedPointZoom = function getNewCenterOfFixedPointZoom(fixedTimePoint, oldSecondsPerPx, newSecondsPerPx, oldCenterTime) {
389
+ var centerToFixedPointPx = (fixedTimePoint - oldCenterTime) / oldSecondsPerPx;
390
+ return fixedTimePoint - centerToFixedPointPx * newSecondsPerPx;
391
+ };
392
+ /**
393
+ * Move the time slider such that a given time point (timePoint)
394
+ * is at a given pixel width (timePointPx).
395
+ * @returns a new center time for the resulting position
396
+ */
397
+ var moveRelativeToTimePoint = function moveRelativeToTimePoint(timePoint, timePointPx, secondsPerPx, canvasWidth) {
398
+ return timePoint - secondsPerPx * (timePointPx - canvasWidth / 2);
399
+ };
400
+ /** This reusable custom hook tells whether given pointer event targets current canvas node.
401
+ * Example:
402
+ *
403
+ * const [isAllowedCanvasNodePointed, nodeRef] = useCanvasTarget('mousedown', false);
404
+ * ...
405
+ * return isAllowedCanvasNodePointed ? (<CanvasComponent ref={nodeRef}>Component with ref</CanvasComponent>) : (<CanvasComponent>Component with NO ref</CanvasComponent>);
406
+ * ...
407
+ */
408
+ var useCanvasTarget = function useCanvasTarget(eventType) {
409
+ var nodeRef = React__default.useRef(null);
410
+ var _React$useState = React__default.useState(false),
411
+ isTargetNode = _React$useState[0],
412
+ setTargetNode = _React$useState[1];
413
+ // Check if pointer event targets current node element
414
+ var pointerEventListener = React__default.useCallback(function (event) {
415
+ setTargetNode(nodeRef.current.canvas ? nodeRef.current.canvas.isEqualNode(event.target) : false);
416
+ }, [nodeRef]);
417
+ React__default.useEffect(function () {
418
+ document.addEventListener(eventType, pointerEventListener);
419
+ return function () {
420
+ return document.removeEventListener(eventType, pointerEventListener);
421
+ };
422
+ }, [eventType, pointerEventListener]); // Only add/remove event listener when listener really changes, that is, NOT necessarily between every re-render.
423
+ return [isTargetNode, nodeRef];
424
+ };
425
+ var timeBoxGeom = {
426
+ smallWidth: 126,
427
+ largeWidth: 167,
428
+ height: 24,
429
+ cornerRadius: 5,
430
+ lineWidth: 1,
431
+ iconWidth: 25,
432
+ calendarWidth: 20
433
+ };
434
+ var AUTO_MOVE_AREA_PADDING = 1;
435
+ var getAutoMoveAreaWidth = function getAutoMoveAreaWidth(scale) {
436
+ return (scale === Scale.Year ? timeBoxGeom.largeWidth + timeBoxGeom.iconWidth : timeBoxGeom.smallWidth + timeBoxGeom.iconWidth) / 2 + AUTO_MOVE_AREA_PADDING;
437
+ };
438
+ var TimeInMinutes;
439
+ (function (TimeInMinutes) {
440
+ TimeInMinutes[TimeInMinutes["YEAR"] = 525600] = "YEAR";
441
+ TimeInMinutes[TimeInMinutes["MONTH"] = 43200] = "MONTH";
442
+ TimeInMinutes[TimeInMinutes["WEEK"] = 10080] = "WEEK";
443
+ TimeInMinutes[TimeInMinutes["DAY"] = 1440] = "DAY";
444
+ TimeInMinutes[TimeInMinutes["HOUR"] = 60] = "HOUR";
445
+ TimeInMinutes[TimeInMinutes["MINUTE"] = 1] = "MINUTE";
446
+ })(TimeInMinutes || (TimeInMinutes = {}));
447
+ /**
448
+ *
449
+ * @param minutes
450
+ * @returns the two highest values in the format yr(s) mo(s) d h m
451
+ */
452
+ var minutesToDescribedDuration = function minutesToDescribedDuration(minutes) {
453
+ var units = [{
454
+ label: 'yr',
455
+ value: TimeInMinutes.YEAR,
456
+ plural: 's'
457
+ }, {
458
+ label: 'mo',
459
+ value: TimeInMinutes.MONTH,
460
+ plural: 's'
461
+ }, {
462
+ label: 'd',
463
+ value: TimeInMinutes.DAY
464
+ }, {
465
+ label: 'h',
466
+ value: TimeInMinutes.HOUR
467
+ }, {
468
+ label: 'm',
469
+ value: TimeInMinutes.MINUTE
470
+ }];
471
+ var durations = units.reduce(function (units, duration) {
472
+ var min = units.min,
473
+ time = units.time,
474
+ count = units.count;
475
+ var label = duration.label,
476
+ value = duration.value,
477
+ _duration$plural = duration.plural,
478
+ plural = _duration$plural === void 0 ? '' : _duration$plural;
479
+ var unit = Math.floor(min / value);
480
+ if (unit > 0 && count < 2) {
481
+ return {
482
+ time: "" + time + unit + label + (unit > 1 ? plural : '') + " ",
483
+ min: min - unit * value,
484
+ count: count + 1
485
+ };
486
+ }
487
+ return {
488
+ min: min,
489
+ time: time,
490
+ count: count
491
+ };
492
+ }, {
493
+ min: minutes,
494
+ time: '',
495
+ count: 0
496
+ });
497
+ return durations.time.trim();
498
+ };
499
+ /**
500
+ * Returns the largest timeunit value divisible by minuts
501
+ * @param minutes
502
+ * @returns
503
+ */
504
+ function getLargestTimeUnit(minutes) {
505
+ var values = Object.values(TimeInMinutes).filter(function (value) {
506
+ return typeof value === 'number';
507
+ });
508
+ for (var _iterator = _createForOfIteratorHelperLoose(values), _step; !(_step = _iterator()).done;) {
509
+ var value = _step.value;
510
+ if (minutes >= value) {
511
+ return value;
512
+ }
513
+ }
514
+ return TimeInMinutes.MINUTE;
515
+ }
516
+ // For a data scale an appropriate fundamental scale is chosen
517
+ // depending on secondsPerPx of data. When a time range of
518
+ // data is for example many months. the fundamental scale Scale.Year
519
+ // is chosen here and the legend of the time slider is drawn in the
520
+ // same as if otiginally a year scale would have been chose.
521
+ //
522
+ // If a time range of data is a few weeks, Scale.Month is chosen. So, all
523
+ // the time range of data can be shown in the window.
524
+ var getFundamentalScale = function getFundamentalScale(secondsPerPx) {
525
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Month]) {
526
+ return Scale.Year;
527
+ }
528
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Week]) {
529
+ return Scale.Month;
530
+ }
531
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Day]) {
532
+ return Scale.Week;
533
+ }
534
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Hours6]) {
535
+ return Scale.Day;
536
+ }
537
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Hours3]) {
538
+ return Scale.Hours6;
539
+ }
540
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Hour]) {
541
+ return Scale.Hours3;
542
+ }
543
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Minutes5]) {
544
+ return Scale.Hour;
545
+ }
546
+ return Scale.Minutes5;
547
+ };
548
+ var getScaleFromSpan = function getScaleFromSpan(span) {
549
+ var sortedScales = [].concat(spanToScale.entries()).sort(function (_ref2, _ref3) {
550
+ var sa = _ref2[0];
551
+ var sb = _ref3[0];
552
+ return sb - sa;
553
+ });
554
+ for (var _iterator2 = _createForOfIteratorHelperLoose(sortedScales), _step2; !(_step2 = _iterator2()).done;) {
555
+ var _step2$value = _step2.value,
556
+ scaleSpan = _step2$value[0],
557
+ scale = _step2$value[1];
558
+ if (span >= scaleSpan) {
559
+ return scale;
560
+ }
561
+ }
562
+ return sortedScales[0][1];
563
+ };
564
+ var calculateMouseTimeAndCheckBounds = function calculateMouseTimeAndCheckBounds(x, startAnimationPosition, endAnimationPosition, DRAG_AREA_WIDTH, pixelsBetweenViewportAndTimesliderOnLeft, centerTime, canvasWidth, secondsPerPx, tooltipPosition) {
565
+ var mousePosition = startAnimationPosition + x;
566
+ var startAnimationMaxPosition = endAnimationPosition - DRAG_AREA_WIDTH * 2;
567
+ var isDraggingWithinBounds = mousePosition >= startAnimationMaxPosition || mousePosition <= 0;
568
+ if (isDraggingWithinBounds) {
569
+ return undefined;
570
+ }
571
+ // eslint-disable-next-line no-param-reassign
572
+ tooltipPosition.current = pixelsBetweenViewportAndTimesliderOnLeft && mousePosition + pixelsBetweenViewportAndTimesliderOnLeft;
573
+ return pixelToTimestamp(mousePosition, centerTime, canvasWidth, secondsPerPx);
574
+ };
575
+ var MockDOMRect = function MockDOMRect(x, y, width, height) {
576
+ this.x = x;
577
+ this.y = y;
578
+ this.width = width;
579
+ this.height = height;
580
+ }; // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
581
+ var setTooltipPosition = function setTooltipPosition(tooltipX, tooltipY) {
582
+ return new MockDOMRect(tooltipX, tooltipY, 0, 0);
583
+ };
584
+ // default values
585
+ var defaultAnimationDelayAtStart = 250;
586
+ var defaultDelay = 1000; // [ms]
587
+ var defaultTimeStep = 60;
588
+ var defaultSecondsPerPx = 80;
589
+ var defaultTimeSpan = 24 * 3600;
590
+ var speedFactors = [0.1, 0.2, 0.5, 1, 2, 4, 8, 16]; // Declares available animation speed multipliers for default delay
591
+ var roundWithTimeStep = function roundWithTimeStep(unixTime, timeStep, type) {
592
+ var adjustedTimeStep = timeStep * 60;
593
+ if (!type || type === 'round') {
594
+ return Math.round(unixTime / adjustedTimeStep) * adjustedTimeStep;
595
+ }
596
+ if (type === 'floor') {
597
+ return Math.floor(unixTime / adjustedTimeStep) * adjustedTimeStep;
598
+ }
599
+ if (type === 'ceil') {
600
+ return Math.ceil(unixTime / adjustedTimeStep) * adjustedTimeStep;
601
+ }
602
+ return undefined;
603
+ };
604
+ /**
605
+ * Returns speed delay for given speedFactor. For options, see defined above in "speedFactors"
606
+ */
607
+ var getSpeedDelay = function getSpeedDelay(speedFactor) {
608
+ return defaultDelay / speedFactor;
609
+ };
610
+ var timeSliderLegendDefaultProps = {
611
+ timeSliderWidth: 100,
612
+ centerTime: dateUtils.unix(dateUtils.set(dateUtils.utc(), {
613
+ hours: 12,
614
+ minutes: 0,
615
+ seconds: 0,
616
+ milliseconds: 0
617
+ })),
618
+ secondsPerPx: defaultSecondsPerPx,
619
+ selectedTime: dateUtils.unix(dateUtils.set(dateUtils.utc(), {
620
+ hours: 12,
621
+ minutes: 0,
622
+ seconds: 0,
623
+ milliseconds: 0
624
+ }))
625
+ };
626
+
627
+ var timeSliderUtils = /*#__PURE__*/Object.freeze({
628
+ __proto__: null,
629
+ AUTO_MOVE_AREA_PADDING: AUTO_MOVE_AREA_PADDING,
630
+ get AnimationLength () { return AnimationLength; },
631
+ get Scale () { return Scale; },
632
+ get TimeInMinutes () { return TimeInMinutes; },
633
+ calculateMouseTimeAndCheckBounds: calculateMouseTimeAndCheckBounds,
634
+ defaultAnimationDelayAtStart: defaultAnimationDelayAtStart,
635
+ defaultDelay: defaultDelay,
636
+ defaultSecondsPerPx: defaultSecondsPerPx,
637
+ defaultTimeSpan: defaultTimeSpan,
638
+ defaultTimeStep: defaultTimeStep,
639
+ getAutoMoveAreaWidth: getAutoMoveAreaWidth,
640
+ getFundamentalScale: getFundamentalScale,
641
+ getLargestTimeUnit: getLargestTimeUnit,
642
+ getNewCenterOfFixedPointZoom: getNewCenterOfFixedPointZoom,
643
+ getScaleFromSpan: getScaleFromSpan,
644
+ getSpeedDelay: getSpeedDelay,
645
+ minutesToDescribedDuration: minutesToDescribedDuration,
646
+ moveRelativeToTimePoint: moveRelativeToTimePoint,
647
+ pixelToTimestamp: pixelToTimestamp,
648
+ roundWithTimeStep: roundWithTimeStep,
649
+ scaleToSecondsPerPx: scaleToSecondsPerPx,
650
+ scalingCoefficient: scalingCoefficient,
651
+ secondsPerPxFromCanvasWidth: secondsPerPxFromCanvasWidth,
652
+ secondsPerPxToScale: secondsPerPxToScale,
653
+ secondsPerPxValues: secondsPerPxValues,
654
+ setTooltipPosition: setTooltipPosition,
655
+ spanToScale: spanToScale,
656
+ speedFactors: speedFactors,
657
+ timeBoxGeom: timeBoxGeom,
658
+ timeSliderLegendDefaultProps: timeSliderLegendDefaultProps,
659
+ timestampToPixel: timestampToPixel,
660
+ timestampToPixelEdges: timestampToPixelEdges,
661
+ useCanvasTarget: useCanvasTarget
662
+ });
663
+
664
+ /* *
665
+ * Licensed under the Apache License, Version 2.0 (the "License");
666
+ * you may not use this file except in compliance with the License.
667
+ * You may obtain a copy of the License at
668
+ *
669
+ * http://www.apache.org/licenses/LICENSE-2.0
670
+ *
671
+ * Unless required by applicable law or agreed to in writing, software
672
+ * distributed under the License is distributed on an "AS IS" BASIS,
673
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
674
+ * See the License for the specific language governing permissions and
675
+ * limitations under the License.
676
+ *
677
+ * Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
678
+ * Copyright 2023 - Finnish Meteorological Institute (FMI)
679
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
680
+ * */
681
+ var onsetNewDateDebounced = debounce(function (dateToSet, onSetNewDate) {
682
+ onSetNewDate(dateToSet);
683
+ }, 4, {
684
+ maxWait: 40
685
+ });
686
+ var setPreviousTimeStep = function setPreviousTimeStep(timeStep, currentTime, dataStartTime, onSetNewDate) {
687
+ var nextTime = currentTime - timeStep;
688
+ var roundedTime = roundWithTimeStep(nextTime, timeStep, 'floor');
689
+ var newTime = Math.max(roundedTime, dataStartTime || roundedTime);
690
+ var selectedTimeString = dateUtils.fromUnix(newTime).toISOString();
691
+ onSetNewDate(selectedTimeString);
692
+ };
693
+ var setNextTimeStep = function setNextTimeStep(timeStep, currentTime, dataEndTime, onSetNewDate) {
694
+ var nextTime = currentTime + timeStep;
695
+ var roundedTime = roundWithTimeStep(nextTime, timeStep, 'ceil');
696
+ var newTime = Math.min(roundedTime, dataEndTime || roundedTime);
697
+ var selectedTimeString = dateUtils.fromUnix(newTime).toISOString();
698
+ onSetNewDate(selectedTimeString);
699
+ };
700
+ /**
701
+ * updates unfiltered selected time and moves selected time a given distance
702
+ * in pixels. Unfiltered selected time can be outside data data limits, but
703
+ * selected time cannot.
704
+ */
705
+ var moveSelectedTimePx = function moveSelectedTimePx(pixelsMoved, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime) {
706
+ var unfilteredSelectedTimePx = timestampToPixel(unfilteredSelectedTime, centerTime, canvasWidth, secondsPerPx);
707
+ var clickedUnfilteredSelectedTimePx = unfilteredSelectedTimePx + pixelsMoved;
708
+ var newUnfilteredSelectedTime = pixelToTimestamp(clickedUnfilteredSelectedTimePx, centerTime, canvasWidth, secondsPerPx);
709
+ setUnfilteredSelectedTime(newUnfilteredSelectedTime);
710
+ };
711
+ function getFilteredTime(unfilteredTime, timeStep, dataStartTime, dataEndTime) {
712
+ if (!timeStep || !dataStartTime || !dataEndTime) {
713
+ return unfilteredTime;
714
+ }
715
+ var roundedTime = roundWithTimeStep(unfilteredTime, timeStep);
716
+ var maxTime = Math.max(roundedTime, dataStartTime);
717
+ return Math.min(maxTime, dataEndTime);
718
+ }
719
+ /** Reusable business logic for how to handle events that set time to now (closest).
720
+ * Used in NowButton and TimeSliderLegend.
721
+ */
722
+ var handleSetNowEvent = function handleSetNowEvent(timeStep, dataStartTime, dataEndTime, currentTime, onSetNewDate, onSetCenterTime) {
723
+ if (dataStartTime < dataEndTime) {
724
+ if (dataEndTime < currentTime) {
725
+ onSetNewDate(dateUtils.fromUnix(dataEndTime).toISOString());
726
+ onSetCenterTime(dataEndTime);
727
+ } else if (dataStartTime > currentTime) {
728
+ onSetNewDate(dateUtils.fromUnix(dataStartTime).toISOString());
729
+ onSetCenterTime(dataStartTime);
730
+ } else {
731
+ var closestToCurrent = roundWithTimeStep(currentTime, timeStep);
732
+ onSetNewDate(dateUtils.fromUnix(closestToCurrent).toISOString());
733
+ onSetCenterTime(closestToCurrent);
734
+ }
735
+ }
736
+ };
737
+
738
+ /* *
739
+ * Licensed under the Apache License, Version 2.0 (the "License");
740
+ * you may not use this file except in compliance with the License.
741
+ * You may obtain a copy of the License at
742
+ *
743
+ * http://www.apache.org/licenses/LICENSE-2.0
744
+ *
745
+ * Unless required by applicable law or agreed to in writing, software
746
+ * distributed under the License is distributed on an "AS IS" BASIS,
747
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
748
+ * See the License for the specific language governing permissions and
749
+ * limitations under the License.
750
+ *
751
+ * Copyright 2024 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
752
+ * Copyright 2024 - Finnish Meteorological Institute (FMI)
753
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
754
+ * */
755
+ var useToggleTimesliderVisibility = function useToggleTimesliderVisibility(mapIsActive, isVisible, onToggleTimeSlider) {
756
+ React__default.useEffect(function () {
757
+ var handleKeyDown = function handleKeyDown(event) {
758
+ var target = event.target;
759
+ if (target.tagName !== 'INPUT' && target.tagName !== 'TEXTAREA' && (event.key === 't' || event.key === 'T') && mapIsActive) {
760
+ onToggleTimeSlider(!isVisible);
761
+ }
762
+ };
763
+ document.addEventListener('keydown', handleKeyDown);
764
+ return function () {
765
+ document.removeEventListener('keydown', handleKeyDown);
766
+ };
767
+ }, [mapIsActive, isVisible, onToggleTimeSlider]);
768
+ };
769
+ var useMoveTimeWithKeyboard = function useMoveTimeWithKeyboard(mapIsActive, timeStep, dataStartTime, dataEndTime, onSetNewDate, onSetCenterTime, selectedTime) {
770
+ React__default.useEffect(function () {
771
+ var handleKeyDown = function handleKeyDown(event) {
772
+ if (event.key === 'Home' && mapIsActive) {
773
+ handleSetNowEvent(timeStep, dataStartTime, dataEndTime, dateUtils.unix(dateUtils.utc()), onSetNewDate, onSetCenterTime);
774
+ }
775
+ if (event.ctrlKey && dataStartTime && dataEndTime && mapIsActive) {
776
+ switch (event.code) {
777
+ case 'ArrowLeft':
778
+ setPreviousTimeStep(timeStep, selectedTime, dataStartTime, onSetNewDate);
779
+ break;
780
+ case 'ArrowRight':
781
+ setNextTimeStep(timeStep, selectedTime, dataEndTime, onSetNewDate);
782
+ break;
783
+ }
784
+ }
785
+ };
786
+ document.addEventListener('keydown', handleKeyDown);
787
+ return function () {
788
+ document.removeEventListener('keydown', handleKeyDown);
789
+ };
790
+ }, [dataEndTime, dataStartTime, mapIsActive, onSetCenterTime, onSetNewDate, selectedTime, timeStep]);
791
+ };
792
+
793
+ /* *
794
+ * Licensed under the Apache License, Version 2.0 (the "License");
795
+ * you may not use this file except in compliance with the License.
796
+ * You may obtain a copy of the License at
797
+ *
798
+ * http://www.apache.org/licenses/LICENSE-2.0
799
+ *
800
+ * Unless required by applicable law or agreed to in writing, software
801
+ * distributed under the License is distributed on an "AS IS" BASIS,
802
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
803
+ * See the License for the specific language governing permissions and
804
+ * limitations under the License.
805
+ *
806
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
807
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
808
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
809
+ * */
810
+ /**
811
+ * @param x The pin location
812
+ * @param selectedTimePx The selected px
813
+ * @param width The default width of a hoverable icon (usually 24px)
814
+ * @returns
815
+ */
816
+ var isSelectedTimeIconArea = function isSelectedTimeIconArea(x, selectedTimePx, width) {
817
+ return x >= selectedTimePx && x <= selectedTimePx + width / 2;
818
+ };
819
+ /**
820
+ * @param x The pin location
821
+ * @param selectedTimePx The selected px
822
+ * @param width The default width of a hoverable icon (usually 24px)
823
+ * @returns
824
+ */
825
+ var isRightAnimationIconArea = function isRightAnimationIconArea(x, rightMarkerPx, width) {
826
+ return x >= rightMarkerPx - width && x <= rightMarkerPx;
827
+ };
828
+ var isInsideAnimationArea = function isInsideAnimationArea(x, leftMarkerPx, rightMarkerPx) {
829
+ var isInsideOnLeftSide = x >= leftMarkerPx;
830
+ var isInsideOnRightSide = x <= rightMarkerPx;
831
+ return isInsideOnLeftSide && isInsideOnRightSide;
832
+ };
833
+ /**
834
+ * @param x The pin location
835
+ * @param selectedTimePx The selected px
836
+ * @param width The default width of a hoverable icon (usually 24px)
837
+ * @returns
838
+ */
839
+ var isLeftAnimationIconArea = function isLeftAnimationIconArea(x, leftMarkerPx, width) {
840
+ return x >= leftMarkerPx && x <= leftMarkerPx + width;
841
+ };
842
+ function convertStringTimeToUnix(time) {
843
+ return time ? dateUtils.unix(new Date(time)) : undefined;
844
+ }
845
+ var timeValues = [3600, 10800, 21600, 43200, 86400, 172800, 604800, 1209600, 2592000, 7776000, 31536000];
846
+ var TIME_SLIDER_LEGEND_HEIGHT = 24;
847
+ var DRAG_AREA_WIDTH = 24;
848
+ var isDraggingStartWithinBounds = function isDraggingStartWithinBounds(endPos, mousePosition) {
849
+ var startAnimationMaxPosition = endPos - DRAG_AREA_WIDTH * 2;
850
+ return mousePosition >= startAnimationMaxPosition || mousePosition <= 0;
851
+ };
852
+ var isDraggingEndWithinBounds = function isDraggingEndWithinBounds(startPos, mousePosition, canvasWidth) {
853
+ var endAnimationMinimumPosition = startPos + DRAG_AREA_WIDTH * 2;
854
+ return endAnimationMinimumPosition >= mousePosition || mousePosition >= canvasWidth;
855
+ };
856
+ var getTimeSliderLegendId = function getTimeSliderLegendId(mapId) {
857
+ return "timeSliderLegend_" + mapId;
858
+ };
859
+ var getTimeSliderLegendElement = function getTimeSliderLegendElement(mapId) {
860
+ return document.querySelector(".timeSliderLegend_" + mapId);
861
+ };
862
+ var getPixelsBetweenViewportAndTimesliderOnLeft = function getPixelsBetweenViewportAndTimesliderOnLeft(mapId) {
863
+ var timeSliderLegendElement = document.querySelector(".timeSliderLegend_" + mapId);
864
+ return timeSliderLegendElement == null ? void 0 : timeSliderLegendElement.getBoundingClientRect()['left'];
865
+ };
866
+ function getPositions(width, unfilteredSelectedTime, centerTime, secondsPerPx, start, end) {
867
+ var selectedTimePosition = timestampToPixel(unfilteredSelectedTime, centerTime, width, secondsPerPx);
868
+ var endAnimationPosition = timestampToPixel(end, centerTime, width, secondsPerPx);
869
+ var startAnimationPosition = timestampToPixel(start, centerTime, width, secondsPerPx);
870
+ return {
871
+ startAnimationPosition: startAnimationPosition,
872
+ endAnimationPosition: endAnimationPosition,
873
+ selectedTimePosition: selectedTimePosition
874
+ };
875
+ }
876
+
877
+ var TimeSlider = function TimeSlider(_ref) {
878
+ var buttons = _ref.buttons,
879
+ timeBox = _ref.timeBox,
880
+ legend = _ref.legend,
881
+ _ref$mapIsActive = _ref.mapIsActive,
882
+ mapIsActive = _ref$mapIsActive === void 0 ? true : _ref$mapIsActive,
883
+ _ref$isVisible = _ref.isVisible,
884
+ isVisible = _ref$isVisible === void 0 ? true : _ref$isVisible,
885
+ timeStep = _ref.timeStep,
886
+ dataStartTime = _ref.dataStartTime,
887
+ dataEndTime = _ref.dataEndTime,
888
+ selectedTime = _ref.selectedTime,
889
+ onSetNewDate = _ref.onSetNewDate,
890
+ onSetCenterTime = _ref.onSetCenterTime,
891
+ _ref$onToggleTimeSlid = _ref.onToggleTimeSlider,
892
+ onToggleTimeSlider = _ref$onToggleTimeSlid === void 0 ? function () {} : _ref$onToggleTimeSlid;
893
+ // set up visibility toggle
894
+ useToggleTimesliderVisibility(mapIsActive, isVisible, onToggleTimeSlider);
895
+ // set up movement with keyboard shortcuts
896
+ useMoveTimeWithKeyboard(mapIsActive, timeStep, dataStartTime, dataEndTime, onSetNewDate, onSetCenterTime, selectedTime);
897
+ // timeBox, buttons and legend are created in TimeSliderConnect.tsx
898
+ // these components will always be created as TimeSlider never runs in isolation from the store
899
+ return isVisible ? jsxs(Grid, {
900
+ container: true,
901
+ sx: {
902
+ display: 'grid',
903
+ gridTemplateColumns: '175px 1fr 40px',
904
+ gridTemplateRows: TIME_SLIDER_LEGEND_HEIGHT,
905
+ gridTemplateAreas: "\". timebox .\"\n \"buttons timelegend toggle\"",
906
+ paddingBottom: 1,
907
+ alignItems: 'center',
908
+ justifyContent: 'center',
909
+ visibility: isVisible ? 'visible' : 'hidden',
910
+ // Apply these styles only one mobile devices on landscape orientation
911
+ '@media screen and (max-width: 1024px) and (orientation: landscape)': {
912
+ paddingLeft: '5%',
913
+ paddingRight: '5%'
914
+ }
915
+ },
916
+ "data-testid": "timeSlider",
917
+ children: [jsx(Grid, {
918
+ sx: {
919
+ gridArea: 'timebox',
920
+ zIndex: 99,
921
+ position: 'relative',
922
+ overflow: 'hidden'
923
+ },
924
+ children: timeBox
925
+ }), jsx(Grid, {
926
+ sx: {
927
+ gridArea: 'buttons'
928
+ },
929
+ children: buttons
930
+ }), jsx(Grid, {
931
+ sx: {
932
+ gridArea: 'timelegend'
933
+ },
934
+ children: legend
935
+ }), jsx(Grid, {
936
+ sx: {
937
+ gridArea: 'toggle',
938
+ paddingLeft: 1
939
+ },
940
+ children: jsx(HideSliderButton, {
941
+ toggleTimeSliderIsVisible: onToggleTimeSlider,
942
+ isVisible: isVisible
943
+ })
944
+ })]
945
+ }) : jsx(Grid, {
946
+ container: true,
947
+ sx: {
948
+ paddingRight: 1,
949
+ paddingBottom: 1,
950
+ alignItems: 'center',
951
+ justifyContent: 'flex-end'
952
+ },
953
+ children: jsx(HideSliderButton, {
954
+ toggleTimeSliderIsVisible: onToggleTimeSlider,
955
+ isVisible: isVisible
956
+ })
957
+ });
958
+ };
959
+
960
+ /* *
961
+ * Licensed under the Apache License, Version 2.0 (the "License");
962
+ * you may not use this file except in compliance with the License.
963
+ * You may obtain a copy of the License at
964
+ *
965
+ * http://www.apache.org/licenses/LICENSE-2.0
966
+ *
967
+ * Unless required by applicable law or agreed to in writing, software
968
+ * distributed under the License is distributed on an "AS IS" BASIS,
969
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
970
+ * See the License for the specific language governing permissions and
971
+ * limitations under the License.
972
+ *
973
+ * Copyright 2024 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
974
+ * Copyright 2024 - Finnish Meteorological Institute (FMI)
975
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
976
+ * */
977
+ // To be used with translations of days in formatted date
978
+ // enum DaysOfWeeki18n {
979
+ // SUNDAY = 'timeslider-sunday',
980
+ // MONDAY = 'timeslider-monday',
981
+ // TUESDAY = 'timeslider-tuesday',
982
+ // WEDNESDAY = 'timeslider-wednesday',
983
+ // THURSDAY = 'timeslider-thursday',
984
+ // FRIDAY = 'timeslider-friday',
985
+ // SATURDAY = 'timeslider-saturday',
986
+ // }
987
+ // To be used with translations of months in formatted date
988
+ // enum MonthsOfTheYeari18n {
989
+ // JANUARY = 'timeslider-january',
990
+ // FEBRUARY = 'timeslider-february',
991
+ // MARCH = 'timeslider-march',
992
+ // APRIL = 'timeslider-april',
993
+ // MAY = 'timeslider-may',
994
+ // JUNE = 'timeslider-june',
995
+ // JULY = 'timeslider-july',
996
+ // AUGUST = 'timeslider-august',
997
+ // SEPTEMBER = 'timeslider-september',
998
+ // OCTOBER = 'timeslider-october',
999
+ // NOVEMBER = 'timeslider-november',
1000
+ // DECEMBER = 'timeslider-december',
1001
+ // }
1002
+ var DaysOfWeek;
1003
+ (function (DaysOfWeek) {
1004
+ DaysOfWeek["SUNDAY"] = "Sun";
1005
+ DaysOfWeek["MONDAY"] = "Mon";
1006
+ DaysOfWeek["TUESDAY"] = "Tue";
1007
+ DaysOfWeek["WEDNESDAY"] = "Wed";
1008
+ DaysOfWeek["THURSDAY"] = "Thu";
1009
+ DaysOfWeek["FRIDAY"] = "Fri";
1010
+ DaysOfWeek["SATURDAY"] = "Sat";
1011
+ })(DaysOfWeek || (DaysOfWeek = {}));
1012
+ var MonthsOfTheYear;
1013
+ (function (MonthsOfTheYear) {
1014
+ MonthsOfTheYear["JANUARY"] = "Jan";
1015
+ MonthsOfTheYear["FEBRUARY"] = "Feb";
1016
+ MonthsOfTheYear["MARCH"] = "Mar";
1017
+ MonthsOfTheYear["APRIL"] = "Apr";
1018
+ MonthsOfTheYear["MAY"] = "May";
1019
+ MonthsOfTheYear["JUNE"] = "Jun";
1020
+ MonthsOfTheYear["JULY"] = "Jul";
1021
+ MonthsOfTheYear["AUGUST"] = "Aug";
1022
+ MonthsOfTheYear["SEPTEMBER"] = "Sep";
1023
+ MonthsOfTheYear["OCTOBER"] = "Oct";
1024
+ MonthsOfTheYear["NOVEMBER"] = "Nov";
1025
+ MonthsOfTheYear["DECEMBER"] = "Dec";
1026
+ })(MonthsOfTheYear || (MonthsOfTheYear = {}));
1027
+ var dateToManualFormatString = function dateToManualFormatString(inDate) {
1028
+ if (!inDate) {
1029
+ return 'Date not available';
1030
+ }
1031
+ var EEE = inDate && Object.values(DaysOfWeek)[inDate.getUTCDay()];
1032
+ var dd = ("0" + (inDate == null ? void 0 : inDate.getUTCDate())).slice(-2);
1033
+ var MMM = inDate && Object.values(MonthsOfTheYear)[inDate.getUTCMonth()];
1034
+ var HH = ("0" + (inDate == null ? void 0 : inDate.getUTCHours())).slice(-2);
1035
+ var mm = ("0" + (inDate == null ? void 0 : inDate.getUTCMinutes())).slice(-2);
1036
+ return EEE + " " + dd + " " + MMM + " " + HH + ":" + mm + " UTC";
1037
+ };
1038
+
1039
+ /**
1040
+ * Format a date to a string
1041
+ *
1042
+ * Expects the following props:
1043
+ * @param {Date} inDate - date to be formatted
1044
+ *
1045
+ */
1046
+ var ClockContainer = function ClockContainer(_ref) {
1047
+ var fontSize = _ref.fontSize,
1048
+ isPopperOpen = _ref.isPopperOpen,
1049
+ hideButton = _ref.hideButton,
1050
+ onButtonClick = _ref.onButtonClick,
1051
+ time = _ref.time,
1052
+ setButtonElement = _ref.setButtonElement,
1053
+ popperPlacement = _ref.popperPlacement;
1054
+ var _useTimesliderTransla = useTimesliderTranslation(),
1055
+ t = _useTimesliderTransla.t;
1056
+ var currentDateString = dateToManualFormatString(dateUtils.fromUnix(time));
1057
+ return jsxs(Grid, {
1058
+ container: true,
1059
+ wrap: "nowrap",
1060
+ sx: {
1061
+ justifyContent: 'space-evenly',
1062
+ alignItems: 'center',
1063
+ cursor: 'move',
1064
+ height: '100%',
1065
+ width: '100%',
1066
+ backgroundColor: 'geowebColors.timeSlider.playerTimeMarkers.fill',
1067
+ borderRadius: '5px'
1068
+ },
1069
+ children: [jsx(Grid, {
1070
+ sx: {
1071
+ width: '4px'
1072
+ }
1073
+ }), !hideButton && jsx(CustomTooltip, {
1074
+ title: t('timeslider-animation-options'),
1075
+ children: jsx(Grid, {
1076
+ ref: setButtonElement,
1077
+ sx: {
1078
+ zIndex: 2
1079
+ },
1080
+ children: jsx(CustomIconButton, {
1081
+ variant: "tool",
1082
+ onClick: onButtonClick,
1083
+ sx: {
1084
+ color: '#fff!important'
1085
+ },
1086
+ "aria-label": "Animation options",
1087
+ isSelected: isPopperOpen,
1088
+ children: jsx(Icon, {
1089
+ isPopperOpen: isPopperOpen,
1090
+ popperPlacement: popperPlacement
1091
+ })
1092
+ })
1093
+ })
1094
+ }), jsx(Grid, {
1095
+ children: jsx(Typography, {
1096
+ variant: "subtitle2",
1097
+ sx: {
1098
+ whiteSpace: 'nowrap',
1099
+ fontSize: fontSize,
1100
+ color: '#fff'
1101
+ },
1102
+ children: currentDateString
1103
+ })
1104
+ })]
1105
+ });
1106
+ };
1107
+ var Icon = function Icon(_ref2) {
1108
+ var isPopperOpen = _ref2.isPopperOpen,
1109
+ popperPlacement = _ref2.popperPlacement;
1110
+ if (isPopperOpen) {
1111
+ if (popperPlacement === 'left') {
1112
+ return jsx(ChevronRight, {});
1113
+ }
1114
+ if (popperPlacement === 'right') {
1115
+ return jsx(ChevronLeft, {});
1116
+ }
1117
+ if (popperPlacement === 'top') {
1118
+ return jsx(ChevronDown, {});
1119
+ }
1120
+ return jsx(ChevronUp, {});
1121
+ }
1122
+ var popperClosedStyle = {
1123
+ backgroundColor: 'geowebColors.timeSlider.playerTimeMarkers.fill',
1124
+ outline: '1px solid white',
1125
+ borderRadius: '5px'
1126
+ };
1127
+ if (popperPlacement === 'left') {
1128
+ return jsx(ChevronLeft, {
1129
+ sx: popperClosedStyle
1130
+ });
1131
+ }
1132
+ if (popperPlacement === 'right') {
1133
+ return jsx(ChevronRight, {
1134
+ sx: popperClosedStyle
1135
+ });
1136
+ }
1137
+ if (popperPlacement === 'top') {
1138
+ return jsx(ChevronUp, {
1139
+ sx: popperClosedStyle
1140
+ });
1141
+ }
1142
+ return jsx(ChevronDown, {
1143
+ sx: popperClosedStyle
1144
+ });
1145
+ };
1146
+
1147
+ var THROTTLE_WAIT_TIME = 300; // [ms]
1148
+ var THROTTLE_OPTIONS = {
1149
+ trailing: false // Invoke function when called, but not more than once every <THROTTLE_WAIT_TIME>.
1150
+ };
1151
+ var TimeSliderMenu = function TimeSliderMenu(_ref) {
1152
+ var marks = _ref.marks,
1153
+ value = _ref.value,
1154
+ allOptionsDisabled = _ref.allOptionsDisabled,
1155
+ isAutoDisabled = _ref.isAutoDisabled,
1156
+ handleAutoClick = _ref.handleAutoClick,
1157
+ isAutoSelected = _ref.isAutoSelected,
1158
+ title = _ref.title,
1159
+ icon = _ref.icon,
1160
+ _ref$onChangeSliderVa = _ref.onChangeSliderValue,
1161
+ onChangeSliderValue = _ref$onChangeSliderVa === void 0 ? function () {} : _ref$onChangeSliderVa,
1162
+ displayCurrentLength = _ref.displayCurrentLength,
1163
+ _ref$disbleUserSetDur = _ref.disbleUserSetDuration,
1164
+ disbleUserSetDuration = _ref$disbleUserSetDur === void 0 ? true : _ref$disbleUserSetDur,
1165
+ customLengthSelector = _ref.customLengthSelector,
1166
+ _ref$setOpen = _ref.setOpen,
1167
+ setOpen = _ref$setOpen === void 0 ? function () {} : _ref$setOpen,
1168
+ _ref$customFieldHeade = _ref.customFieldHeader,
1169
+ customFieldHeader = _ref$customFieldHeade === void 0 ? 'timeslider-length' : _ref$customFieldHeade,
1170
+ open = _ref.open;
1171
+ var currentMarkIndex = marks.findIndex(function (mark) {
1172
+ return mark.value === value;
1173
+ });
1174
+ var currentMark = marks[currentMarkIndex];
1175
+ var _React$useState = React.useState(null),
1176
+ anchorRef = _React$useState[0],
1177
+ setAnchorRef = _React$useState[1];
1178
+ var _useTimesliderTransla = useTimesliderTranslation(),
1179
+ t = _useTimesliderTransla.t;
1180
+ var _useState = useState(false),
1181
+ displayLengthInputField = _useState[0],
1182
+ setdisplayLengthInputField = _useState[1];
1183
+ React.useEffect(function () {
1184
+ if (!open && displayLengthInputField) {
1185
+ setdisplayLengthInputField(false);
1186
+ }
1187
+ }, [displayLengthInputField, open]);
1188
+ var buttonText = function buttonText(value, displayCurrentLength, currentMark) {
1189
+ if (displayCurrentLength) {
1190
+ return minutesToDescribedDuration(value);
1191
+ }
1192
+ if (currentMark) {
1193
+ var parts = t(currentMark.label).split(' ');
1194
+ if (parts.length > 1) {
1195
+ return parts[0] + parts.slice(1).join(' ');
1196
+ }
1197
+ return parts.join('');
1198
+ }
1199
+ return '';
1200
+ };
1201
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1202
+ var throttledScroll = React.useCallback(throttle(function (newValue) {
1203
+ onChangeSliderValue(newValue);
1204
+ }, THROTTLE_WAIT_TIME, THROTTLE_OPTIONS), []);
1205
+ var onWheel = React.useCallback(function (event) {
1206
+ var direction = event.deltaY < 0 ? 1 : -1;
1207
+ var newValue = marks[Math.min(Math.max(currentMarkIndex - direction, 0), marks.length - 1)];
1208
+ throttledScroll(newValue.value);
1209
+ }, [currentMarkIndex, marks, throttledScroll]);
1210
+ return jsxs(Box, {
1211
+ onKeyDown: function onKeyDown(event) {
1212
+ event.stopPropagation();
1213
+ },
1214
+ children: [jsxs(CustomIconButton, {
1215
+ variant: "tool",
1216
+ tooltipTitle: title,
1217
+ onClick: function onClick() {
1218
+ setOpen(true);
1219
+ },
1220
+ ref: setAnchorRef,
1221
+ isSelected: true,
1222
+ onWheel: onWheel,
1223
+ sx: {
1224
+ padding: '11px!important',
1225
+ width: '100%!important'
1226
+ },
1227
+ children: [icon, jsx(Typography, {
1228
+ sx: {
1229
+ fontSize: 12,
1230
+ fontWeight: 400,
1231
+ textTransform: 'none'
1232
+ },
1233
+ children: buttonText(value, displayCurrentLength, currentMark)
1234
+ })]
1235
+ }), anchorRef && jsxs(Menu, {
1236
+ anchorEl: anchorRef,
1237
+ open: open,
1238
+ onClose: function onClose() {
1239
+ return setOpen(false);
1240
+ },
1241
+ BackdropProps: {
1242
+ sx: {
1243
+ backgroundColor: 'transparent'
1244
+ }
1245
+ },
1246
+ anchorOrigin: {
1247
+ vertical: -15,
1248
+ horizontal: 'center'
1249
+ },
1250
+ transformOrigin: {
1251
+ vertical: 'bottom',
1252
+ horizontal: 'center'
1253
+ },
1254
+ children: [jsx(MenuItem, {
1255
+ disabled: true,
1256
+ sx: {
1257
+ fontSize: '12px',
1258
+ opacity: 0.67,
1259
+ padding: '0px 12px',
1260
+ '&.MuiMenuItem-root': {
1261
+ minHeight: '30px!important',
1262
+ minWidth: 150
1263
+ }
1264
+ },
1265
+ children: title
1266
+ }), marks.map(function (mark) {
1267
+ var isSelected = (currentMark == null ? void 0 : currentMark.value) === mark.value && !isAutoSelected;
1268
+ return jsx(MenuItem, {
1269
+ onClick: function onClick() {
1270
+ if (!isSelected) {
1271
+ onChangeSliderValue(mark.value);
1272
+ }
1273
+ setOpen(false);
1274
+ },
1275
+ selected: isSelected && !displayLengthInputField,
1276
+ disabled: allOptionsDisabled,
1277
+ children: mark.label || mark.text
1278
+ }, mark.value);
1279
+ }), handleAutoClick && jsx(MenuItem, {
1280
+ onClick: function onClick() {
1281
+ handleAutoClick();
1282
+ setOpen(false);
1283
+ },
1284
+ selected: isAutoSelected,
1285
+ disabled: allOptionsDisabled || isAutoDisabled,
1286
+ children: t('timeslider-auto')
1287
+ }), displayCurrentLength && jsxs(MenuItem, {
1288
+ onClick: function onClick() {
1289
+ return setdisplayLengthInputField(true);
1290
+ },
1291
+ disabled: disbleUserSetDuration,
1292
+ sx: {
1293
+ maxWidth: '175px'
1294
+ },
1295
+ children: [displayLengthInputField && customLengthSelector, !displayLengthInputField && jsxs(Box, {
1296
+ sx: {
1297
+ flexDirection: 'column',
1298
+ display: 'flex',
1299
+ flexGrow: 1
1300
+ },
1301
+ children: [jsx(CardHeader, {
1302
+ title: t(customFieldHeader),
1303
+ sx: {
1304
+ height: 2,
1305
+ padding: 0,
1306
+ color: 'geowebColors.greys.accessible'
1307
+ },
1308
+ titleTypographyProps: {
1309
+ fontSize: 12
1310
+ }
1311
+ }), jsxs(Box, {
1312
+ sx: {
1313
+ flexDirection: 'row',
1314
+ display: 'flex',
1315
+ justifyContent: 'space-between',
1316
+ flexGrow: 1,
1317
+ paddingTop: 0.5
1318
+ },
1319
+ children: [jsx(Typography, {
1320
+ sx: {
1321
+ fontSize: 14,
1322
+ textTransform: 'none',
1323
+ lineHeight: 2
1324
+ },
1325
+ children: minutesToDescribedDuration(value)
1326
+ }), jsx(CustomTooltip, {
1327
+ title: t('timeslider-edit'),
1328
+ children: jsx("span", {
1329
+ children: jsx(CustomIconButton, {
1330
+ "aria-label": "edit animation option",
1331
+ "data-testid": "editAnimationOption",
1332
+ children: jsx(Edit, {})
1333
+ })
1334
+ })
1335
+ })]
1336
+ })]
1337
+ })]
1338
+ })]
1339
+ })]
1340
+ });
1341
+ };
1342
+
1343
+ var SpeedButton = function SpeedButton(_ref) {
1344
+ var animationDelay = _ref.animationDelay,
1345
+ setMapAnimationDelay = _ref.setMapAnimationDelay;
1346
+ var sorted = [].concat(speedFactors).sort(function (sa, sb) {
1347
+ return sb - sa;
1348
+ });
1349
+ var marks = sorted.map(function (speedFactor) {
1350
+ return {
1351
+ value: getSpeedDelay(speedFactor),
1352
+ text: "x" + speedFactor,
1353
+ label: "x" + speedFactor
1354
+ };
1355
+ });
1356
+ var _useTimesliderTransla = useTimesliderTranslation(),
1357
+ t = _useTimesliderTransla.t;
1358
+ var _useState = useState(false),
1359
+ open = _useState[0],
1360
+ setOpen = _useState[1];
1361
+ return jsx(TimeSliderMenu, {
1362
+ onChangeSliderValue: function onChangeSliderValue(markValue) {
1363
+ setMapAnimationDelay(markValue);
1364
+ },
1365
+ icon: jsx(Speed, {}),
1366
+ marks: marks,
1367
+ title: t('timeslider-speed'),
1368
+ value: animationDelay,
1369
+ open: open,
1370
+ setOpen: setOpen
1371
+ });
1372
+ };
1373
+
1374
+ var marks$2 = [{
1375
+ value: 1,
1376
+ text: 'timeslider-min',
1377
+ count: 1
1378
+ }, {
1379
+ value: 2,
1380
+ text: 'timeslider-min',
1381
+ count: 2
1382
+ }, {
1383
+ value: 5,
1384
+ text: 'timeslider-min',
1385
+ count: 5
1386
+ }, {
1387
+ value: 10,
1388
+ text: 'timeslider-min',
1389
+ count: 10
1390
+ }, {
1391
+ value: 15,
1392
+ text: 'timeslider-min',
1393
+ count: 15
1394
+ }, {
1395
+ value: 30,
1396
+ text: 'timeslider-min',
1397
+ count: 30
1398
+ }, {
1399
+ value: 60,
1400
+ text: 'timeslider-hour',
1401
+ count: 1
1402
+ }, {
1403
+ value: 120,
1404
+ text: 'timeslider-hour',
1405
+ count: 2
1406
+ }, {
1407
+ value: 180,
1408
+ text: 'timeslider-hour',
1409
+ count: 3
1410
+ }, {
1411
+ value: 360,
1412
+ text: 'timeslider-hour',
1413
+ count: 6
1414
+ }, {
1415
+ value: 720,
1416
+ text: 'timeslider-hour',
1417
+ count: 12
1418
+ }, {
1419
+ value: 1440,
1420
+ text: 'timeslider-hour',
1421
+ count: 24
1422
+ }, {
1423
+ value: 2880,
1424
+ text: 'timeslider-hour',
1425
+ count: 48
1426
+ }, {
1427
+ value: 4320,
1428
+ text: 'timeslider-hour',
1429
+ count: 72
1430
+ }, {
1431
+ value: 10080,
1432
+ text: 'timeslider-week',
1433
+ count: 1
1434
+ }, {
1435
+ value: 20160,
1436
+ text: 'timeslider-weeks',
1437
+ count: 2
1438
+ }, {
1439
+ value: 43200,
1440
+ text: 'timeslider-month',
1441
+ count: 1
1442
+ }, {
1443
+ value: 87600,
1444
+ text: 'timeslider-months',
1445
+ count: 2
1446
+ }, {
1447
+ value: 262800,
1448
+ text: 'timeslider-months',
1449
+ count: 6
1450
+ }, {
1451
+ value: 525600,
1452
+ text: 'timeslider-year',
1453
+ count: 1
1454
+ }, {
1455
+ value: 5256000,
1456
+ text: 'timeslider-years',
1457
+ count: 10
1458
+ }].sort(function (ta, tb) {
1459
+ return tb.value - ta.value;
1460
+ });
1461
+ var TimeStepButton = function TimeStepButton(_ref) {
1462
+ var _ref$timeStep = _ref.timeStep,
1463
+ timeStep = _ref$timeStep === void 0 ? marks$2[0].value : _ref$timeStep,
1464
+ _ref$disabled = _ref.disabled,
1465
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
1466
+ _ref$isTimestepAuto = _ref.isTimestepAuto,
1467
+ isTimestepAuto = _ref$isTimestepAuto === void 0 ? false : _ref$isTimestepAuto,
1468
+ onChangeTimeStep = _ref.onChangeTimeStep,
1469
+ _ref$onToggleTimestep = _ref.onToggleTimestepAuto,
1470
+ onToggleTimestepAuto = _ref$onToggleTimestep === void 0 ? function () {} : _ref$onToggleTimestep,
1471
+ _ref$isOpenByDefault = _ref.isOpenByDefault,
1472
+ isOpenByDefault = _ref$isOpenByDefault === void 0 ? false : _ref$isOpenByDefault,
1473
+ timeStepFromLayer = _ref.timeStepFromLayer;
1474
+ var _useTimesliderTransla = useTimesliderTranslation(),
1475
+ t = _useTimesliderTransla.t;
1476
+ var translatedMarks = marks$2.map(function (mark) {
1477
+ return Object.assign({}, mark, {
1478
+ label: mark.count + " " + t(mark.text)
1479
+ });
1480
+ });
1481
+ var onMenuItemClick = function onMenuItemClick(markValue) {
1482
+ if (isTimestepAuto) {
1483
+ onToggleTimestepAuto();
1484
+ }
1485
+ onChangeTimeStep(markValue);
1486
+ };
1487
+ var handleToggleTimeStep = function handleToggleTimeStep() {
1488
+ if (isTimestepAuto) {
1489
+ return;
1490
+ }
1491
+ onToggleTimestepAuto();
1492
+ timeStepFromLayer && onChangeTimeStep(timeStepFromLayer);
1493
+ };
1494
+ var layerHasTimeStep = Boolean(timeStepFromLayer);
1495
+ renderCounter.count(TimeStepButton.name);
1496
+ var _useState = useState(isOpenByDefault),
1497
+ open = _useState[0],
1498
+ setOpen = _useState[1];
1499
+ return jsx(TimeSliderMenu, {
1500
+ title: t('timeslider-time-step'),
1501
+ marks: translatedMarks,
1502
+ value: timeStep || translatedMarks[0].value,
1503
+ onChangeSliderValue: onMenuItemClick,
1504
+ allOptionsDisabled: disabled,
1505
+ isAutoSelected: isTimestepAuto,
1506
+ isAutoDisabled: !layerHasTimeStep,
1507
+ handleAutoClick: handleToggleTimeStep,
1508
+ icon: jsx(FastForward, {
1509
+ "data-testid": "timeStepButton"
1510
+ }),
1511
+ displayCurrentLength: true,
1512
+ open: open,
1513
+ setOpen: setOpen
1514
+ });
1515
+ };
1516
+
1517
+ var TimeSpanButtonCustomSelect = function TimeSpanButtonCustomSelect(_ref) {
1518
+ var timeSliderSpan = _ref.timeSliderSpan,
1519
+ setOpen = _ref.setOpen,
1520
+ onChangeSliderValue = _ref.onChangeSliderValue;
1521
+ var _useTimesliderTransla = useTimesliderTranslation(),
1522
+ t = _useTimesliderTransla.t;
1523
+ var _React$useState = React__default.useState(timeSliderSpan / getLargestTimeUnit(timeSliderSpan)),
1524
+ selectedTimeValue = _React$useState[0],
1525
+ setSelectedTimeValue = _React$useState[1];
1526
+ var _React$useState2 = React__default.useState(getLargestTimeUnit(timeSliderSpan).toString()),
1527
+ selectedTimeResolution = _React$useState2[0],
1528
+ setSelectedTimeResolution = _React$useState2[1];
1529
+ var _React$useState3 = React__default.useState(true),
1530
+ isANumber = _React$useState3[0],
1531
+ setisANumber = _React$useState3[1];
1532
+ return jsx(Box, {
1533
+ children: jsxs(FormControl, {
1534
+ variant: "standard",
1535
+ size: "small",
1536
+ sx: {
1537
+ flexDirection: 'row',
1538
+ display: 'flex'
1539
+ },
1540
+ onKeyDown: function onKeyDown(event) {
1541
+ event.stopPropagation();
1542
+ },
1543
+ children: [jsx(TextField, {
1544
+ label: t('timeslider-span'),
1545
+ size: "small",
1546
+ variant: "standard",
1547
+ value: Math.round(selectedTimeValue * 100) / 100,
1548
+ autoFocus: true,
1549
+ onChange: function onChange(e) {
1550
+ if (!isNaN(+e.target.value)) {
1551
+ setisANumber(true);
1552
+ setSelectedTimeValue(Number(e.target.value));
1553
+ } else {
1554
+ setisANumber(false);
1555
+ }
1556
+ },
1557
+ color: isANumber ? 'primary' : 'warning',
1558
+ onBlur: function onBlur() {
1559
+ onChangeSliderValue(selectedTimeValue * Number(selectedTimeResolution));
1560
+ },
1561
+ onKeyDown: function onKeyDown(e) {
1562
+ if (e.key === 'Enter' || e.key === 'Escape') {
1563
+ onChangeSliderValue(selectedTimeValue * Number(selectedTimeResolution));
1564
+ setOpen(false);
1565
+ }
1566
+ },
1567
+ slotProps: {
1568
+ htmlInput: {
1569
+ maxLength: 4,
1570
+ 'aria-label': 'custom-input'
1571
+ }
1572
+ }
1573
+ }), jsx(Box, {
1574
+ sx: {
1575
+ alignContent: 'end'
1576
+ },
1577
+ children: jsxs(Select, {
1578
+ value: selectedTimeResolution,
1579
+ defaultValue: "h",
1580
+ onChange: function onChange(e) {
1581
+ setSelectedTimeResolution(e.target.value);
1582
+ onChangeSliderValue(selectedTimeValue * Number(e.target.value));
1583
+ setOpen(false);
1584
+ },
1585
+ "aria-label": "time-resolution-selector",
1586
+ size: "small",
1587
+ tabIndex: -1,
1588
+ children: [jsx(MenuItem, {
1589
+ value: TimeInMinutes.YEAR,
1590
+ children: t('years')
1591
+ }), jsx(MenuItem, {
1592
+ value: TimeInMinutes.MONTH,
1593
+ children: t('months')
1594
+ }), jsx(MenuItem, {
1595
+ value: TimeInMinutes.WEEK,
1596
+ children: t('weeks')
1597
+ }), jsx(MenuItem, {
1598
+ value: TimeInMinutes.DAY,
1599
+ children: t('days')
1600
+ }), jsx(MenuItem, {
1601
+ value: TimeInMinutes.HOUR,
1602
+ children: t('hours')
1603
+ }), jsx(MenuItem, {
1604
+ value: TimeInMinutes.MINUTE,
1605
+ children: t('minutes')
1606
+ })]
1607
+ })
1608
+ })]
1609
+ })
1610
+ });
1611
+ };
1612
+
1613
+ var marks$1 = [{
1614
+ value: 60,
1615
+ text: 'timeslider-hour',
1616
+ count: 1
1617
+ }, {
1618
+ value: 3 * 60,
1619
+ text: 'timeslider-hour',
1620
+ count: 3
1621
+ }, {
1622
+ value: 6 * 60,
1623
+ text: 'timeslider-hour',
1624
+ count: 6
1625
+ }, {
1626
+ value: 12 * 60,
1627
+ text: 'timeslider-hour',
1628
+ count: 12
1629
+ }, {
1630
+ value: 24 * 60,
1631
+ text: 'timeslider-hour',
1632
+ count: 24
1633
+ }, {
1634
+ value: 2 * 24 * 60,
1635
+ text: 'timeslider-hour',
1636
+ count: 48
1637
+ }, {
1638
+ value: 7 * 24 * 60,
1639
+ text: 'timeslider-week',
1640
+ count: 1
1641
+ }, {
1642
+ value: 2 * 7 * 24 * 60,
1643
+ text: 'timeslider-weeks',
1644
+ count: 2
1645
+ }, {
1646
+ value: 30 * 24 * 60,
1647
+ text: 'timeslider-month',
1648
+ count: 1
1649
+ }, {
1650
+ value: 3 * 30 * 24 * 60,
1651
+ text: 'timeslider-months',
1652
+ count: 3
1653
+ }, {
1654
+ value: 365 * 24 * 60,
1655
+ text: 'timeslider-year',
1656
+ count: 1
1657
+ }].sort(function (ta, tb) {
1658
+ return tb.value - ta.value;
1659
+ });
1660
+ var TimeSpanButton = function TimeSpanButton(_ref) {
1661
+ var _ref$timeSliderSpan = _ref.timeSliderSpan,
1662
+ timeSliderSpan = _ref$timeSliderSpan === void 0 ? defaultTimeSpan : _ref$timeSliderSpan,
1663
+ _ref$disabled = _ref.disabled,
1664
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
1665
+ _ref$onChangeSliderVa = _ref.onChangeSliderValue,
1666
+ onChangeSliderValue = _ref$onChangeSliderVa === void 0 ? function () {} : _ref$onChangeSliderVa,
1667
+ onToggleTimeSpan = _ref.onToggleTimeSpan,
1668
+ isTimeSpanAuto = _ref.isTimeSpanAuto,
1669
+ _ref$isOpenByDefault = _ref.isOpenByDefault,
1670
+ isOpenByDefault = _ref$isOpenByDefault === void 0 ? false : _ref$isOpenByDefault,
1671
+ _ref$layerHasTimeStep = _ref.layerHasTimeStep,
1672
+ layerHasTimeStep = _ref$layerHasTimeStep === void 0 ? false : _ref$layerHasTimeStep;
1673
+ var _useTimesliderTransla = useTimesliderTranslation(),
1674
+ t = _useTimesliderTransla.t;
1675
+ var translatedMarks = marks$1.map(function (mark) {
1676
+ return Object.assign({}, mark, {
1677
+ label: mark.count + " " + t(mark.text)
1678
+ });
1679
+ });
1680
+ var _useState = useState(isOpenByDefault),
1681
+ open = _useState[0],
1682
+ setOpen = _useState[1];
1683
+ return jsx(TimeSliderMenu, {
1684
+ icon: jsx(Clock, {}),
1685
+ marks: translatedMarks,
1686
+ displayCurrentLength: true,
1687
+ title: t('timeslider-time-span'),
1688
+ customFieldHeader: t('timeslider-span'),
1689
+ value: timeSliderSpan,
1690
+ onChangeSliderValue: onChangeSliderValue,
1691
+ allOptionsDisabled: disabled,
1692
+ isAutoSelected: isTimeSpanAuto,
1693
+ isAutoDisabled: !layerHasTimeStep,
1694
+ handleAutoClick: onToggleTimeSpan,
1695
+ disbleUserSetDuration: false,
1696
+ open: open,
1697
+ setOpen: setOpen,
1698
+ customLengthSelector: jsx(TimeSpanButtonCustomSelect, {
1699
+ timeSliderSpan: timeSliderSpan,
1700
+ setOpen: setOpen,
1701
+ onChangeSliderValue: onChangeSliderValue
1702
+ })
1703
+ });
1704
+ };
1705
+
1706
+ var marks = [{
1707
+ value: AnimationLength.Minutes15,
1708
+ text: 'timeslider-min',
1709
+ count: 15
1710
+ }, {
1711
+ value: AnimationLength.Minutes30,
1712
+ text: 'timeslider-min',
1713
+ count: 30
1714
+ }, {
1715
+ value: AnimationLength.Hours1,
1716
+ text: 'timeslider-hour',
1717
+ count: 1
1718
+ }, {
1719
+ value: AnimationLength.Hours2,
1720
+ text: 'timeslider-hour',
1721
+ count: 2
1722
+ }, {
1723
+ value: AnimationLength.Hours3,
1724
+ text: 'timeslider-hour',
1725
+ count: 3
1726
+ }, {
1727
+ value: AnimationLength.Hours6,
1728
+ text: 'timeslider-hour',
1729
+ count: 6
1730
+ }, {
1731
+ value: AnimationLength.Hours12,
1732
+ text: 'timeslider-hour',
1733
+ count: 12
1734
+ }, {
1735
+ value: AnimationLength.Hours24,
1736
+ text: 'timeslider-hour',
1737
+ count: 24
1738
+ }].sort(function (ta, tb) {
1739
+ return tb.value - ta.value;
1740
+ });
1741
+ var AnimationLengthButton = function AnimationLengthButton(_ref) {
1742
+ var _ref$disabled = _ref.disabled,
1743
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
1744
+ _ref$animationLength = _ref.animationLength,
1745
+ animationLength = _ref$animationLength === void 0 ? AnimationLength.Hours1 : _ref$animationLength,
1746
+ _ref$isAuto = _ref.isAuto,
1747
+ isAuto = _ref$isAuto === void 0 ? false : _ref$isAuto,
1748
+ layerHasTimeStep = _ref.layerHasTimeStep,
1749
+ onChangeAnimationLength = _ref.onChangeAnimationLength,
1750
+ toggleAnimationLengthAuto = _ref.toggleAnimationLengthAuto;
1751
+ var _useTimesliderTransla = useTimesliderTranslation(),
1752
+ t = _useTimesliderTransla.t;
1753
+ var translatedMarks = marks.map(function (mark) {
1754
+ return Object.assign({}, mark, {
1755
+ label: mark.count + " " + t(mark.text)
1756
+ });
1757
+ });
1758
+ var onChangeSliderValue = function onChangeSliderValue(newSliderValue) {
1759
+ var newLength = newSliderValue ? Math.round(newSliderValue) : 0;
1760
+ onChangeAnimationLength && onChangeAnimationLength(newLength);
1761
+ };
1762
+ var _useState = useState(false),
1763
+ open = _useState[0],
1764
+ setOpen = _useState[1];
1765
+ return jsx(TimeSliderMenu, {
1766
+ onChangeSliderValue: onChangeSliderValue,
1767
+ icon: jsx(Animation, {
1768
+ "data-testid": "animationLengthButton"
1769
+ }),
1770
+ marks: translatedMarks,
1771
+ title: t('timeslider-animation'),
1772
+ isAutoSelected: isAuto,
1773
+ isAutoDisabled: !layerHasTimeStep,
1774
+ handleAutoClick: toggleAnimationLengthAuto,
1775
+ allOptionsDisabled: disabled,
1776
+ value: animationLength,
1777
+ displayCurrentLength: true,
1778
+ open: open,
1779
+ setOpen: setOpen
1780
+ });
1781
+ };
1782
+
1783
+ var OptionsMenu = function OptionsMenu(_ref) {
1784
+ var speedBtn = _ref.speedBtn,
1785
+ timeSpanBtn = _ref.timeSpanBtn,
1786
+ timeStepBtn = _ref.timeStepBtn,
1787
+ animationLengthBtn = _ref.animationLengthBtn;
1788
+ return jsxs(Fragment, {
1789
+ children: [jsx(Grid, {
1790
+ size: {
1791
+ xs: 'auto'
1792
+ },
1793
+ children: timeSpanBtn || jsx(TimeSpanButton, {
1794
+ onChangeSliderValue: function onChangeSliderValue() {},
1795
+ onToggleTimeSpan: function onToggleTimeSpan() {},
1796
+ isTimeSpanAuto: false,
1797
+ layerHasTimeStep: false,
1798
+ timeSliderSpan: 0,
1799
+ disabled: false
1800
+ })
1801
+ }), jsx(Grid, {
1802
+ size: {
1803
+ xs: 'auto'
1804
+ },
1805
+ children: animationLengthBtn || jsx(AnimationLengthButton, {
1806
+ toggleAnimationLengthAuto: function toggleAnimationLengthAuto() {},
1807
+ onChangeAnimationLength: function onChangeAnimationLength() {}
1808
+ })
1809
+ }), jsx(Grid, {
1810
+ size: {
1811
+ xs: 'auto'
1812
+ },
1813
+ children: timeStepBtn || jsx(TimeStepButton, {
1814
+ onChangeTimeStep: function onChangeTimeStep() {},
1815
+ isTimestepAuto: false
1816
+ })
1817
+ }), jsx(Grid, {
1818
+ size: {
1819
+ xs: 'auto'
1820
+ },
1821
+ children: speedBtn || jsx(SpeedButton, {
1822
+ animationDelay: defaultAnimationDelayAtStart,
1823
+ setMapAnimationDelay: function setMapAnimationDelay() {}
1824
+ })
1825
+ })]
1826
+ });
1827
+ };
1828
+
1829
+ var PlayButton = function PlayButton(_ref) {
1830
+ var isAnimating = _ref.isAnimating,
1831
+ isDisabled = _ref.isDisabled,
1832
+ _ref$onTogglePlayButt = _ref.onTogglePlayButton,
1833
+ onTogglePlayButton = _ref$onTogglePlayButt === void 0 ? function () {} : _ref$onTogglePlayButt;
1834
+ var onTogglePlay = function onTogglePlay() {
1835
+ onTogglePlayButton();
1836
+ };
1837
+ var _useTimesliderTransla = useTimesliderTranslation(),
1838
+ t = _useTimesliderTransla.t;
1839
+ return jsx(CustomIconButton, {
1840
+ variant: "tool",
1841
+ tooltipTitle: isAnimating ? t('timeslider-pause') : t('timeslider-play'),
1842
+ onClick: onTogglePlay,
1843
+ disabled: isDisabled,
1844
+ "data-testid": "playButton",
1845
+ isSelected: isAnimating,
1846
+ children: isAnimating ? jsx(Pause, {
1847
+ "data-testid": "pause-svg-path"
1848
+ }) : jsx(Play, {
1849
+ "data-testid": "play-svg-path"
1850
+ })
1851
+ });
1852
+ };
1853
+
1854
+ var BackwardForwardStepButton = function BackwardForwardStepButton(_ref) {
1855
+ var isForwardStep = _ref.isForwardStep,
1856
+ isDisabled = _ref.isDisabled,
1857
+ _ref$onClickBFButton = _ref.onClickBFButton,
1858
+ onClickBFButton = _ref$onClickBFButton === void 0 ? function () {} : _ref$onClickBFButton;
1859
+ // Added renderCounter for testing and performance purposes
1860
+ renderCounter.count(BackwardForwardStepButton.name);
1861
+ var _useTimesliderTransla = useTimesliderTranslation(),
1862
+ t = _useTimesliderTransla.t;
1863
+ return jsx(CustomIconButton, {
1864
+ variant: "tool",
1865
+ "data-testid": isForwardStep ? 'stepForwardButton' : 'stepBackwardButton',
1866
+ disabled: isDisabled,
1867
+ "aria-label": isForwardStep ? 'forward' : 'backward',
1868
+ onClick: onClickBFButton,
1869
+ tooltipTitle: isForwardStep ? t('timeslider-forward') : t('timeslider-backward'),
1870
+ children: isForwardStep ? jsx(StepForward, {
1871
+ "data-testid": "step-forward-svg-path"
1872
+ }) : jsx(StepBackward, {
1873
+ "data-testid": "step-backward-svg-path"
1874
+ })
1875
+ });
1876
+ };
1877
+
1878
+ var NowButton = function NowButton(_ref) {
1879
+ var _ref$onSetNow = _ref.onSetNow,
1880
+ onSetNow = _ref$onSetNow === void 0 ? function () {} : _ref$onSetNow,
1881
+ _ref$disabled = _ref.disabled,
1882
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled;
1883
+ var _useTimesliderTransla = useTimesliderTranslation(),
1884
+ t = _useTimesliderTransla.t;
1885
+ return jsx(CustomIconButton, {
1886
+ variant: "tool",
1887
+ "aria-label": "now",
1888
+ tooltipTitle: t('timeslider-now'),
1889
+ "data-testid": "nowButtonTooltip",
1890
+ disabled: disabled,
1891
+ onClick: function onClick() {
1892
+ return onSetNow();
1893
+ },
1894
+ children: jsx(Now, {
1895
+ "data-testid": "now-svg"
1896
+ })
1897
+ });
1898
+ };
1899
+
1900
+ var AutoUpdateButton = function AutoUpdateButton(_ref) {
1901
+ var _ref$toggleAutoUpdate = _ref.toggleAutoUpdate,
1902
+ toggleAutoUpdate = _ref$toggleAutoUpdate === void 0 ? function () {} : _ref$toggleAutoUpdate,
1903
+ _ref$isAutoUpdating = _ref.isAutoUpdating,
1904
+ isAutoUpdating = _ref$isAutoUpdating === void 0 ? false : _ref$isAutoUpdating,
1905
+ _ref$disabled = _ref.disabled,
1906
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled;
1907
+ var _useTimesliderTransla = useTimesliderTranslation(),
1908
+ t = _useTimesliderTransla.t;
1909
+ return jsx(CustomIconButton, {
1910
+ variant: "tool",
1911
+ isSelected: isAutoUpdating,
1912
+ disabled: disabled,
1913
+ onClick: function onClick() {
1914
+ return toggleAutoUpdate();
1915
+ },
1916
+ "data-testid": "autoUpdateButton",
1917
+ tooltipTitle: isAutoUpdating ? t('timeslider-auto-update-on') : t('timeslider-auto-update-off'),
1918
+ children: isAutoUpdating ? jsx(AutoUpdateActive, {
1919
+ "data-testid": "auto-update-svg-on"
1920
+ }) : jsx(AutoUpdateInActive, {
1921
+ "data-testid": "auto-update-svg-off"
1922
+ })
1923
+ });
1924
+ };
1925
+
1926
+ var ControlButtons = function ControlButtons(_ref) {
1927
+ var backwardBtn = _ref.backwardBtn,
1928
+ forwardBtn = _ref.forwardBtn,
1929
+ playBtn = _ref.playBtn,
1930
+ nowBtn = _ref.nowBtn,
1931
+ autoUpdateBtn = _ref.autoUpdateBtn;
1932
+ return jsxs(Fragment, {
1933
+ children: [jsx(Grid, {
1934
+ children: backwardBtn || jsx(BackwardForwardStepButton, {
1935
+ isForwardStep: false
1936
+ })
1937
+ }), jsx(Grid, {
1938
+ children: forwardBtn || jsx(BackwardForwardStepButton, {
1939
+ isForwardStep: true
1940
+ })
1941
+ }), jsx(Grid, {
1942
+ children: playBtn || jsx(PlayButton, {})
1943
+ }), jsx(Grid, {
1944
+ children: nowBtn || jsx(NowButton, {})
1945
+ }), jsx(Grid, {
1946
+ children: autoUpdateBtn || jsx(AutoUpdateButton, {})
1947
+ })]
1948
+ });
1949
+ };
1950
+
1951
+ var PopperMenu = function PopperMenu(_ref) {
1952
+ var controls = _ref.controls,
1953
+ isPopperOpen = _ref.isPopperOpen,
1954
+ options = _ref.options,
1955
+ buttonElement = _ref.buttonElement,
1956
+ popperPlacement = _ref.popperPlacement;
1957
+ if (!buttonElement) {
1958
+ return null;
1959
+ }
1960
+ var direction = ['bottom', 'top'].includes(popperPlacement) ? 'column' : 'row';
1961
+ var margin = getMargin(buttonElement, popperPlacement);
1962
+ return jsx(Popper, {
1963
+ sx: {
1964
+ zIndex: 3
1965
+ },
1966
+ placement: popperPlacement,
1967
+ open: isPopperOpen,
1968
+ anchorEl: direction === 'row' ? buttonElement == null ? void 0 : buttonElement.parentElement : buttonElement,
1969
+ children: jsx(Paper, {
1970
+ sx: Object.assign({}, margin),
1971
+ elevation: 3,
1972
+ children: jsxs(Grid, {
1973
+ sx: Object.assign({
1974
+ padding: '4px 8px 8px'
1975
+ }, direction === 'column' && {
1976
+ '& button': {
1977
+ width: '100%!important'
1978
+ }
1979
+ }, direction === 'row' && {
1980
+ marginTop: -0.5
1981
+ }),
1982
+ container: true,
1983
+ spacing: 0.5,
1984
+ direction: direction,
1985
+ children: [options != null ? options : jsx(OptionsMenu, {}), controls != null ? controls : jsx(ControlButtons, {})]
1986
+ })
1987
+ })
1988
+ });
1989
+ };
1990
+ var getMargin = function getMargin(buttonElement, popperPlacement) {
1991
+ var clock = buttonElement.parentElement.getBoundingClientRect();
1992
+ var button = buttonElement.getBoundingClientRect();
1993
+ var distanceFromButtonToContainer = clock.bottom - button.bottom;
1994
+ if (popperPlacement === 'top') {
1995
+ return {
1996
+ marginBottom: distanceFromButtonToContainer + "px!important"
1997
+ };
1998
+ }
1999
+ if (popperPlacement === 'bottom') {
2000
+ return {
2001
+ marginTop: distanceFromButtonToContainer + "px!important"
2002
+ };
2003
+ }
2004
+ return undefined;
2005
+ };
2006
+
2007
+ var MIN_WIDTH = 170;
2008
+ var MIN_HEIGHT = 32;
2009
+ var MIN_FONT_SIZE = 14; // bigger font size will cause render delay in LCP
2010
+ var FONT_SIZE_WIDTH_RATIO = MIN_FONT_SIZE / MIN_WIDTH;
2011
+ var BUTTON_WIDTH = 40;
2012
+ var POPPER_WIDTH = 356;
2013
+ var POPPER_LENGTH = 240;
2014
+ var TimeSliderClock = function TimeSliderClock(_ref2) {
2015
+ var time = _ref2.time,
2016
+ options = _ref2.options,
2017
+ controls = _ref2.controls,
2018
+ _ref2$hideButton = _ref2.hideButton,
2019
+ hideButton = _ref2$hideButton === void 0 ? true : _ref2$hideButton,
2020
+ _ref2$isPopperOpenByD = _ref2.isPopperOpenByDefault,
2021
+ isPopperOpenByDefault = _ref2$isPopperOpenByD === void 0 ? false : _ref2$isPopperOpenByD;
2022
+ var clockElement = useRef(null);
2023
+ var _useState = useState(null),
2024
+ buttonElement = _useState[0],
2025
+ setButtonElement = _useState[1];
2026
+ var _useState2 = useState(false),
2027
+ isPopperOpen = _useState2[0],
2028
+ setIsPopperOpen = _useState2[1];
2029
+ var _useState3 = useState('left'),
2030
+ popperPlacement = _useState3[0],
2031
+ setPopperPlacement = _useState3[1];
2032
+ var _useState4 = useState({
2033
+ x: 0,
2034
+ y: 0
2035
+ }),
2036
+ position = _useState4[0],
2037
+ setPosition = _useState4[1];
2038
+ useMakeSureContainerStaysInsideWindow(clockElement, position, setPosition);
2039
+ var _useState5 = useState({
2040
+ width: MIN_WIDTH,
2041
+ height: MIN_HEIGHT
2042
+ }),
2043
+ size = _useState5[0],
2044
+ setSize = _useState5[1];
2045
+ var _useState6 = useState(MIN_FONT_SIZE),
2046
+ fontSize = _useState6[0],
2047
+ setFontSize = _useState6[1];
2048
+ useEffect(function () {
2049
+ if (hideButton) {
2050
+ setIsPopperOpen(false);
2051
+ }
2052
+ if (size.width === MIN_WIDTH && hideButton) {
2053
+ return;
2054
+ }
2055
+ var diff = hideButton ? -40 : BUTTON_WIDTH;
2056
+ var width = size.width + diff;
2057
+ setSize(Object.assign({}, size, {
2058
+ width: width
2059
+ }));
2060
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2061
+ }, [hideButton]);
2062
+ useEffect(function () {
2063
+ if (buttonElement && isPopperOpenByDefault) {
2064
+ setIsPopperOpen(true);
2065
+ }
2066
+ }, [buttonElement, isPopperOpenByDefault]);
2067
+ return jsxs(Fragment, {
2068
+ children: [jsx(PopperMenu, {
2069
+ popperPlacement: popperPlacement,
2070
+ isPopperOpen: isPopperOpen,
2071
+ buttonElement: buttonElement,
2072
+ options: options,
2073
+ controls: controls
2074
+ }), jsx(Draggable, {
2075
+ cancel: ".MuiButtonBase-root",
2076
+ nodeRef: clockElement,
2077
+ bounds: "parent",
2078
+ position: position,
2079
+ onStop: function onStop(_event, position) {
2080
+ setPosition(position);
2081
+ setPopperPlacement(getPopperplacement(clockElement.current));
2082
+ },
2083
+ children: jsx("div", {
2084
+ style: {
2085
+ position: 'absolute',
2086
+ zIndex: 1001,
2087
+ top: '10px',
2088
+ right: '10px'
2089
+ },
2090
+ ref: function ref(_ref3) {
2091
+ clockElement.current = _ref3;
2092
+ setPopperPlacement(getPopperplacement(_ref3));
2093
+ },
2094
+ children: jsx(Resizable, {
2095
+ onResizeStart: function onResizeStart(event) {
2096
+ event.stopPropagation();
2097
+ },
2098
+ onResize: function onResize(_event, _direction, _ref, delta) {
2099
+ var width = size.width + delta.width;
2100
+ var adjustedWidth = hideButton ? width : width - BUTTON_WIDTH;
2101
+ var fontSize = FONT_SIZE_WIDTH_RATIO * adjustedWidth;
2102
+ setFontSize(fontSize);
2103
+ },
2104
+ onResizeStop: function onResizeStop(_event, _direction, _ref, delta) {
2105
+ var width = size.width + delta.width;
2106
+ var height = size.height + delta.height;
2107
+ setSize({
2108
+ width: width,
2109
+ height: height
2110
+ });
2111
+ setPopperPlacement(getPopperplacement(clockElement.current));
2112
+ },
2113
+ lockAspectRatio: true,
2114
+ minHeight: MIN_HEIGHT,
2115
+ minWidth: hideButton ? MIN_WIDTH : MIN_WIDTH + BUTTON_WIDTH,
2116
+ size: size,
2117
+ handleComponent: {
2118
+ bottomLeft: jsx(Resize, {
2119
+ isRightAligned: true,
2120
+ style: {
2121
+ fill: '#FFFFFF'
2122
+ }
2123
+ })
2124
+ },
2125
+ enable: resizeHandlePlacement,
2126
+ children: jsx(ClockContainer, {
2127
+ hideButton: hideButton,
2128
+ onButtonClick: function onButtonClick() {
2129
+ if (!isPopperOpen) {
2130
+ setPopperPlacement(getPopperplacement(clockElement.current));
2131
+ }
2132
+ setIsPopperOpen(!isPopperOpen);
2133
+ },
2134
+ isPopperOpen: isPopperOpen,
2135
+ fontSize: fontSize,
2136
+ time: time,
2137
+ setButtonElement: setButtonElement,
2138
+ popperPlacement: popperPlacement
2139
+ })
2140
+ })
2141
+ })
2142
+ })]
2143
+ });
2144
+ };
2145
+ var getPopperplacement = function getPopperplacement(clockElement) {
2146
+ var _clockElement$parentE;
2147
+ var clock = clockElement == null ? void 0 : clockElement.getBoundingClientRect();
2148
+ var mapWindow = clockElement == null || (_clockElement$parentE = clockElement.parentElement) == null ? void 0 : _clockElement$parentE.getBoundingClientRect();
2149
+ if (clock && mapWindow) {
2150
+ var popperIsOutsideWindowOnLeft = mapWindow.left > clock.left - POPPER_WIDTH;
2151
+ var popperIsOutsideWindowOnBottom = clock.bottom + POPPER_LENGTH > mapWindow.bottom;
2152
+ var popperIsOutsideWindowOnRight = clock.right + POPPER_WIDTH > mapWindow.right;
2153
+ if (popperIsOutsideWindowOnLeft && popperIsOutsideWindowOnBottom && popperIsOutsideWindowOnRight) {
2154
+ return 'top';
2155
+ }
2156
+ if (popperIsOutsideWindowOnLeft && popperIsOutsideWindowOnBottom) {
2157
+ return 'right';
2158
+ }
2159
+ if (popperIsOutsideWindowOnLeft) {
2160
+ return 'bottom';
2161
+ }
2162
+ }
2163
+ return 'left';
2164
+ };
2165
+ var resizeHandlePlacement = {
2166
+ top: false,
2167
+ right: false,
2168
+ bottom: false,
2169
+ left: false,
2170
+ topRight: false,
2171
+ bottomRight: false,
2172
+ bottomLeft: true,
2173
+ topLeft: false
2174
+ };
2175
+
2176
+ var _scaleToUnitSeconds, _scaleToRoundableUnit;
2177
+ var scaleToUnitSeconds = (_scaleToUnitSeconds = {}, _scaleToUnitSeconds[Scale.Minutes5] = 5 * 60, _scaleToUnitSeconds[Scale.Hour] = 60 * 60, _scaleToUnitSeconds[Scale.Hours3] = 3 * 60 * 60, _scaleToUnitSeconds[Scale.Hours6] = 6 * 60 * 60, _scaleToUnitSeconds[Scale.Day] = 24 * 60 * 60, _scaleToUnitSeconds[Scale.Week] = 7 * 24 * 60 * 60, _scaleToUnitSeconds[Scale.Weeks2] = 14 * 24 * 60 * 60, _scaleToUnitSeconds);
2178
+ var TICK_MARK_HEIGHT_PRIMARY = 40;
2179
+ var TICK_MARK_HEIGHT_SECONDARY = 10;
2180
+ var TICK_MARK_HEIGHT_TERTIARY = 5;
2181
+ var getStepPxLineHeight = function getStepPxLineHeight(scale, timestep) {
2182
+ var scaleUnitSeconds = scaleToUnitSeconds[scale];
2183
+ var rem = timestep % scaleUnitSeconds;
2184
+ switch (scale) {
2185
+ case Scale.Hour:
2186
+ {
2187
+ if (rem === 0) {
2188
+ return TICK_MARK_HEIGHT_PRIMARY;
2189
+ }
2190
+ // 15 min subdivisions
2191
+ if (rem % (15 * 60) === 0) {
2192
+ return TICK_MARK_HEIGHT_SECONDARY;
2193
+ }
2194
+ return TICK_MARK_HEIGHT_TERTIARY;
2195
+ }
2196
+ case Scale.Hours3:
2197
+ {
2198
+ if (rem === 0) {
2199
+ return TICK_MARK_HEIGHT_PRIMARY;
2200
+ }
2201
+ return TICK_MARK_HEIGHT_TERTIARY;
2202
+ }
2203
+ case Scale.Hours6:
2204
+ {
2205
+ if (rem === 0) {
2206
+ return TICK_MARK_HEIGHT_PRIMARY;
2207
+ }
2208
+ // 3 hour subdivisions
2209
+ if (rem % (3 * 60 * 60) === 0) {
2210
+ return TICK_MARK_HEIGHT_SECONDARY;
2211
+ }
2212
+ return TICK_MARK_HEIGHT_TERTIARY;
2213
+ }
2214
+ case Scale.Day:
2215
+ {
2216
+ if (rem === 0) {
2217
+ return TICK_MARK_HEIGHT_PRIMARY;
2218
+ }
2219
+ // 6 hour subdivisions
2220
+ if (rem % (6 * 60 * 60) === 0) {
2221
+ return TICK_MARK_HEIGHT_SECONDARY;
2222
+ }
2223
+ return TICK_MARK_HEIGHT_TERTIARY;
2224
+ }
2225
+ case Scale.Week:
2226
+ case Scale.Weeks2:
2227
+ {
2228
+ var weekday = dateUtils.getDay(dateUtils.fromUnix(timestep));
2229
+ // dateUtils days range from 0 (Sunday) to 6 (Saturday)
2230
+ if (weekday === 1) {
2231
+ return TICK_MARK_HEIGHT_PRIMARY;
2232
+ }
2233
+ return TICK_MARK_HEIGHT_TERTIARY;
2234
+ }
2235
+ case Scale.Year:
2236
+ {
2237
+ var month = dateUtils.getMonth(dateUtils.fromUnix(timestep));
2238
+ // months are zero indexed
2239
+ if (month === 0) {
2240
+ return TICK_MARK_HEIGHT_PRIMARY;
2241
+ }
2242
+ if (month % 3 === 0) {
2243
+ return TICK_MARK_HEIGHT_SECONDARY;
2244
+ }
2245
+ return TICK_MARK_HEIGHT_TERTIARY;
2246
+ }
2247
+ case Scale.Minutes5:
2248
+ {
2249
+ // add primary line on day change
2250
+ if (timestep % (60 * 60 * 24) === 0) {
2251
+ return TICK_MARK_HEIGHT_PRIMARY;
2252
+ }
2253
+ return TICK_MARK_HEIGHT_TERTIARY;
2254
+ }
2255
+ default:
2256
+ // Scale.Month
2257
+ return TICK_MARK_HEIGHT_TERTIARY;
2258
+ }
2259
+ };
2260
+ var drawStepPxLine = function drawStepPxLine(ctx, theme, stepPx, height, fundamentalScale, timestep) {
2261
+ var ctx2 = ctx;
2262
+ ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
2263
+ ctx2.lineWidth = 1;
2264
+ var stepPxLineHeight = getStepPxLineHeight(fundamentalScale, timestep);
2265
+ ctx2.beginPath();
2266
+ ctx2.moveTo(stepPx, height - stepPxLineHeight);
2267
+ ctx2.lineTo(stepPx, height);
2268
+ ctx2.stroke();
2269
+ };
2270
+ var drawTimeText = function drawTimeText(ctx, theme, stepPx, height, timeText, scale) {
2271
+ var ctx2 = ctx;
2272
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider.timelineText,
2273
+ fontSize = _theme$palette$geoweb.fontSize,
2274
+ fontFamily = _theme$palette$geoweb.fontFamily,
2275
+ color = _theme$palette$geoweb.color;
2276
+ ctx2.fillStyle = color;
2277
+ // time text has smaller font than other timeline text
2278
+ ctx2.font = fontSize + "px " + fontFamily;
2279
+ ctx2.textAlign = 'left';
2280
+ if (scale === Scale.Year || scale === Scale.Months3 || scale === Scale.Month || scale === Scale.Weeks2 || scale === Scale.Week || scale === Scale.Day) {
2281
+ ctx2.fillText(timeText, stepPx, height - 12);
2282
+ } else {
2283
+ ctx2.fillText(timeText, stepPx - 15, height - 12);
2284
+ }
2285
+ };
2286
+ var drawYearScaleText = function drawYearScaleText(ctx, theme, newDate, stepPx, height) {
2287
+ var ctx2 = ctx;
2288
+ var _theme$palette$geoweb2 = theme.palette.geowebColors.timeSlider.timelineText,
2289
+ fontSize = _theme$palette$geoweb2.fontSize,
2290
+ fontFamily = _theme$palette$geoweb2.fontFamily,
2291
+ color = _theme$palette$geoweb2.color;
2292
+ ctx2.fillStyle = color;
2293
+ ctx2.font = fontSize + "px " + fontFamily;
2294
+ ctx2.textAlign = 'left';
2295
+ ctx2.fillText(newDate, stepPx + 2, height - 10);
2296
+ };
2297
+ var drawLeftSideDateText = function drawLeftSideDateText(ctx, theme, newDate, height) {
2298
+ var ctx2 = ctx;
2299
+ var _theme$palette$geoweb3 = theme.palette.geowebColors.timeSlider.timelineText,
2300
+ fontSize = _theme$palette$geoweb3.fontSize,
2301
+ fontFamily = _theme$palette$geoweb3.fontFamily,
2302
+ color = _theme$palette$geoweb3.color;
2303
+ ctx2.fillStyle = color;
2304
+ ctx2.font = fontSize + "px " + fontFamily;
2305
+ ctx2.textAlign = 'left';
2306
+ ctx2.fillText(newDate, 2, height - 30);
2307
+ };
2308
+ var getTimeFormat = function getTimeFormat(scale) {
2309
+ switch (scale) {
2310
+ case Scale.Year:
2311
+ return 'y';
2312
+ case Scale.Month:
2313
+ case Scale.Months3:
2314
+ return 'MMM';
2315
+ case Scale.Week:
2316
+ case Scale.Weeks2:
2317
+ return 'dd MMM';
2318
+ case Scale.Day:
2319
+ return 'EEE dd';
2320
+ default:
2321
+ return dateUtils.DATE_FORMAT_HOURS;
2322
+ }
2323
+ };
2324
+ var drawDateChangeLine = function drawDateChangeLine(ctx, theme, stepPx, height) {
2325
+ var ctx2 = ctx;
2326
+ ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
2327
+ ctx2.lineWidth = 1;
2328
+ ctx2.beginPath();
2329
+ ctx2.moveTo(stepPx, height - 40);
2330
+ ctx2.lineTo(stepPx, height);
2331
+ ctx2.stroke();
2332
+ };
2333
+ var drawDashedMonthChangeLine = function drawDashedMonthChangeLine(ctx, theme, stepPx, height) {
2334
+ var ctx2 = ctx;
2335
+ ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineMonthChangeDash.rgba;
2336
+ ctx2.lineWidth = 3;
2337
+ ctx2.setLineDash([5, 5]);
2338
+ ctx2.beginPath();
2339
+ ctx2.moveTo(stepPx, 0);
2340
+ ctx2.lineTo(stepPx, height);
2341
+ ctx2.stroke();
2342
+ ctx2.setLineDash([]);
2343
+ };
2344
+ var roundByUnitOfTime = function roundByUnitOfTime(timeUnix, unit, roundUp) {
2345
+ if (roundUp === void 0) {
2346
+ roundUp = false;
2347
+ }
2348
+ if (unit === 'hour') {
2349
+ var _timeStartOfPassedUnit = dateUtils.startOfHourUTC(dateUtils.fromUnix(timeUnix));
2350
+ if (roundUp) {
2351
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit, {
2352
+ hours: 1
2353
+ }));
2354
+ }
2355
+ return dateUtils.unix(_timeStartOfPassedUnit);
2356
+ }
2357
+ if (unit === 'day') {
2358
+ var _timeStartOfPassedUnit2 = dateUtils.startOfDayUTC(dateUtils.fromUnix(timeUnix));
2359
+ if (roundUp) {
2360
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit2, {
2361
+ days: 1
2362
+ }));
2363
+ }
2364
+ return dateUtils.unix(_timeStartOfPassedUnit2);
2365
+ }
2366
+ if (unit === 'week') {
2367
+ var _timeStartOfPassedUnit3 = dateUtils.startOfWeekUTC(dateUtils.fromUnix(timeUnix));
2368
+ if (roundUp) {
2369
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit3, {
2370
+ weeks: 1
2371
+ }));
2372
+ }
2373
+ return dateUtils.unix(_timeStartOfPassedUnit3);
2374
+ }
2375
+ if (unit === 'month') {
2376
+ var _timeStartOfPassedUnit4 = dateUtils.startOfMonthUTC(dateUtils.fromUnix(timeUnix));
2377
+ if (roundUp) {
2378
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit4, {
2379
+ months: 1
2380
+ }));
2381
+ }
2382
+ return dateUtils.unix(_timeStartOfPassedUnit4);
2383
+ }
2384
+ // Default unit === 'year'
2385
+ var timeStartOfPassedUnit = dateUtils.startOfYearUTC(dateUtils.fromUnix(timeUnix));
2386
+ if (roundUp) {
2387
+ return dateUtils.unix(dateUtils.add(timeStartOfPassedUnit, {
2388
+ years: 1
2389
+ }));
2390
+ }
2391
+ return dateUtils.unix(timeStartOfPassedUnit);
2392
+ };
2393
+ var roundToNearestMultiple = function roundToNearestMultiple(timeUnix, scale, roundUp) {
2394
+ if (roundUp === void 0) {
2395
+ roundUp = false;
2396
+ }
2397
+ var stepSeconds = scaleToUnitSeconds[scale];
2398
+ var roundFn = roundUp ? Math.ceil : Math.floor;
2399
+ return roundFn(timeUnix / stepSeconds) * stepSeconds;
2400
+ };
2401
+ /**
2402
+ * In this script starting and ending times of the time slider are rounded.
2403
+ * Here it is defined what is a time unit to a start of which a rounding is
2404
+ * done for each scale.
2405
+ * @returns an object where there are rounding units of each scale
2406
+ */
2407
+ var scaleToRoundableUnit = (_scaleToRoundableUnit = {}, _scaleToRoundableUnit[Scale.Hour] = 'hour', _scaleToRoundableUnit[Scale.Day] = 'day', _scaleToRoundableUnit[Scale.Week] = 'week', _scaleToRoundableUnit[Scale.Weeks2] = 'week', _scaleToRoundableUnit[Scale.Month] = 'week', _scaleToRoundableUnit[Scale.Months3] = 'week', _scaleToRoundableUnit[Scale.Year] = 'year', _scaleToRoundableUnit);
2408
+ var getRoundedStartAndEnd = function getRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, scale) {
2409
+ if (scale === Scale.Minutes5 || scale === Scale.Hours3 || scale === Scale.Hours6) {
2410
+ return [roundToNearestMultiple(visibleTimeStart, scale, false), roundToNearestMultiple(visibleTimeEnd, scale, true)];
2411
+ }
2412
+ var unit = scaleToRoundableUnit[scale];
2413
+ return [roundByUnitOfTime(visibleTimeStart, unit, false), roundByUnitOfTime(visibleTimeEnd, unit, true)];
2414
+ };
2415
+ var getCustomRoundedStartAndEndScale = function getCustomRoundedStartAndEndScale(scale) {
2416
+ switch (scale) {
2417
+ case Scale.Year:
2418
+ return 'month';
2419
+ case Scale.Month:
2420
+ case Scale.Months3:
2421
+ return 'week';
2422
+ case Scale.Week:
2423
+ case Scale.Weeks2:
2424
+ return 'day';
2425
+ default:
2426
+ return 'day';
2427
+ }
2428
+ };
2429
+ var getCustomRoundedStartAndEnd = function getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, unit) {
2430
+ var scale = getCustomRoundedStartAndEndScale(unit);
2431
+ return [roundByUnitOfTime(visibleTimeStart, scale, false), roundByUnitOfTime(visibleTimeEnd, scale, true)];
2432
+ };
2433
+ var incrementTimestep = function incrementTimestep(timeAtTimeStep, fundamentalScale) {
2434
+ switch (fundamentalScale) {
2435
+ case Scale.Minutes5:
2436
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2437
+ minutes: 1
2438
+ }));
2439
+ case Scale.Hour:
2440
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2441
+ minutes: 5
2442
+ }));
2443
+ case Scale.Hours3:
2444
+ case Scale.Hours6:
2445
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2446
+ hours: 1
2447
+ }));
2448
+ case Scale.Day:
2449
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2450
+ hours: 3
2451
+ }));
2452
+ case Scale.Week:
2453
+ case Scale.Weeks2:
2454
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2455
+ days: 1
2456
+ }));
2457
+ case Scale.Month:
2458
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2459
+ weeks: 1
2460
+ }));
2461
+ case Scale.Year:
2462
+ case Scale.Months3:
2463
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2464
+ months: 1
2465
+ }));
2466
+ default:
2467
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2468
+ months: 1
2469
+ }));
2470
+ }
2471
+ };
2472
+ var getTimesteps = function getTimesteps(roundedStart, roundedEnd, fundamentalScaleType) {
2473
+ var timesteps = [];
2474
+ var timestep = roundedStart;
2475
+ while (timestep <= roundedEnd) {
2476
+ timesteps.push(timestep);
2477
+ timestep = incrementTimestep(timestep, fundamentalScaleType);
2478
+ }
2479
+ return timesteps;
2480
+ };
2481
+ var getCustomTimesteps = function getCustomTimesteps(roundedStart, roundedEnd, increment) {
2482
+ var timesteps = [];
2483
+ var timestep = roundedStart;
2484
+ while (timestep <= roundedEnd) {
2485
+ var _dateUtils$add;
2486
+ timesteps.push(timestep);
2487
+ timestep = dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timestep), (_dateUtils$add = {}, _dateUtils$add[increment] = 1, _dateUtils$add)));
2488
+ }
2489
+ return timesteps;
2490
+ };
2491
+ var getLeftSideDateText = function getLeftSideDateText(timestamp, fundamentalScale) {
2492
+ var time = dateUtils.fromUnix(timestamp);
2493
+ switch (fundamentalScale) {
2494
+ case Scale.Minutes5:
2495
+ case Scale.Hour:
2496
+ case Scale.Hours3:
2497
+ case Scale.Hours6:
2498
+ return dateUtils.dateToString(time, 'y MMM EEE dd');
2499
+ case Scale.Day:
2500
+ case Scale.Week:
2501
+ case Scale.Weeks2:
2502
+ return dateUtils.dateToString(time, 'y MMM');
2503
+ case Scale.Month:
2504
+ case Scale.Months3:
2505
+ return dateUtils.dateToString(time, 'y');
2506
+ case Scale.Year:
2507
+ return dateUtils.dateToString(time, 'y');
2508
+ default:
2509
+ return '';
2510
+ }
2511
+ };
2512
+ var drawTimeScale = function drawTimeScale(context, theme, visibleTimeStart, visibleTimeEnd, canvasWidth, height, secondsPerPx) {
2513
+ var fundamentalScale = getFundamentalScale(secondsPerPx);
2514
+ var _getRoundedStartAndEn = getRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, fundamentalScale),
2515
+ roundedStart = _getRoundedStartAndEn[0],
2516
+ roundedEnd = _getRoundedStartAndEn[1];
2517
+ // draw regular tickmarks
2518
+ var ctx = context;
2519
+ getTimesteps(roundedStart, roundedEnd, fundamentalScale).forEach(function (timestep) {
2520
+ var stepPx = timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
2521
+ // Move 1 pixel line by 0.5 pixels to prevent it from being shown as blurry: https://usefulangle.com/post/17/html5-canvas-drawing-1px-crisp-straight-lines
2522
+ drawStepPxLine(ctx, theme, Math.floor(stepPx) + 0.5, height, fundamentalScale, timestep);
2523
+ // Draw the time step time as text
2524
+ var timeFormat = getTimeFormat(fundamentalScale);
2525
+ var timeText = dateUtils.dateToString(dateUtils.fromUnix(timestep), timeFormat);
2526
+ if ([Scale.Minutes5, Scale.Hour, Scale.Hours3, Scale.Hours6, Scale.Day].includes(fundamentalScale) &&
2527
+ // eslint-disable-next-line @typescript-eslint/no-confusing-non-null-assertion
2528
+ timestep % scaleToUnitSeconds[fundamentalScale] === 0 || fundamentalScale === Scale.Week && dateUtils.getDay(dateUtils.fromUnix(timestep)) === 1) {
2529
+ drawTimeText(ctx, theme, stepPx, height, timeText, fundamentalScale);
2530
+ }
2531
+ if (fundamentalScale === Scale.Year && dateUtils.getMonth(dateUtils.fromUnix(timestep)) === 0) {
2532
+ drawYearScaleText(ctx, theme, timeText, stepPx, height);
2533
+ }
2534
+ });
2535
+ // draw month overlay lines
2536
+ if (fundamentalScale === Scale.Week || fundamentalScale === Scale.Weeks2 || fundamentalScale === Scale.Month || fundamentalScale === Scale.Months3) {
2537
+ var _getCustomRoundedStar = getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, Scale.Year),
2538
+ _roundedStart = _getCustomRoundedStar[0],
2539
+ _roundedEnd = _getCustomRoundedStar[1];
2540
+ var monthTimesteps = getCustomTimesteps(_roundedStart, _roundedEnd, 'months');
2541
+ monthTimesteps.forEach(function (timestep) {
2542
+ var stepPx = timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
2543
+ if (fundamentalScale === Scale.Month || fundamentalScale === Scale.Months3) {
2544
+ var month = dateUtils.dateToString(dateUtils.fromUnix(timestep), 'MMM');
2545
+ // Move 1 pixel line by 0.5 pixels to prevent it from being shown as blurry: https://usefulangle.com/post/17/html5-canvas-drawing-1px-crisp-straight-lines
2546
+ drawDateChangeLine(ctx, theme, Math.floor(stepPx) + 0.5, height);
2547
+ drawTimeText(ctx, theme, stepPx, height, month, fundamentalScale);
2548
+ return;
2549
+ }
2550
+ // adding 0.5 to make line not so blurred
2551
+ drawDashedMonthChangeLine(ctx, theme, Math.floor(stepPx) + 0.5, height);
2552
+ });
2553
+ }
2554
+ // draw date change texts
2555
+ if (fundamentalScale === Scale.Year) {
2556
+ return;
2557
+ }
2558
+ var dateText = getLeftSideDateText(visibleTimeStart, fundamentalScale);
2559
+ drawLeftSideDateText(ctx, theme, dateText, height);
2560
+ };
2561
+
2562
+ /* *
2563
+ * Licensed under the Apache License, Version 2.0 (the "License");
2564
+ * you may not use this file except in compliance with the License.
2565
+ * You may obtain a copy of the License at
2566
+ *
2567
+ * http://www.apache.org/licenses/LICENSE-2.0
2568
+ *
2569
+ * Unless required by applicable law or agreed to in writing, software
2570
+ * distributed under the License is distributed on an "AS IS" BASIS,
2571
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2572
+ * See the License for the specific language governing permissions and
2573
+ * limitations under the License.
2574
+ *
2575
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2576
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
2577
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
2578
+ * */
2579
+ var drawNeedle = function drawNeedle(context, theme, width, height, startTime, endTime, selectedTime) {
2580
+ if (!selectedTime) {
2581
+ return;
2582
+ }
2583
+ var ctx = context;
2584
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
2585
+ playerNeedlePlayer = _theme$palette$geoweb.playerNeedlePlayer,
2586
+ playerNeedlePlayerTop = _theme$palette$geoweb.playerNeedlePlayerTop,
2587
+ playerTimeMarkers = _theme$palette$geoweb.playerTimeMarkers;
2588
+ var selectedPx = timestampToPixelEdges(selectedTime, startTime, endTime, width);
2589
+ // Draw a high vertical line (needle) indicating the current or selected time
2590
+ ctx.beginPath();
2591
+ // Move 1 pixel line by 0.5 pixels to prevent it from being shown as blurry: https://usefulangle.com/post/17/html5-canvas-drawing-1px-crisp-straight-lines
2592
+ ctx.moveTo(Math.floor(selectedPx) + 0.5, height - 50);
2593
+ ctx.lineTo(Math.floor(selectedPx) + 0.5, height);
2594
+ ctx.lineWidth = 5;
2595
+ ctx.strokeStyle = playerNeedlePlayer.rgba;
2596
+ ctx.stroke();
2597
+ ctx.lineWidth = 1;
2598
+ ctx.strokeStyle = playerNeedlePlayerTop.rgba;
2599
+ ctx.stroke();
2600
+ // Triange connecting timebox.
2601
+ ctx.beginPath();
2602
+ ctx.moveTo(Math.floor(selectedPx) + 5, 0);
2603
+ ctx.lineTo(Math.floor(selectedPx) + 0.5, 5);
2604
+ ctx.lineTo(Math.floor(selectedPx) - 5, 0);
2605
+ ctx.closePath();
2606
+ ctx.fillStyle = playerTimeMarkers.fill;
2607
+ ctx.fill();
2608
+ };
2609
+
2610
+ /* *
2611
+ * Licensed under the Apache License, Version 2.0 (the "License");
2612
+ * you may not use this file except in compliance with the License.
2613
+ * You may obtain a copy of the License at
2614
+ *
2615
+ * http://www.apache.org/licenses/LICENSE-2.0
2616
+ *
2617
+ * Unless required by applicable law or agreed to in writing, software
2618
+ * distributed under the License is distributed on an "AS IS" BASIS,
2619
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2620
+ * See the License for the specific language governing permissions and
2621
+ * limitations under the License.
2622
+ *
2623
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2624
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
2625
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
2626
+ * */
2627
+ var drawCurrentTime = function drawCurrentTime(context, theme, width, height, startTime, endTime, currentTime) {
2628
+ var ctx = context;
2629
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
2630
+ playerNeedleTime = _theme$palette$geoweb.playerNeedleTime,
2631
+ playerNeedleTimeTop = _theme$palette$geoweb.playerNeedleTimeTop;
2632
+ var current = currentTime;
2633
+ var currentPx = current ? timestampToPixelEdges(current, startTime, endTime, width) : 0;
2634
+ // Draw a high vertical line (needle) indicating the current or selected time
2635
+ ctx.beginPath();
2636
+ // Move 1 pixel line by 0.5 pixels to prevent it from being shown as blurry: https://usefulangle.com/post/17/html5-canvas-drawing-1px-crisp-straight-lines
2637
+ ctx.moveTo(Math.floor(currentPx) + 0.5, height - 24);
2638
+ ctx.lineTo(Math.floor(currentPx) + 0.5, height);
2639
+ ctx.lineWidth = 5;
2640
+ ctx.strokeStyle = playerNeedleTime.rgba;
2641
+ ctx.stroke();
2642
+ ctx.lineWidth = 1;
2643
+ ctx.strokeStyle = playerNeedleTimeTop.rgba;
2644
+ ctx.stroke();
2645
+ };
2646
+
2647
+ /* *
2648
+ * Licensed under the Apache License, Version 2.0 (the "License");
2649
+ * you may not use this file except in compliance with the License.
2650
+ * You may obtain a copy of the License at
2651
+ *
2652
+ * http://www.apache.org/licenses/LICENSE-2.0
2653
+ *
2654
+ * Unless required by applicable law or agreed to in writing, software
2655
+ * distributed under the License is distributed on an "AS IS" BASIS,
2656
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2657
+ * See the License for the specific language governing permissions and
2658
+ * limitations under the License.
2659
+ *
2660
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2661
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
2662
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
2663
+ * */
2664
+ var drawBackground = function drawBackground(context, theme, visibleTimeStart, visibleTimeEnd, animationStartPx, animationEndPx, canvasWidth, height, secondsPerPx, timeSliderSpan, dataStartPx, dataEndPx, currentTimePx) {
2665
+ var ctx = context;
2666
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
2667
+ timelineNightTime = _theme$palette$geoweb.timelineNightTime,
2668
+ ledgendObservedBackground = _theme$palette$geoweb.ledgendObservedBackground,
2669
+ legendForecastBackground = _theme$palette$geoweb.legendForecastBackground,
2670
+ legendNoDataBackground = _theme$palette$geoweb.legendNoDataBackground;
2671
+ // top spacing
2672
+ var y = 0;
2673
+ var scaleToUse = timeSliderSpan ? getScaleFromSpan(timeSliderSpan) : getFundamentalScale(secondsPerPx);
2674
+ drawDefaultBackground();
2675
+ drawObservedData();
2676
+ drawForecastData();
2677
+ drawNightOrAlternateTime();
2678
+ drawAnimationArea();
2679
+ drawDraggableIcons();
2680
+ function drawDefaultBackground() {
2681
+ ctx.fillStyle = legendNoDataBackground.rgba;
2682
+ ctx.fillRect(0, y, canvasWidth, height);
2683
+ }
2684
+ function drawObservedData() {
2685
+ if (dataStartPx < currentTimePx) {
2686
+ ctx.fillStyle = ledgendObservedBackground.fill;
2687
+ ctx.fillRect(Math.max(dataStartPx, y), y, Math.min(currentTimePx, dataEndPx) - Math.max(dataStartPx, y), height);
2688
+ }
2689
+ }
2690
+ function drawForecastData() {
2691
+ if (dataEndPx > currentTimePx) {
2692
+ ctx.fillStyle = legendForecastBackground.fill;
2693
+ ctx.fillRect(Math.max(currentTimePx, dataStartPx), y, Math.min(canvasWidth, dataEndPx) - Math.max(currentTimePx, dataStartPx), height);
2694
+ }
2695
+ }
2696
+ function drawAnimationArea() {
2697
+ ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineSelectionBackground.rgba;
2698
+ ctx.strokeStyle = theme.palette.geowebColors.timeSlider.timelineSelectionOutline.rgba;
2699
+ ctx.lineWidth = 3;
2700
+ ctx.rect(animationStartPx, y, Math.max(animationEndPx - animationStartPx, y), height);
2701
+ ctx.fill();
2702
+ ctx.stroke();
2703
+ }
2704
+ function drawDraggableIcons() {
2705
+ ctx.save();
2706
+ var path = new Path2D(dragHandlePath);
2707
+ ctx.translate(animationStartPx, y);
2708
+ ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
2709
+ ctx.fill(path);
2710
+ ctx.restore();
2711
+ ctx.save();
2712
+ ctx.translate(animationEndPx - 24, y);
2713
+ ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
2714
+ ctx.fill(path);
2715
+ ctx.restore();
2716
+ }
2717
+ function drawNightOrAlternateTime() {
2718
+ var colorChangeTimesteps = getColorChangeTimesteps(scaleToUse, visibleTimeStart, visibleTimeEnd);
2719
+ colorChangeTimesteps.forEach(function (timestep, i, arr) {
2720
+ if (i === 0) {
2721
+ return;
2722
+ }
2723
+ var _map = [arr[i - 1], timestep].map(function (timestep) {
2724
+ return timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
2725
+ }),
2726
+ prevPx = _map[0],
2727
+ currPx = _map[1];
2728
+ if (!isColorIntervalEven(scaleToUse, timestep)) {
2729
+ ctx.fillStyle = timelineNightTime.rgba;
2730
+ var TOP_OFFSET = 0;
2731
+ ctx.fillRect(prevPx, TOP_OFFSET, currPx - prevPx, height);
2732
+ }
2733
+ });
2734
+ }
2735
+ };
2736
+ var getColorChangeTimestepUnit = function getColorChangeTimestepUnit(scale) {
2737
+ switch (scale) {
2738
+ case Scale.Year:
2739
+ return 'months';
2740
+ case Scale.Month:
2741
+ case Scale.Months3:
2742
+ return 'weeks';
2743
+ case Scale.Weeks2:
2744
+ case Scale.Week:
2745
+ return 'days';
2746
+ default:
2747
+ return 'days';
2748
+ }
2749
+ };
2750
+ var isColorIntervalEven = function isColorIntervalEven(scale, timestep) {
2751
+ var time = dateUtils.fromUnix(timestep);
2752
+ switch (scale) {
2753
+ case Scale.Year:
2754
+ return dateUtils.getMonth(time) % 2 === 0;
2755
+ case Scale.Month:
2756
+ case Scale.Months3:
2757
+ return dateUtils.getWeek(time) % 2 === 0;
2758
+ case Scale.Week:
2759
+ case Scale.Weeks2:
2760
+ return dateUtils.getDayOfYear(time) % 2 === 0;
2761
+ default:
2762
+ {
2763
+ return dateUtils.getDayOfYear(time) % 2 === 0;
2764
+ }
2765
+ }
2766
+ };
2767
+ function getColorChangeTimesteps(scale, visibleTimeStart, visibleTimeEnd) {
2768
+ var _getCustomRoundedStar = getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, scale),
2769
+ colorChangeStart = _getCustomRoundedStar[0],
2770
+ colorChangeEnd = _getCustomRoundedStar[1];
2771
+ var colorChangeUnit = getColorChangeTimestepUnit(scale);
2772
+ var colorChangeTimesteps = getCustomTimesteps(colorChangeStart, colorChangeEnd, colorChangeUnit);
2773
+ return colorChangeTimesteps;
2774
+ }
2775
+
2776
+ /* *
2777
+ * Licensed under the Apache License, Version 2.0 (the "License");
2778
+ * you may not use this file except in compliance with the License.
2779
+ * You may obtain a copy of the License at
2780
+ *
2781
+ * http://www.apache.org/licenses/LICENSE-2.0
2782
+ *
2783
+ * Unless required by applicable law or agreed to in writing, software
2784
+ * distributed under the License is distributed on an "AS IS" BASIS,
2785
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2786
+ * See the License for the specific language governing permissions and
2787
+ * limitations under the License.
2788
+ *
2789
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2790
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
2791
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
2792
+ * */
2793
+ var drawTimeSliderLegend = function drawTimeSliderLegend(context, theme, canvasWidth, height, centerTime, secondsPerPx, timeSliderSpan, selectedTimeUnix, currentTimeUnix, animationStartTime, animationEndTime, dataStartTime, dataEndTime) {
2794
+ var ctx = context;
2795
+ var _map = [0, canvasWidth].map(function (px) {
2796
+ return pixelToTimestamp(px, centerTime, canvasWidth, secondsPerPx);
2797
+ }),
2798
+ visibleTimeStart = _map[0],
2799
+ visibleTimeEnd = _map[1];
2800
+ var _map2 = [animationStartTime, animationEndTime, dataStartTime, dataEndTime, currentTimeUnix].map(function (time) {
2801
+ return timestampToPixel(time, centerTime, canvasWidth, secondsPerPx);
2802
+ }),
2803
+ animationStartPx = _map2[0],
2804
+ animationEndPx = _map2[1],
2805
+ dataStartPx = _map2[2],
2806
+ dataEndPx = _map2[3],
2807
+ currentTimePx = _map2[4];
2808
+ ctx.clearRect(0, 0, canvasWidth, height);
2809
+ drawBackground(ctx, theme, visibleTimeStart, visibleTimeEnd, animationStartPx, animationEndPx, canvasWidth, height, secondsPerPx, timeSliderSpan, dataStartPx, dataEndPx, currentTimePx);
2810
+ drawTimeScale(ctx, theme, visibleTimeStart, visibleTimeEnd, canvasWidth, height, secondsPerPx);
2811
+ drawCurrentTime(ctx, theme, canvasWidth, height, visibleTimeStart, visibleTimeEnd, currentTimeUnix);
2812
+ drawNeedle(ctx, theme, canvasWidth, height, visibleTimeStart, visibleTimeEnd, selectedTimeUnix);
2813
+ };
2814
+
2815
+ // Explanation of props can be found here:
2816
+ // https://drive.google.com/file/d/1jqqNcciCH0UJiZ04HO-1vknmPPpT8fK5/view?usp=sharing
2817
+ var TimeSliderLegend = function TimeSliderLegend(_ref) {
2818
+ var _node$current, _getTimeSliderLegendE;
2819
+ var mapId = _ref.mapId,
2820
+ isTimeScrollingEnabled = _ref.isTimeScrollingEnabled,
2821
+ mapWindowRef = _ref.mapWindowRef,
2822
+ centerTime = _ref.centerTime,
2823
+ canvasWidth = _ref.timeSliderWidth,
2824
+ _ref$secondsPerPx = _ref.secondsPerPx,
2825
+ secondsPerPx = _ref$secondsPerPx === void 0 ? defaultSecondsPerPx : _ref$secondsPerPx,
2826
+ currentTime = _ref.currentTime,
2827
+ dataStartTime = _ref.dataStartTime,
2828
+ dataEndTime = _ref.dataEndTime,
2829
+ reduxAnimationStartTime = _ref.reduxAnimationStartTime,
2830
+ reduxAnimationEndTime = _ref.reduxAnimationEndTime,
2831
+ timeStep = _ref.timeStep,
2832
+ unfilteredSelectedTime = _ref.unfilteredSelectedTime,
2833
+ isDraggingStartAnimation = _ref.isDraggingStartAnimation,
2834
+ isDraggingEndAnimation = _ref.isDraggingEndAnimation,
2835
+ isTimeSliderHoverOn = _ref.isTimeSliderHoverOn,
2836
+ timeSliderSpan = _ref.timeSliderSpan,
2837
+ _ref$setUnfilteredSel = _ref.setUnfilteredSelectedTime,
2838
+ setUnfilteredSelectedTime = _ref$setUnfilteredSel === void 0 ? function () {} : _ref$setUnfilteredSel,
2839
+ _ref$onSetCenterTime = _ref.onSetCenterTime,
2840
+ onSetCenterTime = _ref$onSetCenterTime === void 0 ? function () {} : _ref$onSetCenterTime,
2841
+ _ref$onSetAnimationSt = _ref.onSetAnimationStartTime,
2842
+ onSetAnimationStartTime = _ref$onSetAnimationSt === void 0 ? function () {} : _ref$onSetAnimationSt,
2843
+ _ref$onSetAnimationEn = _ref.onSetAnimationEndTime,
2844
+ onSetAnimationEndTime = _ref$onSetAnimationEn === void 0 ? function () {} : _ref$onSetAnimationEn,
2845
+ _ref$updateCanvasWidt = _ref.updateCanvasWidth,
2846
+ updateCanvasWidth = _ref$updateCanvasWidt === void 0 ? function () {} : _ref$updateCanvasWidt,
2847
+ setIsDraggingStartAnimation = _ref.setIsDraggingStartAnimation,
2848
+ setIsDraggingEndAnimation = _ref.setIsDraggingEndAnimation,
2849
+ onStartTimeChange = _ref.onStartTimeChange,
2850
+ onEndTimeChange = _ref.onEndTimeChange,
2851
+ onSetTimeSliderSpan = _ref.onSetTimeSliderSpan,
2852
+ _ref$adjustSelectedTi = _ref.adjustSelectedTimeOnWheel,
2853
+ adjustSelectedTimeOnWheel = _ref$adjustSelectedTi === void 0 ? function () {} : _ref$adjustSelectedTi;
2854
+ var _useCanvasTarget = useCanvasTarget('mousedown'),
2855
+ node = _useCanvasTarget[1];
2856
+ var theme = useTheme();
2857
+ var _useState = useState(false),
2858
+ isDraggingSelectedTime = _useState[0],
2859
+ setIsDraggingSelectedTime = _useState[1];
2860
+ var _useState2 = useState(false),
2861
+ isDraggingLegend = _useState2[0],
2862
+ setIsDraggingLegend = _useState2[1];
2863
+ var xOffset = ((_node$current = node.current) == null || (_node$current = _node$current.canvas) == null ? void 0 : _node$current.getBoundingClientRect().x) || 0;
2864
+ var _useState3 = useState(false),
2865
+ isDraggingAnimationArea = _useState3[0],
2866
+ setIsDraggingAnimationArea = _useState3[1];
2867
+ var _useState4 = useState(false),
2868
+ isMouseOverCanvas = _useState4[0],
2869
+ setIsMouseOverCanvas = _useState4[1];
2870
+ var _useState5 = useState('auto'),
2871
+ cursorStyle = _useState5[0],
2872
+ setCursorStyle = _useState5[1];
2873
+ var _useState6 = useState(undefined),
2874
+ showTooltip = _useState6[0],
2875
+ setShowTooltip = _useState6[1];
2876
+ var _useState7 = useState(),
2877
+ lastHandledRoundedTime = _useState7[0],
2878
+ setLastHandledRoundedTime = _useState7[1];
2879
+ // remove active drag. can happen outside canvas.
2880
+ var _useState8 = useState(),
2881
+ localAnimationStartTime = _useState8[0],
2882
+ setLocalAnimationStartTime = _useState8[1];
2883
+ var _useState9 = useState(),
2884
+ localAnimationEndTime = _useState9[0],
2885
+ setLocalAnimationEndTime = _useState9[1];
2886
+ var _useState0 = useState(),
2887
+ pointerTime = _useState0[0],
2888
+ setPointerTime = _useState0[1];
2889
+ var _useState1 = useState(false),
2890
+ showPointerTimeTooltip = _useState1[0],
2891
+ setShowPointerTimeTooltip = _useState1[1];
2892
+ var debouncedSetShowPointerTimeTooltip = useRef(debounce(setShowPointerTimeTooltip, 500)).current;
2893
+ var timeBetweenMouseAndStartAndEnd = useRef();
2894
+ var pixelsMovedSinceStartDragging = useRef(0);
2895
+ var isAnimationTimeModifiedSetRef = useRef(false);
2896
+ var tooltipPosition = useRef();
2897
+ var startDraggingPosition = useRef(0);
2898
+ var popperRef = useRef(null);
2899
+ var isClickOrDrag = useRef();
2900
+ var filteredTime = getFilteredTime(unfilteredSelectedTime, timeStep, dataStartTime, dataEndTime);
2901
+ var start = localAnimationStartTime;
2902
+ var end = localAnimationEndTime;
2903
+ var pixelsBetweenViewportAndTimesliderOnTop = (_getTimeSliderLegendE = getTimeSliderLegendElement(mapId)) == null ? void 0 : _getTimeSliderLegendE.getBoundingClientRect()['top'];
2904
+ var setTooltipPosition = function setTooltipPosition() {
2905
+ var tooltipX = tooltipPosition.current;
2906
+ var tooltipY = pixelsBetweenViewportAndTimesliderOnTop && pixelsBetweenViewportAndTimesliderOnTop - TIME_SLIDER_LEGEND_HEIGHT * 2.5;
2907
+ return new DOMRect(tooltipX, tooltipY, 0, 0);
2908
+ };
2909
+ var getTooltipTime = function getTooltipTime() {
2910
+ switch (showTooltip) {
2911
+ case 'animationStart':
2912
+ return localAnimationStartTime;
2913
+ case 'animationEnd':
2914
+ return localAnimationEndTime;
2915
+ case 'mousePointer':
2916
+ return pointerTime;
2917
+ default:
2918
+ return undefined;
2919
+ }
2920
+ };
2921
+ var getTooltipText = function getTooltipText() {
2922
+ var time = getTooltipTime();
2923
+ if (!time) {
2924
+ return undefined;
2925
+ }
2926
+ var roundedTooltipTime = showTooltip === 'mousePointer' ? time : roundWithTimeStep$1(time);
2927
+ var tooltipText = dateUtils.dateToString(dateUtils.fromUnix(roundedTooltipTime), dateUtils.DATE_FORMAT_HOURS);
2928
+ return tooltipText;
2929
+ };
2930
+ var roundWithTimeStep$1 = function roundWithTimeStep$1(time) {
2931
+ return roundWithTimeStep(time, timeStep);
2932
+ };
2933
+ var currentIndex = timeValues.indexOf(timeSliderSpan);
2934
+ var updateTimeSpan = function updateTimeSpan(deltaY) {
2935
+ if (onSetTimeSliderSpan) {
2936
+ // Don't do anything if we are already at the edges of the timespan options
2937
+ if (deltaY < 0 && currentIndex === 0 || deltaY > 0 && currentIndex === timeValues.length - 1) {
2938
+ return;
2939
+ }
2940
+ var newTimeSpan = deltaY < 0 ? timeValues[currentIndex - 1] : timeValues[currentIndex + 1];
2941
+ onSetTimeSliderSpan(newTimeSpan, centerTime);
2942
+ }
2943
+ };
2944
+ var throttledUpdateTimeSpan = throttle(updateTimeSpan, 200);
2945
+ var debouncedAndThrottledUpdateTimeSpan = debounce(throttledUpdateTimeSpan, 20);
2946
+ var handleAnimationDragging = React.useCallback(function (x, clientX) {
2947
+ if (!localAnimationStartTime || !localAnimationEndTime) {
2948
+ return;
2949
+ }
2950
+ var mousePosition = clientX - xOffset;
2951
+ var startPos = timestampToPixel(localAnimationStartTime, centerTime, canvasWidth, secondsPerPx);
2952
+ var endPos = timestampToPixel(localAnimationEndTime, centerTime, canvasWidth, secondsPerPx);
2953
+ var mouseTimeUnix = pixelToTimestamp(mousePosition, centerTime, canvasWidth, secondsPerPx);
2954
+ var startTime = roundWithTimeStep(mouseTimeUnix, timeStep);
2955
+ var endTime = roundWithTimeStep(mouseTimeUnix, timeStep);
2956
+ var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
2957
+ if (isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
2958
+ if (!isAnimationTimeModifiedSetRef.current) {
2959
+ isAnimationTimeModifiedSetRef.current = true;
2960
+ }
2961
+ }
2962
+ if (isDraggingStartAnimation) {
2963
+ if (isDraggingStartWithinBounds(endPos, mousePosition)) {
2964
+ return;
2965
+ }
2966
+ setLocalAnimationStartTime(roundWithTimeStep(mouseTimeUnix, timeStep));
2967
+ if (lastHandledRoundedTime !== startTime) {
2968
+ setLastHandledRoundedTime(startTime);
2969
+ setShowTooltip('animationStart');
2970
+ onStartTimeChange && onStartTimeChange(startTime);
2971
+ }
2972
+ } else if (isDraggingEndAnimation && pixelsBetweenOnLeft) {
2973
+ if (isDraggingEndWithinBounds(startPos, mousePosition, canvasWidth)) {
2974
+ return;
2975
+ }
2976
+ setLocalAnimationEndTime(roundWithTimeStep(mouseTimeUnix, timeStep));
2977
+ if (lastHandledRoundedTime !== endTime) {
2978
+ setLastHandledRoundedTime(endTime);
2979
+ setShowTooltip('animationEnd');
2980
+ onEndTimeChange && onEndTimeChange(endTime);
2981
+ }
2982
+ }
2983
+ if (isDraggingAnimationArea) {
2984
+ if (timeBetweenMouseAndStartAndEnd.current === undefined) {
2985
+ // to move the whole animation area we need to calculate the distance
2986
+ // between the mouse position and the start and end position
2987
+ var _timeFromMouseToStart = mouseTimeUnix - start;
2988
+ var _timeFromMouseToEnd = end - mouseTimeUnix;
2989
+ timeBetweenMouseAndStartAndEnd.current = {
2990
+ timeFromMouseToEnd: _timeFromMouseToEnd,
2991
+ timeFromMouseToStart: _timeFromMouseToStart
2992
+ };
2993
+ return;
2994
+ }
2995
+ pixelsMovedSinceStartDragging.current += x;
2996
+ var _timeBetweenMouseAndS = timeBetweenMouseAndStartAndEnd.current,
2997
+ timeFromMouseToEnd = _timeBetweenMouseAndS.timeFromMouseToEnd,
2998
+ timeFromMouseToStart = _timeBetweenMouseAndS.timeFromMouseToStart;
2999
+ var newStartTime = mouseTimeUnix - timeFromMouseToStart;
3000
+ var newEndTime = mouseTimeUnix + timeFromMouseToEnd;
3001
+ var roundedNewStartTime = roundWithTimeStep(newStartTime, timeStep);
3002
+ var roundedNewEndTime = roundWithTimeStep(newEndTime, timeStep);
3003
+ setLocalAnimationStartTime(roundedNewStartTime);
3004
+ setLocalAnimationEndTime(roundedNewEndTime);
3005
+ }
3006
+ }, [canvasWidth, centerTime, end, isDraggingAnimationArea, isDraggingEndAnimation, isDraggingStartAnimation, lastHandledRoundedTime, localAnimationEndTime, localAnimationStartTime, mapId, onEndTimeChange, onStartTimeChange, secondsPerPx, start, timeStep, xOffset]);
3007
+ useEffect(function () {
3008
+ var handleMouseUp = function handleMouseUp() {
3009
+ pixelsMovedSinceStartDragging.current = 0;
3010
+ timeBetweenMouseAndStartAndEnd.current = undefined;
3011
+ };
3012
+ document.addEventListener('mouseup', handleMouseUp);
3013
+ return function () {
3014
+ document.removeEventListener('mouseup', handleMouseUp);
3015
+ };
3016
+ }, []);
3017
+ useEffect(function () {
3018
+ var startTimestamp = convertStringTimeToUnix(reduxAnimationStartTime);
3019
+ var endTimestamp = convertStringTimeToUnix(reduxAnimationEndTime);
3020
+ setLocalAnimationStartTime(startTimestamp);
3021
+ setLocalAnimationEndTime(endTimestamp);
3022
+ }, [reduxAnimationStartTime, reduxAnimationEndTime, setLocalAnimationStartTime, setLocalAnimationEndTime]);
3023
+ useEffect(function () {
3024
+ var stoppedDragging = !isDraggingStartAnimation && !isDraggingEndAnimation && !isDraggingAnimationArea;
3025
+ if (stoppedDragging && isAnimationTimeModifiedSetRef.current) {
3026
+ if (start && start !== localAnimationStartTime) {
3027
+ onSetAnimationStartTime(dateUtils.fromUnix(start).toISOString());
3028
+ }
3029
+ if (end && end !== localAnimationEndTime) {
3030
+ onSetAnimationEndTime(dateUtils.fromUnix(end).toISOString());
3031
+ }
3032
+ isAnimationTimeModifiedSetRef.current = false;
3033
+ }
3034
+ }, [isDraggingStartAnimation, isDraggingEndAnimation, isDraggingAnimationArea, isAnimationTimeModifiedSetRef, localAnimationStartTime, localAnimationEndTime, onSetAnimationStartTime, onSetAnimationEndTime, start, end]);
3035
+ useEffect(function () {
3036
+ var handleMouseUp = function handleMouseUp() {
3037
+ if (isDraggingAnimationArea) {
3038
+ onStartTimeChange && onStartTimeChange(localAnimationStartTime);
3039
+ onEndTimeChange && onEndTimeChange(localAnimationEndTime);
3040
+ }
3041
+ setCursorStyle('auto');
3042
+ setIsDraggingSelectedTime(false);
3043
+ setIsDraggingStartAnimation && setIsDraggingStartAnimation(false);
3044
+ setIsDraggingEndAnimation && setIsDraggingEndAnimation(false);
3045
+ setIsDraggingLegend(false);
3046
+ setShowTooltip(undefined);
3047
+ setIsDraggingAnimationArea(false);
3048
+ startDraggingPosition.current = 0;
3049
+ if (isAnimationTimeModifiedSetRef.current) {
3050
+ isAnimationTimeModifiedSetRef.current = false;
3051
+ }
3052
+ };
3053
+ document.addEventListener('mouseup', handleMouseUp);
3054
+ return function () {
3055
+ document.removeEventListener('mouseup', handleMouseUp);
3056
+ };
3057
+ }, [setIsDraggingStartAnimation, setIsDraggingEndAnimation, localAnimationStartTime, localAnimationEndTime, onStartTimeChange, onEndTimeChange, isDraggingAnimationArea]);
3058
+ useEffect(function () {
3059
+ var handleMouseActions = function handleMouseActions(event) {
3060
+ if (event.movementX === 0) {
3061
+ return;
3062
+ }
3063
+ if (isDraggingLegend) {
3064
+ var dragDistanceTime = event.movementX * secondsPerPx;
3065
+ var newCenterTime = centerTime - dragDistanceTime;
3066
+ onSetCenterTime(newCenterTime);
3067
+ } else if (isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
3068
+ handleAnimationDragging(event.movementX, event.clientX);
3069
+ } else if (isDraggingSelectedTime) {
3070
+ moveSelectedTimePx(event.movementX, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
3071
+ }
3072
+ if (isMouseOverCanvas && isTimeSliderHoverOn) {
3073
+ moveSelectedTimePx(event.movementX, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
3074
+ }
3075
+ };
3076
+ var handleMouseMove = function handleMouseMove(event) {
3077
+ handleMouseActions(event);
3078
+ };
3079
+ document.addEventListener('mousemove', handleMouseMove);
3080
+ return function () {
3081
+ document.removeEventListener('mousemove', handleMouseMove);
3082
+ };
3083
+ }, [isDraggingLegend, isDraggingStartAnimation, isDraggingEndAnimation, isDraggingAnimationArea, isDraggingSelectedTime, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime, onSetCenterTime, isTimeSliderHoverOn, isMouseOverCanvas, handleAnimationDragging]);
3084
+ useEffect(function () {
3085
+ if (!showTooltip && pointerTime) {
3086
+ if (showPointerTimeTooltip) {
3087
+ setShowTooltip('mousePointer');
3088
+ } else {
3089
+ debouncedSetShowPointerTimeTooltip(true);
3090
+ }
3091
+ } else if (showTooltip === 'mousePointer' && !pointerTime) {
3092
+ setShowTooltip(undefined);
3093
+ debouncedSetShowPointerTimeTooltip(false);
3094
+ debouncedSetShowPointerTimeTooltip.flush();
3095
+ } else if (showTooltip !== 'mousePointer') {
3096
+ debouncedSetShowPointerTimeTooltip(false);
3097
+ debouncedSetShowPointerTimeTooltip.flush();
3098
+ }
3099
+ }, [debouncedSetShowPointerTimeTooltip, pointerTime, showPointerTimeTooltip, showTooltip]);
3100
+ var onMouseDown = function onMouseDown(x, y, width) {
3101
+ isClickOrDrag.current = 'click';
3102
+ startDraggingPosition.current = x;
3103
+ var _getPositions = getPositions(width, unfilteredSelectedTime, centerTime, secondsPerPx, start, end),
3104
+ startAnimationPosition = _getPositions.startAnimationPosition,
3105
+ endAnimationPosition = _getPositions.endAnimationPosition,
3106
+ selectedTimePosition = _getPositions.selectedTimePosition;
3107
+ // start dragging selected time.
3108
+ if (isSelectedTimeIconArea(x, selectedTimePosition, DRAG_AREA_WIDTH)) {
3109
+ setCursorStyle('grabbing');
3110
+ setIsDraggingSelectedTime(true);
3111
+ return;
3112
+ }
3113
+ if (reduxAnimationStartTime && reduxAnimationEndTime) {
3114
+ var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
3115
+ tooltipPosition.current = pixelsBetweenOnLeft ? x + pixelsBetweenOnLeft : x;
3116
+ // start dragging either marker
3117
+ if (isLeftAnimationIconArea(x, startAnimationPosition, DRAG_AREA_WIDTH)) {
3118
+ setCursorStyle('grabbing');
3119
+ setIsDraggingStartAnimation && setIsDraggingStartAnimation(true);
3120
+ setShowTooltip('animationStart');
3121
+ return;
3122
+ }
3123
+ if (isRightAnimationIconArea(x, endAnimationPosition, DRAG_AREA_WIDTH)) {
3124
+ setCursorStyle('grabbing');
3125
+ setIsDraggingEndAnimation && setIsDraggingEndAnimation(true);
3126
+ setShowTooltip('animationEnd');
3127
+ return;
3128
+ }
3129
+ if (isInsideAnimationArea(x, startAnimationPosition, endAnimationPosition)) {
3130
+ setCursorStyle('grabbing');
3131
+ setIsDraggingAnimationArea(true);
3132
+ return;
3133
+ }
3134
+ }
3135
+ // clicking the timeslider
3136
+ setIsDraggingLegend(true);
3137
+ };
3138
+ var onMouseUp = function onMouseUp(x) {
3139
+ if (isClickOrDrag.current === 'click') {
3140
+ var unfilteredSelectedTimePx = timestampToPixel(unfilteredSelectedTime, centerTime, canvasWidth, secondsPerPx);
3141
+ moveSelectedTimePx(x - unfilteredSelectedTimePx, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
3142
+ }
3143
+ isClickOrDrag.current = undefined;
3144
+ };
3145
+ var onMouseMove = function onMouseMove(x, y, event, width) {
3146
+ var mousePosition = x;
3147
+ setPointerTime(pixelToTimestamp(mousePosition, centerTime, canvasWidth, secondsPerPx));
3148
+ var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
3149
+ tooltipPosition.current = pixelsBetweenOnLeft && mousePosition + pixelsBetweenOnLeft;
3150
+ if (isClickOrDrag.current === 'click') {
3151
+ isClickOrDrag.current = 'drag';
3152
+ }
3153
+ if (isDraggingSelectedTime || isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
3154
+ return;
3155
+ }
3156
+ var _getPositions2 = getPositions(width, unfilteredSelectedTime, centerTime, secondsPerPx, start, end),
3157
+ startAnimationPosition = _getPositions2.startAnimationPosition,
3158
+ endAnimationPosition = _getPositions2.endAnimationPosition,
3159
+ selectedTimePosition = _getPositions2.selectedTimePosition;
3160
+ // Adjust mouse cursor while hovering draggable areas
3161
+ var leftAnimationIconArea = isLeftAnimationIconArea(x, startAnimationPosition, DRAG_AREA_WIDTH);
3162
+ var rightAnimationIconArea = isRightAnimationIconArea(x, endAnimationPosition, DRAG_AREA_WIDTH);
3163
+ var selectedTimeArea = isSelectedTimeIconArea(x, selectedTimePosition, DRAG_AREA_WIDTH);
3164
+ var insideAnimationArea = isInsideAnimationArea(x, startAnimationPosition, endAnimationPosition);
3165
+ var hoveringLegendHandles = leftAnimationIconArea || rightAnimationIconArea || selectedTimeArea || isDraggingLegend;
3166
+ if (hoveringLegendHandles) {
3167
+ setCursorStyle('ew-resize');
3168
+ } else if (insideAnimationArea && !isDraggingAnimationArea) {
3169
+ setCursorStyle('grab');
3170
+ } else if (insideAnimationArea && isDraggingAnimationArea) {
3171
+ setCursorStyle('grabbing');
3172
+ } else {
3173
+ setCursorStyle('auto');
3174
+ }
3175
+ };
3176
+ var onWheel = React.useCallback(function (_ref2) {
3177
+ var event = _ref2.event,
3178
+ deltaY = _ref2.deltaY;
3179
+ event.preventDefault();
3180
+ if (event.ctrlKey || event.metaKey) {
3181
+ debouncedAndThrottledUpdateTimeSpan(deltaY);
3182
+ }
3183
+ }, [debouncedAndThrottledUpdateTimeSpan]);
3184
+ var onWheelOverCanvas = React.useCallback(function (props) {
3185
+ onWheel(props);
3186
+ adjustSelectedTimeOnWheel(props);
3187
+ }, [adjustSelectedTimeOnWheel, onWheel]);
3188
+ React.useEffect(function () {
3189
+ if (isTimeScrollingEnabled && mapWindowRef != null && mapWindowRef.current) {
3190
+ var handleWheel = function handleWheel(event) {
3191
+ event.preventDefault();
3192
+ onWheel({
3193
+ event: event,
3194
+ deltaY: event.deltaY
3195
+ });
3196
+ };
3197
+ var element = mapWindowRef.current;
3198
+ element.addEventListener('wheel', handleWheel);
3199
+ return function () {
3200
+ element.removeEventListener('wheel', handleWheel);
3201
+ };
3202
+ }
3203
+ return undefined;
3204
+ }, [isTimeScrollingEnabled, mapWindowRef, onWheel]);
3205
+ return jsxs(Box, {
3206
+ sx: {
3207
+ position: 'relative',
3208
+ height: TIME_SLIDER_LEGEND_HEIGHT + "px"
3209
+ },
3210
+ children: [jsx(CustomTooltip, {
3211
+ title: getTooltipText(),
3212
+ open: Boolean(showTooltip),
3213
+ PopperProps: {
3214
+ popperRef: popperRef,
3215
+ anchorEl: {
3216
+ getBoundingClientRect: setTooltipPosition
3217
+ }
3218
+ },
3219
+ children: jsx(Box, {
3220
+ "data-testid": "timeSliderLegend",
3221
+ className: getTimeSliderLegendId(mapId),
3222
+ sx: {
3223
+ height: TIME_SLIDER_LEGEND_HEIGHT + "px",
3224
+ borderRadius: '4.5px',
3225
+ overflow: 'hidden',
3226
+ cursor: cursorStyle
3227
+ },
3228
+ onMouseLeave: function onMouseLeave() {
3229
+ setPointerTime(undefined);
3230
+ },
3231
+ children: jsx(CanvasComponent, {
3232
+ ref: node,
3233
+ onMouseMove: onMouseMove,
3234
+ onWheel: onWheelOverCanvas,
3235
+ onMouseDown: onMouseDown,
3236
+ onMouseUp: onMouseUp,
3237
+ onRenderCanvas: function onRenderCanvas(ctx, width, height) {
3238
+ updateCanvasWidth(canvasWidth, width);
3239
+ drawTimeSliderLegend(ctx, theme, width, height, centerTime, secondsPerPx, timeSliderSpan, filteredTime, currentTime, start, end, dataStartTime, dataEndTime);
3240
+ }
3241
+ })
3242
+ })
3243
+ }), isTimeSliderHoverOn && jsx(Box, {
3244
+ "data-testid": "customCanvasMouseOverContainer",
3245
+ sx: {
3246
+ position: 'absolute',
3247
+ top: '-40px',
3248
+ left: 0,
3249
+ right: 0,
3250
+ bottom: 0,
3251
+ height: TIME_SLIDER_LEGEND_HEIGHT + " + 40px",
3252
+ zIndex: isMouseOverCanvas ? 100 : 0
3253
+ },
3254
+ onMouseOver: function onMouseOver() {
3255
+ return setIsMouseOverCanvas(true);
3256
+ },
3257
+ onMouseLeave: function onMouseLeave() {
3258
+ return setIsMouseOverCanvas(false);
3259
+ }
3260
+ })]
3261
+ });
3262
+ };
3263
+
3264
+ var OptionsMenuButton = function OptionsMenuButton(_ref) {
3265
+ var speedBtn = _ref.speedBtn,
3266
+ timeStepBtn = _ref.timeStepBtn,
3267
+ timeSpanBtn = _ref.timeSpanBtn,
3268
+ animationLengthBtn = _ref.animationLengthBtn,
3269
+ _ref$isOpenByDefault = _ref.isOpenByDefault,
3270
+ isOpenByDefault = _ref$isOpenByDefault === void 0 ? false : _ref$isOpenByDefault;
3271
+ var _useState = useState(null),
3272
+ anchorEl = _useState[0],
3273
+ setAnchorEl = _useState[1];
3274
+ var _useState2 = useState(false),
3275
+ open = _useState2[0],
3276
+ setOpen = _useState2[1];
3277
+ var _useTimesliderTransla = useTimesliderTranslation(),
3278
+ t = _useTimesliderTransla.t;
3279
+ useEffect(function () {
3280
+ if (anchorEl && isOpenByDefault) {
3281
+ setOpen(true);
3282
+ }
3283
+ }, [anchorEl, isOpenByDefault]);
3284
+ return jsxs("div", {
3285
+ children: [jsx(CustomIconButton, {
3286
+ variant: "tool",
3287
+ onClick: function onClick() {
3288
+ setOpen(!open);
3289
+ },
3290
+ "data-testid": "optionsMenuButton",
3291
+ isSelected: open,
3292
+ "aria-label": "animation options",
3293
+ tooltipProps: {
3294
+ title: t('timeslider-animation-options'),
3295
+ placement: 'bottom'
3296
+ },
3297
+ ref: function ref(_ref2) {
3298
+ setAnchorEl(_ref2);
3299
+ },
3300
+ children: jsx(Options, {})
3301
+ }), jsx(Popper, {
3302
+ sx: {
3303
+ zIndex: 10
3304
+ },
3305
+ placement: "top-start",
3306
+ open: open,
3307
+ "data-testid": "optionsMenuPopOver",
3308
+ anchorEl: anchorEl,
3309
+ children: jsx(Paper, {
3310
+ elevation: 3,
3311
+ sx: {
3312
+ position: 'relative',
3313
+ top: '-2rem'
3314
+ },
3315
+ children: jsx(Grid, {
3316
+ sx: {
3317
+ padding: '10px'
3318
+ },
3319
+ container: true,
3320
+ spacing: 1,
3321
+ children: jsx(OptionsMenu, {
3322
+ timeSpanBtn: timeSpanBtn,
3323
+ timeStepBtn: timeStepBtn,
3324
+ speedBtn: speedBtn,
3325
+ animationLengthBtn: animationLengthBtn
3326
+ })
3327
+ })
3328
+ })
3329
+ })]
3330
+ });
3331
+ };
3332
+
3333
+ var TimeSliderButtons = function TimeSliderButtons(_ref) {
3334
+ var optionsMenuBtn = _ref.optionsMenuBtn,
3335
+ playBtn = _ref.playBtn,
3336
+ backwardBtn = _ref.backwardBtn,
3337
+ forwardBtn = _ref.forwardBtn,
3338
+ nowBtn = _ref.nowBtn,
3339
+ autoUpdateBtn = _ref.autoUpdateBtn;
3340
+ return jsx("div", {
3341
+ "data-testid": "timeSliderButtons",
3342
+ children: jsxs(Grid, {
3343
+ container: true,
3344
+ spacing: 0.5,
3345
+ sx: {
3346
+ alignItems: 'center',
3347
+ justifyContent: 'center'
3348
+ },
3349
+ children: [jsx(Grid, {
3350
+ children: optionsMenuBtn || jsx(OptionsMenuButton, {})
3351
+ }), jsx(ControlButtons, {
3352
+ backwardBtn: backwardBtn,
3353
+ forwardBtn: forwardBtn,
3354
+ playBtn: playBtn,
3355
+ nowBtn: nowBtn,
3356
+ autoUpdateBtn: autoUpdateBtn
3357
+ })]
3358
+ })
3359
+ });
3360
+ };
3361
+
3362
+ /* *
3363
+ * Licensed under the Apache License, Version 2.0 (the "License");
3364
+ * you may not use this file except in compliance with the License.
3365
+ * You may obtain a copy of the License at
3366
+ *
3367
+ * http://www.apache.org/licenses/LICENSE-2.0
3368
+ *
3369
+ * Unless required by applicable law or agreed to in writing, software
3370
+ * distributed under the License is distributed on an "AS IS" BASIS,
3371
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3372
+ * See the License for the specific language governing permissions and
3373
+ * limitations under the License.
3374
+ *
3375
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3376
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
3377
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
3378
+ * */
3379
+ var onMouseMove = function onMouseMove(x, width, selectedTime, centerTime, secondsPerPx, mouseDownInTimeBox, isTimeBoxArea, setCursorStyle) {
3380
+ if (!selectedTime || mouseDownInTimeBox) {
3381
+ return;
3382
+ }
3383
+ var selectedTimePx = timestampToPixel(selectedTime, centerTime, width, secondsPerPx);
3384
+ if (isTimeBoxArea(x, selectedTimePx)) {
3385
+ setCursorStyle('grab');
3386
+ } else {
3387
+ setCursorStyle('auto');
3388
+ }
3389
+ };
3390
+ var onMouseDown = function onMouseDown(x, width, selectedTime, centerTime, secondsPerPx, isTimeBoxArea, setCursorStyle, setMouseDownInTimeBox) {
3391
+ if (!selectedTime) {
3392
+ return;
3393
+ }
3394
+ var selectedTimePx = timestampToPixel(selectedTime, centerTime, width, secondsPerPx);
3395
+ if (isTimeBoxArea(x, selectedTimePx)) {
3396
+ setCursorStyle('grabbing');
3397
+ }
3398
+ setMouseDownInTimeBox(true);
3399
+ };
3400
+
3401
+ /* *
3402
+ * Licensed under the Apache License, Version 2.0 (the "License");
3403
+ * you may not use this file except in compliance with the License.
3404
+ * You may obtain a copy of the License at
3405
+ *
3406
+ * http://www.apache.org/licenses/LICENSE-2.0
3407
+ *
3408
+ * Unless required by applicable law or agreed to in writing, software
3409
+ * distributed under the License is distributed on an "AS IS" BASIS,
3410
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3411
+ * See the License for the specific language governing permissions and
3412
+ * limitations under the License.
3413
+ *
3414
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3415
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
3416
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
3417
+ * */
3418
+ var secondsInYear = 365 * 24 * 3600;
3419
+ var drawRoundedRectangle = function drawRoundedRectangle(ctx, x, y, width, height, cornerRadius, theme) {
3420
+ ctx.save();
3421
+ ctx.translate(x, y);
3422
+ var playerTimeMarkers = theme.palette.geowebColors.timeSlider.playerTimeMarkers;
3423
+ ctx.beginPath();
3424
+ ctx.strokeStyle = playerTimeMarkers.fill;
3425
+ ctx.fillStyle = playerTimeMarkers.fill;
3426
+ ctx.lineWidth = timeBoxGeom.lineWidth;
3427
+ var halfLineWidth = timeBoxGeom.lineWidth / 2;
3428
+ // Top left corner
3429
+ ctx.moveTo(halfLineWidth, height / 2);
3430
+ ctx.arcTo(halfLineWidth, halfLineWidth, width / 2, halfLineWidth, cornerRadius);
3431
+ // Top right corner
3432
+ ctx.arcTo(width - halfLineWidth, halfLineWidth, width - halfLineWidth, height / 2, cornerRadius);
3433
+ // Bottom right corner
3434
+ ctx.arcTo(width - halfLineWidth, height - halfLineWidth, width / 2, height - halfLineWidth, cornerRadius);
3435
+ // Bottom left corner
3436
+ ctx.arcTo(halfLineWidth, height - halfLineWidth, halfLineWidth, height / 2, cornerRadius);
3437
+ ctx.lineTo(halfLineWidth, height / 2);
3438
+ ctx.fill();
3439
+ ctx.stroke();
3440
+ ctx.restore();
3441
+ };
3442
+ var drawAutoUpdateIcon = function drawAutoUpdateIcon(ctx, x, y, theme, isAutoUpdating) {
3443
+ ctx.save();
3444
+ ctx.translate(x, y);
3445
+ var playerTimeText = theme.palette.geowebColors.timeSlider.playerTimeText;
3446
+ ctx.fillStyle = isAutoUpdating ? '#7BACFF' : '#B4B4B4';
3447
+ var path = new Path2D('M12.385 3.295l5 3-5 3V7.723l-.085.014c-3.08.548-5.418 3.24-5.418 6.479 0 3.634 2.945 6.58 6.577 6.58 2.914 0 5.385-1.896 6.248-4.523l2.815-1.626c-.225 4.814-4.197 8.648-9.063 8.648-5.012 0-9.074-4.065-9.074-9.08 0-4.65 3.495-8.484 8-9.015V3.295z');
3448
+ ctx.translate(7, -8);
3449
+ ctx.rotate(13.295);
3450
+ ctx.fill(path);
3451
+ ctx.restore();
3452
+ var text = 'Auto';
3453
+ ctx.save();
3454
+ ctx.translate(x, y);
3455
+ ctx.fillStyle = isAutoUpdating ? '#7BACFF' : '#B4B4B4'; // ON
3456
+ ctx.font = "7px " + playerTimeText.fontFamily;
3457
+ ctx.fillText(text, 5, 14);
3458
+ ctx.restore();
3459
+ };
3460
+ var drawTextAnnotation = function drawTextAnnotation(ctx, x, y, text, theme) {
3461
+ var playerTimeText = theme.palette.geowebColors.timeSlider.playerTimeText;
3462
+ ctx.save();
3463
+ ctx.translate(x, y);
3464
+ ctx.fillStyle = playerTimeText.color;
3465
+ ctx.font = playerTimeText.fontSize + "px " + playerTimeText.fontFamily;
3466
+ var textMetrics = ctx.measureText(text);
3467
+ var actualTextWidth = textMetrics.actualBoundingBoxRight - textMetrics.actualBoundingBoxLeft;
3468
+ var actualTextHeight = ctx.measureText('O').width;
3469
+ ctx.fillText(text, -actualTextWidth / 2, actualTextHeight / 2);
3470
+ ctx.restore();
3471
+ };
3472
+ var drawNewCurrentTimeBox = function drawNewCurrentTimeBox(ctx, selectedTime, selectedPx, span, theme, isAutoUpdating) {
3473
+ var smallWidth = timeBoxGeom.smallWidth,
3474
+ largeWidth = timeBoxGeom.largeWidth,
3475
+ height = timeBoxGeom.height,
3476
+ iconWidth = timeBoxGeom.iconWidth,
3477
+ calendarWidth = timeBoxGeom.calendarWidth;
3478
+ var boxWidth = span >= secondsInYear ? largeWidth : smallWidth;
3479
+ var needleX = selectedPx - boxWidth / 2;
3480
+ var needleY = timeBoxGeom.lineWidth;
3481
+ drawRoundedRectangle(ctx, needleX - iconWidth / 2 - calendarWidth / 2, needleY, boxWidth + iconWidth + calendarWidth, height, timeBoxGeom.cornerRadius, theme);
3482
+ var timeFormat = span >= secondsInYear ? "y " + dateUtils.DATE_FORMAT_NAME_OF_DAY_MONTH : dateUtils.DATE_FORMAT_NAME_OF_DAY_MONTH;
3483
+ var timeText = dateUtils.dateToString(dateUtils.fromUnix(selectedTime), timeFormat) || '';
3484
+ drawTextAnnotation(ctx, needleX + boxWidth / 2 - iconWidth / 2 + calendarWidth / 2, needleY + height / 2, timeText, theme);
3485
+ drawAutoUpdateIcon(ctx, needleX + boxWidth + calendarWidth - iconWidth / 2 - calendarWidth / 2, needleY, theme, isAutoUpdating);
3486
+ };
3487
+ var renderTimeSliderCurrentTimeBox = function renderTimeSliderCurrentTimeBox(ctx, theme, width, height, centerTime, selected, secondsPerPx, span, isAutoUpdating) {
3488
+ // map unix timestamps to pixel values
3489
+ var _map = [selected].map(function (t) {
3490
+ return timestampToPixel(t, centerTime, width, secondsPerPx);
3491
+ }),
3492
+ selectedPx = _map[0];
3493
+ ctx.clearRect(0, 0, width, height);
3494
+ drawNewCurrentTimeBox(ctx, selected, selectedPx, span, theme, isAutoUpdating);
3495
+ };
3496
+
3497
+ var _excluded = ["day", "today", "outsideCurrentMonth"];
3498
+ var getTimezoneOffsetS = function getTimezoneOffsetS(value) {
3499
+ return value.getTimezoneOffset() * 60;
3500
+ };
3501
+ var toLocalTime = function toLocalTime(dateTime) {
3502
+ return dateUtils.fromUnix(dateTime + getTimezoneOffsetS(dateUtils.fromUnix(dateTime)));
3503
+ };
3504
+ var toUTCTime = function toUTCTime(dateTime) {
3505
+ return dateUtils.unix(dateTime) - getTimezoneOffsetS(dateTime);
3506
+ };
3507
+ var OpenPicker = function OpenPicker() {
3508
+ return jsx(CalendarToday, {});
3509
+ };
3510
+ var enabledAndSelectedButtonStyle = {
3511
+ borderWidth: '6px',
3512
+ borderBottomStyle: 'solid',
3513
+ borderRadius: 0,
3514
+ borderColor: 'rgb(170, 210, 240)',
3515
+ backgroundColor: 'rgba(170, 210, 240, 0.3)'
3516
+ };
3517
+ var enabledButUnSelectedButtonStyle = Object.assign({}, enabledAndSelectedButtonStyle, {
3518
+ backgroundColor: 'transparent'
3519
+ });
3520
+ var disabledButtonStyle = Object.assign({}, enabledAndSelectedButtonStyle, {
3521
+ borderColor: 'transparent',
3522
+ backgroundColor: 'transparent'
3523
+ });
3524
+ var AvailableDayByTimeRange = function AvailableDayByTimeRange(props, isDisabledStyle) {
3525
+ var day = props.day,
3526
+ today = props.today,
3527
+ outsideCurrentMonth = props.outsideCurrentMonth,
3528
+ other = _objectWithoutPropertiesLoose(props, _excluded);
3529
+ var _React$useState = React__default.useState({}),
3530
+ calendarDayStyle = _React$useState[0],
3531
+ setCalendarDayStyle = _React$useState[1];
3532
+ React__default.useEffect(function () {
3533
+ if (outsideCurrentMonth || isDisabledStyle) {
3534
+ setCalendarDayStyle(disabledButtonStyle);
3535
+ } else if (today) {
3536
+ setCalendarDayStyle(enabledAndSelectedButtonStyle);
3537
+ } else {
3538
+ setCalendarDayStyle(enabledButUnSelectedButtonStyle);
3539
+ }
3540
+ }, [day, today, outsideCurrentMonth, isDisabledStyle]);
3541
+ return /*#__PURE__*/createElement(PickersDay, Object.assign({}, other, {
3542
+ key: day.toString(),
3543
+ sx: Object.assign({}, calendarDayStyle),
3544
+ outsideCurrentMonth: outsideCurrentMonth,
3545
+ day: day,
3546
+ disableMargin: true,
3547
+ disableHighlightToday: true
3548
+ }));
3549
+ };
3550
+ var MarkerTimeSelector = function MarkerTimeSelector(_ref) {
3551
+ var value = _ref.value,
3552
+ _ref$format = _ref.format,
3553
+ format = _ref$format === void 0 ? dateUtils.DATE_FORMAT_DATEPICKER : _ref$format,
3554
+ dataStartTime = _ref.dataStartTime,
3555
+ dataEndTime = _ref.dataEndTime,
3556
+ _ref$onSelect = _ref.onSelect,
3557
+ onSelect = _ref$onSelect === void 0 ? function () {} : _ref$onSelect,
3558
+ _ref$onCancel = _ref.onCancel,
3559
+ onCancel = _ref$onCancel === void 0 ? function () {} : _ref$onCancel;
3560
+ var _useTimesliderTransla = useTimesliderTranslation(),
3561
+ t = _useTimesliderTransla.t;
3562
+ var _React$useState2 = React__default.useState(value ? toLocalTime(value) : null),
3563
+ localTimeValue = _React$useState2[0],
3564
+ setLocalTimeValue = _React$useState2[1];
3565
+ var _React$useState3 = React__default.useState(!dataStartTime || !dataEndTime || dataStartTime > dataEndTime),
3566
+ isUndefinedDateRange = _React$useState3[0],
3567
+ setIsUndefinedDateRange = _React$useState3[1];
3568
+ var isDateRangeDisabled = React__default.useCallback(function (date) {
3569
+ if (dataStartTime === undefined || dataEndTime === undefined || dataStartTime > dataEndTime) {
3570
+ return true;
3571
+ }
3572
+ var startOfFirstDay = dateUtils.fromUnix(dataStartTime);
3573
+ startOfFirstDay.setHours(0, 0, 0);
3574
+ var endOfLastDay = dateUtils.fromUnix(dataEndTime);
3575
+ var day = dateUtils.unix(date);
3576
+ return day < dateUtils.unix(startOfFirstDay) || day > dateUtils.unix(endOfLastDay);
3577
+ }, [dataStartTime, dataEndTime]);
3578
+ var _React$useState4 = React__default.useState(isDateRangeDisabled(localTimeValue)),
3579
+ isDisabledRange = _React$useState4[0],
3580
+ setIsDisabledRange = _React$useState4[1];
3581
+ var handleSelect = function handleSelect() {
3582
+ if (localTimeValue) {
3583
+ onSelect(toUTCTime(localTimeValue));
3584
+ }
3585
+ };
3586
+ var handleKeyDown = function handleKeyDown(event) {
3587
+ if (event.key === 'Enter') {
3588
+ handleSelect();
3589
+ } else if (event.key === 'Escape') {
3590
+ onCancel();
3591
+ }
3592
+ };
3593
+ var isDisabledDateWithSomeAvailableData = function isDisabledDateWithSomeAvailableData() {
3594
+ return isUndefinedDateRange ? false : isDisabledRange;
3595
+ };
3596
+ var handleDateChange = function handleDateChange(value) {
3597
+ if (value instanceof Date || value === null || isDisabledDateWithSomeAvailableData()) {
3598
+ setLocalTimeValue(value);
3599
+ }
3600
+ };
3601
+ var AvailableDay = function AvailableDay(props) {
3602
+ return AvailableDayByTimeRange(props, isDateRangeDisabled(props.day));
3603
+ };
3604
+ React__default.useEffect(function () {
3605
+ setIsUndefinedDateRange(!dataStartTime || !dataEndTime || dataStartTime > dataEndTime);
3606
+ setIsDisabledRange(isDateRangeDisabled(localTimeValue));
3607
+ }, [dataStartTime, dataEndTime, localTimeValue, isDateRangeDisabled]);
3608
+ return jsx(Paper, {
3609
+ sx: {
3610
+ borderRadius: '0px',
3611
+ width: '240px'
3612
+ },
3613
+ children: jsxs(Stack, {
3614
+ "data-testid": "markerTimeSelector",
3615
+ children: [jsx(Paper, {
3616
+ sx: {
3617
+ height: '24px',
3618
+ align: 'center',
3619
+ display: 'flex',
3620
+ justifyContent: 'center',
3621
+ alignItems: 'center',
3622
+ borderRadius: '0px'
3623
+ },
3624
+ children: jsx(Paper, {
3625
+ sx: {
3626
+ variant: 'subtitle',
3627
+ textAlign: 'center',
3628
+ display: 'flex',
3629
+ justifyContent: 'center',
3630
+ alignItems: 'center',
3631
+ font: {
3632
+ fontWeight: 'medium',
3633
+ fontFamily: 'Roboto',
3634
+ fontSize: '12px'
3635
+ },
3636
+ borderRadius: '0px',
3637
+ boxShadow: 'none'
3638
+ },
3639
+ children: t('timeslider-marker')
3640
+ })
3641
+ }), jsx(LocalizationProvider, {
3642
+ dateAdapter: AdapterDateFns,
3643
+ children: jsx(DateTimePicker, {
3644
+ desktopModeMediaQuery: "@media (min-width: 720px)",
3645
+ label: t('timeslider-marker-label'),
3646
+ ampm: false,
3647
+ value: localTimeValue,
3648
+ format: format,
3649
+ onChange: handleDateChange,
3650
+ closeOnSelect: false,
3651
+ onClose: handleSelect,
3652
+ autoFocus: true,
3653
+ disableIgnoringDatePartForTimeValidation: true,
3654
+ shouldDisableDate: isDisabledDateWithSomeAvailableData,
3655
+ minDateTime: isUndefinedDateRange ? undefined : toLocalTime(dataStartTime),
3656
+ maxDateTime: isUndefinedDateRange ? undefined : toLocalTime(dataEndTime),
3657
+ sx: {
3658
+ marginTop: '8px',
3659
+ marginBottom: '8px',
3660
+ marginLeft: '8px',
3661
+ marginRight: '8px',
3662
+ borderRadius: '0px'
3663
+ },
3664
+ slotProps: {
3665
+ textField: {
3666
+ variant: 'filled',
3667
+ InputProps: {
3668
+ onKeyDownCapture: handleKeyDown,
3669
+ endAdornment: jsx(InputAdornment, {
3670
+ sx: {
3671
+ paddingTop: '16px'
3672
+ },
3673
+ position: "end",
3674
+ children: "UTC"
3675
+ })
3676
+ }
3677
+ },
3678
+ field: {
3679
+ openPickerButtonPosition: 'start'
3680
+ },
3681
+ openPickerButton: {
3682
+ size: 'small',
3683
+ sx: {
3684
+ padding: 0
3685
+ }
3686
+ }
3687
+ },
3688
+ slots: {
3689
+ openPickerIcon: OpenPicker,
3690
+ day: AvailableDay
3691
+ },
3692
+ timeSteps: {
3693
+ minutes: 1
3694
+ }
3695
+ })
3696
+ })]
3697
+ })
3698
+ });
3699
+ };
3700
+
3701
+ var style = {
3702
+ '&.MuiToggleButton-root': {
3703
+ color: '#B4B4B4',
3704
+ '&:hover': {
3705
+ color: '#F8F9F9 !important',
3706
+ backgroundColor: 'rgba(255,255,225, 0.3)'
3707
+ },
3708
+ '&.Mui-selected': {
3709
+ color: '#7BACFF !important',
3710
+ '&:hover': {
3711
+ backgroundColor: 'rgba(255,255,225, 0.3)'
3712
+ }
3713
+ }
3714
+ },
3715
+ width: '26px',
3716
+ height: '24px!important'
3717
+ };
3718
+ var CalendarButton = function CalendarButton(_ref) {
3719
+ var calendarIconPx = _ref.calendarIconPx,
3720
+ dataStartTime = _ref.dataStartTime,
3721
+ dataEndTime = _ref.dataEndTime,
3722
+ selectedTime = _ref.selectedTime,
3723
+ _ref$onSelect = _ref.onSelect,
3724
+ _onSelect = _ref$onSelect === void 0 ? function () {} : _ref$onSelect;
3725
+ var _React$useState = React__default.useState(null),
3726
+ anchorEl = _React$useState[0],
3727
+ setAnchorEl = _React$useState[1];
3728
+ var _React$useState2 = React__default.useState(false),
3729
+ open = _React$useState2[0],
3730
+ setOpen = _React$useState2[1];
3731
+ var _useTimesliderTransla = useTimesliderTranslation(),
3732
+ t = _useTimesliderTransla.t;
3733
+ return jsx(ClickAwayListener, {
3734
+ onClickAway: function onClickAway() {
3735
+ return setOpen(false);
3736
+ },
3737
+ mouseEvent: "onMouseDown",
3738
+ children: jsxs("div", {
3739
+ style: {
3740
+ position: 'absolute',
3741
+ top: '-2px',
3742
+ left: calendarIconPx + "px"
3743
+ },
3744
+ children: [jsx(CustomTooltip, {
3745
+ title: !open && t('timeslider-marker-placement'),
3746
+ TransitionProps: {
3747
+ exit: false
3748
+ },
3749
+ children: jsx(CustomToggleButton, {
3750
+ sx: style,
3751
+ selected: open,
3752
+ variant: "flat",
3753
+ onClick: function onClick() {
3754
+ return setOpen(!open);
3755
+ },
3756
+ ref: function ref(_ref2) {
3757
+ setAnchorEl(_ref2);
3758
+ },
3759
+ children: jsx(CalendarToday, {
3760
+ style: {
3761
+ marginRight: '0px'
3762
+ }
3763
+ })
3764
+ })
3765
+ }), jsx(Popper, {
3766
+ sx: {
3767
+ zIndex: 10
3768
+ },
3769
+ placement: "top-start",
3770
+ open: open,
3771
+ "data-testid": "dateTimePickerPopOver",
3772
+ anchorEl: anchorEl,
3773
+ children: jsx(MarkerTimeSelector, {
3774
+ dataStartTime: dataStartTime,
3775
+ dataEndTime: dataEndTime,
3776
+ value: selectedTime,
3777
+ onSelect: function onSelect(newTime) {
3778
+ setOpen(false);
3779
+ _onSelect(newTime);
3780
+ },
3781
+ onCancel: function onCancel() {
3782
+ return setOpen(false);
3783
+ }
3784
+ })
3785
+ })]
3786
+ })
3787
+ });
3788
+ };
3789
+
3790
+ var getTimeBoxWidth = function getTimeBoxWidth(span) {
3791
+ var smallWidth = timeBoxGeom.smallWidth,
3792
+ largeWidth = timeBoxGeom.largeWidth,
3793
+ iconWidth = timeBoxGeom.iconWidth,
3794
+ calendarWidth = timeBoxGeom.calendarWidth;
3795
+ var mainWidth = span >= secondsInYear ? largeWidth : smallWidth;
3796
+ return mainWidth + iconWidth + calendarWidth;
3797
+ };
3798
+ var CALENDAR_ICON_LEFT_SPACING = 1;
3799
+ var TimeSliderCurrentTimeBox = function TimeSliderCurrentTimeBox(_ref) {
3800
+ var centerTime = _ref.centerTime,
3801
+ _ref$secondsPerPx = _ref.secondsPerPx,
3802
+ secondsPerPx = _ref$secondsPerPx === void 0 ? 50 : _ref$secondsPerPx,
3803
+ _ref$span = _ref.span,
3804
+ span = _ref$span === void 0 ? defaultTimeSpan : _ref$span,
3805
+ timeStep = _ref.timeStep,
3806
+ dataStartTime = _ref.dataStartTime,
3807
+ dataEndTime = _ref.dataEndTime,
3808
+ unfilteredSelectedTime = _ref.unfilteredSelectedTime,
3809
+ isAutoUpdating = _ref.isAutoUpdating,
3810
+ setUnfilteredSelectedTime = _ref.setUnfilteredSelectedTime,
3811
+ onCalendarSelect = _ref.onCalendarSelect,
3812
+ onSetCenterTime = _ref.onSetCenterTime;
3813
+ var timeBoxWidth = getTimeBoxWidth(span);
3814
+ var theme = useTheme();
3815
+ var _useCanvasTarget = useCanvasTarget('mousedown'),
3816
+ node = _useCanvasTarget[1];
3817
+ var _React$useState = React__default.useState('auto'),
3818
+ cursorStyle = _React$useState[0],
3819
+ setCursorStyle = _React$useState[1];
3820
+ var _React$useState2 = React__default.useState(false),
3821
+ mouseDownInTimeBox = _React$useState2[0],
3822
+ setMouseDownInTimeBox = _React$useState2[1];
3823
+ var _React$useState3 = React__default.useState(0),
3824
+ canvasWidth = _React$useState3[0],
3825
+ setCanvasWidth = _React$useState3[1];
3826
+ // Move TimeBox back to view if it goes out of bounds
3827
+ useEffect(function () {
3828
+ if (!(onSetCenterTime && canvasWidth && !mouseDownInTimeBox)) {
3829
+ return;
3830
+ }
3831
+ var receivedTimePx = timestampToPixel(unfilteredSelectedTime, centerTime, canvasWidth, secondsPerPx);
3832
+ var moveWidth = getAutoMoveAreaWidth(getFundamentalScale(secondsPerPx));
3833
+ if (receivedTimePx < moveWidth) {
3834
+ onSetCenterTime(pixelToTimestamp(canvasWidth / 2 - (moveWidth - receivedTimePx), centerTime, canvasWidth, secondsPerPx));
3835
+ } else if (receivedTimePx > canvasWidth - moveWidth) {
3836
+ onSetCenterTime(pixelToTimestamp(canvasWidth / 2 + (receivedTimePx - (canvasWidth - moveWidth)), centerTime, canvasWidth, secondsPerPx));
3837
+ }
3838
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3839
+ }, [unfilteredSelectedTime]);
3840
+ var isTimeBoxArea = function isTimeBoxArea(x, selectedTimePx) {
3841
+ return x > selectedTimePx - timeBoxWidth / 2 && x < selectedTimePx + timeBoxWidth / 2;
3842
+ };
3843
+ var mouseDownX = useRef(0);
3844
+ var unfilteredSelectedTimePxAtMouseDown = useRef(0);
3845
+ React__default.useEffect(function () {
3846
+ var handleMouseUp = function handleMouseUp() {
3847
+ mouseDownInTimeBox ? setCursorStyle('grab') : setCursorStyle('auto');
3848
+ setMouseDownInTimeBox(false);
3849
+ };
3850
+ var handleMouseDown = function handleMouseDown(event) {
3851
+ mouseDownX.current = event.clientX;
3852
+ unfilteredSelectedTimePxAtMouseDown.current = timestampToPixel(unfilteredSelectedTime, centerTime, canvasWidth, secondsPerPx);
3853
+ };
3854
+ var handleMouseMove = function handleMouseMove(event) {
3855
+ if (mouseDownInTimeBox) {
3856
+ if (mouseDownX.current) {
3857
+ var pixelsMoved = event.clientX - mouseDownX.current;
3858
+ var clickedUnfilteredSelectedTimePx = unfilteredSelectedTimePxAtMouseDown.current + pixelsMoved;
3859
+ var newUnfilteredSelectedTime = pixelToTimestamp(clickedUnfilteredSelectedTimePx, centerTime, canvasWidth, secondsPerPx);
3860
+ setUnfilteredSelectedTime(newUnfilteredSelectedTime);
3861
+ }
3862
+ }
3863
+ };
3864
+ document.addEventListener('mouseup', handleMouseUp);
3865
+ document.addEventListener('mousemove', handleMouseMove);
3866
+ document.addEventListener('mousedown', handleMouseDown);
3867
+ return function () {
3868
+ document.removeEventListener('mousemove', handleMouseMove);
3869
+ document.removeEventListener('mousedown', handleMouseDown);
3870
+ document.removeEventListener('mouseup', handleMouseUp);
3871
+ };
3872
+ }, [canvasWidth, centerTime, mouseDownInTimeBox, secondsPerPx, setUnfilteredSelectedTime, unfilteredSelectedTime]);
3873
+ var filteredTime = getFilteredTime(unfilteredSelectedTime, timeStep, dataStartTime, dataEndTime);
3874
+ var timePx = timestampToPixel(filteredTime, centerTime, canvasWidth, secondsPerPx);
3875
+ var currentTimeBoxWidth = getTimeBoxWidth(span);
3876
+ var calendarIconPx = timePx - currentTimeBoxWidth / 2 + CALENDAR_ICON_LEFT_SPACING;
3877
+ return jsxs(Box$1, {
3878
+ "data-testid": "timeSliderTimeBox",
3879
+ className: "timeSliderTimeBox",
3880
+ sx: {
3881
+ height: '24px',
3882
+ cursor: cursorStyle
3883
+ },
3884
+ children: [jsx(CanvasComponent, {
3885
+ ref: node,
3886
+ onMouseMove: function onMouseMove$1(x, y, event, width) {
3887
+ if (!unfilteredSelectedTime) {
3888
+ return;
3889
+ }
3890
+ onMouseMove(x, width, unfilteredSelectedTime, centerTime, secondsPerPx, mouseDownInTimeBox, isTimeBoxArea, setCursorStyle);
3891
+ },
3892
+ onMouseDown: function onMouseDown$1(x, y, width) {
3893
+ if (!unfilteredSelectedTime) {
3894
+ return;
3895
+ }
3896
+ onMouseDown(x, width, unfilteredSelectedTime, centerTime, secondsPerPx, isTimeBoxArea, setCursorStyle, setMouseDownInTimeBox);
3897
+ },
3898
+ onRenderCanvas: function onRenderCanvas(ctx, width, height) {
3899
+ setCanvasWidth(width);
3900
+ var filteredTime = getFilteredTime(unfilteredSelectedTime, timeStep, dataStartTime, dataEndTime);
3901
+ renderTimeSliderCurrentTimeBox(ctx, theme, width, height, centerTime, filteredTime, secondsPerPx, span, isAutoUpdating);
3902
+ }
3903
+ }), jsx(CalendarButton, {
3904
+ calendarIconPx: calendarIconPx,
3905
+ dataStartTime: dataStartTime,
3906
+ dataEndTime: dataEndTime,
3907
+ selectedTime: filteredTime,
3908
+ onSelect: function onSelect(newSelectedTime) {
3909
+ if (newSelectedTime) {
3910
+ onCalendarSelect(newSelectedTime);
3911
+ if (onSetCenterTime) {
3912
+ onSetCenterTime(newSelectedTime - filteredTime + centerTime);
3913
+ }
3914
+ }
3915
+ }
3916
+ })]
3917
+ });
3918
+ };
3919
+
3920
+ var TimesliderI18nProvider = function TimesliderI18nProvider(_ref) {
3921
+ var children = _ref.children;
3922
+ initTimesliderI18n();
3923
+ return jsx(I18nextProvider, {
3924
+ i18n: i18n,
3925
+ children: children
3926
+ });
3927
+ };
3928
+ var DemoWrapper = function DemoWrapper(_ref2) {
3929
+ var children = _ref2.children,
3930
+ _ref2$theme = _ref2.theme,
3931
+ theme = _ref2$theme === void 0 ? 'light' : _ref2$theme;
3932
+ var themeToApply = theme === 'light' ? lightTheme : darkTheme;
3933
+ return jsx(TimesliderI18nProvider, {
3934
+ children: jsx(ThemeWrapper, {
3935
+ theme: themeToApply,
3936
+ children: children
3937
+ })
3938
+ });
3939
+ };
3940
+
3941
+ export { AUTO_MOVE_AREA_PADDING, AnimationLength, AnimationLengthButton, AutoUpdateButton, BackwardForwardStepButton, ControlButtons, DRAG_AREA_WIDTH, DemoWrapper, HideSliderButton, NowButton, OptionsMenu, OptionsMenuButton, PlayButton, Scale, SpeedButton, TIME_SLIDER_LEGEND_HEIGHT, TIME_SLIDER_NAMESPACE, TimeInMinutes, TimeSlider, TimeSliderButtons, TimeSliderClock, TimeSliderCurrentTimeBox, TimeSliderLegend, TimeSliderMenu, TimeSpanButton, TimeStepButton, calculateMouseTimeAndCheckBounds, convertStringTimeToUnix, defaultAnimationDelayAtStart, defaultDelay, defaultSecondsPerPx, defaultTimeSpan, defaultTimeStep, getAutoMoveAreaWidth, getFilteredTime, getFundamentalScale, getLargestTimeUnit, getNewCenterOfFixedPointZoom, getPixelsBetweenViewportAndTimesliderOnLeft, getPositions, getScaleFromSpan, getSpeedDelay, getTimeBoxWidth, getTimeSliderLegendElement, getTimeSliderLegendId, handleSetNowEvent, isDraggingEndWithinBounds, isDraggingStartWithinBounds, isInsideAnimationArea, isLeftAnimationIconArea, isRightAnimationIconArea, isSelectedTimeIconArea, marks$1 as marks, minutesToDescribedDuration, moveRelativeToTimePoint, moveSelectedTimePx, onsetNewDateDebounced, pixelToTimestamp, roundWithTimeStep, scaleToSecondsPerPx, scalingCoefficient, secondsPerPxFromCanvasWidth, secondsPerPxToScale, secondsPerPxValues, setNextTimeStep, setPreviousTimeStep, setTooltipPosition, spanToScale, speedFactors, timeBoxGeom, timeSliderLegendDefaultProps, timeSliderUtils, timeValues, timesliderTranslations, timestampToPixel, timestampToPixelEdges, useCanvasTarget };