@opengeoweb/time-slider 14.5.2 → 15.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.
package/index.esm.js CHANGED
@@ -1,13 +1,11 @@
1
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';
2
+ import { Grid, useTheme, Box, Typography, Menu, MenuItem, CardHeader, FormControl, TextField, Select, Popper, Paper, Stack, InputAdornment, ClickAwayListener } from '@mui/material';
3
3
  import React, { useState, useRef, useEffect, createElement } from 'react';
4
- import { dateUtils, safelyInitI18nForTestsAndStories, CustomIconButton, CustomTooltip, renderCounter, useMakeSureContainerStaysInsideWindow, CanvasComponent, CustomToggleButton } from '@opengeoweb/shared';
4
+ import { dateUtils, safelyInitI18nForTestsAndStories, CustomIconButton, CustomTooltip, CanvasComponent, renderCounter, CustomToggleButton } from '@opengeoweb/shared';
5
5
  import { debounce, throttle } from 'lodash';
6
- import { ChevronDown, ChevronUp, ChevronRight, ChevronLeft, AutoUpdateActive, AutoUpdateInActive, StepForward, StepBackward, Now, Pause, Play, Edit, Animation, Speed, Clock, FastForward, Resize, dragHandlePath, Options, CalendarToday, ThemeWrapper, lightTheme, darkTheme } from '@opengeoweb/theme';
6
+ import { ChevronDown, ChevronUp, dragHandlePath, Edit, Animation, AutoUpdateActive, AutoUpdateInActive, StepForward, StepBackward, Now, Pause, Play, Speed, Clock, FastForward, Options, CalendarToday, ThemeWrapper, lightTheme, darkTheme } from '@opengeoweb/theme';
7
7
  import i18n from 'i18next';
8
8
  import { useTranslation, I18nextProvider } from 'react-i18next';
9
- import { Resizable } from 're-resizable';
10
- import Draggable from 'react-draggable';
11
9
  import { Box as Box$1 } from '@mui/system';
12
10
  import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
13
11
  import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
@@ -948,2312 +946,1900 @@ var TimeSlider = function TimeSlider(_ref) {
948
946
  });
949
947
  };
950
948
 
951
- /* *
952
- * Licensed under the Apache License, Version 2.0 (the "License");
953
- * you may not use this file except in compliance with the License.
954
- * You may obtain a copy of the License at
955
- *
956
- * http://www.apache.org/licenses/LICENSE-2.0
957
- *
958
- * Unless required by applicable law or agreed to in writing, software
959
- * distributed under the License is distributed on an "AS IS" BASIS,
960
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
961
- * See the License for the specific language governing permissions and
962
- * limitations under the License.
963
- *
964
- * Copyright 2024 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
965
- * Copyright 2024 - Finnish Meteorological Institute (FMI)
966
- * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
967
- * */
968
- // To be used with translations of days in formatted date
969
- // enum DaysOfWeeki18n {
970
- // SUNDAY = 'timeslider-sunday',
971
- // MONDAY = 'timeslider-monday',
972
- // TUESDAY = 'timeslider-tuesday',
973
- // WEDNESDAY = 'timeslider-wednesday',
974
- // THURSDAY = 'timeslider-thursday',
975
- // FRIDAY = 'timeslider-friday',
976
- // SATURDAY = 'timeslider-saturday',
977
- // }
978
- // To be used with translations of months in formatted date
979
- // enum MonthsOfTheYeari18n {
980
- // JANUARY = 'timeslider-january',
981
- // FEBRUARY = 'timeslider-february',
982
- // MARCH = 'timeslider-march',
983
- // APRIL = 'timeslider-april',
984
- // MAY = 'timeslider-may',
985
- // JUNE = 'timeslider-june',
986
- // JULY = 'timeslider-july',
987
- // AUGUST = 'timeslider-august',
988
- // SEPTEMBER = 'timeslider-september',
989
- // OCTOBER = 'timeslider-october',
990
- // NOVEMBER = 'timeslider-november',
991
- // DECEMBER = 'timeslider-december',
992
- // }
993
- var DaysOfWeek;
994
- (function (DaysOfWeek) {
995
- DaysOfWeek["SUNDAY"] = "Sun";
996
- DaysOfWeek["MONDAY"] = "Mon";
997
- DaysOfWeek["TUESDAY"] = "Tue";
998
- DaysOfWeek["WEDNESDAY"] = "Wed";
999
- DaysOfWeek["THURSDAY"] = "Thu";
1000
- DaysOfWeek["FRIDAY"] = "Fri";
1001
- DaysOfWeek["SATURDAY"] = "Sat";
1002
- })(DaysOfWeek || (DaysOfWeek = {}));
1003
- var MonthsOfTheYear;
1004
- (function (MonthsOfTheYear) {
1005
- MonthsOfTheYear["JANUARY"] = "Jan";
1006
- MonthsOfTheYear["FEBRUARY"] = "Feb";
1007
- MonthsOfTheYear["MARCH"] = "Mar";
1008
- MonthsOfTheYear["APRIL"] = "Apr";
1009
- MonthsOfTheYear["MAY"] = "May";
1010
- MonthsOfTheYear["JUNE"] = "Jun";
1011
- MonthsOfTheYear["JULY"] = "Jul";
1012
- MonthsOfTheYear["AUGUST"] = "Aug";
1013
- MonthsOfTheYear["SEPTEMBER"] = "Sep";
1014
- MonthsOfTheYear["OCTOBER"] = "Oct";
1015
- MonthsOfTheYear["NOVEMBER"] = "Nov";
1016
- MonthsOfTheYear["DECEMBER"] = "Dec";
1017
- })(MonthsOfTheYear || (MonthsOfTheYear = {}));
1018
- var dateToManualFormatString = function dateToManualFormatString(inDate) {
1019
- if (!inDate) {
1020
- return 'Date not available';
949
+ var _scaleToUnitSeconds, _scaleToRoundableUnit;
950
+ 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);
951
+ var TICK_MARK_HEIGHT_PRIMARY = 40;
952
+ var TICK_MARK_HEIGHT_SECONDARY = 10;
953
+ var TICK_MARK_HEIGHT_TERTIARY = 5;
954
+ var getStepPxLineHeight = function getStepPxLineHeight(scale, timestep) {
955
+ var scaleUnitSeconds = scaleToUnitSeconds[scale];
956
+ var rem = timestep % scaleUnitSeconds;
957
+ switch (scale) {
958
+ case Scale.Hour:
959
+ {
960
+ if (rem === 0) {
961
+ return TICK_MARK_HEIGHT_PRIMARY;
962
+ }
963
+ // 15 min subdivisions
964
+ if (rem % (15 * 60) === 0) {
965
+ return TICK_MARK_HEIGHT_SECONDARY;
966
+ }
967
+ return TICK_MARK_HEIGHT_TERTIARY;
968
+ }
969
+ case Scale.Hours3:
970
+ {
971
+ if (rem === 0) {
972
+ return TICK_MARK_HEIGHT_PRIMARY;
973
+ }
974
+ return TICK_MARK_HEIGHT_TERTIARY;
975
+ }
976
+ case Scale.Hours6:
977
+ {
978
+ if (rem === 0) {
979
+ return TICK_MARK_HEIGHT_PRIMARY;
980
+ }
981
+ // 3 hour subdivisions
982
+ if (rem % (3 * 60 * 60) === 0) {
983
+ return TICK_MARK_HEIGHT_SECONDARY;
984
+ }
985
+ return TICK_MARK_HEIGHT_TERTIARY;
986
+ }
987
+ case Scale.Day:
988
+ {
989
+ if (rem === 0) {
990
+ return TICK_MARK_HEIGHT_PRIMARY;
991
+ }
992
+ // 6 hour subdivisions
993
+ if (rem % (6 * 60 * 60) === 0) {
994
+ return TICK_MARK_HEIGHT_SECONDARY;
995
+ }
996
+ return TICK_MARK_HEIGHT_TERTIARY;
997
+ }
998
+ case Scale.Week:
999
+ case Scale.Weeks2:
1000
+ {
1001
+ var weekday = dateUtils.getDay(dateUtils.fromUnix(timestep));
1002
+ // dateUtils days range from 0 (Sunday) to 6 (Saturday)
1003
+ if (weekday === 1) {
1004
+ return TICK_MARK_HEIGHT_PRIMARY;
1005
+ }
1006
+ return TICK_MARK_HEIGHT_TERTIARY;
1007
+ }
1008
+ case Scale.Year:
1009
+ {
1010
+ var month = dateUtils.getMonth(dateUtils.fromUnix(timestep));
1011
+ // months are zero indexed
1012
+ if (month === 0) {
1013
+ return TICK_MARK_HEIGHT_PRIMARY;
1014
+ }
1015
+ if (month % 3 === 0) {
1016
+ return TICK_MARK_HEIGHT_SECONDARY;
1017
+ }
1018
+ return TICK_MARK_HEIGHT_TERTIARY;
1019
+ }
1020
+ case Scale.Minutes5:
1021
+ {
1022
+ // add primary line on day change
1023
+ if (timestep % (60 * 60 * 24) === 0) {
1024
+ return TICK_MARK_HEIGHT_PRIMARY;
1025
+ }
1026
+ return TICK_MARK_HEIGHT_TERTIARY;
1027
+ }
1028
+ default:
1029
+ // Scale.Month
1030
+ return TICK_MARK_HEIGHT_TERTIARY;
1021
1031
  }
1022
- var EEE = inDate && Object.values(DaysOfWeek)[inDate.getUTCDay()];
1023
- var dd = ("0" + (inDate == null ? void 0 : inDate.getUTCDate())).slice(-2);
1024
- var MMM = inDate && Object.values(MonthsOfTheYear)[inDate.getUTCMonth()];
1025
- var HH = ("0" + (inDate == null ? void 0 : inDate.getUTCHours())).slice(-2);
1026
- var mm = ("0" + (inDate == null ? void 0 : inDate.getUTCMinutes())).slice(-2);
1027
- return EEE + " " + dd + " " + MMM + " " + HH + ":" + mm + " UTC";
1028
1032
  };
1029
-
1030
- /**
1031
- * Format a date to a string
1032
- *
1033
- * Expects the following props:
1034
- * @param {Date} inDate - date to be formatted
1035
- *
1036
- */
1037
- var ClockContainer = function ClockContainer(_ref) {
1038
- var fontSize = _ref.fontSize,
1039
- isPopperOpen = _ref.isPopperOpen,
1040
- hideButton = _ref.hideButton,
1041
- onButtonClick = _ref.onButtonClick,
1042
- time = _ref.time,
1043
- setButtonElement = _ref.setButtonElement,
1044
- popperPlacement = _ref.popperPlacement;
1045
- var _useTimesliderTransla = useTimesliderTranslation(),
1046
- t = _useTimesliderTransla.t;
1047
- var currentDateString = dateToManualFormatString(dateUtils.fromUnix(time));
1048
- return jsxs(Grid, {
1049
- container: true,
1050
- sx: {
1051
- justifyContent: 'space-evenly',
1052
- alignItems: 'center',
1053
- cursor: 'move',
1054
- height: '100%',
1055
- width: '100%',
1056
- backgroundColor: 'geowebColors.timeSlider.playerTimeMarkers.fill',
1057
- borderRadius: '5px'
1058
- },
1059
- wrap: "nowrap",
1060
- children: [jsx(Grid, {
1061
- sx: {
1062
- width: '4px'
1063
- }
1064
- }), !hideButton && jsx(CustomTooltip, {
1065
- title: t('timeslider-animation-options'),
1066
- children: jsx(Grid, {
1067
- ref: setButtonElement,
1068
- sx: {
1069
- zIndex: 2
1070
- },
1071
- children: jsx(CustomIconButton, {
1072
- "aria-label": "Animation options",
1073
- isSelected: isPopperOpen,
1074
- onClick: onButtonClick,
1075
- sx: {
1076
- color: '#fff!important'
1077
- },
1078
- variant: "tool",
1079
- children: jsx(Icon, {
1080
- isPopperOpen: isPopperOpen,
1081
- popperPlacement: popperPlacement
1082
- })
1083
- })
1084
- })
1085
- }), jsx(Grid, {
1086
- children: jsx(Typography, {
1087
- sx: {
1088
- whiteSpace: 'nowrap',
1089
- fontSize: fontSize,
1090
- color: '#fff'
1091
- },
1092
- variant: "subtitle2",
1093
- children: currentDateString
1094
- })
1095
- })]
1096
- });
1033
+ var drawStepPxLine = function drawStepPxLine(ctx, theme, stepPx, height, fundamentalScale, timestep) {
1034
+ var ctx2 = ctx;
1035
+ ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
1036
+ ctx2.lineWidth = 1;
1037
+ var stepPxLineHeight = getStepPxLineHeight(fundamentalScale, timestep);
1038
+ ctx2.beginPath();
1039
+ ctx2.moveTo(stepPx, height - stepPxLineHeight);
1040
+ ctx2.lineTo(stepPx, height);
1041
+ ctx2.stroke();
1097
1042
  };
1098
- var Icon = function Icon(_ref2) {
1099
- var isPopperOpen = _ref2.isPopperOpen,
1100
- popperPlacement = _ref2.popperPlacement;
1101
- if (isPopperOpen) {
1102
- if (popperPlacement === 'left') {
1103
- return jsx(ChevronRight, {});
1104
- }
1105
- if (popperPlacement === 'right') {
1106
- return jsx(ChevronLeft, {});
1043
+ var drawTimeText = function drawTimeText(ctx, theme, stepPx, height, timeText, scale) {
1044
+ var ctx2 = ctx;
1045
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider.timelineText,
1046
+ fontSize = _theme$palette$geoweb.fontSize,
1047
+ fontFamily = _theme$palette$geoweb.fontFamily,
1048
+ color = _theme$palette$geoweb.color;
1049
+ ctx2.fillStyle = color;
1050
+ // time text has smaller font than other timeline text
1051
+ ctx2.font = fontSize + "px " + fontFamily;
1052
+ ctx2.textAlign = 'left';
1053
+ if (scale === Scale.Year || scale === Scale.Months3 || scale === Scale.Month || scale === Scale.Weeks2 || scale === Scale.Week || scale === Scale.Day) {
1054
+ ctx2.fillText(timeText, stepPx, height - 12);
1055
+ } else {
1056
+ ctx2.fillText(timeText, stepPx - 15, height - 12);
1057
+ }
1058
+ };
1059
+ var drawYearScaleText = function drawYearScaleText(ctx, theme, newDate, stepPx, height) {
1060
+ var ctx2 = ctx;
1061
+ var _theme$palette$geoweb2 = theme.palette.geowebColors.timeSlider.timelineText,
1062
+ fontSize = _theme$palette$geoweb2.fontSize,
1063
+ fontFamily = _theme$palette$geoweb2.fontFamily,
1064
+ color = _theme$palette$geoweb2.color;
1065
+ ctx2.fillStyle = color;
1066
+ ctx2.font = fontSize + "px " + fontFamily;
1067
+ ctx2.textAlign = 'left';
1068
+ ctx2.fillText(newDate, stepPx + 2, height - 10);
1069
+ };
1070
+ var drawLeftSideDateText = function drawLeftSideDateText(ctx, theme, newDate, height) {
1071
+ var ctx2 = ctx;
1072
+ var _theme$palette$geoweb3 = theme.palette.geowebColors.timeSlider.timelineText,
1073
+ fontSize = _theme$palette$geoweb3.fontSize,
1074
+ fontFamily = _theme$palette$geoweb3.fontFamily,
1075
+ color = _theme$palette$geoweb3.color;
1076
+ ctx2.fillStyle = color;
1077
+ ctx2.font = fontSize + "px " + fontFamily;
1078
+ ctx2.textAlign = 'left';
1079
+ ctx2.fillText(newDate, 2, height - 30);
1080
+ };
1081
+ var getTimeFormat = function getTimeFormat(scale) {
1082
+ switch (scale) {
1083
+ case Scale.Year:
1084
+ return 'y';
1085
+ case Scale.Month:
1086
+ case Scale.Months3:
1087
+ return 'MMM';
1088
+ case Scale.Week:
1089
+ case Scale.Weeks2:
1090
+ return 'dd MMM';
1091
+ case Scale.Day:
1092
+ return 'EEE dd';
1093
+ default:
1094
+ return dateUtils.DATE_FORMAT_HOURS;
1095
+ }
1096
+ };
1097
+ var drawDateChangeLine = function drawDateChangeLine(ctx, theme, stepPx, height) {
1098
+ var ctx2 = ctx;
1099
+ ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
1100
+ ctx2.lineWidth = 1;
1101
+ ctx2.beginPath();
1102
+ ctx2.moveTo(stepPx, height - 40);
1103
+ ctx2.lineTo(stepPx, height);
1104
+ ctx2.stroke();
1105
+ };
1106
+ var drawDashedMonthChangeLine = function drawDashedMonthChangeLine(ctx, theme, stepPx, height) {
1107
+ var ctx2 = ctx;
1108
+ ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineMonthChangeDash.rgba;
1109
+ ctx2.lineWidth = 3;
1110
+ ctx2.setLineDash([5, 5]);
1111
+ ctx2.beginPath();
1112
+ ctx2.moveTo(stepPx, 0);
1113
+ ctx2.lineTo(stepPx, height);
1114
+ ctx2.stroke();
1115
+ ctx2.setLineDash([]);
1116
+ };
1117
+ var roundByUnitOfTime = function roundByUnitOfTime(timeUnix, unit, roundUp) {
1118
+ if (roundUp === void 0) {
1119
+ roundUp = false;
1120
+ }
1121
+ if (unit === 'hour') {
1122
+ var _timeStartOfPassedUnit = dateUtils.startOfHourUTC(dateUtils.fromUnix(timeUnix));
1123
+ if (roundUp) {
1124
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit, {
1125
+ hours: 1
1126
+ }));
1107
1127
  }
1108
- if (popperPlacement === 'top') {
1109
- return jsx(ChevronDown, {});
1128
+ return dateUtils.unix(_timeStartOfPassedUnit);
1129
+ }
1130
+ if (unit === 'day') {
1131
+ var _timeStartOfPassedUnit2 = dateUtils.startOfDayUTC(dateUtils.fromUnix(timeUnix));
1132
+ if (roundUp) {
1133
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit2, {
1134
+ days: 1
1135
+ }));
1110
1136
  }
1111
- return jsx(ChevronUp, {});
1137
+ return dateUtils.unix(_timeStartOfPassedUnit2);
1112
1138
  }
1113
- var popperClosedStyle = {
1114
- backgroundColor: 'geowebColors.timeSlider.playerTimeMarkers.fill',
1115
- outline: '1px solid white',
1116
- borderRadius: '5px'
1117
- };
1118
- if (popperPlacement === 'left') {
1119
- return jsx(ChevronLeft, {
1120
- sx: popperClosedStyle
1121
- });
1139
+ if (unit === 'week') {
1140
+ var _timeStartOfPassedUnit3 = dateUtils.startOfWeekUTC(dateUtils.fromUnix(timeUnix));
1141
+ if (roundUp) {
1142
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit3, {
1143
+ weeks: 1
1144
+ }));
1145
+ }
1146
+ return dateUtils.unix(_timeStartOfPassedUnit3);
1122
1147
  }
1123
- if (popperPlacement === 'right') {
1124
- return jsx(ChevronRight, {
1125
- sx: popperClosedStyle
1126
- });
1148
+ if (unit === 'month') {
1149
+ var _timeStartOfPassedUnit4 = dateUtils.startOfMonthUTC(dateUtils.fromUnix(timeUnix));
1150
+ if (roundUp) {
1151
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit4, {
1152
+ months: 1
1153
+ }));
1154
+ }
1155
+ return dateUtils.unix(_timeStartOfPassedUnit4);
1127
1156
  }
1128
- if (popperPlacement === 'top') {
1129
- return jsx(ChevronUp, {
1130
- sx: popperClosedStyle
1131
- });
1157
+ // Default unit === 'year'
1158
+ var timeStartOfPassedUnit = dateUtils.startOfYearUTC(dateUtils.fromUnix(timeUnix));
1159
+ if (roundUp) {
1160
+ return dateUtils.unix(dateUtils.add(timeStartOfPassedUnit, {
1161
+ years: 1
1162
+ }));
1132
1163
  }
1133
- return jsx(ChevronDown, {
1134
- sx: popperClosedStyle
1135
- });
1164
+ return dateUtils.unix(timeStartOfPassedUnit);
1136
1165
  };
1137
-
1138
- var AutoUpdateButton = function AutoUpdateButton(_ref) {
1139
- var _ref$toggleAutoUpdate = _ref.toggleAutoUpdate,
1140
- toggleAutoUpdate = _ref$toggleAutoUpdate === void 0 ? function () {} : _ref$toggleAutoUpdate,
1141
- _ref$isAutoUpdating = _ref.isAutoUpdating,
1142
- isAutoUpdating = _ref$isAutoUpdating === void 0 ? false : _ref$isAutoUpdating,
1143
- _ref$disabled = _ref.disabled,
1144
- disabled = _ref$disabled === void 0 ? false : _ref$disabled;
1145
- var _useTimesliderTransla = useTimesliderTranslation(),
1146
- t = _useTimesliderTransla.t;
1147
- return jsx(CustomIconButton, {
1148
- "data-testid": "autoUpdateButton",
1149
- disabled: disabled,
1150
- isSelected: isAutoUpdating,
1151
- onClick: function onClick() {
1152
- return toggleAutoUpdate();
1153
- },
1154
- tooltipTitle: isAutoUpdating ? t('timeslider-auto-update-on') : t('timeslider-auto-update-off'),
1155
- variant: "tool",
1156
- children: isAutoUpdating ? jsx(AutoUpdateActive, {
1157
- "data-testid": "auto-update-svg-on"
1158
- }) : jsx(AutoUpdateInActive, {
1159
- "data-testid": "auto-update-svg-off"
1160
- })
1161
- });
1166
+ var roundToNearestMultiple = function roundToNearestMultiple(timeUnix, scale, roundUp) {
1167
+ if (roundUp === void 0) {
1168
+ roundUp = false;
1169
+ }
1170
+ var stepSeconds = scaleToUnitSeconds[scale];
1171
+ var roundFn = roundUp ? Math.ceil : Math.floor;
1172
+ return roundFn(timeUnix / stepSeconds) * stepSeconds;
1162
1173
  };
1163
-
1164
- var BackwardForwardStepButton = function BackwardForwardStepButton(_ref) {
1165
- var isForwardStep = _ref.isForwardStep,
1166
- isDisabled = _ref.isDisabled,
1167
- _ref$onClickBFButton = _ref.onClickBFButton,
1168
- onClickBFButton = _ref$onClickBFButton === void 0 ? function () {} : _ref$onClickBFButton;
1169
- // Added renderCounter for testing and performance purposes
1170
- renderCounter.count(BackwardForwardStepButton.name);
1171
- var _useTimesliderTransla = useTimesliderTranslation(),
1172
- t = _useTimesliderTransla.t;
1173
- return jsx(CustomIconButton, {
1174
- "aria-label": isForwardStep ? 'forward' : 'backward',
1175
- "data-testid": isForwardStep ? 'stepForwardButton' : 'stepBackwardButton',
1176
- disabled: isDisabled,
1177
- onClick: onClickBFButton,
1178
- tooltipTitle: isForwardStep ? t('timeslider-forward') : t('timeslider-backward'),
1179
- variant: "tool",
1180
- children: isForwardStep ? jsx(StepForward, {
1181
- "data-testid": "step-forward-svg-path"
1182
- }) : jsx(StepBackward, {
1183
- "data-testid": "step-backward-svg-path"
1184
- })
1185
- });
1174
+ /**
1175
+ * In this script starting and ending times of the time slider are rounded.
1176
+ * Here it is defined what is a time unit to a start of which a rounding is
1177
+ * done for each scale.
1178
+ * @returns an object where there are rounding units of each scale
1179
+ */
1180
+ 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);
1181
+ var getRoundedStartAndEnd = function getRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, scale) {
1182
+ if (scale === Scale.Minutes5 || scale === Scale.Hours3 || scale === Scale.Hours6) {
1183
+ return [roundToNearestMultiple(visibleTimeStart, scale, false), roundToNearestMultiple(visibleTimeEnd, scale, true)];
1184
+ }
1185
+ var unit = scaleToRoundableUnit[scale];
1186
+ return [roundByUnitOfTime(visibleTimeStart, unit, false), roundByUnitOfTime(visibleTimeEnd, unit, true)];
1186
1187
  };
1187
-
1188
- var NowButton = function NowButton(_ref) {
1189
- var _ref$onSetNow = _ref.onSetNow,
1190
- onSetNow = _ref$onSetNow === void 0 ? function () {} : _ref$onSetNow,
1191
- _ref$disabled = _ref.disabled,
1192
- disabled = _ref$disabled === void 0 ? false : _ref$disabled;
1193
- var _useTimesliderTransla = useTimesliderTranslation(),
1194
- t = _useTimesliderTransla.t;
1195
- return jsx(CustomIconButton, {
1196
- "aria-label": "now",
1197
- "data-testid": "nowButtonTooltip",
1198
- disabled: disabled,
1199
- onClick: function onClick() {
1200
- return onSetNow();
1201
- },
1202
- tooltipTitle: t('timeslider-now'),
1203
- variant: "tool",
1204
- children: jsx(Now, {
1205
- "data-testid": "now-svg"
1206
- })
1207
- });
1188
+ var getCustomRoundedStartAndEndScale = function getCustomRoundedStartAndEndScale(scale) {
1189
+ switch (scale) {
1190
+ case Scale.Year:
1191
+ return 'month';
1192
+ case Scale.Month:
1193
+ case Scale.Months3:
1194
+ return 'week';
1195
+ case Scale.Week:
1196
+ case Scale.Weeks2:
1197
+ return 'day';
1198
+ default:
1199
+ return 'day';
1200
+ }
1208
1201
  };
1209
-
1210
- var PlayButton = function PlayButton(_ref) {
1211
- var isAnimating = _ref.isAnimating,
1212
- isDisabled = _ref.isDisabled,
1213
- _ref$onTogglePlayButt = _ref.onTogglePlayButton,
1214
- onTogglePlayButton = _ref$onTogglePlayButt === void 0 ? function () {} : _ref$onTogglePlayButt;
1215
- var onTogglePlay = function onTogglePlay() {
1216
- onTogglePlayButton();
1217
- };
1218
- var _useTimesliderTransla = useTimesliderTranslation(),
1219
- t = _useTimesliderTransla.t;
1220
- return jsx(CustomIconButton, {
1221
- "data-testid": "playButton",
1222
- disabled: isDisabled,
1223
- isSelected: isAnimating,
1224
- onClick: onTogglePlay,
1225
- tooltipTitle: isAnimating ? t('timeslider-pause') : t('timeslider-play'),
1226
- variant: "tool",
1227
- children: isAnimating ? jsx(Pause, {
1228
- "data-testid": "pause-svg-path"
1229
- }) : jsx(Play, {
1230
- "data-testid": "play-svg-path"
1231
- })
1232
- });
1202
+ var getCustomRoundedStartAndEnd = function getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, unit) {
1203
+ var scale = getCustomRoundedStartAndEndScale(unit);
1204
+ return [roundByUnitOfTime(visibleTimeStart, scale, false), roundByUnitOfTime(visibleTimeEnd, scale, true)];
1233
1205
  };
1234
-
1235
- var ControlButtons = function ControlButtons(_ref) {
1236
- var backwardBtn = _ref.backwardBtn,
1237
- forwardBtn = _ref.forwardBtn,
1238
- playBtn = _ref.playBtn,
1239
- nowBtn = _ref.nowBtn,
1240
- autoUpdateBtn = _ref.autoUpdateBtn;
1241
- return jsxs(Fragment, {
1242
- children: [jsx(Grid, {
1243
- children: backwardBtn || jsx(BackwardForwardStepButton, {
1244
- isForwardStep: false
1245
- })
1246
- }), jsx(Grid, {
1247
- children: forwardBtn || jsx(BackwardForwardStepButton, {
1248
- isForwardStep: true
1249
- })
1250
- }), jsx(Grid, {
1251
- children: playBtn || jsx(PlayButton, {})
1252
- }), jsx(Grid, {
1253
- children: nowBtn || jsx(NowButton, {})
1254
- }), jsx(Grid, {
1255
- children: autoUpdateBtn || jsx(AutoUpdateButton, {})
1256
- })]
1257
- });
1206
+ var incrementTimestep = function incrementTimestep(timeAtTimeStep, fundamentalScale) {
1207
+ switch (fundamentalScale) {
1208
+ case Scale.Minutes5:
1209
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1210
+ minutes: 1
1211
+ }));
1212
+ case Scale.Hour:
1213
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1214
+ minutes: 5
1215
+ }));
1216
+ case Scale.Hours3:
1217
+ case Scale.Hours6:
1218
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1219
+ hours: 1
1220
+ }));
1221
+ case Scale.Day:
1222
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1223
+ hours: 3
1224
+ }));
1225
+ case Scale.Week:
1226
+ case Scale.Weeks2:
1227
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1228
+ days: 1
1229
+ }));
1230
+ case Scale.Month:
1231
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1232
+ weeks: 1
1233
+ }));
1234
+ case Scale.Year:
1235
+ case Scale.Months3:
1236
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1237
+ months: 1
1238
+ }));
1239
+ default:
1240
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1241
+ months: 1
1242
+ }));
1243
+ }
1258
1244
  };
1259
-
1260
- var THROTTLE_WAIT_TIME = 300; // [ms]
1261
- var THROTTLE_OPTIONS = {
1262
- trailing: false // Invoke function when called, but not more than once every <THROTTLE_WAIT_TIME>.
1245
+ var getTimesteps = function getTimesteps(roundedStart, roundedEnd, fundamentalScaleType) {
1246
+ var timesteps = [];
1247
+ var timestep = roundedStart;
1248
+ while (timestep <= roundedEnd) {
1249
+ timesteps.push(timestep);
1250
+ timestep = incrementTimestep(timestep, fundamentalScaleType);
1251
+ }
1252
+ return timesteps;
1263
1253
  };
1264
- var TimeSliderMenu = function TimeSliderMenu(_ref) {
1265
- var marks = _ref.marks,
1266
- value = _ref.value,
1267
- allOptionsDisabled = _ref.allOptionsDisabled,
1268
- isAutoDisabled = _ref.isAutoDisabled,
1269
- handleAutoClick = _ref.handleAutoClick,
1270
- isAutoSelected = _ref.isAutoSelected,
1271
- title = _ref.title,
1272
- icon = _ref.icon,
1273
- _ref$onChangeSliderVa = _ref.onChangeSliderValue,
1274
- onChangeSliderValue = _ref$onChangeSliderVa === void 0 ? function () {} : _ref$onChangeSliderVa,
1275
- displayCurrentLength = _ref.displayCurrentLength,
1276
- _ref$disbleUserSetDur = _ref.disbleUserSetDuration,
1277
- disbleUserSetDuration = _ref$disbleUserSetDur === void 0 ? true : _ref$disbleUserSetDur,
1278
- customLengthSelector = _ref.customLengthSelector,
1279
- _ref$setOpen = _ref.setOpen,
1280
- setOpen = _ref$setOpen === void 0 ? function () {} : _ref$setOpen,
1281
- _ref$customFieldHeade = _ref.customFieldHeader,
1282
- customFieldHeader = _ref$customFieldHeade === void 0 ? 'timeslider-length' : _ref$customFieldHeade,
1283
- open = _ref.open;
1284
- var currentMarkIndex = marks.findIndex(function (mark) {
1285
- return mark.value === value;
1286
- });
1287
- var currentMark = marks[currentMarkIndex];
1288
- var _React$useState = React.useState(null),
1289
- anchorRef = _React$useState[0],
1290
- setAnchorRef = _React$useState[1];
1291
- var _useTimesliderTransla = useTimesliderTranslation(),
1292
- t = _useTimesliderTransla.t;
1293
- var _useState = useState(false),
1294
- displayLengthInputField = _useState[0],
1295
- setDisplayLengthInputField = _useState[1];
1296
- React.useEffect(function () {
1297
- if (!open && displayLengthInputField) {
1298
- setDisplayLengthInputField(false);
1299
- }
1300
- }, [displayLengthInputField, open]);
1301
- var buttonText = function buttonText(value, displayCurrentLength, currentMark) {
1302
- if (displayCurrentLength) {
1303
- return minutesToDescribedDuration(value);
1304
- }
1305
- if (currentMark) {
1306
- var parts = t(currentMark.label).split(' ');
1307
- if (parts.length > 1) {
1308
- return parts[0] + parts.slice(1).join(' ');
1309
- }
1310
- return parts.join('');
1311
- }
1312
- return '';
1313
- };
1314
- // eslint-disable-next-line react-hooks/exhaustive-deps
1315
- var throttledScroll = React.useCallback(throttle(function (newValue) {
1316
- onChangeSliderValue(newValue);
1317
- }, THROTTLE_WAIT_TIME, THROTTLE_OPTIONS), []);
1318
- var onWheel = React.useCallback(function (event) {
1319
- var direction = event.deltaY < 0 ? 1 : -1;
1320
- var newValue = marks[Math.min(Math.max(currentMarkIndex - direction, 0), marks.length - 1)];
1321
- throttledScroll(newValue.value);
1322
- }, [currentMarkIndex, marks, throttledScroll]);
1323
- return jsxs(Box, {
1324
- onKeyDown: function onKeyDown(event) {
1325
- event.stopPropagation();
1326
- },
1327
- children: [jsxs(CustomIconButton, {
1328
- isSelected: true,
1329
- onClick: function onClick() {
1330
- setOpen(true);
1331
- },
1332
- onWheel: onWheel,
1333
- ref: setAnchorRef,
1334
- sx: {
1335
- padding: '11px!important',
1336
- width: '100%!important'
1337
- },
1338
- tooltipTitle: title,
1339
- variant: "tool",
1340
- children: [icon, jsx(Typography, {
1341
- sx: {
1342
- fontSize: 12,
1343
- fontWeight: 400,
1344
- textTransform: 'none'
1345
- },
1346
- children: buttonText(value, displayCurrentLength, currentMark)
1347
- })]
1348
- }), !!anchorRef && jsxs(Menu, {
1349
- anchorEl: anchorRef,
1350
- anchorOrigin: {
1351
- vertical: -15,
1352
- horizontal: 'center'
1353
- },
1354
- onClose: function onClose() {
1355
- return setOpen(false);
1356
- },
1357
- open: open,
1358
- slotProps: {
1359
- backdrop: {
1360
- sx: {
1361
- backgroundColor: 'transparent'
1362
- }
1363
- }
1364
- },
1365
- transformOrigin: {
1366
- vertical: 'bottom',
1367
- horizontal: 'center'
1368
- },
1369
- children: [jsx(MenuItem, {
1370
- disabled: true,
1371
- sx: {
1372
- fontSize: '12px',
1373
- opacity: 0.67,
1374
- padding: '0px 12px',
1375
- '&.MuiMenuItem-root': {
1376
- minHeight: '30px!important',
1377
- minWidth: 150
1378
- }
1379
- },
1380
- children: title
1381
- }), marks.map(function (mark) {
1382
- var isSelected = (currentMark == null ? void 0 : currentMark.value) === mark.value && !isAutoSelected;
1383
- return jsx(MenuItem, {
1384
- disabled: allOptionsDisabled,
1385
- onClick: function onClick() {
1386
- if (!isSelected) {
1387
- onChangeSliderValue(mark.value);
1388
- }
1389
- setOpen(false);
1390
- },
1391
- selected: !!isSelected && !displayLengthInputField,
1392
- children: mark.label || mark.text
1393
- }, mark.value);
1394
- }), !!handleAutoClick && jsx(MenuItem, {
1395
- disabled: allOptionsDisabled || isAutoDisabled,
1396
- onClick: function onClick() {
1397
- handleAutoClick();
1398
- setOpen(false);
1399
- },
1400
- selected: isAutoSelected,
1401
- children: t('timeslider-auto')
1402
- }), !!displayCurrentLength && jsxs(MenuItem, {
1403
- disabled: disbleUserSetDuration,
1404
- onClick: function onClick() {
1405
- return setDisplayLengthInputField(true);
1406
- },
1407
- sx: {
1408
- maxWidth: '175px'
1409
- },
1410
- children: [!!displayLengthInputField && customLengthSelector, !displayLengthInputField && jsxs(Box, {
1411
- sx: {
1412
- flexDirection: 'column',
1413
- display: 'flex',
1414
- flexGrow: 1
1415
- },
1416
- children: [jsx(CardHeader, {
1417
- slotProps: {
1418
- title: {
1419
- fontSize: 12
1420
- }
1421
- },
1422
- sx: {
1423
- height: 2,
1424
- padding: 0,
1425
- color: 'geowebColors.greys.accessible'
1426
- },
1427
- title: t(customFieldHeader)
1428
- }), jsxs(Box, {
1429
- sx: {
1430
- flexDirection: 'row',
1431
- display: 'flex',
1432
- justifyContent: 'space-between',
1433
- flexGrow: 1,
1434
- paddingTop: 0.5
1435
- },
1436
- children: [jsx(Typography, {
1437
- sx: {
1438
- fontSize: 14,
1439
- textTransform: 'none',
1440
- lineHeight: 2
1441
- },
1442
- children: minutesToDescribedDuration(value)
1443
- }), jsx(CustomTooltip, {
1444
- title: t('timeslider-edit'),
1445
- children: jsx("span", {
1446
- children: jsx(CustomIconButton, {
1447
- "aria-label": "edit animation option",
1448
- "data-testid": "editAnimationOption",
1449
- children: jsx(Edit, {})
1450
- })
1451
- })
1452
- })]
1453
- })]
1454
- })]
1455
- })]
1456
- })]
1254
+ var getCustomTimesteps = function getCustomTimesteps(roundedStart, roundedEnd, increment) {
1255
+ var timesteps = [];
1256
+ var timestep = roundedStart;
1257
+ while (timestep <= roundedEnd) {
1258
+ var _dateUtils$add;
1259
+ timesteps.push(timestep);
1260
+ timestep = dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timestep), (_dateUtils$add = {}, _dateUtils$add[increment] = 1, _dateUtils$add)));
1261
+ }
1262
+ return timesteps;
1263
+ };
1264
+ var getLeftSideDateText = function getLeftSideDateText(timestamp, fundamentalScale) {
1265
+ var time = dateUtils.fromUnix(timestamp);
1266
+ switch (fundamentalScale) {
1267
+ case Scale.Minutes5:
1268
+ case Scale.Hour:
1269
+ case Scale.Hours3:
1270
+ case Scale.Hours6:
1271
+ return dateUtils.dateToString(time, 'y MMM EEE dd');
1272
+ case Scale.Day:
1273
+ case Scale.Week:
1274
+ case Scale.Weeks2:
1275
+ return dateUtils.dateToString(time, 'y MMM');
1276
+ case Scale.Month:
1277
+ case Scale.Months3:
1278
+ return dateUtils.dateToString(time, 'y');
1279
+ case Scale.Year:
1280
+ return dateUtils.dateToString(time, 'y');
1281
+ default:
1282
+ return '';
1283
+ }
1284
+ };
1285
+ var drawTimeScale = function drawTimeScale(context, theme, visibleTimeStart, visibleTimeEnd, canvasWidth, height, secondsPerPx) {
1286
+ var fundamentalScale = getFundamentalScale(secondsPerPx);
1287
+ var _getRoundedStartAndEn = getRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, fundamentalScale),
1288
+ roundedStart = _getRoundedStartAndEn[0],
1289
+ roundedEnd = _getRoundedStartAndEn[1];
1290
+ // draw regular tickmarks
1291
+ var ctx = context;
1292
+ getTimesteps(roundedStart, roundedEnd, fundamentalScale).forEach(function (timestep) {
1293
+ var stepPx = timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
1294
+ // 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
1295
+ drawStepPxLine(ctx, theme, Math.floor(stepPx) + 0.5, height, fundamentalScale, timestep);
1296
+ // Draw the time step time as text
1297
+ var timeFormat = getTimeFormat(fundamentalScale);
1298
+ var timeText = dateUtils.dateToString(dateUtils.fromUnix(timestep), timeFormat);
1299
+ if ([Scale.Minutes5, Scale.Hour, Scale.Hours3, Scale.Hours6, Scale.Day].includes(fundamentalScale) &&
1300
+ // eslint-disable-next-line @typescript-eslint/no-confusing-non-null-assertion
1301
+ timestep % scaleToUnitSeconds[fundamentalScale] === 0 || fundamentalScale === Scale.Week && dateUtils.getDay(dateUtils.fromUnix(timestep)) === 1) {
1302
+ drawTimeText(ctx, theme, stepPx, height, timeText, fundamentalScale);
1303
+ }
1304
+ if (fundamentalScale === Scale.Year && dateUtils.getMonth(dateUtils.fromUnix(timestep)) === 0) {
1305
+ drawYearScaleText(ctx, theme, timeText, stepPx, height);
1306
+ }
1457
1307
  });
1308
+ // draw month overlay lines
1309
+ if (fundamentalScale === Scale.Week || fundamentalScale === Scale.Weeks2 || fundamentalScale === Scale.Month || fundamentalScale === Scale.Months3) {
1310
+ var _getCustomRoundedStar = getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, Scale.Year),
1311
+ _roundedStart = _getCustomRoundedStar[0],
1312
+ _roundedEnd = _getCustomRoundedStar[1];
1313
+ var monthTimesteps = getCustomTimesteps(_roundedStart, _roundedEnd, 'months');
1314
+ monthTimesteps.forEach(function (timestep) {
1315
+ var stepPx = timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
1316
+ if (fundamentalScale === Scale.Month || fundamentalScale === Scale.Months3) {
1317
+ var month = dateUtils.dateToString(dateUtils.fromUnix(timestep), 'MMM');
1318
+ // 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
1319
+ drawDateChangeLine(ctx, theme, Math.floor(stepPx) + 0.5, height);
1320
+ drawTimeText(ctx, theme, stepPx, height, month, fundamentalScale);
1321
+ return;
1322
+ }
1323
+ // adding 0.5 to make line not so blurred
1324
+ drawDashedMonthChangeLine(ctx, theme, Math.floor(stepPx) + 0.5, height);
1325
+ });
1326
+ }
1327
+ // draw date change texts
1328
+ if (fundamentalScale === Scale.Year) {
1329
+ return;
1330
+ }
1331
+ var dateText = getLeftSideDateText(visibleTimeStart, fundamentalScale);
1332
+ drawLeftSideDateText(ctx, theme, dateText, height);
1458
1333
  };
1459
1334
 
1460
- var marks$2 = [{
1461
- value: AnimationLength.Minutes15,
1462
- text: 'timeslider-min',
1463
- count: 15
1464
- }, {
1465
- value: AnimationLength.Minutes30,
1466
- text: 'timeslider-min',
1467
- count: 30
1468
- }, {
1469
- value: AnimationLength.Hours1,
1470
- text: 'timeslider-hour',
1471
- count: 1
1472
- }, {
1473
- value: AnimationLength.Hours2,
1474
- text: 'timeslider-hour',
1475
- count: 2
1476
- }, {
1477
- value: AnimationLength.Hours3,
1478
- text: 'timeslider-hour',
1479
- count: 3
1480
- }, {
1481
- value: AnimationLength.Hours6,
1482
- text: 'timeslider-hour',
1483
- count: 6
1484
- }, {
1485
- value: AnimationLength.Hours12,
1486
- text: 'timeslider-hour',
1487
- count: 12
1488
- }, {
1489
- value: AnimationLength.Hours24,
1490
- text: 'timeslider-hour',
1491
- count: 24
1492
- }].sort(function (ta, tb) {
1493
- return tb.value - ta.value;
1494
- });
1495
- var AnimationLengthButton = function AnimationLengthButton(_ref) {
1496
- var _ref$disabled = _ref.disabled,
1497
- disabled = _ref$disabled === void 0 ? false : _ref$disabled,
1498
- _ref$animationLength = _ref.animationLength,
1499
- animationLength = _ref$animationLength === void 0 ? AnimationLength.Hours1 : _ref$animationLength,
1500
- _ref$isAuto = _ref.isAuto,
1501
- isAuto = _ref$isAuto === void 0 ? false : _ref$isAuto,
1502
- layerHasTimeStep = _ref.layerHasTimeStep,
1503
- onChangeAnimationLength = _ref.onChangeAnimationLength,
1504
- toggleAnimationLengthAuto = _ref.toggleAnimationLengthAuto;
1505
- var _useTimesliderTransla = useTimesliderTranslation(),
1506
- t = _useTimesliderTransla.t;
1507
- var translatedMarks = marks$2.map(function (mark) {
1508
- return Object.assign({}, mark, {
1509
- label: mark.count + " " + t(mark.text)
1335
+ /* *
1336
+ * Licensed under the Apache License, Version 2.0 (the "License");
1337
+ * you may not use this file except in compliance with the License.
1338
+ * You may obtain a copy of the License at
1339
+ *
1340
+ * http://www.apache.org/licenses/LICENSE-2.0
1341
+ *
1342
+ * Unless required by applicable law or agreed to in writing, software
1343
+ * distributed under the License is distributed on an "AS IS" BASIS,
1344
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1345
+ * See the License for the specific language governing permissions and
1346
+ * limitations under the License.
1347
+ *
1348
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
1349
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
1350
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
1351
+ * */
1352
+ var drawBackground = function drawBackground(context, theme, visibleTimeStart, visibleTimeEnd, animationStartPx, animationEndPx, canvasWidth, height, secondsPerPx, timeSliderSpan, dataStartPx, dataEndPx, currentTimePx) {
1353
+ var ctx = context;
1354
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
1355
+ timelineNightTime = _theme$palette$geoweb.timelineNightTime,
1356
+ ledgendObservedBackground = _theme$palette$geoweb.ledgendObservedBackground,
1357
+ legendForecastBackground = _theme$palette$geoweb.legendForecastBackground,
1358
+ legendNoDataBackground = _theme$palette$geoweb.legendNoDataBackground;
1359
+ // top spacing
1360
+ var y = 0;
1361
+ var scaleToUse = timeSliderSpan ? getScaleFromSpan(timeSliderSpan) : getFundamentalScale(secondsPerPx);
1362
+ drawDefaultBackground();
1363
+ drawObservedData();
1364
+ drawForecastData();
1365
+ drawNightOrAlternateTime();
1366
+ drawAnimationArea();
1367
+ drawDraggableIcons();
1368
+ function drawDefaultBackground() {
1369
+ ctx.fillStyle = legendNoDataBackground.rgba;
1370
+ ctx.fillRect(0, y, canvasWidth, height);
1371
+ }
1372
+ function drawObservedData() {
1373
+ if (dataStartPx < currentTimePx) {
1374
+ ctx.fillStyle = ledgendObservedBackground.fill;
1375
+ ctx.fillRect(Math.max(dataStartPx, y), y, Math.min(currentTimePx, dataEndPx) - Math.max(dataStartPx, y), height);
1376
+ }
1377
+ }
1378
+ function drawForecastData() {
1379
+ if (dataEndPx > currentTimePx) {
1380
+ ctx.fillStyle = legendForecastBackground.fill;
1381
+ ctx.fillRect(Math.max(currentTimePx, dataStartPx), y, Math.min(canvasWidth, dataEndPx) - Math.max(currentTimePx, dataStartPx), height);
1382
+ }
1383
+ }
1384
+ function drawAnimationArea() {
1385
+ ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineSelectionBackground.rgba;
1386
+ ctx.strokeStyle = theme.palette.geowebColors.timeSlider.timelineSelectionOutline.rgba;
1387
+ ctx.lineWidth = 3;
1388
+ ctx.rect(animationStartPx, y, Math.max(animationEndPx - animationStartPx, y), height);
1389
+ ctx.fill();
1390
+ ctx.stroke();
1391
+ }
1392
+ function drawDraggableIcons() {
1393
+ ctx.save();
1394
+ var path = new Path2D(dragHandlePath);
1395
+ ctx.translate(animationStartPx, y);
1396
+ ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
1397
+ ctx.fill(path);
1398
+ ctx.restore();
1399
+ ctx.save();
1400
+ ctx.translate(animationEndPx - 24, y);
1401
+ ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
1402
+ ctx.fill(path);
1403
+ ctx.restore();
1404
+ }
1405
+ function drawNightOrAlternateTime() {
1406
+ var colorChangeTimesteps = getColorChangeTimesteps(scaleToUse, visibleTimeStart, visibleTimeEnd);
1407
+ colorChangeTimesteps.forEach(function (timestep, i, arr) {
1408
+ if (i === 0) {
1409
+ return;
1410
+ }
1411
+ var _map = [arr[i - 1], timestep].map(function (timestep) {
1412
+ return timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
1413
+ }),
1414
+ prevPx = _map[0],
1415
+ currPx = _map[1];
1416
+ if (!isColorIntervalEven(scaleToUse, timestep)) {
1417
+ ctx.fillStyle = timelineNightTime.rgba;
1418
+ var TOP_OFFSET = 0;
1419
+ ctx.fillRect(prevPx, TOP_OFFSET, currPx - prevPx, height);
1420
+ }
1510
1421
  });
1511
- });
1512
- var onChangeSliderValue = function onChangeSliderValue(newSliderValue) {
1513
- var newLength = newSliderValue ? Math.round(newSliderValue) : 0;
1514
- onChangeAnimationLength == null || onChangeAnimationLength(newLength);
1515
- };
1516
- var _useState = useState(false),
1517
- open = _useState[0],
1518
- setOpen = _useState[1];
1519
- return jsx(TimeSliderMenu, {
1520
- allOptionsDisabled: disabled,
1521
- displayCurrentLength: true,
1522
- handleAutoClick: toggleAnimationLengthAuto,
1523
- icon: jsx(Animation, {
1524
- "data-testid": "animationLengthButton"
1525
- }),
1526
- isAutoDisabled: !layerHasTimeStep,
1527
- isAutoSelected: isAuto,
1528
- marks: translatedMarks,
1529
- onChangeSliderValue: onChangeSliderValue,
1530
- open: open,
1531
- setOpen: setOpen,
1532
- title: t('timeslider-animation'),
1533
- value: animationLength
1534
- });
1422
+ }
1423
+ };
1424
+ var getColorChangeTimestepUnit = function getColorChangeTimestepUnit(scale) {
1425
+ switch (scale) {
1426
+ case Scale.Year:
1427
+ return 'months';
1428
+ case Scale.Month:
1429
+ case Scale.Months3:
1430
+ return 'weeks';
1431
+ case Scale.Weeks2:
1432
+ case Scale.Week:
1433
+ return 'days';
1434
+ default:
1435
+ return 'days';
1436
+ }
1437
+ };
1438
+ var isColorIntervalEven = function isColorIntervalEven(scale, timestep) {
1439
+ var time = dateUtils.fromUnix(timestep);
1440
+ switch (scale) {
1441
+ case Scale.Year:
1442
+ return dateUtils.getMonth(time) % 2 === 0;
1443
+ case Scale.Month:
1444
+ case Scale.Months3:
1445
+ return dateUtils.getWeek(time) % 2 === 0;
1446
+ case Scale.Week:
1447
+ case Scale.Weeks2:
1448
+ return dateUtils.getDayOfYear(time) % 2 === 0;
1449
+ default:
1450
+ {
1451
+ return dateUtils.getDayOfYear(time) % 2 === 0;
1452
+ }
1453
+ }
1535
1454
  };
1455
+ function getColorChangeTimesteps(scale, visibleTimeStart, visibleTimeEnd) {
1456
+ var _getCustomRoundedStar = getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, scale),
1457
+ colorChangeStart = _getCustomRoundedStar[0],
1458
+ colorChangeEnd = _getCustomRoundedStar[1];
1459
+ var colorChangeUnit = getColorChangeTimestepUnit(scale);
1460
+ var colorChangeTimesteps = getCustomTimesteps(colorChangeStart, colorChangeEnd, colorChangeUnit);
1461
+ return colorChangeTimesteps;
1462
+ }
1536
1463
 
1537
- var SpeedButton = function SpeedButton(_ref) {
1538
- var animationDelay = _ref.animationDelay,
1539
- setMapAnimationDelay = _ref.setMapAnimationDelay;
1540
- var sorted = [].concat(speedFactors).sort(function (sa, sb) {
1541
- return sb - sa;
1542
- });
1543
- var marks = sorted.map(function (speedFactor) {
1544
- return {
1545
- value: getSpeedDelay(speedFactor),
1546
- text: "x" + speedFactor,
1547
- label: "x" + speedFactor
1548
- };
1549
- });
1550
- var _useTimesliderTransla = useTimesliderTranslation(),
1551
- t = _useTimesliderTransla.t;
1552
- var _useState = useState(false),
1553
- open = _useState[0],
1554
- setOpen = _useState[1];
1555
- return jsx(TimeSliderMenu, {
1556
- icon: jsx(Speed, {}),
1557
- marks: marks,
1558
- onChangeSliderValue: function onChangeSliderValue(markValue) {
1559
- setMapAnimationDelay(markValue);
1560
- },
1561
- open: open,
1562
- setOpen: setOpen,
1563
- title: t('timeslider-speed'),
1564
- value: animationDelay
1565
- });
1464
+ /* *
1465
+ * Licensed under the Apache License, Version 2.0 (the "License");
1466
+ * you may not use this file except in compliance with the License.
1467
+ * You may obtain a copy of the License at
1468
+ *
1469
+ * http://www.apache.org/licenses/LICENSE-2.0
1470
+ *
1471
+ * Unless required by applicable law or agreed to in writing, software
1472
+ * distributed under the License is distributed on an "AS IS" BASIS,
1473
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1474
+ * See the License for the specific language governing permissions and
1475
+ * limitations under the License.
1476
+ *
1477
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
1478
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
1479
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
1480
+ * */
1481
+ var drawCurrentTime = function drawCurrentTime(context, theme, width, height, startTime, endTime, currentTime) {
1482
+ var ctx = context;
1483
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
1484
+ playerNeedleTime = _theme$palette$geoweb.playerNeedleTime,
1485
+ playerNeedleTimeTop = _theme$palette$geoweb.playerNeedleTimeTop;
1486
+ var current = currentTime;
1487
+ var currentPx = current ? timestampToPixelEdges(current, startTime, endTime, width) : 0;
1488
+ // Draw a high vertical line (needle) indicating the current or selected time
1489
+ ctx.beginPath();
1490
+ // 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
1491
+ ctx.moveTo(Math.floor(currentPx) + 0.5, height - 24);
1492
+ ctx.lineTo(Math.floor(currentPx) + 0.5, height);
1493
+ ctx.lineWidth = 5;
1494
+ ctx.strokeStyle = playerNeedleTime.rgba;
1495
+ ctx.stroke();
1496
+ ctx.lineWidth = 1;
1497
+ ctx.strokeStyle = playerNeedleTimeTop.rgba;
1498
+ ctx.stroke();
1566
1499
  };
1567
1500
 
1568
- var TimeSpanButtonCustomSelect = function TimeSpanButtonCustomSelect(_ref) {
1569
- var timeSliderSpan = _ref.timeSliderSpan,
1570
- setOpen = _ref.setOpen,
1571
- onChangeSliderValue = _ref.onChangeSliderValue;
1572
- var _useTimesliderTransla = useTimesliderTranslation(),
1573
- t = _useTimesliderTransla.t;
1574
- var _React$useState = React.useState(timeSliderSpan / getLargestTimeUnit(timeSliderSpan)),
1575
- selectedTimeValue = _React$useState[0],
1576
- setSelectedTimeValue = _React$useState[1];
1577
- var _React$useState2 = React.useState(getLargestTimeUnit(timeSliderSpan).toString()),
1578
- selectedTimeResolution = _React$useState2[0],
1579
- setSelectedTimeResolution = _React$useState2[1];
1580
- var _React$useState3 = React.useState(true),
1581
- isANumber = _React$useState3[0],
1582
- setIsANumber = _React$useState3[1];
1583
- return jsx(Box, {
1584
- children: jsxs(FormControl, {
1585
- onKeyDown: function onKeyDown(event) {
1586
- event.stopPropagation();
1587
- },
1588
- size: "small",
1589
- sx: {
1590
- flexDirection: 'row',
1591
- display: 'flex'
1592
- },
1593
- variant: "standard",
1594
- children: [jsx(TextField, {
1595
- autoFocus: true,
1596
- color: isANumber ? 'primary' : 'warning',
1597
- label: t('timeslider-span'),
1598
- onBlur: function onBlur() {
1599
- onChangeSliderValue(selectedTimeValue * Number(selectedTimeResolution));
1600
- },
1601
- onChange: function onChange(e) {
1602
- if (!isNaN(+e.target.value)) {
1603
- setIsANumber(true);
1604
- setSelectedTimeValue(Number(e.target.value));
1605
- } else {
1606
- setIsANumber(false);
1607
- }
1608
- },
1609
- onKeyDown: function onKeyDown(e) {
1610
- if (e.key === 'Enter' || e.key === 'Escape') {
1611
- onChangeSliderValue(selectedTimeValue * Number(selectedTimeResolution));
1612
- setOpen(false);
1613
- }
1614
- },
1615
- size: "small",
1616
- slotProps: {
1617
- htmlInput: {
1618
- maxLength: 4,
1619
- 'aria-label': 'custom-input'
1620
- }
1621
- },
1622
- value: Math.round(selectedTimeValue * 100) / 100,
1623
- variant: "standard"
1624
- }), jsx(Box, {
1625
- sx: {
1626
- alignContent: 'end'
1627
- },
1628
- children: jsxs(Select, {
1629
- "aria-label": "time-resolution-selector",
1630
- defaultValue: "h",
1631
- onChange: function onChange(e) {
1632
- setSelectedTimeResolution(e.target.value);
1633
- onChangeSliderValue(selectedTimeValue * Number(e.target.value));
1634
- setOpen(false);
1635
- },
1636
- size: "small",
1637
- tabIndex: -1,
1638
- value: selectedTimeResolution,
1639
- children: [jsx(MenuItem, {
1640
- value: TimeInMinutes.YEAR,
1641
- children: t('years')
1642
- }), jsx(MenuItem, {
1643
- value: TimeInMinutes.MONTH,
1644
- children: t('months')
1645
- }), jsx(MenuItem, {
1646
- value: TimeInMinutes.WEEK,
1647
- children: t('weeks')
1648
- }), jsx(MenuItem, {
1649
- value: TimeInMinutes.DAY,
1650
- children: t('days')
1651
- }), jsx(MenuItem, {
1652
- value: TimeInMinutes.HOUR,
1653
- children: t('hours')
1654
- }), jsx(MenuItem, {
1655
- value: TimeInMinutes.MINUTE,
1656
- children: t('minutes')
1657
- })]
1658
- })
1659
- })]
1660
- })
1661
- });
1501
+ /* *
1502
+ * Licensed under the Apache License, Version 2.0 (the "License");
1503
+ * you may not use this file except in compliance with the License.
1504
+ * You may obtain a copy of the License at
1505
+ *
1506
+ * http://www.apache.org/licenses/LICENSE-2.0
1507
+ *
1508
+ * Unless required by applicable law or agreed to in writing, software
1509
+ * distributed under the License is distributed on an "AS IS" BASIS,
1510
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1511
+ * See the License for the specific language governing permissions and
1512
+ * limitations under the License.
1513
+ *
1514
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
1515
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
1516
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
1517
+ * */
1518
+ var drawNeedle = function drawNeedle(context, theme, width, height, startTime, endTime, selectedTime) {
1519
+ if (!selectedTime) {
1520
+ return;
1521
+ }
1522
+ var ctx = context;
1523
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
1524
+ playerNeedlePlayer = _theme$palette$geoweb.playerNeedlePlayer,
1525
+ playerNeedlePlayerTop = _theme$palette$geoweb.playerNeedlePlayerTop,
1526
+ playerTimeMarkers = _theme$palette$geoweb.playerTimeMarkers;
1527
+ var selectedPx = timestampToPixelEdges(selectedTime, startTime, endTime, width);
1528
+ // Draw a high vertical line (needle) indicating the current or selected time
1529
+ ctx.beginPath();
1530
+ // 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
1531
+ ctx.moveTo(Math.floor(selectedPx) + 0.5, height - 50);
1532
+ ctx.lineTo(Math.floor(selectedPx) + 0.5, height);
1533
+ ctx.lineWidth = 5;
1534
+ ctx.strokeStyle = playerNeedlePlayer.rgba;
1535
+ ctx.stroke();
1536
+ ctx.lineWidth = 1;
1537
+ ctx.strokeStyle = playerNeedlePlayerTop.rgba;
1538
+ ctx.stroke();
1539
+ // Triange connecting timebox.
1540
+ ctx.beginPath();
1541
+ ctx.moveTo(Math.floor(selectedPx) + 5, 0);
1542
+ ctx.lineTo(Math.floor(selectedPx) + 0.5, 5);
1543
+ ctx.lineTo(Math.floor(selectedPx) - 5, 0);
1544
+ ctx.closePath();
1545
+ ctx.fillStyle = playerTimeMarkers.fill;
1546
+ ctx.fill();
1662
1547
  };
1663
1548
 
1664
- var marks$1 = [{
1665
- value: 60,
1666
- text: 'timeslider-hour',
1667
- count: 1
1668
- }, {
1669
- value: 3 * 60,
1670
- text: 'timeslider-hour',
1671
- count: 3
1672
- }, {
1673
- value: 6 * 60,
1674
- text: 'timeslider-hour',
1675
- count: 6
1676
- }, {
1677
- value: 12 * 60,
1678
- text: 'timeslider-hour',
1679
- count: 12
1680
- }, {
1681
- value: 24 * 60,
1682
- text: 'timeslider-hour',
1683
- count: 24
1684
- }, {
1685
- value: 2 * 24 * 60,
1686
- text: 'timeslider-hour',
1687
- count: 48
1688
- }, {
1689
- value: 7 * 24 * 60,
1690
- text: 'timeslider-week',
1691
- count: 1
1692
- }, {
1693
- value: 2 * 7 * 24 * 60,
1694
- text: 'timeslider-weeks',
1695
- count: 2
1696
- }, {
1697
- value: 30 * 24 * 60,
1698
- text: 'timeslider-month',
1699
- count: 1
1700
- }, {
1701
- value: 3 * 30 * 24 * 60,
1702
- text: 'timeslider-months',
1703
- count: 3
1704
- }, {
1705
- value: 365 * 24 * 60,
1706
- text: 'timeslider-year',
1707
- count: 1
1708
- }].sort(function (ta, tb) {
1709
- return tb.value - ta.value;
1710
- });
1711
- var TimeSpanButton = function TimeSpanButton(_ref) {
1712
- var _ref$timeSliderSpan = _ref.timeSliderSpan,
1713
- timeSliderSpan = _ref$timeSliderSpan === void 0 ? defaultTimeSpan : _ref$timeSliderSpan,
1714
- _ref$disabled = _ref.disabled,
1715
- disabled = _ref$disabled === void 0 ? false : _ref$disabled,
1716
- _ref$onChangeSliderVa = _ref.onChangeSliderValue,
1717
- onChangeSliderValue = _ref$onChangeSliderVa === void 0 ? function () {} : _ref$onChangeSliderVa,
1718
- onToggleTimeSpan = _ref.onToggleTimeSpan,
1719
- isTimeSpanAuto = _ref.isTimeSpanAuto,
1720
- _ref$isOpenByDefault = _ref.isOpenByDefault,
1721
- isOpenByDefault = _ref$isOpenByDefault === void 0 ? false : _ref$isOpenByDefault,
1722
- _ref$layerHasTimeStep = _ref.layerHasTimeStep,
1723
- layerHasTimeStep = _ref$layerHasTimeStep === void 0 ? false : _ref$layerHasTimeStep;
1724
- var _useTimesliderTransla = useTimesliderTranslation(),
1725
- t = _useTimesliderTransla.t;
1726
- var translatedMarks = marks$1.map(function (mark) {
1727
- return Object.assign({}, mark, {
1728
- label: mark.count + " " + t(mark.text)
1729
- });
1730
- });
1731
- var _useState = useState(isOpenByDefault),
1732
- open = _useState[0],
1733
- setOpen = _useState[1];
1734
- return jsx(TimeSliderMenu, {
1735
- allOptionsDisabled: disabled,
1736
- customFieldHeader: t('timeslider-span'),
1737
- customLengthSelector: jsx(TimeSpanButtonCustomSelect, {
1738
- onChangeSliderValue: onChangeSliderValue,
1739
- setOpen: setOpen,
1740
- timeSliderSpan: timeSliderSpan
1549
+ /* *
1550
+ * Licensed under the Apache License, Version 2.0 (the "License");
1551
+ * you may not use this file except in compliance with the License.
1552
+ * You may obtain a copy of the License at
1553
+ *
1554
+ * http://www.apache.org/licenses/LICENSE-2.0
1555
+ *
1556
+ * Unless required by applicable law or agreed to in writing, software
1557
+ * distributed under the License is distributed on an "AS IS" BASIS,
1558
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1559
+ * See the License for the specific language governing permissions and
1560
+ * limitations under the License.
1561
+ *
1562
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
1563
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
1564
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
1565
+ * */
1566
+ var drawTimeSliderLegend = function drawTimeSliderLegend(context, theme, canvasWidth, height, centerTime, secondsPerPx, timeSliderSpan, selectedTimeUnix, currentTimeUnix, animationStartTime, animationEndTime, dataStartTime, dataEndTime) {
1567
+ var ctx = context;
1568
+ var _map = [0, canvasWidth].map(function (px) {
1569
+ return pixelToTimestamp(px, centerTime, canvasWidth, secondsPerPx);
1741
1570
  }),
1742
- disbleUserSetDuration: false,
1743
- displayCurrentLength: true,
1744
- handleAutoClick: onToggleTimeSpan,
1745
- icon: jsx(Clock, {}),
1746
- isAutoDisabled: !layerHasTimeStep,
1747
- isAutoSelected: isTimeSpanAuto,
1748
- marks: translatedMarks,
1749
- onChangeSliderValue: onChangeSliderValue,
1750
- open: open,
1751
- setOpen: setOpen,
1752
- title: t('timeslider-time-span'),
1753
- value: timeSliderSpan
1754
- });
1571
+ visibleTimeStart = _map[0],
1572
+ visibleTimeEnd = _map[1];
1573
+ var _map2 = [animationStartTime, animationEndTime, dataStartTime, dataEndTime, currentTimeUnix].map(function (time) {
1574
+ return timestampToPixel(time, centerTime, canvasWidth, secondsPerPx);
1575
+ }),
1576
+ animationStartPx = _map2[0],
1577
+ animationEndPx = _map2[1],
1578
+ dataStartPx = _map2[2],
1579
+ dataEndPx = _map2[3],
1580
+ currentTimePx = _map2[4];
1581
+ ctx.clearRect(0, 0, canvasWidth, height);
1582
+ drawBackground(ctx, theme, visibleTimeStart, visibleTimeEnd, animationStartPx, animationEndPx, canvasWidth, height, secondsPerPx, timeSliderSpan, dataStartPx, dataEndPx, currentTimePx);
1583
+ drawTimeScale(ctx, theme, visibleTimeStart, visibleTimeEnd, canvasWidth, height, secondsPerPx);
1584
+ drawCurrentTime(ctx, theme, canvasWidth, height, visibleTimeStart, visibleTimeEnd, currentTimeUnix);
1585
+ drawNeedle(ctx, theme, canvasWidth, height, visibleTimeStart, visibleTimeEnd, selectedTimeUnix);
1755
1586
  };
1756
1587
 
1757
- var marks = [{
1758
- value: 1,
1759
- text: 'timeslider-min',
1760
- count: 1
1761
- }, {
1762
- value: 2,
1763
- text: 'timeslider-min',
1764
- count: 2
1765
- }, {
1766
- value: 5,
1767
- text: 'timeslider-min',
1768
- count: 5
1769
- }, {
1770
- value: 10,
1771
- text: 'timeslider-min',
1772
- count: 10
1773
- }, {
1774
- value: 15,
1775
- text: 'timeslider-min',
1776
- count: 15
1777
- }, {
1778
- value: 30,
1779
- text: 'timeslider-min',
1780
- count: 30
1781
- }, {
1782
- value: 60,
1783
- text: 'timeslider-hour',
1784
- count: 1
1785
- }, {
1786
- value: 120,
1787
- text: 'timeslider-hour',
1788
- count: 2
1789
- }, {
1790
- value: 180,
1791
- text: 'timeslider-hour',
1792
- count: 3
1793
- }, {
1794
- value: 360,
1795
- text: 'timeslider-hour',
1796
- count: 6
1797
- }, {
1798
- value: 720,
1799
- text: 'timeslider-hour',
1800
- count: 12
1801
- }, {
1802
- value: 1440,
1803
- text: 'timeslider-hour',
1804
- count: 24
1805
- }, {
1806
- value: 2880,
1807
- text: 'timeslider-hour',
1808
- count: 48
1809
- }, {
1810
- value: 4320,
1811
- text: 'timeslider-hour',
1812
- count: 72
1813
- }, {
1814
- value: 10080,
1815
- text: 'timeslider-week',
1816
- count: 1
1817
- }, {
1818
- value: 20160,
1819
- text: 'timeslider-weeks',
1820
- count: 2
1821
- }, {
1822
- value: 43200,
1823
- text: 'timeslider-month',
1824
- count: 1
1825
- }, {
1826
- value: 87600,
1827
- text: 'timeslider-months',
1828
- count: 2
1829
- }, {
1830
- value: 262800,
1831
- text: 'timeslider-months',
1832
- count: 6
1833
- }, {
1834
- value: 525600,
1835
- text: 'timeslider-year',
1836
- count: 1
1837
- }, {
1838
- value: 5256000,
1839
- text: 'timeslider-years',
1840
- count: 10
1841
- }].sort(function (ta, tb) {
1842
- return tb.value - ta.value;
1843
- });
1844
- var TimeStepButton = function TimeStepButton(_ref) {
1845
- var _ref$timeStep = _ref.timeStep,
1846
- timeStep = _ref$timeStep === void 0 ? marks[0].value : _ref$timeStep,
1847
- _ref$disabled = _ref.disabled,
1848
- disabled = _ref$disabled === void 0 ? false : _ref$disabled,
1849
- _ref$isTimestepAuto = _ref.isTimestepAuto,
1850
- isTimestepAuto = _ref$isTimestepAuto === void 0 ? false : _ref$isTimestepAuto,
1851
- onChangeTimeStep = _ref.onChangeTimeStep,
1852
- _ref$onToggleTimestep = _ref.onToggleTimestepAuto,
1853
- onToggleTimestepAuto = _ref$onToggleTimestep === void 0 ? function () {} : _ref$onToggleTimestep,
1854
- _ref$isOpenByDefault = _ref.isOpenByDefault,
1855
- isOpenByDefault = _ref$isOpenByDefault === void 0 ? false : _ref$isOpenByDefault,
1856
- timeStepFromLayer = _ref.timeStepFromLayer;
1857
- var _useTimesliderTransla = useTimesliderTranslation(),
1858
- t = _useTimesliderTransla.t;
1859
- var translatedMarks = marks.map(function (mark) {
1860
- return Object.assign({}, mark, {
1861
- label: mark.count + " " + t(mark.text)
1862
- });
1863
- });
1864
- var onMenuItemClick = function onMenuItemClick(markValue) {
1865
- if (isTimestepAuto) {
1866
- onToggleTimestepAuto();
1588
+ // Explanation of props can be found here:
1589
+ // https://drive.google.com/file/d/1jqqNcciCH0UJiZ04HO-1vknmPPpT8fK5/view?usp=sharing
1590
+ var TimeSliderLegend = function TimeSliderLegend(_ref) {
1591
+ var _node$current, _getTimeSliderLegendE;
1592
+ var mapId = _ref.mapId,
1593
+ isTimeScrollingEnabled = _ref.isTimeScrollingEnabled,
1594
+ mapWindowRef = _ref.mapWindowRef,
1595
+ centerTime = _ref.centerTime,
1596
+ canvasWidth = _ref.timeSliderWidth,
1597
+ _ref$secondsPerPx = _ref.secondsPerPx,
1598
+ secondsPerPx = _ref$secondsPerPx === void 0 ? defaultSecondsPerPx : _ref$secondsPerPx,
1599
+ currentTime = _ref.currentTime,
1600
+ dataStartTime = _ref.dataStartTime,
1601
+ dataEndTime = _ref.dataEndTime,
1602
+ reduxAnimationStartTime = _ref.reduxAnimationStartTime,
1603
+ reduxAnimationEndTime = _ref.reduxAnimationEndTime,
1604
+ timeStep = _ref.timeStep,
1605
+ unfilteredSelectedTime = _ref.unfilteredSelectedTime,
1606
+ isDraggingStartAnimation = _ref.isDraggingStartAnimation,
1607
+ isDraggingEndAnimation = _ref.isDraggingEndAnimation,
1608
+ isTimeSliderHoverOn = _ref.isTimeSliderHoverOn,
1609
+ timeSliderSpan = _ref.timeSliderSpan,
1610
+ _ref$setUnfilteredSel = _ref.setUnfilteredSelectedTime,
1611
+ setUnfilteredSelectedTime = _ref$setUnfilteredSel === void 0 ? function () {} : _ref$setUnfilteredSel,
1612
+ _ref$onSetCenterTime = _ref.onSetCenterTime,
1613
+ onSetCenterTime = _ref$onSetCenterTime === void 0 ? function () {} : _ref$onSetCenterTime,
1614
+ _ref$onSetAnimationSt = _ref.onSetAnimationStartTime,
1615
+ onSetAnimationStartTime = _ref$onSetAnimationSt === void 0 ? function () {} : _ref$onSetAnimationSt,
1616
+ _ref$onSetAnimationEn = _ref.onSetAnimationEndTime,
1617
+ onSetAnimationEndTime = _ref$onSetAnimationEn === void 0 ? function () {} : _ref$onSetAnimationEn,
1618
+ _ref$updateCanvasWidt = _ref.updateCanvasWidth,
1619
+ updateCanvasWidth = _ref$updateCanvasWidt === void 0 ? function () {} : _ref$updateCanvasWidt,
1620
+ setIsDraggingStartAnimation = _ref.setIsDraggingStartAnimation,
1621
+ setIsDraggingEndAnimation = _ref.setIsDraggingEndAnimation,
1622
+ onStartTimeChange = _ref.onStartTimeChange,
1623
+ onEndTimeChange = _ref.onEndTimeChange,
1624
+ onSetTimeSliderSpan = _ref.onSetTimeSliderSpan,
1625
+ _ref$adjustSelectedTi = _ref.adjustSelectedTimeOnWheel,
1626
+ adjustSelectedTimeOnWheel = _ref$adjustSelectedTi === void 0 ? function () {} : _ref$adjustSelectedTi;
1627
+ var _useCanvasTarget = useCanvasTarget('mousedown'),
1628
+ node = _useCanvasTarget[1];
1629
+ var theme = useTheme();
1630
+ var _useState = useState(false),
1631
+ isDraggingSelectedTime = _useState[0],
1632
+ setIsDraggingSelectedTime = _useState[1];
1633
+ var _useState2 = useState(false),
1634
+ isDraggingLegend = _useState2[0],
1635
+ setIsDraggingLegend = _useState2[1];
1636
+ var xOffset = ((_node$current = node.current) == null || (_node$current = _node$current.canvas) == null ? void 0 : _node$current.getBoundingClientRect().x) || 0;
1637
+ var _useState3 = useState(false),
1638
+ isDraggingAnimationArea = _useState3[0],
1639
+ setIsDraggingAnimationArea = _useState3[1];
1640
+ var _useState4 = useState(false),
1641
+ isMouseOverCanvas = _useState4[0],
1642
+ setIsMouseOverCanvas = _useState4[1];
1643
+ var _useState5 = useState('auto'),
1644
+ cursorStyle = _useState5[0],
1645
+ setCursorStyle = _useState5[1];
1646
+ var _useState6 = useState(undefined),
1647
+ showTooltip = _useState6[0],
1648
+ setShowTooltip = _useState6[1];
1649
+ var _useState7 = useState(),
1650
+ lastHandledRoundedTime = _useState7[0],
1651
+ setLastHandledRoundedTime = _useState7[1];
1652
+ // remove active drag. can happen outside canvas.
1653
+ var _useState8 = useState(),
1654
+ localAnimationStartTime = _useState8[0],
1655
+ setLocalAnimationStartTime = _useState8[1];
1656
+ var _useState9 = useState(),
1657
+ localAnimationEndTime = _useState9[0],
1658
+ setLocalAnimationEndTime = _useState9[1];
1659
+ var _useState0 = useState(),
1660
+ pointerTime = _useState0[0],
1661
+ setPointerTime = _useState0[1];
1662
+ var _useState1 = useState(false),
1663
+ showPointerTimeTooltip = _useState1[0],
1664
+ setShowPointerTimeTooltip = _useState1[1];
1665
+ var debouncedSetShowPointerTimeTooltip = useRef(debounce(setShowPointerTimeTooltip, 500)).current;
1666
+ var timeBetweenMouseAndStartAndEnd = useRef();
1667
+ var pixelsMovedSinceStartDragging = useRef(0);
1668
+ var isAnimationTimeModifiedSetRef = useRef(false);
1669
+ var tooltipPosition = useRef();
1670
+ var startDraggingPosition = useRef(0);
1671
+ var popperRef = useRef(null);
1672
+ var isClickOrDrag = useRef();
1673
+ var filteredTime = getFilteredTime(unfilteredSelectedTime, timeStep, dataStartTime, dataEndTime);
1674
+ var start = localAnimationStartTime;
1675
+ var end = localAnimationEndTime;
1676
+ var pixelsBetweenViewportAndTimesliderOnTop = (_getTimeSliderLegendE = getTimeSliderLegendElement(mapId)) == null ? void 0 : _getTimeSliderLegendE.getBoundingClientRect()['top'];
1677
+ var setTooltipPosition = function setTooltipPosition() {
1678
+ var tooltipX = tooltipPosition.current;
1679
+ var tooltipY = pixelsBetweenViewportAndTimesliderOnTop && pixelsBetweenViewportAndTimesliderOnTop - TIME_SLIDER_LEGEND_HEIGHT * 2.5;
1680
+ return new DOMRect(tooltipX, tooltipY, 0, 0);
1681
+ };
1682
+ var getTooltipTime = function getTooltipTime() {
1683
+ switch (showTooltip) {
1684
+ case 'animationStart':
1685
+ return localAnimationStartTime;
1686
+ case 'animationEnd':
1687
+ return localAnimationEndTime;
1688
+ case 'mousePointer':
1689
+ return pointerTime;
1690
+ default:
1691
+ return undefined;
1867
1692
  }
1868
- onChangeTimeStep(markValue);
1869
1693
  };
1870
- var handleToggleTimeStep = function handleToggleTimeStep() {
1871
- if (isTimestepAuto) {
1872
- return;
1694
+ var getTooltipText = function getTooltipText() {
1695
+ var time = getTooltipTime();
1696
+ if (!time) {
1697
+ return undefined;
1873
1698
  }
1874
- onToggleTimestepAuto();
1875
- timeStepFromLayer && onChangeTimeStep(timeStepFromLayer);
1699
+ var roundedTooltipTime = showTooltip === 'mousePointer' ? time : roundWithTimeStep$1(time);
1700
+ var tooltipText = dateUtils.dateToString(dateUtils.fromUnix(roundedTooltipTime), dateUtils.DATE_FORMAT_HOURS);
1701
+ return tooltipText;
1876
1702
  };
1877
- var layerHasTimeStep = Boolean(timeStepFromLayer);
1878
- renderCounter.count(TimeStepButton.name);
1879
- var _useState = useState(isOpenByDefault),
1880
- open = _useState[0],
1881
- setOpen = _useState[1];
1882
- return jsx(TimeSliderMenu, {
1883
- allOptionsDisabled: disabled,
1884
- displayCurrentLength: true,
1885
- handleAutoClick: handleToggleTimeStep,
1886
- icon: jsx(FastForward, {
1887
- "data-testid": "timeStepButton"
1888
- }),
1889
- isAutoDisabled: !layerHasTimeStep,
1890
- isAutoSelected: isTimestepAuto,
1891
- marks: translatedMarks,
1892
- onChangeSliderValue: onMenuItemClick,
1893
- open: open,
1894
- setOpen: setOpen,
1895
- title: t('timeslider-time-step'),
1896
- value: timeStep || translatedMarks[0].value
1897
- });
1898
- };
1899
-
1900
- var OptionsMenu = function OptionsMenu(_ref) {
1901
- var speedBtn = _ref.speedBtn,
1902
- timeSpanBtn = _ref.timeSpanBtn,
1903
- timeStepBtn = _ref.timeStepBtn,
1904
- animationLengthBtn = _ref.animationLengthBtn;
1905
- return jsxs(Fragment, {
1906
- children: [jsx(Grid, {
1907
- size: {
1908
- xs: 'auto'
1909
- },
1910
- children: timeSpanBtn || jsx(TimeSpanButton, {
1911
- disabled: false,
1912
- isTimeSpanAuto: false,
1913
- layerHasTimeStep: false,
1914
- onChangeSliderValue: function onChangeSliderValue() {},
1915
- onToggleTimeSpan: function onToggleTimeSpan() {},
1916
- timeSliderSpan: 0
1917
- })
1918
- }), jsx(Grid, {
1919
- size: {
1920
- xs: 'auto'
1921
- },
1922
- children: animationLengthBtn || jsx(AnimationLengthButton, {
1923
- onChangeAnimationLength: function onChangeAnimationLength() {},
1924
- toggleAnimationLengthAuto: function toggleAnimationLengthAuto() {}
1925
- })
1926
- }), jsx(Grid, {
1927
- size: {
1928
- xs: 'auto'
1929
- },
1930
- children: timeStepBtn || jsx(TimeStepButton, {
1931
- isTimestepAuto: false,
1932
- onChangeTimeStep: function onChangeTimeStep() {}
1933
- })
1934
- }), jsx(Grid, {
1935
- size: {
1936
- xs: 'auto'
1937
- },
1938
- children: speedBtn || jsx(SpeedButton, {
1939
- animationDelay: defaultAnimationDelayAtStart,
1940
- setMapAnimationDelay: function setMapAnimationDelay() {}
1941
- })
1942
- })]
1943
- });
1944
- };
1945
-
1946
- var PopperMenu = function PopperMenu(_ref) {
1947
- var controls = _ref.controls,
1948
- isPopperOpen = _ref.isPopperOpen,
1949
- options = _ref.options,
1950
- buttonElement = _ref.buttonElement,
1951
- popperPlacement = _ref.popperPlacement;
1952
- if (!buttonElement) {
1953
- return null;
1954
- }
1955
- var direction = ['bottom', 'top'].includes(popperPlacement) ? 'column' : 'row';
1956
- var margin = getMargin(buttonElement, popperPlacement);
1957
- return jsx(Popper, {
1958
- anchorEl: direction === 'row' ? buttonElement == null ? void 0 : buttonElement.parentElement : buttonElement,
1959
- open: isPopperOpen,
1960
- placement: popperPlacement,
1961
- sx: {
1962
- zIndex: 3
1963
- },
1964
- children: jsx(Paper, {
1965
- elevation: 3,
1966
- sx: Object.assign({}, margin),
1967
- children: jsxs(Grid, {
1968
- container: true,
1969
- direction: direction,
1970
- spacing: 0.5,
1971
- sx: Object.assign({
1972
- padding: '4px 8px 8px'
1973
- }, direction === 'column' && {
1974
- '& button': {
1975
- width: '100%!important'
1976
- }
1977
- }, direction === 'row' && {
1978
- marginTop: -0.5
1979
- }),
1980
- children: [options != null ? options : jsx(OptionsMenu, {}), controls != null ? controls : jsx(ControlButtons, {})]
1981
- })
1982
- })
1983
- });
1984
- };
1985
- var getMargin = function getMargin(buttonElement, popperPlacement) {
1986
- var clock = buttonElement.parentElement.getBoundingClientRect();
1987
- var button = buttonElement.getBoundingClientRect();
1988
- var distanceFromButtonToContainer = clock.bottom - button.bottom;
1989
- if (popperPlacement === 'top') {
1990
- return {
1991
- marginBottom: distanceFromButtonToContainer + "px!important"
1992
- };
1993
- }
1994
- if (popperPlacement === 'bottom') {
1995
- return {
1996
- marginTop: distanceFromButtonToContainer + "px!important"
1997
- };
1998
- }
1999
- return undefined;
2000
- };
2001
-
2002
- var MIN_WIDTH = 170;
2003
- var MIN_HEIGHT = 32;
2004
- var MIN_FONT_SIZE = 14; // bigger font size will cause render delay in LCP
2005
- var FONT_SIZE_WIDTH_RATIO = MIN_FONT_SIZE / MIN_WIDTH;
2006
- var BUTTON_WIDTH = 40;
2007
- var POPPER_WIDTH = 356;
2008
- var POPPER_LENGTH = 240;
2009
- var TimeSliderClock = function TimeSliderClock(_ref2) {
2010
- var time = _ref2.time,
2011
- options = _ref2.options,
2012
- controls = _ref2.controls,
2013
- _ref2$hideButton = _ref2.hideButton,
2014
- hideButton = _ref2$hideButton === void 0 ? true : _ref2$hideButton,
2015
- _ref2$isPopperOpenByD = _ref2.isPopperOpenByDefault,
2016
- isPopperOpenByDefault = _ref2$isPopperOpenByD === void 0 ? false : _ref2$isPopperOpenByD;
2017
- var clockElement = useRef(null);
2018
- var _useState = useState(null),
2019
- buttonElement = _useState[0],
2020
- setButtonElement = _useState[1];
2021
- var _useState2 = useState(false),
2022
- isPopperOpen = _useState2[0],
2023
- setIsPopperOpen = _useState2[1];
2024
- var _useState3 = useState('left'),
2025
- popperPlacement = _useState3[0],
2026
- setPopperPlacement = _useState3[1];
2027
- var _useState4 = useState({
2028
- x: 0,
2029
- y: 0
2030
- }),
2031
- position = _useState4[0],
2032
- setPosition = _useState4[1];
2033
- useMakeSureContainerStaysInsideWindow(clockElement, position, setPosition);
2034
- var _useState5 = useState({
2035
- width: MIN_WIDTH,
2036
- height: MIN_HEIGHT
2037
- }),
2038
- size = _useState5[0],
2039
- setSize = _useState5[1];
2040
- var _useState6 = useState(MIN_FONT_SIZE),
2041
- fontSize = _useState6[0],
2042
- setFontSize = _useState6[1];
2043
- useEffect(function () {
2044
- if (hideButton) {
2045
- setIsPopperOpen(false);
1703
+ var roundWithTimeStep$1 = function roundWithTimeStep$1(time) {
1704
+ return roundWithTimeStep(time, timeStep);
1705
+ };
1706
+ var currentIndex = timeValues.indexOf(timeSliderSpan);
1707
+ var updateTimeSpan = function updateTimeSpan(deltaY) {
1708
+ if (onSetTimeSliderSpan) {
1709
+ // Don't do anything if we are already at the edges of the timespan options
1710
+ if (deltaY < 0 && currentIndex === 0 || deltaY > 0 && currentIndex === timeValues.length - 1) {
1711
+ return;
1712
+ }
1713
+ var newTimeSpan = deltaY < 0 ? timeValues[currentIndex - 1] : timeValues[currentIndex + 1];
1714
+ onSetTimeSliderSpan(newTimeSpan, centerTime);
2046
1715
  }
2047
- if (size.width === MIN_WIDTH && hideButton) {
1716
+ };
1717
+ var throttledUpdateTimeSpan = throttle(updateTimeSpan, 200);
1718
+ var debouncedAndThrottledUpdateTimeSpan = debounce(throttledUpdateTimeSpan, 20);
1719
+ var handleAnimationDragging = React.useCallback(function (x, clientX) {
1720
+ if (!localAnimationStartTime || !localAnimationEndTime) {
2048
1721
  return;
2049
1722
  }
2050
- var diff = hideButton ? -40 : BUTTON_WIDTH;
2051
- var width = size.width + diff;
2052
- setSize(Object.assign({}, size, {
2053
- width: width
2054
- }));
2055
- // eslint-disable-next-line react-hooks/exhaustive-deps
2056
- }, [hideButton]);
2057
- useEffect(function () {
2058
- if (buttonElement && isPopperOpenByDefault) {
2059
- setIsPopperOpen(true);
1723
+ var mousePosition = clientX - xOffset;
1724
+ var startPos = timestampToPixel(localAnimationStartTime, centerTime, canvasWidth, secondsPerPx);
1725
+ var endPos = timestampToPixel(localAnimationEndTime, centerTime, canvasWidth, secondsPerPx);
1726
+ var mouseTimeUnix = pixelToTimestamp(mousePosition, centerTime, canvasWidth, secondsPerPx);
1727
+ var startTime = roundWithTimeStep(mouseTimeUnix, timeStep);
1728
+ var endTime = roundWithTimeStep(mouseTimeUnix, timeStep);
1729
+ var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
1730
+ if (isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
1731
+ if (!isAnimationTimeModifiedSetRef.current) {
1732
+ isAnimationTimeModifiedSetRef.current = true;
1733
+ }
2060
1734
  }
2061
- }, [buttonElement, isPopperOpenByDefault]);
2062
- return jsxs(Fragment, {
2063
- children: [jsx(PopperMenu, {
2064
- buttonElement: buttonElement,
2065
- controls: controls,
2066
- isPopperOpen: isPopperOpen,
2067
- options: options,
2068
- popperPlacement: popperPlacement
2069
- }), jsx(Draggable, {
2070
- bounds: "parent",
2071
- cancel: ".MuiButtonBase-root",
2072
- nodeRef: clockElement,
2073
- onStop: function onStop(_event, position) {
2074
- setPosition(position);
2075
- setPopperPlacement(getPopperplacement(clockElement.current));
2076
- },
2077
- position: position,
2078
- children: jsx("div", {
2079
- ref: function ref(_ref3) {
2080
- clockElement.current = _ref3;
2081
- setPopperPlacement(getPopperplacement(_ref3));
2082
- },
2083
- style: {
2084
- position: 'absolute',
2085
- zIndex: 1001,
2086
- top: '10px',
2087
- right: '10px'
2088
- },
2089
- children: jsx(Resizable, {
2090
- enable: resizeHandlePlacement,
2091
- handleComponent: {
2092
- bottomLeft: jsx(Resize, {
2093
- isRightAligned: true,
2094
- style: {
2095
- fill: '#FFFFFF'
2096
- }
2097
- })
2098
- },
2099
- lockAspectRatio: true,
2100
- minHeight: MIN_HEIGHT,
2101
- minWidth: hideButton ? MIN_WIDTH : MIN_WIDTH + BUTTON_WIDTH,
2102
- onResize: function onResize(_event, _direction, _ref, delta) {
2103
- var width = size.width + delta.width;
2104
- var adjustedWidth = hideButton ? width : width - BUTTON_WIDTH;
2105
- var fontSize = FONT_SIZE_WIDTH_RATIO * adjustedWidth;
2106
- setFontSize(fontSize);
2107
- },
2108
- onResizeStart: function onResizeStart(event) {
2109
- event.stopPropagation();
2110
- },
2111
- onResizeStop: function onResizeStop(_event, _direction, _ref, delta) {
2112
- var width = size.width + delta.width;
2113
- var height = size.height + delta.height;
2114
- setSize({
2115
- width: width,
2116
- height: height
2117
- });
2118
- setPopperPlacement(getPopperplacement(clockElement.current));
2119
- },
2120
- size: size,
2121
- children: jsx(ClockContainer, {
2122
- fontSize: fontSize,
2123
- hideButton: hideButton,
2124
- isPopperOpen: isPopperOpen,
2125
- onButtonClick: function onButtonClick() {
2126
- if (!isPopperOpen) {
2127
- setPopperPlacement(getPopperplacement(clockElement.current));
2128
- }
2129
- setIsPopperOpen(!isPopperOpen);
2130
- },
2131
- popperPlacement: popperPlacement,
2132
- setButtonElement: setButtonElement,
2133
- time: time
2134
- })
2135
- })
2136
- })
2137
- })]
2138
- });
2139
- };
2140
- var getPopperplacement = function getPopperplacement(clockElement) {
2141
- var _clockElement$parentE;
2142
- var clock = clockElement == null ? void 0 : clockElement.getBoundingClientRect();
2143
- var mapWindow = clockElement == null || (_clockElement$parentE = clockElement.parentElement) == null ? void 0 : _clockElement$parentE.getBoundingClientRect();
2144
- if (clock && mapWindow) {
2145
- var popperIsOutsideWindowOnLeft = mapWindow.left > clock.left - POPPER_WIDTH;
2146
- var popperIsOutsideWindowOnBottom = clock.bottom + POPPER_LENGTH > mapWindow.bottom;
2147
- var popperIsOutsideWindowOnRight = clock.right + POPPER_WIDTH > mapWindow.right;
2148
- if (popperIsOutsideWindowOnLeft && popperIsOutsideWindowOnBottom && popperIsOutsideWindowOnRight) {
2149
- return 'top';
1735
+ if (isDraggingStartAnimation) {
1736
+ if (isDraggingStartWithinBounds(endPos, mousePosition)) {
1737
+ return;
1738
+ }
1739
+ setLocalAnimationStartTime(roundWithTimeStep(mouseTimeUnix, timeStep));
1740
+ if (lastHandledRoundedTime !== startTime) {
1741
+ setLastHandledRoundedTime(startTime);
1742
+ setShowTooltip('animationStart');
1743
+ onStartTimeChange == null || onStartTimeChange(startTime);
1744
+ }
1745
+ } else if (isDraggingEndAnimation && pixelsBetweenOnLeft) {
1746
+ if (isDraggingEndWithinBounds(startPos, mousePosition, canvasWidth)) {
1747
+ return;
1748
+ }
1749
+ setLocalAnimationEndTime(roundWithTimeStep(mouseTimeUnix, timeStep));
1750
+ if (lastHandledRoundedTime !== endTime) {
1751
+ setLastHandledRoundedTime(endTime);
1752
+ setShowTooltip('animationEnd');
1753
+ onEndTimeChange == null || onEndTimeChange(endTime);
1754
+ }
2150
1755
  }
2151
- if (popperIsOutsideWindowOnLeft && popperIsOutsideWindowOnBottom) {
2152
- return 'right';
1756
+ if (isDraggingAnimationArea) {
1757
+ if (timeBetweenMouseAndStartAndEnd.current === undefined) {
1758
+ // to move the whole animation area we need to calculate the distance
1759
+ // between the mouse position and the start and end position
1760
+ var _timeFromMouseToStart = mouseTimeUnix - start;
1761
+ var _timeFromMouseToEnd = end - mouseTimeUnix;
1762
+ timeBetweenMouseAndStartAndEnd.current = {
1763
+ timeFromMouseToEnd: _timeFromMouseToEnd,
1764
+ timeFromMouseToStart: _timeFromMouseToStart
1765
+ };
1766
+ return;
1767
+ }
1768
+ pixelsMovedSinceStartDragging.current += x;
1769
+ var _timeBetweenMouseAndS = timeBetweenMouseAndStartAndEnd.current,
1770
+ timeFromMouseToEnd = _timeBetweenMouseAndS.timeFromMouseToEnd,
1771
+ timeFromMouseToStart = _timeBetweenMouseAndS.timeFromMouseToStart;
1772
+ var newStartTime = mouseTimeUnix - timeFromMouseToStart;
1773
+ var newEndTime = mouseTimeUnix + timeFromMouseToEnd;
1774
+ var roundedNewStartTime = roundWithTimeStep(newStartTime, timeStep);
1775
+ var roundedNewEndTime = roundWithTimeStep(newEndTime, timeStep);
1776
+ setLocalAnimationStartTime(roundedNewStartTime);
1777
+ setLocalAnimationEndTime(roundedNewEndTime);
2153
1778
  }
2154
- if (popperIsOutsideWindowOnLeft) {
2155
- return 'bottom';
1779
+ }, [canvasWidth, centerTime, end, isDraggingAnimationArea, isDraggingEndAnimation, isDraggingStartAnimation, lastHandledRoundedTime, localAnimationEndTime, localAnimationStartTime, mapId, onEndTimeChange, onStartTimeChange, secondsPerPx, start, timeStep, xOffset]);
1780
+ useEffect(function () {
1781
+ var handleMouseUp = function handleMouseUp() {
1782
+ pixelsMovedSinceStartDragging.current = 0;
1783
+ timeBetweenMouseAndStartAndEnd.current = undefined;
1784
+ };
1785
+ document.addEventListener('mouseup', handleMouseUp);
1786
+ return function () {
1787
+ document.removeEventListener('mouseup', handleMouseUp);
1788
+ };
1789
+ }, []);
1790
+ useEffect(function () {
1791
+ var startTimestamp = convertStringTimeToUnix(reduxAnimationStartTime);
1792
+ var endTimestamp = convertStringTimeToUnix(reduxAnimationEndTime);
1793
+ setLocalAnimationStartTime(startTimestamp);
1794
+ setLocalAnimationEndTime(endTimestamp);
1795
+ }, [reduxAnimationStartTime, reduxAnimationEndTime, setLocalAnimationStartTime, setLocalAnimationEndTime]);
1796
+ useEffect(function () {
1797
+ var stoppedDragging = !isDraggingStartAnimation && !isDraggingEndAnimation && !isDraggingAnimationArea;
1798
+ if (stoppedDragging && isAnimationTimeModifiedSetRef.current) {
1799
+ if (start && start !== localAnimationStartTime) {
1800
+ onSetAnimationStartTime(dateUtils.fromUnix(start).toISOString());
1801
+ }
1802
+ if (end && end !== localAnimationEndTime) {
1803
+ onSetAnimationEndTime(dateUtils.fromUnix(end).toISOString());
1804
+ }
1805
+ isAnimationTimeModifiedSetRef.current = false;
2156
1806
  }
2157
- }
2158
- return 'left';
2159
- };
2160
- var resizeHandlePlacement = {
2161
- top: false,
2162
- right: false,
2163
- bottom: false,
2164
- left: false,
2165
- topRight: false,
2166
- bottomRight: false,
2167
- bottomLeft: true,
2168
- topLeft: false
2169
- };
2170
-
2171
- var _scaleToUnitSeconds, _scaleToRoundableUnit;
2172
- 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);
2173
- var TICK_MARK_HEIGHT_PRIMARY = 40;
2174
- var TICK_MARK_HEIGHT_SECONDARY = 10;
2175
- var TICK_MARK_HEIGHT_TERTIARY = 5;
2176
- var getStepPxLineHeight = function getStepPxLineHeight(scale, timestep) {
2177
- var scaleUnitSeconds = scaleToUnitSeconds[scale];
2178
- var rem = timestep % scaleUnitSeconds;
2179
- switch (scale) {
2180
- case Scale.Hour:
2181
- {
2182
- if (rem === 0) {
2183
- return TICK_MARK_HEIGHT_PRIMARY;
2184
- }
2185
- // 15 min subdivisions
2186
- if (rem % (15 * 60) === 0) {
2187
- return TICK_MARK_HEIGHT_SECONDARY;
2188
- }
2189
- return TICK_MARK_HEIGHT_TERTIARY;
1807
+ }, [isDraggingStartAnimation, isDraggingEndAnimation, isDraggingAnimationArea, isAnimationTimeModifiedSetRef, localAnimationStartTime, localAnimationEndTime, onSetAnimationStartTime, onSetAnimationEndTime, start, end]);
1808
+ useEffect(function () {
1809
+ var handleMouseUp = function handleMouseUp() {
1810
+ if (isDraggingAnimationArea) {
1811
+ onStartTimeChange == null || onStartTimeChange(localAnimationStartTime);
1812
+ onEndTimeChange == null || onEndTimeChange(localAnimationEndTime);
2190
1813
  }
2191
- case Scale.Hours3:
2192
- {
2193
- if (rem === 0) {
2194
- return TICK_MARK_HEIGHT_PRIMARY;
2195
- }
2196
- return TICK_MARK_HEIGHT_TERTIARY;
1814
+ setCursorStyle('auto');
1815
+ setIsDraggingSelectedTime(false);
1816
+ setIsDraggingStartAnimation == null || setIsDraggingStartAnimation(false);
1817
+ setIsDraggingEndAnimation == null || setIsDraggingEndAnimation(false);
1818
+ setIsDraggingLegend(false);
1819
+ setShowTooltip(undefined);
1820
+ setIsDraggingAnimationArea(false);
1821
+ startDraggingPosition.current = 0;
1822
+ if (isAnimationTimeModifiedSetRef.current) {
1823
+ isAnimationTimeModifiedSetRef.current = false;
2197
1824
  }
2198
- case Scale.Hours6:
2199
- {
2200
- if (rem === 0) {
2201
- return TICK_MARK_HEIGHT_PRIMARY;
2202
- }
2203
- // 3 hour subdivisions
2204
- if (rem % (3 * 60 * 60) === 0) {
2205
- return TICK_MARK_HEIGHT_SECONDARY;
2206
- }
2207
- return TICK_MARK_HEIGHT_TERTIARY;
1825
+ };
1826
+ document.addEventListener('mouseup', handleMouseUp);
1827
+ return function () {
1828
+ document.removeEventListener('mouseup', handleMouseUp);
1829
+ };
1830
+ }, [setIsDraggingStartAnimation, setIsDraggingEndAnimation, localAnimationStartTime, localAnimationEndTime, onStartTimeChange, onEndTimeChange, isDraggingAnimationArea]);
1831
+ useEffect(function () {
1832
+ var handleMouseActions = function handleMouseActions(event) {
1833
+ if (event.movementX === 0) {
1834
+ return;
2208
1835
  }
2209
- case Scale.Day:
2210
- {
2211
- if (rem === 0) {
2212
- return TICK_MARK_HEIGHT_PRIMARY;
2213
- }
2214
- // 6 hour subdivisions
2215
- if (rem % (6 * 60 * 60) === 0) {
2216
- return TICK_MARK_HEIGHT_SECONDARY;
2217
- }
2218
- return TICK_MARK_HEIGHT_TERTIARY;
1836
+ if (isDraggingLegend) {
1837
+ var dragDistanceTime = event.movementX * secondsPerPx;
1838
+ var newCenterTime = centerTime - dragDistanceTime;
1839
+ onSetCenterTime(newCenterTime);
1840
+ } else if (isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
1841
+ handleAnimationDragging(event.movementX, event.clientX);
1842
+ } else if (isDraggingSelectedTime) {
1843
+ moveSelectedTimePx(event.movementX, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
2219
1844
  }
2220
- case Scale.Week:
2221
- case Scale.Weeks2:
2222
- {
2223
- var weekday = dateUtils.getDay(dateUtils.fromUnix(timestep));
2224
- // dateUtils days range from 0 (Sunday) to 6 (Saturday)
2225
- if (weekday === 1) {
2226
- return TICK_MARK_HEIGHT_PRIMARY;
2227
- }
2228
- return TICK_MARK_HEIGHT_TERTIARY;
1845
+ if (isMouseOverCanvas && isTimeSliderHoverOn) {
1846
+ moveSelectedTimePx(event.movementX, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
2229
1847
  }
2230
- case Scale.Year:
2231
- {
2232
- var month = dateUtils.getMonth(dateUtils.fromUnix(timestep));
2233
- // months are zero indexed
2234
- if (month === 0) {
2235
- return TICK_MARK_HEIGHT_PRIMARY;
2236
- }
2237
- if (month % 3 === 0) {
2238
- return TICK_MARK_HEIGHT_SECONDARY;
2239
- }
2240
- return TICK_MARK_HEIGHT_TERTIARY;
1848
+ };
1849
+ var handleMouseMove = function handleMouseMove(event) {
1850
+ handleMouseActions(event);
1851
+ };
1852
+ document.addEventListener('mousemove', handleMouseMove);
1853
+ return function () {
1854
+ document.removeEventListener('mousemove', handleMouseMove);
1855
+ };
1856
+ }, [isDraggingLegend, isDraggingStartAnimation, isDraggingEndAnimation, isDraggingAnimationArea, isDraggingSelectedTime, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime, onSetCenterTime, isTimeSliderHoverOn, isMouseOverCanvas, handleAnimationDragging]);
1857
+ useEffect(function () {
1858
+ if (!showTooltip && pointerTime) {
1859
+ if (showPointerTimeTooltip) {
1860
+ setShowTooltip('mousePointer');
1861
+ } else {
1862
+ debouncedSetShowPointerTimeTooltip(true);
2241
1863
  }
2242
- case Scale.Minutes5:
2243
- {
2244
- // add primary line on day change
2245
- if (timestep % (60 * 60 * 24) === 0) {
2246
- return TICK_MARK_HEIGHT_PRIMARY;
2247
- }
2248
- return TICK_MARK_HEIGHT_TERTIARY;
1864
+ } else if (showTooltip === 'mousePointer' && !pointerTime) {
1865
+ setShowTooltip(undefined);
1866
+ debouncedSetShowPointerTimeTooltip(false);
1867
+ debouncedSetShowPointerTimeTooltip.flush();
1868
+ } else if (showTooltip !== 'mousePointer') {
1869
+ debouncedSetShowPointerTimeTooltip(false);
1870
+ debouncedSetShowPointerTimeTooltip.flush();
1871
+ }
1872
+ }, [debouncedSetShowPointerTimeTooltip, pointerTime, showPointerTimeTooltip, showTooltip]);
1873
+ var onMouseDown = function onMouseDown(x, y, width) {
1874
+ isClickOrDrag.current = 'click';
1875
+ startDraggingPosition.current = x;
1876
+ var _getPositions = getPositions(width, unfilteredSelectedTime, centerTime, secondsPerPx, start, end),
1877
+ startAnimationPosition = _getPositions.startAnimationPosition,
1878
+ endAnimationPosition = _getPositions.endAnimationPosition,
1879
+ selectedTimePosition = _getPositions.selectedTimePosition;
1880
+ // start dragging selected time.
1881
+ if (isSelectedTimeIconArea(x, selectedTimePosition, DRAG_AREA_WIDTH)) {
1882
+ setCursorStyle('grabbing');
1883
+ setIsDraggingSelectedTime(true);
1884
+ return;
1885
+ }
1886
+ if (reduxAnimationStartTime && reduxAnimationEndTime) {
1887
+ var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
1888
+ tooltipPosition.current = pixelsBetweenOnLeft ? x + pixelsBetweenOnLeft : x;
1889
+ // start dragging either marker
1890
+ if (isLeftAnimationIconArea(x, startAnimationPosition, DRAG_AREA_WIDTH)) {
1891
+ setCursorStyle('grabbing');
1892
+ setIsDraggingStartAnimation == null || setIsDraggingStartAnimation(true);
1893
+ setShowTooltip('animationStart');
1894
+ return;
1895
+ }
1896
+ if (isRightAnimationIconArea(x, endAnimationPosition, DRAG_AREA_WIDTH)) {
1897
+ setCursorStyle('grabbing');
1898
+ setIsDraggingEndAnimation == null || setIsDraggingEndAnimation(true);
1899
+ setShowTooltip('animationEnd');
1900
+ return;
1901
+ }
1902
+ if (isInsideAnimationArea(x, startAnimationPosition, endAnimationPosition)) {
1903
+ setCursorStyle('grabbing');
1904
+ setIsDraggingAnimationArea(true);
1905
+ return;
2249
1906
  }
2250
- default:
2251
- // Scale.Month
2252
- return TICK_MARK_HEIGHT_TERTIARY;
2253
- }
2254
- };
2255
- var drawStepPxLine = function drawStepPxLine(ctx, theme, stepPx, height, fundamentalScale, timestep) {
2256
- var ctx2 = ctx;
2257
- ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
2258
- ctx2.lineWidth = 1;
2259
- var stepPxLineHeight = getStepPxLineHeight(fundamentalScale, timestep);
2260
- ctx2.beginPath();
2261
- ctx2.moveTo(stepPx, height - stepPxLineHeight);
2262
- ctx2.lineTo(stepPx, height);
2263
- ctx2.stroke();
2264
- };
2265
- var drawTimeText = function drawTimeText(ctx, theme, stepPx, height, timeText, scale) {
2266
- var ctx2 = ctx;
2267
- var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider.timelineText,
2268
- fontSize = _theme$palette$geoweb.fontSize,
2269
- fontFamily = _theme$palette$geoweb.fontFamily,
2270
- color = _theme$palette$geoweb.color;
2271
- ctx2.fillStyle = color;
2272
- // time text has smaller font than other timeline text
2273
- ctx2.font = fontSize + "px " + fontFamily;
2274
- ctx2.textAlign = 'left';
2275
- if (scale === Scale.Year || scale === Scale.Months3 || scale === Scale.Month || scale === Scale.Weeks2 || scale === Scale.Week || scale === Scale.Day) {
2276
- ctx2.fillText(timeText, stepPx, height - 12);
2277
- } else {
2278
- ctx2.fillText(timeText, stepPx - 15, height - 12);
2279
- }
2280
- };
2281
- var drawYearScaleText = function drawYearScaleText(ctx, theme, newDate, stepPx, height) {
2282
- var ctx2 = ctx;
2283
- var _theme$palette$geoweb2 = theme.palette.geowebColors.timeSlider.timelineText,
2284
- fontSize = _theme$palette$geoweb2.fontSize,
2285
- fontFamily = _theme$palette$geoweb2.fontFamily,
2286
- color = _theme$palette$geoweb2.color;
2287
- ctx2.fillStyle = color;
2288
- ctx2.font = fontSize + "px " + fontFamily;
2289
- ctx2.textAlign = 'left';
2290
- ctx2.fillText(newDate, stepPx + 2, height - 10);
2291
- };
2292
- var drawLeftSideDateText = function drawLeftSideDateText(ctx, theme, newDate, height) {
2293
- var ctx2 = ctx;
2294
- var _theme$palette$geoweb3 = theme.palette.geowebColors.timeSlider.timelineText,
2295
- fontSize = _theme$palette$geoweb3.fontSize,
2296
- fontFamily = _theme$palette$geoweb3.fontFamily,
2297
- color = _theme$palette$geoweb3.color;
2298
- ctx2.fillStyle = color;
2299
- ctx2.font = fontSize + "px " + fontFamily;
2300
- ctx2.textAlign = 'left';
2301
- ctx2.fillText(newDate, 2, height - 30);
2302
- };
2303
- var getTimeFormat = function getTimeFormat(scale) {
2304
- switch (scale) {
2305
- case Scale.Year:
2306
- return 'y';
2307
- case Scale.Month:
2308
- case Scale.Months3:
2309
- return 'MMM';
2310
- case Scale.Week:
2311
- case Scale.Weeks2:
2312
- return 'dd MMM';
2313
- case Scale.Day:
2314
- return 'EEE dd';
2315
- default:
2316
- return dateUtils.DATE_FORMAT_HOURS;
2317
- }
2318
- };
2319
- var drawDateChangeLine = function drawDateChangeLine(ctx, theme, stepPx, height) {
2320
- var ctx2 = ctx;
2321
- ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
2322
- ctx2.lineWidth = 1;
2323
- ctx2.beginPath();
2324
- ctx2.moveTo(stepPx, height - 40);
2325
- ctx2.lineTo(stepPx, height);
2326
- ctx2.stroke();
2327
- };
2328
- var drawDashedMonthChangeLine = function drawDashedMonthChangeLine(ctx, theme, stepPx, height) {
2329
- var ctx2 = ctx;
2330
- ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineMonthChangeDash.rgba;
2331
- ctx2.lineWidth = 3;
2332
- ctx2.setLineDash([5, 5]);
2333
- ctx2.beginPath();
2334
- ctx2.moveTo(stepPx, 0);
2335
- ctx2.lineTo(stepPx, height);
2336
- ctx2.stroke();
2337
- ctx2.setLineDash([]);
2338
- };
2339
- var roundByUnitOfTime = function roundByUnitOfTime(timeUnix, unit, roundUp) {
2340
- if (roundUp === void 0) {
2341
- roundUp = false;
2342
- }
2343
- if (unit === 'hour') {
2344
- var _timeStartOfPassedUnit = dateUtils.startOfHourUTC(dateUtils.fromUnix(timeUnix));
2345
- if (roundUp) {
2346
- return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit, {
2347
- hours: 1
2348
- }));
2349
1907
  }
2350
- return dateUtils.unix(_timeStartOfPassedUnit);
2351
- }
2352
- if (unit === 'day') {
2353
- var _timeStartOfPassedUnit2 = dateUtils.startOfDayUTC(dateUtils.fromUnix(timeUnix));
2354
- if (roundUp) {
2355
- return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit2, {
2356
- days: 1
2357
- }));
1908
+ // clicking the timeslider
1909
+ setIsDraggingLegend(true);
1910
+ };
1911
+ var onMouseUp = function onMouseUp(x) {
1912
+ if (isClickOrDrag.current === 'click') {
1913
+ var unfilteredSelectedTimePx = timestampToPixel(unfilteredSelectedTime, centerTime, canvasWidth, secondsPerPx);
1914
+ moveSelectedTimePx(x - unfilteredSelectedTimePx, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
2358
1915
  }
2359
- return dateUtils.unix(_timeStartOfPassedUnit2);
2360
- }
2361
- if (unit === 'week') {
2362
- var _timeStartOfPassedUnit3 = dateUtils.startOfWeekUTC(dateUtils.fromUnix(timeUnix));
2363
- if (roundUp) {
2364
- return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit3, {
2365
- weeks: 1
2366
- }));
1916
+ isClickOrDrag.current = undefined;
1917
+ };
1918
+ var onMouseMove = function onMouseMove(x, y, event, width) {
1919
+ var mousePosition = x;
1920
+ setPointerTime(pixelToTimestamp(mousePosition, centerTime, canvasWidth, secondsPerPx));
1921
+ var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
1922
+ tooltipPosition.current = pixelsBetweenOnLeft && mousePosition + pixelsBetweenOnLeft;
1923
+ if (isClickOrDrag.current === 'click') {
1924
+ isClickOrDrag.current = 'drag';
2367
1925
  }
2368
- return dateUtils.unix(_timeStartOfPassedUnit3);
2369
- }
2370
- if (unit === 'month') {
2371
- var _timeStartOfPassedUnit4 = dateUtils.startOfMonthUTC(dateUtils.fromUnix(timeUnix));
2372
- if (roundUp) {
2373
- return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit4, {
2374
- months: 1
2375
- }));
1926
+ if (isDraggingSelectedTime || isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
1927
+ return;
2376
1928
  }
2377
- return dateUtils.unix(_timeStartOfPassedUnit4);
2378
- }
2379
- // Default unit === 'year'
2380
- var timeStartOfPassedUnit = dateUtils.startOfYearUTC(dateUtils.fromUnix(timeUnix));
2381
- if (roundUp) {
2382
- return dateUtils.unix(dateUtils.add(timeStartOfPassedUnit, {
2383
- years: 1
2384
- }));
2385
- }
2386
- return dateUtils.unix(timeStartOfPassedUnit);
2387
- };
2388
- var roundToNearestMultiple = function roundToNearestMultiple(timeUnix, scale, roundUp) {
2389
- if (roundUp === void 0) {
2390
- roundUp = false;
2391
- }
2392
- var stepSeconds = scaleToUnitSeconds[scale];
2393
- var roundFn = roundUp ? Math.ceil : Math.floor;
2394
- return roundFn(timeUnix / stepSeconds) * stepSeconds;
2395
- };
2396
- /**
2397
- * In this script starting and ending times of the time slider are rounded.
2398
- * Here it is defined what is a time unit to a start of which a rounding is
2399
- * done for each scale.
2400
- * @returns an object where there are rounding units of each scale
2401
- */
2402
- 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);
2403
- var getRoundedStartAndEnd = function getRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, scale) {
2404
- if (scale === Scale.Minutes5 || scale === Scale.Hours3 || scale === Scale.Hours6) {
2405
- return [roundToNearestMultiple(visibleTimeStart, scale, false), roundToNearestMultiple(visibleTimeEnd, scale, true)];
2406
- }
2407
- var unit = scaleToRoundableUnit[scale];
2408
- return [roundByUnitOfTime(visibleTimeStart, unit, false), roundByUnitOfTime(visibleTimeEnd, unit, true)];
2409
- };
2410
- var getCustomRoundedStartAndEndScale = function getCustomRoundedStartAndEndScale(scale) {
2411
- switch (scale) {
2412
- case Scale.Year:
2413
- return 'month';
2414
- case Scale.Month:
2415
- case Scale.Months3:
2416
- return 'week';
2417
- case Scale.Week:
2418
- case Scale.Weeks2:
2419
- return 'day';
2420
- default:
2421
- return 'day';
2422
- }
2423
- };
2424
- var getCustomRoundedStartAndEnd = function getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, unit) {
2425
- var scale = getCustomRoundedStartAndEndScale(unit);
2426
- return [roundByUnitOfTime(visibleTimeStart, scale, false), roundByUnitOfTime(visibleTimeEnd, scale, true)];
2427
- };
2428
- var incrementTimestep = function incrementTimestep(timeAtTimeStep, fundamentalScale) {
2429
- switch (fundamentalScale) {
2430
- case Scale.Minutes5:
2431
- return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2432
- minutes: 1
2433
- }));
2434
- case Scale.Hour:
2435
- return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2436
- minutes: 5
2437
- }));
2438
- case Scale.Hours3:
2439
- case Scale.Hours6:
2440
- return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2441
- hours: 1
2442
- }));
2443
- case Scale.Day:
2444
- return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2445
- hours: 3
2446
- }));
2447
- case Scale.Week:
2448
- case Scale.Weeks2:
2449
- return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2450
- days: 1
2451
- }));
2452
- case Scale.Month:
2453
- return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2454
- weeks: 1
2455
- }));
2456
- case Scale.Year:
2457
- case Scale.Months3:
2458
- return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2459
- months: 1
2460
- }));
2461
- default:
2462
- return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
2463
- months: 1
2464
- }));
2465
- }
2466
- };
2467
- var getTimesteps = function getTimesteps(roundedStart, roundedEnd, fundamentalScaleType) {
2468
- var timesteps = [];
2469
- var timestep = roundedStart;
2470
- while (timestep <= roundedEnd) {
2471
- timesteps.push(timestep);
2472
- timestep = incrementTimestep(timestep, fundamentalScaleType);
2473
- }
2474
- return timesteps;
2475
- };
2476
- var getCustomTimesteps = function getCustomTimesteps(roundedStart, roundedEnd, increment) {
2477
- var timesteps = [];
2478
- var timestep = roundedStart;
2479
- while (timestep <= roundedEnd) {
2480
- var _dateUtils$add;
2481
- timesteps.push(timestep);
2482
- timestep = dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timestep), (_dateUtils$add = {}, _dateUtils$add[increment] = 1, _dateUtils$add)));
2483
- }
2484
- return timesteps;
2485
- };
2486
- var getLeftSideDateText = function getLeftSideDateText(timestamp, fundamentalScale) {
2487
- var time = dateUtils.fromUnix(timestamp);
2488
- switch (fundamentalScale) {
2489
- case Scale.Minutes5:
2490
- case Scale.Hour:
2491
- case Scale.Hours3:
2492
- case Scale.Hours6:
2493
- return dateUtils.dateToString(time, 'y MMM EEE dd');
2494
- case Scale.Day:
2495
- case Scale.Week:
2496
- case Scale.Weeks2:
2497
- return dateUtils.dateToString(time, 'y MMM');
2498
- case Scale.Month:
2499
- case Scale.Months3:
2500
- return dateUtils.dateToString(time, 'y');
2501
- case Scale.Year:
2502
- return dateUtils.dateToString(time, 'y');
2503
- default:
2504
- return '';
2505
- }
2506
- };
2507
- var drawTimeScale = function drawTimeScale(context, theme, visibleTimeStart, visibleTimeEnd, canvasWidth, height, secondsPerPx) {
2508
- var fundamentalScale = getFundamentalScale(secondsPerPx);
2509
- var _getRoundedStartAndEn = getRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, fundamentalScale),
2510
- roundedStart = _getRoundedStartAndEn[0],
2511
- roundedEnd = _getRoundedStartAndEn[1];
2512
- // draw regular tickmarks
2513
- var ctx = context;
2514
- getTimesteps(roundedStart, roundedEnd, fundamentalScale).forEach(function (timestep) {
2515
- var stepPx = timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
2516
- // 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
2517
- drawStepPxLine(ctx, theme, Math.floor(stepPx) + 0.5, height, fundamentalScale, timestep);
2518
- // Draw the time step time as text
2519
- var timeFormat = getTimeFormat(fundamentalScale);
2520
- var timeText = dateUtils.dateToString(dateUtils.fromUnix(timestep), timeFormat);
2521
- if ([Scale.Minutes5, Scale.Hour, Scale.Hours3, Scale.Hours6, Scale.Day].includes(fundamentalScale) &&
2522
- // eslint-disable-next-line @typescript-eslint/no-confusing-non-null-assertion
2523
- timestep % scaleToUnitSeconds[fundamentalScale] === 0 || fundamentalScale === Scale.Week && dateUtils.getDay(dateUtils.fromUnix(timestep)) === 1) {
2524
- drawTimeText(ctx, theme, stepPx, height, timeText, fundamentalScale);
1929
+ var _getPositions2 = getPositions(width, unfilteredSelectedTime, centerTime, secondsPerPx, start, end),
1930
+ startAnimationPosition = _getPositions2.startAnimationPosition,
1931
+ endAnimationPosition = _getPositions2.endAnimationPosition,
1932
+ selectedTimePosition = _getPositions2.selectedTimePosition;
1933
+ // Adjust mouse cursor while hovering draggable areas
1934
+ var leftAnimationIconArea = isLeftAnimationIconArea(x, startAnimationPosition, DRAG_AREA_WIDTH);
1935
+ var rightAnimationIconArea = isRightAnimationIconArea(x, endAnimationPosition, DRAG_AREA_WIDTH);
1936
+ var selectedTimeArea = isSelectedTimeIconArea(x, selectedTimePosition, DRAG_AREA_WIDTH);
1937
+ var insideAnimationArea = isInsideAnimationArea(x, startAnimationPosition, endAnimationPosition);
1938
+ var hoveringLegendHandles = leftAnimationIconArea || rightAnimationIconArea || selectedTimeArea || isDraggingLegend;
1939
+ if (hoveringLegendHandles) {
1940
+ setCursorStyle('ew-resize');
1941
+ } else if (insideAnimationArea && !isDraggingAnimationArea) {
1942
+ setCursorStyle('grab');
1943
+ } else if (insideAnimationArea && isDraggingAnimationArea) {
1944
+ setCursorStyle('grabbing');
1945
+ } else {
1946
+ setCursorStyle('auto');
2525
1947
  }
2526
- if (fundamentalScale === Scale.Year && dateUtils.getMonth(dateUtils.fromUnix(timestep)) === 0) {
2527
- drawYearScaleText(ctx, theme, timeText, stepPx, height);
1948
+ };
1949
+ var onWheel = React.useCallback(function (_ref2) {
1950
+ var event = _ref2.event,
1951
+ deltaY = _ref2.deltaY;
1952
+ event.preventDefault();
1953
+ if (event.ctrlKey || event.metaKey) {
1954
+ debouncedAndThrottledUpdateTimeSpan(deltaY);
2528
1955
  }
2529
- });
2530
- // draw month overlay lines
2531
- if (fundamentalScale === Scale.Week || fundamentalScale === Scale.Weeks2 || fundamentalScale === Scale.Month || fundamentalScale === Scale.Months3) {
2532
- var _getCustomRoundedStar = getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, Scale.Year),
2533
- _roundedStart = _getCustomRoundedStar[0],
2534
- _roundedEnd = _getCustomRoundedStar[1];
2535
- var monthTimesteps = getCustomTimesteps(_roundedStart, _roundedEnd, 'months');
2536
- monthTimesteps.forEach(function (timestep) {
2537
- var stepPx = timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
2538
- if (fundamentalScale === Scale.Month || fundamentalScale === Scale.Months3) {
2539
- var month = dateUtils.dateToString(dateUtils.fromUnix(timestep), 'MMM');
2540
- // 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
2541
- drawDateChangeLine(ctx, theme, Math.floor(stepPx) + 0.5, height);
2542
- drawTimeText(ctx, theme, stepPx, height, month, fundamentalScale);
2543
- return;
1956
+ }, [debouncedAndThrottledUpdateTimeSpan]);
1957
+ var onWheelOverCanvas = React.useCallback(function (props) {
1958
+ onWheel(props);
1959
+ adjustSelectedTimeOnWheel(props);
1960
+ }, [adjustSelectedTimeOnWheel, onWheel]);
1961
+ React.useEffect(function () {
1962
+ if (isTimeScrollingEnabled && mapWindowRef != null && mapWindowRef.current) {
1963
+ var handleWheel = function handleWheel(event) {
1964
+ event.preventDefault();
1965
+ onWheel({
1966
+ event: event,
1967
+ deltaY: event.deltaY
1968
+ });
1969
+ };
1970
+ var element = mapWindowRef.current;
1971
+ element.addEventListener('wheel', handleWheel);
1972
+ return function () {
1973
+ element.removeEventListener('wheel', handleWheel);
1974
+ };
1975
+ }
1976
+ return undefined;
1977
+ }, [isTimeScrollingEnabled, mapWindowRef, onWheel]);
1978
+ return jsxs(Box, {
1979
+ sx: {
1980
+ position: 'relative',
1981
+ height: TIME_SLIDER_LEGEND_HEIGHT + "px"
1982
+ },
1983
+ children: [jsx(CustomTooltip, {
1984
+ open: Boolean(showTooltip),
1985
+ slotProps: {
1986
+ popper: {
1987
+ popperRef: popperRef,
1988
+ anchorEl: {
1989
+ getBoundingClientRect: setTooltipPosition
1990
+ }
1991
+ }
1992
+ },
1993
+ title: getTooltipText(),
1994
+ children: jsx(Box, {
1995
+ className: getTimeSliderLegendId(mapId),
1996
+ "data-testid": "timeSliderLegend",
1997
+ onMouseLeave: function onMouseLeave() {
1998
+ setPointerTime(undefined);
1999
+ },
2000
+ sx: {
2001
+ height: TIME_SLIDER_LEGEND_HEIGHT + "px",
2002
+ borderRadius: '4.5px',
2003
+ overflow: 'hidden',
2004
+ cursor: cursorStyle
2005
+ },
2006
+ children: jsx(CanvasComponent, {
2007
+ onMouseDown: onMouseDown,
2008
+ onMouseMove: onMouseMove,
2009
+ onMouseUp: onMouseUp,
2010
+ onRenderCanvas: function onRenderCanvas(ctx, width, height) {
2011
+ updateCanvasWidth(canvasWidth, width);
2012
+ drawTimeSliderLegend(ctx, theme, width, height, centerTime, secondsPerPx, timeSliderSpan, filteredTime, currentTime, start, end, dataStartTime, dataEndTime);
2013
+ },
2014
+ onWheel: onWheelOverCanvas,
2015
+ ref: node
2016
+ })
2017
+ })
2018
+ }), !!isTimeSliderHoverOn && jsx(Box, {
2019
+ "data-testid": "customCanvasMouseOverContainer",
2020
+ onMouseLeave: function onMouseLeave() {
2021
+ return setIsMouseOverCanvas(false);
2022
+ },
2023
+ onMouseOver: function onMouseOver() {
2024
+ return setIsMouseOverCanvas(true);
2025
+ },
2026
+ sx: {
2027
+ position: 'absolute',
2028
+ top: '-40px',
2029
+ left: 0,
2030
+ right: 0,
2031
+ bottom: 0,
2032
+ height: TIME_SLIDER_LEGEND_HEIGHT + " + 40px",
2033
+ zIndex: isMouseOverCanvas ? 100 : 0
2544
2034
  }
2545
- // adding 0.5 to make line not so blurred
2546
- drawDashedMonthChangeLine(ctx, theme, Math.floor(stepPx) + 0.5, height);
2547
- });
2548
- }
2549
- // draw date change texts
2550
- if (fundamentalScale === Scale.Year) {
2551
- return;
2552
- }
2553
- var dateText = getLeftSideDateText(visibleTimeStart, fundamentalScale);
2554
- drawLeftSideDateText(ctx, theme, dateText, height);
2035
+ })]
2036
+ });
2555
2037
  };
2556
2038
 
2557
- /* *
2558
- * Licensed under the Apache License, Version 2.0 (the "License");
2559
- * you may not use this file except in compliance with the License.
2560
- * You may obtain a copy of the License at
2561
- *
2562
- * http://www.apache.org/licenses/LICENSE-2.0
2563
- *
2564
- * Unless required by applicable law or agreed to in writing, software
2565
- * distributed under the License is distributed on an "AS IS" BASIS,
2566
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2567
- * See the License for the specific language governing permissions and
2568
- * limitations under the License.
2569
- *
2570
- * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2571
- * Copyright 2022 - Finnish Meteorological Institute (FMI)
2572
- * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
2573
- * */
2574
- var drawBackground = function drawBackground(context, theme, visibleTimeStart, visibleTimeEnd, animationStartPx, animationEndPx, canvasWidth, height, secondsPerPx, timeSliderSpan, dataStartPx, dataEndPx, currentTimePx) {
2575
- var ctx = context;
2576
- var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
2577
- timelineNightTime = _theme$palette$geoweb.timelineNightTime,
2578
- ledgendObservedBackground = _theme$palette$geoweb.ledgendObservedBackground,
2579
- legendForecastBackground = _theme$palette$geoweb.legendForecastBackground,
2580
- legendNoDataBackground = _theme$palette$geoweb.legendNoDataBackground;
2581
- // top spacing
2582
- var y = 0;
2583
- var scaleToUse = timeSliderSpan ? getScaleFromSpan(timeSliderSpan) : getFundamentalScale(secondsPerPx);
2584
- drawDefaultBackground();
2585
- drawObservedData();
2586
- drawForecastData();
2587
- drawNightOrAlternateTime();
2588
- drawAnimationArea();
2589
- drawDraggableIcons();
2590
- function drawDefaultBackground() {
2591
- ctx.fillStyle = legendNoDataBackground.rgba;
2592
- ctx.fillRect(0, y, canvasWidth, height);
2593
- }
2594
- function drawObservedData() {
2595
- if (dataStartPx < currentTimePx) {
2596
- ctx.fillStyle = ledgendObservedBackground.fill;
2597
- ctx.fillRect(Math.max(dataStartPx, y), y, Math.min(currentTimePx, dataEndPx) - Math.max(dataStartPx, y), height);
2039
+ var THROTTLE_WAIT_TIME = 300; // [ms]
2040
+ var THROTTLE_OPTIONS = {
2041
+ trailing: false // Invoke function when called, but not more than once every <THROTTLE_WAIT_TIME>.
2042
+ };
2043
+ var TimeSliderMenu = function TimeSliderMenu(_ref) {
2044
+ var marks = _ref.marks,
2045
+ value = _ref.value,
2046
+ allOptionsDisabled = _ref.allOptionsDisabled,
2047
+ isAutoDisabled = _ref.isAutoDisabled,
2048
+ handleAutoClick = _ref.handleAutoClick,
2049
+ isAutoSelected = _ref.isAutoSelected,
2050
+ title = _ref.title,
2051
+ icon = _ref.icon,
2052
+ _ref$onChangeSliderVa = _ref.onChangeSliderValue,
2053
+ onChangeSliderValue = _ref$onChangeSliderVa === void 0 ? function () {} : _ref$onChangeSliderVa,
2054
+ displayCurrentLength = _ref.displayCurrentLength,
2055
+ _ref$disbleUserSetDur = _ref.disbleUserSetDuration,
2056
+ disbleUserSetDuration = _ref$disbleUserSetDur === void 0 ? true : _ref$disbleUserSetDur,
2057
+ customLengthSelector = _ref.customLengthSelector,
2058
+ _ref$setOpen = _ref.setOpen,
2059
+ setOpen = _ref$setOpen === void 0 ? function () {} : _ref$setOpen,
2060
+ _ref$customFieldHeade = _ref.customFieldHeader,
2061
+ customFieldHeader = _ref$customFieldHeade === void 0 ? 'timeslider-length' : _ref$customFieldHeade,
2062
+ open = _ref.open;
2063
+ var currentMarkIndex = marks.findIndex(function (mark) {
2064
+ return mark.value === value;
2065
+ });
2066
+ var currentMark = marks[currentMarkIndex];
2067
+ var _React$useState = React.useState(null),
2068
+ anchorRef = _React$useState[0],
2069
+ setAnchorRef = _React$useState[1];
2070
+ var _useTimesliderTransla = useTimesliderTranslation(),
2071
+ t = _useTimesliderTransla.t;
2072
+ var _useState = useState(false),
2073
+ displayLengthInputField = _useState[0],
2074
+ setDisplayLengthInputField = _useState[1];
2075
+ React.useEffect(function () {
2076
+ if (!open && displayLengthInputField) {
2077
+ setDisplayLengthInputField(false);
2598
2078
  }
2599
- }
2600
- function drawForecastData() {
2601
- if (dataEndPx > currentTimePx) {
2602
- ctx.fillStyle = legendForecastBackground.fill;
2603
- ctx.fillRect(Math.max(currentTimePx, dataStartPx), y, Math.min(canvasWidth, dataEndPx) - Math.max(currentTimePx, dataStartPx), height);
2079
+ }, [displayLengthInputField, open]);
2080
+ var buttonText = function buttonText(value, displayCurrentLength, currentMark) {
2081
+ if (displayCurrentLength) {
2082
+ return minutesToDescribedDuration(value);
2604
2083
  }
2605
- }
2606
- function drawAnimationArea() {
2607
- ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineSelectionBackground.rgba;
2608
- ctx.strokeStyle = theme.palette.geowebColors.timeSlider.timelineSelectionOutline.rgba;
2609
- ctx.lineWidth = 3;
2610
- ctx.rect(animationStartPx, y, Math.max(animationEndPx - animationStartPx, y), height);
2611
- ctx.fill();
2612
- ctx.stroke();
2613
- }
2614
- function drawDraggableIcons() {
2615
- ctx.save();
2616
- var path = new Path2D(dragHandlePath);
2617
- ctx.translate(animationStartPx, y);
2618
- ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
2619
- ctx.fill(path);
2620
- ctx.restore();
2621
- ctx.save();
2622
- ctx.translate(animationEndPx - 24, y);
2623
- ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
2624
- ctx.fill(path);
2625
- ctx.restore();
2626
- }
2627
- function drawNightOrAlternateTime() {
2628
- var colorChangeTimesteps = getColorChangeTimesteps(scaleToUse, visibleTimeStart, visibleTimeEnd);
2629
- colorChangeTimesteps.forEach(function (timestep, i, arr) {
2630
- if (i === 0) {
2631
- return;
2632
- }
2633
- var _map = [arr[i - 1], timestep].map(function (timestep) {
2634
- return timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
2635
- }),
2636
- prevPx = _map[0],
2637
- currPx = _map[1];
2638
- if (!isColorIntervalEven(scaleToUse, timestep)) {
2639
- ctx.fillStyle = timelineNightTime.rgba;
2640
- var TOP_OFFSET = 0;
2641
- ctx.fillRect(prevPx, TOP_OFFSET, currPx - prevPx, height);
2642
- }
2643
- });
2644
- }
2645
- };
2646
- var getColorChangeTimestepUnit = function getColorChangeTimestepUnit(scale) {
2647
- switch (scale) {
2648
- case Scale.Year:
2649
- return 'months';
2650
- case Scale.Month:
2651
- case Scale.Months3:
2652
- return 'weeks';
2653
- case Scale.Weeks2:
2654
- case Scale.Week:
2655
- return 'days';
2656
- default:
2657
- return 'days';
2658
- }
2659
- };
2660
- var isColorIntervalEven = function isColorIntervalEven(scale, timestep) {
2661
- var time = dateUtils.fromUnix(timestep);
2662
- switch (scale) {
2663
- case Scale.Year:
2664
- return dateUtils.getMonth(time) % 2 === 0;
2665
- case Scale.Month:
2666
- case Scale.Months3:
2667
- return dateUtils.getWeek(time) % 2 === 0;
2668
- case Scale.Week:
2669
- case Scale.Weeks2:
2670
- return dateUtils.getDayOfYear(time) % 2 === 0;
2671
- default:
2672
- {
2673
- return dateUtils.getDayOfYear(time) % 2 === 0;
2084
+ if (currentMark) {
2085
+ var parts = t(currentMark.label).split(' ');
2086
+ if (parts.length > 1) {
2087
+ return parts[0] + parts.slice(1).join(' ');
2674
2088
  }
2675
- }
2676
- };
2677
- function getColorChangeTimesteps(scale, visibleTimeStart, visibleTimeEnd) {
2678
- var _getCustomRoundedStar = getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, scale),
2679
- colorChangeStart = _getCustomRoundedStar[0],
2680
- colorChangeEnd = _getCustomRoundedStar[1];
2681
- var colorChangeUnit = getColorChangeTimestepUnit(scale);
2682
- var colorChangeTimesteps = getCustomTimesteps(colorChangeStart, colorChangeEnd, colorChangeUnit);
2683
- return colorChangeTimesteps;
2684
- }
2685
-
2686
- /* *
2687
- * Licensed under the Apache License, Version 2.0 (the "License");
2688
- * you may not use this file except in compliance with the License.
2689
- * You may obtain a copy of the License at
2690
- *
2691
- * http://www.apache.org/licenses/LICENSE-2.0
2692
- *
2693
- * Unless required by applicable law or agreed to in writing, software
2694
- * distributed under the License is distributed on an "AS IS" BASIS,
2695
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2696
- * See the License for the specific language governing permissions and
2697
- * limitations under the License.
2698
- *
2699
- * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2700
- * Copyright 2022 - Finnish Meteorological Institute (FMI)
2701
- * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
2702
- * */
2703
- var drawCurrentTime = function drawCurrentTime(context, theme, width, height, startTime, endTime, currentTime) {
2704
- var ctx = context;
2705
- var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
2706
- playerNeedleTime = _theme$palette$geoweb.playerNeedleTime,
2707
- playerNeedleTimeTop = _theme$palette$geoweb.playerNeedleTimeTop;
2708
- var current = currentTime;
2709
- var currentPx = current ? timestampToPixelEdges(current, startTime, endTime, width) : 0;
2710
- // Draw a high vertical line (needle) indicating the current or selected time
2711
- ctx.beginPath();
2712
- // 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
2713
- ctx.moveTo(Math.floor(currentPx) + 0.5, height - 24);
2714
- ctx.lineTo(Math.floor(currentPx) + 0.5, height);
2715
- ctx.lineWidth = 5;
2716
- ctx.strokeStyle = playerNeedleTime.rgba;
2717
- ctx.stroke();
2718
- ctx.lineWidth = 1;
2719
- ctx.strokeStyle = playerNeedleTimeTop.rgba;
2720
- ctx.stroke();
2721
- };
2722
-
2723
- /* *
2724
- * Licensed under the Apache License, Version 2.0 (the "License");
2725
- * you may not use this file except in compliance with the License.
2726
- * You may obtain a copy of the License at
2727
- *
2728
- * http://www.apache.org/licenses/LICENSE-2.0
2729
- *
2730
- * Unless required by applicable law or agreed to in writing, software
2731
- * distributed under the License is distributed on an "AS IS" BASIS,
2732
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2733
- * See the License for the specific language governing permissions and
2734
- * limitations under the License.
2735
- *
2736
- * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2737
- * Copyright 2022 - Finnish Meteorological Institute (FMI)
2738
- * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
2739
- * */
2740
- var drawNeedle = function drawNeedle(context, theme, width, height, startTime, endTime, selectedTime) {
2741
- if (!selectedTime) {
2742
- return;
2743
- }
2744
- var ctx = context;
2745
- var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
2746
- playerNeedlePlayer = _theme$palette$geoweb.playerNeedlePlayer,
2747
- playerNeedlePlayerTop = _theme$palette$geoweb.playerNeedlePlayerTop,
2748
- playerTimeMarkers = _theme$palette$geoweb.playerTimeMarkers;
2749
- var selectedPx = timestampToPixelEdges(selectedTime, startTime, endTime, width);
2750
- // Draw a high vertical line (needle) indicating the current or selected time
2751
- ctx.beginPath();
2752
- // 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
2753
- ctx.moveTo(Math.floor(selectedPx) + 0.5, height - 50);
2754
- ctx.lineTo(Math.floor(selectedPx) + 0.5, height);
2755
- ctx.lineWidth = 5;
2756
- ctx.strokeStyle = playerNeedlePlayer.rgba;
2757
- ctx.stroke();
2758
- ctx.lineWidth = 1;
2759
- ctx.strokeStyle = playerNeedlePlayerTop.rgba;
2760
- ctx.stroke();
2761
- // Triange connecting timebox.
2762
- ctx.beginPath();
2763
- ctx.moveTo(Math.floor(selectedPx) + 5, 0);
2764
- ctx.lineTo(Math.floor(selectedPx) + 0.5, 5);
2765
- ctx.lineTo(Math.floor(selectedPx) - 5, 0);
2766
- ctx.closePath();
2767
- ctx.fillStyle = playerTimeMarkers.fill;
2768
- ctx.fill();
2769
- };
2770
-
2771
- /* *
2772
- * Licensed under the Apache License, Version 2.0 (the "License");
2773
- * you may not use this file except in compliance with the License.
2774
- * You may obtain a copy of the License at
2775
- *
2776
- * http://www.apache.org/licenses/LICENSE-2.0
2777
- *
2778
- * Unless required by applicable law or agreed to in writing, software
2779
- * distributed under the License is distributed on an "AS IS" BASIS,
2780
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2781
- * See the License for the specific language governing permissions and
2782
- * limitations under the License.
2783
- *
2784
- * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2785
- * Copyright 2022 - Finnish Meteorological Institute (FMI)
2786
- * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
2787
- * */
2788
- var drawTimeSliderLegend = function drawTimeSliderLegend(context, theme, canvasWidth, height, centerTime, secondsPerPx, timeSliderSpan, selectedTimeUnix, currentTimeUnix, animationStartTime, animationEndTime, dataStartTime, dataEndTime) {
2789
- var ctx = context;
2790
- var _map = [0, canvasWidth].map(function (px) {
2791
- return pixelToTimestamp(px, centerTime, canvasWidth, secondsPerPx);
2792
- }),
2793
- visibleTimeStart = _map[0],
2794
- visibleTimeEnd = _map[1];
2795
- var _map2 = [animationStartTime, animationEndTime, dataStartTime, dataEndTime, currentTimeUnix].map(function (time) {
2796
- return timestampToPixel(time, centerTime, canvasWidth, secondsPerPx);
2089
+ return parts.join('');
2090
+ }
2091
+ return '';
2092
+ };
2093
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2094
+ var throttledScroll = React.useCallback(throttle(function (newValue) {
2095
+ onChangeSliderValue(newValue);
2096
+ }, THROTTLE_WAIT_TIME, THROTTLE_OPTIONS), []);
2097
+ var onWheel = React.useCallback(function (event) {
2098
+ var direction = event.deltaY < 0 ? 1 : -1;
2099
+ var newValue = marks[Math.min(Math.max(currentMarkIndex - direction, 0), marks.length - 1)];
2100
+ throttledScroll(newValue.value);
2101
+ }, [currentMarkIndex, marks, throttledScroll]);
2102
+ return jsxs(Box, {
2103
+ onKeyDown: function onKeyDown(event) {
2104
+ event.stopPropagation();
2105
+ },
2106
+ children: [jsxs(CustomIconButton, {
2107
+ isSelected: true,
2108
+ onClick: function onClick() {
2109
+ setOpen(true);
2110
+ },
2111
+ onWheel: onWheel,
2112
+ ref: setAnchorRef,
2113
+ sx: {
2114
+ padding: '11px!important',
2115
+ width: '100%!important'
2116
+ },
2117
+ tooltipTitle: title,
2118
+ variant: "tool",
2119
+ children: [icon, jsx(Typography, {
2120
+ sx: {
2121
+ fontSize: 12,
2122
+ fontWeight: 400,
2123
+ textTransform: 'none'
2124
+ },
2125
+ children: buttonText(value, displayCurrentLength, currentMark)
2126
+ })]
2127
+ }), !!anchorRef && jsxs(Menu, {
2128
+ anchorEl: anchorRef,
2129
+ anchorOrigin: {
2130
+ vertical: -15,
2131
+ horizontal: 'center'
2132
+ },
2133
+ onClose: function onClose() {
2134
+ return setOpen(false);
2135
+ },
2136
+ open: open,
2137
+ slotProps: {
2138
+ backdrop: {
2139
+ sx: {
2140
+ backgroundColor: 'transparent'
2141
+ }
2142
+ }
2143
+ },
2144
+ transformOrigin: {
2145
+ vertical: 'bottom',
2146
+ horizontal: 'center'
2147
+ },
2148
+ children: [jsx(MenuItem, {
2149
+ disabled: true,
2150
+ sx: {
2151
+ fontSize: '12px',
2152
+ opacity: 0.67,
2153
+ padding: '0px 12px',
2154
+ '&.MuiMenuItem-root': {
2155
+ minHeight: '30px!important',
2156
+ minWidth: 150
2157
+ }
2158
+ },
2159
+ children: title
2160
+ }), marks.map(function (mark) {
2161
+ var isSelected = (currentMark == null ? void 0 : currentMark.value) === mark.value && !isAutoSelected;
2162
+ return jsx(MenuItem, {
2163
+ disabled: allOptionsDisabled,
2164
+ onClick: function onClick() {
2165
+ if (!isSelected) {
2166
+ onChangeSliderValue(mark.value);
2167
+ }
2168
+ setOpen(false);
2169
+ },
2170
+ selected: !!isSelected && !displayLengthInputField,
2171
+ children: mark.label || mark.text
2172
+ }, mark.value);
2173
+ }), !!handleAutoClick && jsx(MenuItem, {
2174
+ disabled: allOptionsDisabled || isAutoDisabled,
2175
+ onClick: function onClick() {
2176
+ handleAutoClick();
2177
+ setOpen(false);
2178
+ },
2179
+ selected: isAutoSelected,
2180
+ children: t('timeslider-auto')
2181
+ }), !!displayCurrentLength && jsxs(MenuItem, {
2182
+ disabled: disbleUserSetDuration,
2183
+ onClick: function onClick() {
2184
+ return setDisplayLengthInputField(true);
2185
+ },
2186
+ sx: {
2187
+ maxWidth: '175px'
2188
+ },
2189
+ children: [!!displayLengthInputField && customLengthSelector, !displayLengthInputField && jsxs(Box, {
2190
+ sx: {
2191
+ flexDirection: 'column',
2192
+ display: 'flex',
2193
+ flexGrow: 1
2194
+ },
2195
+ children: [jsx(CardHeader, {
2196
+ slotProps: {
2197
+ title: {
2198
+ fontSize: 12
2199
+ }
2200
+ },
2201
+ sx: {
2202
+ height: 2,
2203
+ padding: 0,
2204
+ color: 'geowebColors.greys.accessible'
2205
+ },
2206
+ title: t(customFieldHeader)
2207
+ }), jsxs(Box, {
2208
+ sx: {
2209
+ flexDirection: 'row',
2210
+ display: 'flex',
2211
+ justifyContent: 'space-between',
2212
+ flexGrow: 1,
2213
+ paddingTop: 0.5
2214
+ },
2215
+ children: [jsx(Typography, {
2216
+ sx: {
2217
+ fontSize: 14,
2218
+ textTransform: 'none',
2219
+ lineHeight: 2
2220
+ },
2221
+ children: minutesToDescribedDuration(value)
2222
+ }), jsx(CustomTooltip, {
2223
+ title: t('timeslider-edit'),
2224
+ children: jsx("span", {
2225
+ children: jsx(CustomIconButton, {
2226
+ "aria-label": "edit animation option",
2227
+ "data-testid": "editAnimationOption",
2228
+ children: jsx(Edit, {})
2229
+ })
2230
+ })
2231
+ })]
2232
+ })]
2233
+ })]
2234
+ })]
2235
+ })]
2236
+ });
2237
+ };
2238
+
2239
+ var marks$2 = [{
2240
+ value: AnimationLength.Minutes15,
2241
+ text: 'timeslider-min',
2242
+ count: 15
2243
+ }, {
2244
+ value: AnimationLength.Minutes30,
2245
+ text: 'timeslider-min',
2246
+ count: 30
2247
+ }, {
2248
+ value: AnimationLength.Hours1,
2249
+ text: 'timeslider-hour',
2250
+ count: 1
2251
+ }, {
2252
+ value: AnimationLength.Hours2,
2253
+ text: 'timeslider-hour',
2254
+ count: 2
2255
+ }, {
2256
+ value: AnimationLength.Hours3,
2257
+ text: 'timeslider-hour',
2258
+ count: 3
2259
+ }, {
2260
+ value: AnimationLength.Hours6,
2261
+ text: 'timeslider-hour',
2262
+ count: 6
2263
+ }, {
2264
+ value: AnimationLength.Hours12,
2265
+ text: 'timeslider-hour',
2266
+ count: 12
2267
+ }, {
2268
+ value: AnimationLength.Hours24,
2269
+ text: 'timeslider-hour',
2270
+ count: 24
2271
+ }].sort(function (ta, tb) {
2272
+ return tb.value - ta.value;
2273
+ });
2274
+ var AnimationLengthButton = function AnimationLengthButton(_ref) {
2275
+ var _ref$disabled = _ref.disabled,
2276
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
2277
+ _ref$animationLength = _ref.animationLength,
2278
+ animationLength = _ref$animationLength === void 0 ? AnimationLength.Hours1 : _ref$animationLength,
2279
+ _ref$isAuto = _ref.isAuto,
2280
+ isAuto = _ref$isAuto === void 0 ? false : _ref$isAuto,
2281
+ layerHasTimeStep = _ref.layerHasTimeStep,
2282
+ onChangeAnimationLength = _ref.onChangeAnimationLength,
2283
+ toggleAnimationLengthAuto = _ref.toggleAnimationLengthAuto;
2284
+ var _useTimesliderTransla = useTimesliderTranslation(),
2285
+ t = _useTimesliderTransla.t;
2286
+ var translatedMarks = marks$2.map(function (mark) {
2287
+ return Object.assign({}, mark, {
2288
+ label: mark.count + " " + t(mark.text)
2289
+ });
2290
+ });
2291
+ var onChangeSliderValue = function onChangeSliderValue(newSliderValue) {
2292
+ var newLength = newSliderValue ? Math.round(newSliderValue) : 0;
2293
+ onChangeAnimationLength == null || onChangeAnimationLength(newLength);
2294
+ };
2295
+ var _useState = useState(false),
2296
+ open = _useState[0],
2297
+ setOpen = _useState[1];
2298
+ return jsx(TimeSliderMenu, {
2299
+ allOptionsDisabled: disabled,
2300
+ displayCurrentLength: true,
2301
+ handleAutoClick: toggleAnimationLengthAuto,
2302
+ icon: jsx(Animation, {
2303
+ "data-testid": "animationLengthButton"
2797
2304
  }),
2798
- animationStartPx = _map2[0],
2799
- animationEndPx = _map2[1],
2800
- dataStartPx = _map2[2],
2801
- dataEndPx = _map2[3],
2802
- currentTimePx = _map2[4];
2803
- ctx.clearRect(0, 0, canvasWidth, height);
2804
- drawBackground(ctx, theme, visibleTimeStart, visibleTimeEnd, animationStartPx, animationEndPx, canvasWidth, height, secondsPerPx, timeSliderSpan, dataStartPx, dataEndPx, currentTimePx);
2805
- drawTimeScale(ctx, theme, visibleTimeStart, visibleTimeEnd, canvasWidth, height, secondsPerPx);
2806
- drawCurrentTime(ctx, theme, canvasWidth, height, visibleTimeStart, visibleTimeEnd, currentTimeUnix);
2807
- drawNeedle(ctx, theme, canvasWidth, height, visibleTimeStart, visibleTimeEnd, selectedTimeUnix);
2305
+ isAutoDisabled: !layerHasTimeStep,
2306
+ isAutoSelected: isAuto,
2307
+ marks: translatedMarks,
2308
+ onChangeSliderValue: onChangeSliderValue,
2309
+ open: open,
2310
+ setOpen: setOpen,
2311
+ title: t('timeslider-animation'),
2312
+ value: animationLength
2313
+ });
2808
2314
  };
2809
2315
 
2810
- // Explanation of props can be found here:
2811
- // https://drive.google.com/file/d/1jqqNcciCH0UJiZ04HO-1vknmPPpT8fK5/view?usp=sharing
2812
- var TimeSliderLegend = function TimeSliderLegend(_ref) {
2813
- var _node$current, _getTimeSliderLegendE;
2814
- var mapId = _ref.mapId,
2815
- isTimeScrollingEnabled = _ref.isTimeScrollingEnabled,
2816
- mapWindowRef = _ref.mapWindowRef,
2817
- centerTime = _ref.centerTime,
2818
- canvasWidth = _ref.timeSliderWidth,
2819
- _ref$secondsPerPx = _ref.secondsPerPx,
2820
- secondsPerPx = _ref$secondsPerPx === void 0 ? defaultSecondsPerPx : _ref$secondsPerPx,
2821
- currentTime = _ref.currentTime,
2822
- dataStartTime = _ref.dataStartTime,
2823
- dataEndTime = _ref.dataEndTime,
2824
- reduxAnimationStartTime = _ref.reduxAnimationStartTime,
2825
- reduxAnimationEndTime = _ref.reduxAnimationEndTime,
2826
- timeStep = _ref.timeStep,
2827
- unfilteredSelectedTime = _ref.unfilteredSelectedTime,
2828
- isDraggingStartAnimation = _ref.isDraggingStartAnimation,
2829
- isDraggingEndAnimation = _ref.isDraggingEndAnimation,
2830
- isTimeSliderHoverOn = _ref.isTimeSliderHoverOn,
2831
- timeSliderSpan = _ref.timeSliderSpan,
2832
- _ref$setUnfilteredSel = _ref.setUnfilteredSelectedTime,
2833
- setUnfilteredSelectedTime = _ref$setUnfilteredSel === void 0 ? function () {} : _ref$setUnfilteredSel,
2834
- _ref$onSetCenterTime = _ref.onSetCenterTime,
2835
- onSetCenterTime = _ref$onSetCenterTime === void 0 ? function () {} : _ref$onSetCenterTime,
2836
- _ref$onSetAnimationSt = _ref.onSetAnimationStartTime,
2837
- onSetAnimationStartTime = _ref$onSetAnimationSt === void 0 ? function () {} : _ref$onSetAnimationSt,
2838
- _ref$onSetAnimationEn = _ref.onSetAnimationEndTime,
2839
- onSetAnimationEndTime = _ref$onSetAnimationEn === void 0 ? function () {} : _ref$onSetAnimationEn,
2840
- _ref$updateCanvasWidt = _ref.updateCanvasWidth,
2841
- updateCanvasWidth = _ref$updateCanvasWidt === void 0 ? function () {} : _ref$updateCanvasWidt,
2842
- setIsDraggingStartAnimation = _ref.setIsDraggingStartAnimation,
2843
- setIsDraggingEndAnimation = _ref.setIsDraggingEndAnimation,
2844
- onStartTimeChange = _ref.onStartTimeChange,
2845
- onEndTimeChange = _ref.onEndTimeChange,
2846
- onSetTimeSliderSpan = _ref.onSetTimeSliderSpan,
2847
- _ref$adjustSelectedTi = _ref.adjustSelectedTimeOnWheel,
2848
- adjustSelectedTimeOnWheel = _ref$adjustSelectedTi === void 0 ? function () {} : _ref$adjustSelectedTi;
2849
- var _useCanvasTarget = useCanvasTarget('mousedown'),
2850
- node = _useCanvasTarget[1];
2851
- var theme = useTheme();
2852
- var _useState = useState(false),
2853
- isDraggingSelectedTime = _useState[0],
2854
- setIsDraggingSelectedTime = _useState[1];
2855
- var _useState2 = useState(false),
2856
- isDraggingLegend = _useState2[0],
2857
- setIsDraggingLegend = _useState2[1];
2858
- var xOffset = ((_node$current = node.current) == null || (_node$current = _node$current.canvas) == null ? void 0 : _node$current.getBoundingClientRect().x) || 0;
2859
- var _useState3 = useState(false),
2860
- isDraggingAnimationArea = _useState3[0],
2861
- setIsDraggingAnimationArea = _useState3[1];
2862
- var _useState4 = useState(false),
2863
- isMouseOverCanvas = _useState4[0],
2864
- setIsMouseOverCanvas = _useState4[1];
2865
- var _useState5 = useState('auto'),
2866
- cursorStyle = _useState5[0],
2867
- setCursorStyle = _useState5[1];
2868
- var _useState6 = useState(undefined),
2869
- showTooltip = _useState6[0],
2870
- setShowTooltip = _useState6[1];
2871
- var _useState7 = useState(),
2872
- lastHandledRoundedTime = _useState7[0],
2873
- setLastHandledRoundedTime = _useState7[1];
2874
- // remove active drag. can happen outside canvas.
2875
- var _useState8 = useState(),
2876
- localAnimationStartTime = _useState8[0],
2877
- setLocalAnimationStartTime = _useState8[1];
2878
- var _useState9 = useState(),
2879
- localAnimationEndTime = _useState9[0],
2880
- setLocalAnimationEndTime = _useState9[1];
2881
- var _useState0 = useState(),
2882
- pointerTime = _useState0[0],
2883
- setPointerTime = _useState0[1];
2884
- var _useState1 = useState(false),
2885
- showPointerTimeTooltip = _useState1[0],
2886
- setShowPointerTimeTooltip = _useState1[1];
2887
- var debouncedSetShowPointerTimeTooltip = useRef(debounce(setShowPointerTimeTooltip, 500)).current;
2888
- var timeBetweenMouseAndStartAndEnd = useRef();
2889
- var pixelsMovedSinceStartDragging = useRef(0);
2890
- var isAnimationTimeModifiedSetRef = useRef(false);
2891
- var tooltipPosition = useRef();
2892
- var startDraggingPosition = useRef(0);
2893
- var popperRef = useRef(null);
2894
- var isClickOrDrag = useRef();
2895
- var filteredTime = getFilteredTime(unfilteredSelectedTime, timeStep, dataStartTime, dataEndTime);
2896
- var start = localAnimationStartTime;
2897
- var end = localAnimationEndTime;
2898
- var pixelsBetweenViewportAndTimesliderOnTop = (_getTimeSliderLegendE = getTimeSliderLegendElement(mapId)) == null ? void 0 : _getTimeSliderLegendE.getBoundingClientRect()['top'];
2899
- var setTooltipPosition = function setTooltipPosition() {
2900
- var tooltipX = tooltipPosition.current;
2901
- var tooltipY = pixelsBetweenViewportAndTimesliderOnTop && pixelsBetweenViewportAndTimesliderOnTop - TIME_SLIDER_LEGEND_HEIGHT * 2.5;
2902
- return new DOMRect(tooltipX, tooltipY, 0, 0);
2903
- };
2904
- var getTooltipTime = function getTooltipTime() {
2905
- switch (showTooltip) {
2906
- case 'animationStart':
2907
- return localAnimationStartTime;
2908
- case 'animationEnd':
2909
- return localAnimationEndTime;
2910
- case 'mousePointer':
2911
- return pointerTime;
2912
- default:
2913
- return undefined;
2914
- }
2915
- };
2916
- var getTooltipText = function getTooltipText() {
2917
- var time = getTooltipTime();
2918
- if (!time) {
2919
- return undefined;
2920
- }
2921
- var roundedTooltipTime = showTooltip === 'mousePointer' ? time : roundWithTimeStep$1(time);
2922
- var tooltipText = dateUtils.dateToString(dateUtils.fromUnix(roundedTooltipTime), dateUtils.DATE_FORMAT_HOURS);
2923
- return tooltipText;
2924
- };
2925
- var roundWithTimeStep$1 = function roundWithTimeStep$1(time) {
2926
- return roundWithTimeStep(time, timeStep);
2927
- };
2928
- var currentIndex = timeValues.indexOf(timeSliderSpan);
2929
- var updateTimeSpan = function updateTimeSpan(deltaY) {
2930
- if (onSetTimeSliderSpan) {
2931
- // Don't do anything if we are already at the edges of the timespan options
2932
- if (deltaY < 0 && currentIndex === 0 || deltaY > 0 && currentIndex === timeValues.length - 1) {
2933
- return;
2934
- }
2935
- var newTimeSpan = deltaY < 0 ? timeValues[currentIndex - 1] : timeValues[currentIndex + 1];
2936
- onSetTimeSliderSpan(newTimeSpan, centerTime);
2937
- }
2316
+ var AutoUpdateButton = function AutoUpdateButton(_ref) {
2317
+ var _ref$toggleAutoUpdate = _ref.toggleAutoUpdate,
2318
+ toggleAutoUpdate = _ref$toggleAutoUpdate === void 0 ? function () {} : _ref$toggleAutoUpdate,
2319
+ _ref$isAutoUpdating = _ref.isAutoUpdating,
2320
+ isAutoUpdating = _ref$isAutoUpdating === void 0 ? false : _ref$isAutoUpdating,
2321
+ _ref$disabled = _ref.disabled,
2322
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled;
2323
+ var _useTimesliderTransla = useTimesliderTranslation(),
2324
+ t = _useTimesliderTransla.t;
2325
+ return jsx(CustomIconButton, {
2326
+ "data-testid": "autoUpdateButton",
2327
+ disabled: disabled,
2328
+ isSelected: isAutoUpdating,
2329
+ onClick: function onClick() {
2330
+ return toggleAutoUpdate();
2331
+ },
2332
+ tooltipTitle: isAutoUpdating ? t('timeslider-auto-update-on') : t('timeslider-auto-update-off'),
2333
+ variant: "tool",
2334
+ children: isAutoUpdating ? jsx(AutoUpdateActive, {
2335
+ "data-testid": "auto-update-svg-on"
2336
+ }) : jsx(AutoUpdateInActive, {
2337
+ "data-testid": "auto-update-svg-off"
2338
+ })
2339
+ });
2340
+ };
2341
+
2342
+ var BackwardForwardStepButton = function BackwardForwardStepButton(_ref) {
2343
+ var isForwardStep = _ref.isForwardStep,
2344
+ isDisabled = _ref.isDisabled,
2345
+ _ref$onClickBFButton = _ref.onClickBFButton,
2346
+ onClickBFButton = _ref$onClickBFButton === void 0 ? function () {} : _ref$onClickBFButton;
2347
+ // Added renderCounter for testing and performance purposes
2348
+ renderCounter.count(BackwardForwardStepButton.name);
2349
+ var _useTimesliderTransla = useTimesliderTranslation(),
2350
+ t = _useTimesliderTransla.t;
2351
+ return jsx(CustomIconButton, {
2352
+ "aria-label": isForwardStep ? 'forward' : 'backward',
2353
+ "data-testid": isForwardStep ? 'stepForwardButton' : 'stepBackwardButton',
2354
+ disabled: isDisabled,
2355
+ onClick: onClickBFButton,
2356
+ tooltipTitle: isForwardStep ? t('timeslider-forward') : t('timeslider-backward'),
2357
+ variant: "tool",
2358
+ children: isForwardStep ? jsx(StepForward, {
2359
+ "data-testid": "step-forward-svg-path"
2360
+ }) : jsx(StepBackward, {
2361
+ "data-testid": "step-backward-svg-path"
2362
+ })
2363
+ });
2364
+ };
2365
+
2366
+ var NowButton = function NowButton(_ref) {
2367
+ var _ref$onSetNow = _ref.onSetNow,
2368
+ onSetNow = _ref$onSetNow === void 0 ? function () {} : _ref$onSetNow,
2369
+ _ref$disabled = _ref.disabled,
2370
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled;
2371
+ var _useTimesliderTransla = useTimesliderTranslation(),
2372
+ t = _useTimesliderTransla.t;
2373
+ return jsx(CustomIconButton, {
2374
+ "aria-label": "now",
2375
+ "data-testid": "nowButtonTooltip",
2376
+ disabled: disabled,
2377
+ onClick: function onClick() {
2378
+ return onSetNow();
2379
+ },
2380
+ tooltipTitle: t('timeslider-now'),
2381
+ variant: "tool",
2382
+ children: jsx(Now, {
2383
+ "data-testid": "now-svg"
2384
+ })
2385
+ });
2386
+ };
2387
+
2388
+ var PlayButton = function PlayButton(_ref) {
2389
+ var isAnimating = _ref.isAnimating,
2390
+ isDisabled = _ref.isDisabled,
2391
+ _ref$onTogglePlayButt = _ref.onTogglePlayButton,
2392
+ onTogglePlayButton = _ref$onTogglePlayButt === void 0 ? function () {} : _ref$onTogglePlayButt;
2393
+ var onTogglePlay = function onTogglePlay() {
2394
+ onTogglePlayButton();
2938
2395
  };
2939
- var throttledUpdateTimeSpan = throttle(updateTimeSpan, 200);
2940
- var debouncedAndThrottledUpdateTimeSpan = debounce(throttledUpdateTimeSpan, 20);
2941
- var handleAnimationDragging = React.useCallback(function (x, clientX) {
2942
- if (!localAnimationStartTime || !localAnimationEndTime) {
2943
- return;
2944
- }
2945
- var mousePosition = clientX - xOffset;
2946
- var startPos = timestampToPixel(localAnimationStartTime, centerTime, canvasWidth, secondsPerPx);
2947
- var endPos = timestampToPixel(localAnimationEndTime, centerTime, canvasWidth, secondsPerPx);
2948
- var mouseTimeUnix = pixelToTimestamp(mousePosition, centerTime, canvasWidth, secondsPerPx);
2949
- var startTime = roundWithTimeStep(mouseTimeUnix, timeStep);
2950
- var endTime = roundWithTimeStep(mouseTimeUnix, timeStep);
2951
- var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
2952
- if (isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
2953
- if (!isAnimationTimeModifiedSetRef.current) {
2954
- isAnimationTimeModifiedSetRef.current = true;
2955
- }
2956
- }
2957
- if (isDraggingStartAnimation) {
2958
- if (isDraggingStartWithinBounds(endPos, mousePosition)) {
2959
- return;
2960
- }
2961
- setLocalAnimationStartTime(roundWithTimeStep(mouseTimeUnix, timeStep));
2962
- if (lastHandledRoundedTime !== startTime) {
2963
- setLastHandledRoundedTime(startTime);
2964
- setShowTooltip('animationStart');
2965
- onStartTimeChange == null || onStartTimeChange(startTime);
2966
- }
2967
- } else if (isDraggingEndAnimation && pixelsBetweenOnLeft) {
2968
- if (isDraggingEndWithinBounds(startPos, mousePosition, canvasWidth)) {
2969
- return;
2970
- }
2971
- setLocalAnimationEndTime(roundWithTimeStep(mouseTimeUnix, timeStep));
2972
- if (lastHandledRoundedTime !== endTime) {
2973
- setLastHandledRoundedTime(endTime);
2974
- setShowTooltip('animationEnd');
2975
- onEndTimeChange == null || onEndTimeChange(endTime);
2976
- }
2977
- }
2978
- if (isDraggingAnimationArea) {
2979
- if (timeBetweenMouseAndStartAndEnd.current === undefined) {
2980
- // to move the whole animation area we need to calculate the distance
2981
- // between the mouse position and the start and end position
2982
- var _timeFromMouseToStart = mouseTimeUnix - start;
2983
- var _timeFromMouseToEnd = end - mouseTimeUnix;
2984
- timeBetweenMouseAndStartAndEnd.current = {
2985
- timeFromMouseToEnd: _timeFromMouseToEnd,
2986
- timeFromMouseToStart: _timeFromMouseToStart
2987
- };
2988
- return;
2989
- }
2990
- pixelsMovedSinceStartDragging.current += x;
2991
- var _timeBetweenMouseAndS = timeBetweenMouseAndStartAndEnd.current,
2992
- timeFromMouseToEnd = _timeBetweenMouseAndS.timeFromMouseToEnd,
2993
- timeFromMouseToStart = _timeBetweenMouseAndS.timeFromMouseToStart;
2994
- var newStartTime = mouseTimeUnix - timeFromMouseToStart;
2995
- var newEndTime = mouseTimeUnix + timeFromMouseToEnd;
2996
- var roundedNewStartTime = roundWithTimeStep(newStartTime, timeStep);
2997
- var roundedNewEndTime = roundWithTimeStep(newEndTime, timeStep);
2998
- setLocalAnimationStartTime(roundedNewStartTime);
2999
- setLocalAnimationEndTime(roundedNewEndTime);
3000
- }
3001
- }, [canvasWidth, centerTime, end, isDraggingAnimationArea, isDraggingEndAnimation, isDraggingStartAnimation, lastHandledRoundedTime, localAnimationEndTime, localAnimationStartTime, mapId, onEndTimeChange, onStartTimeChange, secondsPerPx, start, timeStep, xOffset]);
3002
- useEffect(function () {
3003
- var handleMouseUp = function handleMouseUp() {
3004
- pixelsMovedSinceStartDragging.current = 0;
3005
- timeBetweenMouseAndStartAndEnd.current = undefined;
3006
- };
3007
- document.addEventListener('mouseup', handleMouseUp);
3008
- return function () {
3009
- document.removeEventListener('mouseup', handleMouseUp);
3010
- };
3011
- }, []);
3012
- useEffect(function () {
3013
- var startTimestamp = convertStringTimeToUnix(reduxAnimationStartTime);
3014
- var endTimestamp = convertStringTimeToUnix(reduxAnimationEndTime);
3015
- setLocalAnimationStartTime(startTimestamp);
3016
- setLocalAnimationEndTime(endTimestamp);
3017
- }, [reduxAnimationStartTime, reduxAnimationEndTime, setLocalAnimationStartTime, setLocalAnimationEndTime]);
3018
- useEffect(function () {
3019
- var stoppedDragging = !isDraggingStartAnimation && !isDraggingEndAnimation && !isDraggingAnimationArea;
3020
- if (stoppedDragging && isAnimationTimeModifiedSetRef.current) {
3021
- if (start && start !== localAnimationStartTime) {
3022
- onSetAnimationStartTime(dateUtils.fromUnix(start).toISOString());
3023
- }
3024
- if (end && end !== localAnimationEndTime) {
3025
- onSetAnimationEndTime(dateUtils.fromUnix(end).toISOString());
3026
- }
3027
- isAnimationTimeModifiedSetRef.current = false;
3028
- }
3029
- }, [isDraggingStartAnimation, isDraggingEndAnimation, isDraggingAnimationArea, isAnimationTimeModifiedSetRef, localAnimationStartTime, localAnimationEndTime, onSetAnimationStartTime, onSetAnimationEndTime, start, end]);
3030
- useEffect(function () {
3031
- var handleMouseUp = function handleMouseUp() {
3032
- if (isDraggingAnimationArea) {
3033
- onStartTimeChange == null || onStartTimeChange(localAnimationStartTime);
3034
- onEndTimeChange == null || onEndTimeChange(localAnimationEndTime);
3035
- }
3036
- setCursorStyle('auto');
3037
- setIsDraggingSelectedTime(false);
3038
- setIsDraggingStartAnimation == null || setIsDraggingStartAnimation(false);
3039
- setIsDraggingEndAnimation == null || setIsDraggingEndAnimation(false);
3040
- setIsDraggingLegend(false);
3041
- setShowTooltip(undefined);
3042
- setIsDraggingAnimationArea(false);
3043
- startDraggingPosition.current = 0;
3044
- if (isAnimationTimeModifiedSetRef.current) {
3045
- isAnimationTimeModifiedSetRef.current = false;
3046
- }
3047
- };
3048
- document.addEventListener('mouseup', handleMouseUp);
3049
- return function () {
3050
- document.removeEventListener('mouseup', handleMouseUp);
3051
- };
3052
- }, [setIsDraggingStartAnimation, setIsDraggingEndAnimation, localAnimationStartTime, localAnimationEndTime, onStartTimeChange, onEndTimeChange, isDraggingAnimationArea]);
3053
- useEffect(function () {
3054
- var handleMouseActions = function handleMouseActions(event) {
3055
- if (event.movementX === 0) {
3056
- return;
3057
- }
3058
- if (isDraggingLegend) {
3059
- var dragDistanceTime = event.movementX * secondsPerPx;
3060
- var newCenterTime = centerTime - dragDistanceTime;
3061
- onSetCenterTime(newCenterTime);
3062
- } else if (isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
3063
- handleAnimationDragging(event.movementX, event.clientX);
3064
- } else if (isDraggingSelectedTime) {
3065
- moveSelectedTimePx(event.movementX, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
3066
- }
3067
- if (isMouseOverCanvas && isTimeSliderHoverOn) {
3068
- moveSelectedTimePx(event.movementX, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
3069
- }
3070
- };
3071
- var handleMouseMove = function handleMouseMove(event) {
3072
- handleMouseActions(event);
3073
- };
3074
- document.addEventListener('mousemove', handleMouseMove);
3075
- return function () {
3076
- document.removeEventListener('mousemove', handleMouseMove);
2396
+ var _useTimesliderTransla = useTimesliderTranslation(),
2397
+ t = _useTimesliderTransla.t;
2398
+ return jsx(CustomIconButton, {
2399
+ "data-testid": "playButton",
2400
+ disabled: isDisabled,
2401
+ isSelected: isAnimating,
2402
+ onClick: onTogglePlay,
2403
+ tooltipTitle: isAnimating ? t('timeslider-pause') : t('timeslider-play'),
2404
+ variant: "tool",
2405
+ children: isAnimating ? jsx(Pause, {
2406
+ "data-testid": "pause-svg-path"
2407
+ }) : jsx(Play, {
2408
+ "data-testid": "play-svg-path"
2409
+ })
2410
+ });
2411
+ };
2412
+
2413
+ var ControlButtons = function ControlButtons(_ref) {
2414
+ var backwardBtn = _ref.backwardBtn,
2415
+ forwardBtn = _ref.forwardBtn,
2416
+ playBtn = _ref.playBtn,
2417
+ nowBtn = _ref.nowBtn,
2418
+ autoUpdateBtn = _ref.autoUpdateBtn;
2419
+ return jsxs(Fragment, {
2420
+ children: [jsx(Grid, {
2421
+ children: backwardBtn || jsx(BackwardForwardStepButton, {
2422
+ isForwardStep: false
2423
+ })
2424
+ }), jsx(Grid, {
2425
+ children: forwardBtn || jsx(BackwardForwardStepButton, {
2426
+ isForwardStep: true
2427
+ })
2428
+ }), jsx(Grid, {
2429
+ children: playBtn || jsx(PlayButton, {})
2430
+ }), jsx(Grid, {
2431
+ children: nowBtn || jsx(NowButton, {})
2432
+ }), jsx(Grid, {
2433
+ children: autoUpdateBtn || jsx(AutoUpdateButton, {})
2434
+ })]
2435
+ });
2436
+ };
2437
+
2438
+ var SpeedButton = function SpeedButton(_ref) {
2439
+ var animationDelay = _ref.animationDelay,
2440
+ setMapAnimationDelay = _ref.setMapAnimationDelay;
2441
+ var sorted = [].concat(speedFactors).sort(function (sa, sb) {
2442
+ return sb - sa;
2443
+ });
2444
+ var marks = sorted.map(function (speedFactor) {
2445
+ return {
2446
+ value: getSpeedDelay(speedFactor),
2447
+ text: "x" + speedFactor,
2448
+ label: "x" + speedFactor
3077
2449
  };
3078
- }, [isDraggingLegend, isDraggingStartAnimation, isDraggingEndAnimation, isDraggingAnimationArea, isDraggingSelectedTime, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime, onSetCenterTime, isTimeSliderHoverOn, isMouseOverCanvas, handleAnimationDragging]);
3079
- useEffect(function () {
3080
- if (!showTooltip && pointerTime) {
3081
- if (showPointerTimeTooltip) {
3082
- setShowTooltip('mousePointer');
3083
- } else {
3084
- debouncedSetShowPointerTimeTooltip(true);
3085
- }
3086
- } else if (showTooltip === 'mousePointer' && !pointerTime) {
3087
- setShowTooltip(undefined);
3088
- debouncedSetShowPointerTimeTooltip(false);
3089
- debouncedSetShowPointerTimeTooltip.flush();
3090
- } else if (showTooltip !== 'mousePointer') {
3091
- debouncedSetShowPointerTimeTooltip(false);
3092
- debouncedSetShowPointerTimeTooltip.flush();
3093
- }
3094
- }, [debouncedSetShowPointerTimeTooltip, pointerTime, showPointerTimeTooltip, showTooltip]);
3095
- var onMouseDown = function onMouseDown(x, y, width) {
3096
- isClickOrDrag.current = 'click';
3097
- startDraggingPosition.current = x;
3098
- var _getPositions = getPositions(width, unfilteredSelectedTime, centerTime, secondsPerPx, start, end),
3099
- startAnimationPosition = _getPositions.startAnimationPosition,
3100
- endAnimationPosition = _getPositions.endAnimationPosition,
3101
- selectedTimePosition = _getPositions.selectedTimePosition;
3102
- // start dragging selected time.
3103
- if (isSelectedTimeIconArea(x, selectedTimePosition, DRAG_AREA_WIDTH)) {
3104
- setCursorStyle('grabbing');
3105
- setIsDraggingSelectedTime(true);
3106
- return;
3107
- }
3108
- if (reduxAnimationStartTime && reduxAnimationEndTime) {
3109
- var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
3110
- tooltipPosition.current = pixelsBetweenOnLeft ? x + pixelsBetweenOnLeft : x;
3111
- // start dragging either marker
3112
- if (isLeftAnimationIconArea(x, startAnimationPosition, DRAG_AREA_WIDTH)) {
3113
- setCursorStyle('grabbing');
3114
- setIsDraggingStartAnimation == null || setIsDraggingStartAnimation(true);
3115
- setShowTooltip('animationStart');
3116
- return;
3117
- }
3118
- if (isRightAnimationIconArea(x, endAnimationPosition, DRAG_AREA_WIDTH)) {
3119
- setCursorStyle('grabbing');
3120
- setIsDraggingEndAnimation == null || setIsDraggingEndAnimation(true);
3121
- setShowTooltip('animationEnd');
3122
- return;
3123
- }
3124
- if (isInsideAnimationArea(x, startAnimationPosition, endAnimationPosition)) {
3125
- setCursorStyle('grabbing');
3126
- setIsDraggingAnimationArea(true);
3127
- return;
3128
- }
3129
- }
3130
- // clicking the timeslider
3131
- setIsDraggingLegend(true);
3132
- };
3133
- var onMouseUp = function onMouseUp(x) {
3134
- if (isClickOrDrag.current === 'click') {
3135
- var unfilteredSelectedTimePx = timestampToPixel(unfilteredSelectedTime, centerTime, canvasWidth, secondsPerPx);
3136
- moveSelectedTimePx(x - unfilteredSelectedTimePx, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
2450
+ });
2451
+ var _useTimesliderTransla = useTimesliderTranslation(),
2452
+ t = _useTimesliderTransla.t;
2453
+ var _useState = useState(false),
2454
+ open = _useState[0],
2455
+ setOpen = _useState[1];
2456
+ return jsx(TimeSliderMenu, {
2457
+ icon: jsx(Speed, {}),
2458
+ marks: marks,
2459
+ onChangeSliderValue: function onChangeSliderValue(markValue) {
2460
+ setMapAnimationDelay(markValue);
2461
+ },
2462
+ open: open,
2463
+ setOpen: setOpen,
2464
+ title: t('timeslider-speed'),
2465
+ value: animationDelay
2466
+ });
2467
+ };
2468
+
2469
+ var TimeSpanButtonCustomSelect = function TimeSpanButtonCustomSelect(_ref) {
2470
+ var timeSliderSpan = _ref.timeSliderSpan,
2471
+ setOpen = _ref.setOpen,
2472
+ onChangeSliderValue = _ref.onChangeSliderValue;
2473
+ var _useTimesliderTransla = useTimesliderTranslation(),
2474
+ t = _useTimesliderTransla.t;
2475
+ var _React$useState = React.useState(timeSliderSpan / getLargestTimeUnit(timeSliderSpan)),
2476
+ selectedTimeValue = _React$useState[0],
2477
+ setSelectedTimeValue = _React$useState[1];
2478
+ var _React$useState2 = React.useState(getLargestTimeUnit(timeSliderSpan).toString()),
2479
+ selectedTimeResolution = _React$useState2[0],
2480
+ setSelectedTimeResolution = _React$useState2[1];
2481
+ var _React$useState3 = React.useState(true),
2482
+ isANumber = _React$useState3[0],
2483
+ setIsANumber = _React$useState3[1];
2484
+ return jsx(Box, {
2485
+ children: jsxs(FormControl, {
2486
+ onKeyDown: function onKeyDown(event) {
2487
+ event.stopPropagation();
2488
+ },
2489
+ size: "small",
2490
+ sx: {
2491
+ flexDirection: 'row',
2492
+ display: 'flex'
2493
+ },
2494
+ variant: "standard",
2495
+ children: [jsx(TextField, {
2496
+ autoFocus: true,
2497
+ color: isANumber ? 'primary' : 'warning',
2498
+ label: t('timeslider-span'),
2499
+ onBlur: function onBlur() {
2500
+ onChangeSliderValue(selectedTimeValue * Number(selectedTimeResolution));
2501
+ },
2502
+ onChange: function onChange(e) {
2503
+ if (!isNaN(+e.target.value)) {
2504
+ setIsANumber(true);
2505
+ setSelectedTimeValue(Number(e.target.value));
2506
+ } else {
2507
+ setIsANumber(false);
2508
+ }
2509
+ },
2510
+ onKeyDown: function onKeyDown(e) {
2511
+ if (e.key === 'Enter' || e.key === 'Escape') {
2512
+ onChangeSliderValue(selectedTimeValue * Number(selectedTimeResolution));
2513
+ setOpen(false);
2514
+ }
2515
+ },
2516
+ size: "small",
2517
+ slotProps: {
2518
+ htmlInput: {
2519
+ maxLength: 4,
2520
+ 'aria-label': 'custom-input'
2521
+ }
2522
+ },
2523
+ value: Math.round(selectedTimeValue * 100) / 100,
2524
+ variant: "standard"
2525
+ }), jsx(Box, {
2526
+ sx: {
2527
+ alignContent: 'end'
2528
+ },
2529
+ children: jsxs(Select, {
2530
+ "aria-label": "time-resolution-selector",
2531
+ defaultValue: "h",
2532
+ onChange: function onChange(e) {
2533
+ setSelectedTimeResolution(e.target.value);
2534
+ onChangeSliderValue(selectedTimeValue * Number(e.target.value));
2535
+ setOpen(false);
2536
+ },
2537
+ size: "small",
2538
+ tabIndex: -1,
2539
+ value: selectedTimeResolution,
2540
+ children: [jsx(MenuItem, {
2541
+ value: TimeInMinutes.YEAR,
2542
+ children: t('years')
2543
+ }), jsx(MenuItem, {
2544
+ value: TimeInMinutes.MONTH,
2545
+ children: t('months')
2546
+ }), jsx(MenuItem, {
2547
+ value: TimeInMinutes.WEEK,
2548
+ children: t('weeks')
2549
+ }), jsx(MenuItem, {
2550
+ value: TimeInMinutes.DAY,
2551
+ children: t('days')
2552
+ }), jsx(MenuItem, {
2553
+ value: TimeInMinutes.HOUR,
2554
+ children: t('hours')
2555
+ }), jsx(MenuItem, {
2556
+ value: TimeInMinutes.MINUTE,
2557
+ children: t('minutes')
2558
+ })]
2559
+ })
2560
+ })]
2561
+ })
2562
+ });
2563
+ };
2564
+
2565
+ var marks$1 = [{
2566
+ value: 60,
2567
+ text: 'timeslider-hour',
2568
+ count: 1
2569
+ }, {
2570
+ value: 3 * 60,
2571
+ text: 'timeslider-hour',
2572
+ count: 3
2573
+ }, {
2574
+ value: 6 * 60,
2575
+ text: 'timeslider-hour',
2576
+ count: 6
2577
+ }, {
2578
+ value: 12 * 60,
2579
+ text: 'timeslider-hour',
2580
+ count: 12
2581
+ }, {
2582
+ value: 24 * 60,
2583
+ text: 'timeslider-hour',
2584
+ count: 24
2585
+ }, {
2586
+ value: 2 * 24 * 60,
2587
+ text: 'timeslider-hour',
2588
+ count: 48
2589
+ }, {
2590
+ value: 7 * 24 * 60,
2591
+ text: 'timeslider-week',
2592
+ count: 1
2593
+ }, {
2594
+ value: 2 * 7 * 24 * 60,
2595
+ text: 'timeslider-weeks',
2596
+ count: 2
2597
+ }, {
2598
+ value: 30 * 24 * 60,
2599
+ text: 'timeslider-month',
2600
+ count: 1
2601
+ }, {
2602
+ value: 3 * 30 * 24 * 60,
2603
+ text: 'timeslider-months',
2604
+ count: 3
2605
+ }, {
2606
+ value: 365 * 24 * 60,
2607
+ text: 'timeslider-year',
2608
+ count: 1
2609
+ }].sort(function (ta, tb) {
2610
+ return tb.value - ta.value;
2611
+ });
2612
+ var TimeSpanButton = function TimeSpanButton(_ref) {
2613
+ var _ref$timeSliderSpan = _ref.timeSliderSpan,
2614
+ timeSliderSpan = _ref$timeSliderSpan === void 0 ? defaultTimeSpan : _ref$timeSliderSpan,
2615
+ _ref$disabled = _ref.disabled,
2616
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
2617
+ _ref$onChangeSliderVa = _ref.onChangeSliderValue,
2618
+ onChangeSliderValue = _ref$onChangeSliderVa === void 0 ? function () {} : _ref$onChangeSliderVa,
2619
+ onToggleTimeSpan = _ref.onToggleTimeSpan,
2620
+ isTimeSpanAuto = _ref.isTimeSpanAuto,
2621
+ _ref$isOpenByDefault = _ref.isOpenByDefault,
2622
+ isOpenByDefault = _ref$isOpenByDefault === void 0 ? false : _ref$isOpenByDefault,
2623
+ _ref$layerHasTimeStep = _ref.layerHasTimeStep,
2624
+ layerHasTimeStep = _ref$layerHasTimeStep === void 0 ? false : _ref$layerHasTimeStep;
2625
+ var _useTimesliderTransla = useTimesliderTranslation(),
2626
+ t = _useTimesliderTransla.t;
2627
+ var translatedMarks = marks$1.map(function (mark) {
2628
+ return Object.assign({}, mark, {
2629
+ label: mark.count + " " + t(mark.text)
2630
+ });
2631
+ });
2632
+ var _useState = useState(isOpenByDefault),
2633
+ open = _useState[0],
2634
+ setOpen = _useState[1];
2635
+ return jsx(TimeSliderMenu, {
2636
+ allOptionsDisabled: disabled,
2637
+ customFieldHeader: t('timeslider-span'),
2638
+ customLengthSelector: jsx(TimeSpanButtonCustomSelect, {
2639
+ onChangeSliderValue: onChangeSliderValue,
2640
+ setOpen: setOpen,
2641
+ timeSliderSpan: timeSliderSpan
2642
+ }),
2643
+ disbleUserSetDuration: false,
2644
+ displayCurrentLength: true,
2645
+ handleAutoClick: onToggleTimeSpan,
2646
+ icon: jsx(Clock, {}),
2647
+ isAutoDisabled: !layerHasTimeStep,
2648
+ isAutoSelected: isTimeSpanAuto,
2649
+ marks: translatedMarks,
2650
+ onChangeSliderValue: onChangeSliderValue,
2651
+ open: open,
2652
+ setOpen: setOpen,
2653
+ title: t('timeslider-time-span'),
2654
+ value: timeSliderSpan
2655
+ });
2656
+ };
2657
+
2658
+ var marks = [{
2659
+ value: 1,
2660
+ text: 'timeslider-min',
2661
+ count: 1
2662
+ }, {
2663
+ value: 2,
2664
+ text: 'timeslider-min',
2665
+ count: 2
2666
+ }, {
2667
+ value: 5,
2668
+ text: 'timeslider-min',
2669
+ count: 5
2670
+ }, {
2671
+ value: 10,
2672
+ text: 'timeslider-min',
2673
+ count: 10
2674
+ }, {
2675
+ value: 15,
2676
+ text: 'timeslider-min',
2677
+ count: 15
2678
+ }, {
2679
+ value: 30,
2680
+ text: 'timeslider-min',
2681
+ count: 30
2682
+ }, {
2683
+ value: 60,
2684
+ text: 'timeslider-hour',
2685
+ count: 1
2686
+ }, {
2687
+ value: 120,
2688
+ text: 'timeslider-hour',
2689
+ count: 2
2690
+ }, {
2691
+ value: 180,
2692
+ text: 'timeslider-hour',
2693
+ count: 3
2694
+ }, {
2695
+ value: 360,
2696
+ text: 'timeslider-hour',
2697
+ count: 6
2698
+ }, {
2699
+ value: 720,
2700
+ text: 'timeslider-hour',
2701
+ count: 12
2702
+ }, {
2703
+ value: 1440,
2704
+ text: 'timeslider-hour',
2705
+ count: 24
2706
+ }, {
2707
+ value: 2880,
2708
+ text: 'timeslider-hour',
2709
+ count: 48
2710
+ }, {
2711
+ value: 4320,
2712
+ text: 'timeslider-hour',
2713
+ count: 72
2714
+ }, {
2715
+ value: 10080,
2716
+ text: 'timeslider-week',
2717
+ count: 1
2718
+ }, {
2719
+ value: 20160,
2720
+ text: 'timeslider-weeks',
2721
+ count: 2
2722
+ }, {
2723
+ value: 43200,
2724
+ text: 'timeslider-month',
2725
+ count: 1
2726
+ }, {
2727
+ value: 87600,
2728
+ text: 'timeslider-months',
2729
+ count: 2
2730
+ }, {
2731
+ value: 262800,
2732
+ text: 'timeslider-months',
2733
+ count: 6
2734
+ }, {
2735
+ value: 525600,
2736
+ text: 'timeslider-year',
2737
+ count: 1
2738
+ }, {
2739
+ value: 5256000,
2740
+ text: 'timeslider-years',
2741
+ count: 10
2742
+ }].sort(function (ta, tb) {
2743
+ return tb.value - ta.value;
2744
+ });
2745
+ var TimeStepButton = function TimeStepButton(_ref) {
2746
+ var _ref$timeStep = _ref.timeStep,
2747
+ timeStep = _ref$timeStep === void 0 ? marks[0].value : _ref$timeStep,
2748
+ _ref$disabled = _ref.disabled,
2749
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
2750
+ _ref$isTimestepAuto = _ref.isTimestepAuto,
2751
+ isTimestepAuto = _ref$isTimestepAuto === void 0 ? false : _ref$isTimestepAuto,
2752
+ onChangeTimeStep = _ref.onChangeTimeStep,
2753
+ _ref$onToggleTimestep = _ref.onToggleTimestepAuto,
2754
+ onToggleTimestepAuto = _ref$onToggleTimestep === void 0 ? function () {} : _ref$onToggleTimestep,
2755
+ _ref$isOpenByDefault = _ref.isOpenByDefault,
2756
+ isOpenByDefault = _ref$isOpenByDefault === void 0 ? false : _ref$isOpenByDefault,
2757
+ timeStepFromLayer = _ref.timeStepFromLayer;
2758
+ var _useTimesliderTransla = useTimesliderTranslation(),
2759
+ t = _useTimesliderTransla.t;
2760
+ var translatedMarks = marks.map(function (mark) {
2761
+ return Object.assign({}, mark, {
2762
+ label: mark.count + " " + t(mark.text)
2763
+ });
2764
+ });
2765
+ var onMenuItemClick = function onMenuItemClick(markValue) {
2766
+ if (isTimestepAuto) {
2767
+ onToggleTimestepAuto();
3137
2768
  }
3138
- isClickOrDrag.current = undefined;
2769
+ onChangeTimeStep(markValue);
3139
2770
  };
3140
- var onMouseMove = function onMouseMove(x, y, event, width) {
3141
- var mousePosition = x;
3142
- setPointerTime(pixelToTimestamp(mousePosition, centerTime, canvasWidth, secondsPerPx));
3143
- var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
3144
- tooltipPosition.current = pixelsBetweenOnLeft && mousePosition + pixelsBetweenOnLeft;
3145
- if (isClickOrDrag.current === 'click') {
3146
- isClickOrDrag.current = 'drag';
3147
- }
3148
- if (isDraggingSelectedTime || isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
2771
+ var handleToggleTimeStep = function handleToggleTimeStep() {
2772
+ if (isTimestepAuto) {
3149
2773
  return;
3150
2774
  }
3151
- var _getPositions2 = getPositions(width, unfilteredSelectedTime, centerTime, secondsPerPx, start, end),
3152
- startAnimationPosition = _getPositions2.startAnimationPosition,
3153
- endAnimationPosition = _getPositions2.endAnimationPosition,
3154
- selectedTimePosition = _getPositions2.selectedTimePosition;
3155
- // Adjust mouse cursor while hovering draggable areas
3156
- var leftAnimationIconArea = isLeftAnimationIconArea(x, startAnimationPosition, DRAG_AREA_WIDTH);
3157
- var rightAnimationIconArea = isRightAnimationIconArea(x, endAnimationPosition, DRAG_AREA_WIDTH);
3158
- var selectedTimeArea = isSelectedTimeIconArea(x, selectedTimePosition, DRAG_AREA_WIDTH);
3159
- var insideAnimationArea = isInsideAnimationArea(x, startAnimationPosition, endAnimationPosition);
3160
- var hoveringLegendHandles = leftAnimationIconArea || rightAnimationIconArea || selectedTimeArea || isDraggingLegend;
3161
- if (hoveringLegendHandles) {
3162
- setCursorStyle('ew-resize');
3163
- } else if (insideAnimationArea && !isDraggingAnimationArea) {
3164
- setCursorStyle('grab');
3165
- } else if (insideAnimationArea && isDraggingAnimationArea) {
3166
- setCursorStyle('grabbing');
3167
- } else {
3168
- setCursorStyle('auto');
3169
- }
2775
+ onToggleTimestepAuto();
2776
+ timeStepFromLayer && onChangeTimeStep(timeStepFromLayer);
3170
2777
  };
3171
- var onWheel = React.useCallback(function (_ref2) {
3172
- var event = _ref2.event,
3173
- deltaY = _ref2.deltaY;
3174
- event.preventDefault();
3175
- if (event.ctrlKey || event.metaKey) {
3176
- debouncedAndThrottledUpdateTimeSpan(deltaY);
3177
- }
3178
- }, [debouncedAndThrottledUpdateTimeSpan]);
3179
- var onWheelOverCanvas = React.useCallback(function (props) {
3180
- onWheel(props);
3181
- adjustSelectedTimeOnWheel(props);
3182
- }, [adjustSelectedTimeOnWheel, onWheel]);
3183
- React.useEffect(function () {
3184
- if (isTimeScrollingEnabled && mapWindowRef != null && mapWindowRef.current) {
3185
- var handleWheel = function handleWheel(event) {
3186
- event.preventDefault();
3187
- onWheel({
3188
- event: event,
3189
- deltaY: event.deltaY
3190
- });
3191
- };
3192
- var element = mapWindowRef.current;
3193
- element.addEventListener('wheel', handleWheel);
3194
- return function () {
3195
- element.removeEventListener('wheel', handleWheel);
3196
- };
3197
- }
3198
- return undefined;
3199
- }, [isTimeScrollingEnabled, mapWindowRef, onWheel]);
3200
- return jsxs(Box, {
3201
- sx: {
3202
- position: 'relative',
3203
- height: TIME_SLIDER_LEGEND_HEIGHT + "px"
3204
- },
3205
- children: [jsx(CustomTooltip, {
3206
- open: Boolean(showTooltip),
3207
- slotProps: {
3208
- popper: {
3209
- popperRef: popperRef,
3210
- anchorEl: {
3211
- getBoundingClientRect: setTooltipPosition
3212
- }
3213
- }
2778
+ var layerHasTimeStep = Boolean(timeStepFromLayer);
2779
+ renderCounter.count(TimeStepButton.name);
2780
+ var _useState = useState(isOpenByDefault),
2781
+ open = _useState[0],
2782
+ setOpen = _useState[1];
2783
+ return jsx(TimeSliderMenu, {
2784
+ allOptionsDisabled: disabled,
2785
+ displayCurrentLength: true,
2786
+ handleAutoClick: handleToggleTimeStep,
2787
+ icon: jsx(FastForward, {
2788
+ "data-testid": "timeStepButton"
2789
+ }),
2790
+ isAutoDisabled: !layerHasTimeStep,
2791
+ isAutoSelected: isTimestepAuto,
2792
+ marks: translatedMarks,
2793
+ onChangeSliderValue: onMenuItemClick,
2794
+ open: open,
2795
+ setOpen: setOpen,
2796
+ title: t('timeslider-time-step'),
2797
+ value: timeStep || translatedMarks[0].value
2798
+ });
2799
+ };
2800
+
2801
+ var OptionsMenu = function OptionsMenu(_ref) {
2802
+ var speedBtn = _ref.speedBtn,
2803
+ timeSpanBtn = _ref.timeSpanBtn,
2804
+ timeStepBtn = _ref.timeStepBtn,
2805
+ animationLengthBtn = _ref.animationLengthBtn;
2806
+ return jsxs(Fragment, {
2807
+ children: [jsx(Grid, {
2808
+ size: {
2809
+ xs: 'auto'
3214
2810
  },
3215
- title: getTooltipText(),
3216
- children: jsx(Box, {
3217
- className: getTimeSliderLegendId(mapId),
3218
- "data-testid": "timeSliderLegend",
3219
- onMouseLeave: function onMouseLeave() {
3220
- setPointerTime(undefined);
3221
- },
3222
- sx: {
3223
- height: TIME_SLIDER_LEGEND_HEIGHT + "px",
3224
- borderRadius: '4.5px',
3225
- overflow: 'hidden',
3226
- cursor: cursorStyle
3227
- },
3228
- children: jsx(CanvasComponent, {
3229
- onMouseDown: onMouseDown,
3230
- onMouseMove: onMouseMove,
3231
- onMouseUp: onMouseUp,
3232
- onRenderCanvas: function onRenderCanvas(ctx, width, height) {
3233
- updateCanvasWidth(canvasWidth, width);
3234
- drawTimeSliderLegend(ctx, theme, width, height, centerTime, secondsPerPx, timeSliderSpan, filteredTime, currentTime, start, end, dataStartTime, dataEndTime);
3235
- },
3236
- onWheel: onWheelOverCanvas,
3237
- ref: node
3238
- })
2811
+ children: timeSpanBtn || jsx(TimeSpanButton, {
2812
+ disabled: false,
2813
+ isTimeSpanAuto: false,
2814
+ layerHasTimeStep: false,
2815
+ onChangeSliderValue: function onChangeSliderValue() {},
2816
+ onToggleTimeSpan: function onToggleTimeSpan() {},
2817
+ timeSliderSpan: 0
3239
2818
  })
3240
- }), !!isTimeSliderHoverOn && jsx(Box, {
3241
- "data-testid": "customCanvasMouseOverContainer",
3242
- onMouseLeave: function onMouseLeave() {
3243
- return setIsMouseOverCanvas(false);
2819
+ }), jsx(Grid, {
2820
+ size: {
2821
+ xs: 'auto'
3244
2822
  },
3245
- onMouseOver: function onMouseOver() {
3246
- return setIsMouseOverCanvas(true);
2823
+ children: animationLengthBtn || jsx(AnimationLengthButton, {
2824
+ onChangeAnimationLength: function onChangeAnimationLength() {},
2825
+ toggleAnimationLengthAuto: function toggleAnimationLengthAuto() {}
2826
+ })
2827
+ }), jsx(Grid, {
2828
+ size: {
2829
+ xs: 'auto'
3247
2830
  },
3248
- sx: {
3249
- position: 'absolute',
3250
- top: '-40px',
3251
- left: 0,
3252
- right: 0,
3253
- bottom: 0,
3254
- height: TIME_SLIDER_LEGEND_HEIGHT + " + 40px",
3255
- zIndex: isMouseOverCanvas ? 100 : 0
3256
- }
2831
+ children: timeStepBtn || jsx(TimeStepButton, {
2832
+ isTimestepAuto: false,
2833
+ onChangeTimeStep: function onChangeTimeStep() {}
2834
+ })
2835
+ }), jsx(Grid, {
2836
+ size: {
2837
+ xs: 'auto'
2838
+ },
2839
+ children: speedBtn || jsx(SpeedButton, {
2840
+ animationDelay: defaultAnimationDelayAtStart,
2841
+ setMapAnimationDelay: function setMapAnimationDelay() {}
2842
+ })
3257
2843
  })]
3258
2844
  });
3259
2845
  };
@@ -3944,4 +3530,4 @@ var DemoWrapper = function DemoWrapper(_ref2) {
3944
3530
  });
3945
3531
  };
3946
3532
 
3947
- 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, spanToScale, speedFactors, timeBoxGeom, timeSliderLegendDefaultProps, timeSliderUtils, timeValues, timesliderTranslations, timestampToPixel, timestampToPixelEdges, useCanvasTarget };
3533
+ 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, 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, spanToScale, speedFactors, timeBoxGeom, timeSliderLegendDefaultProps, timeSliderUtils, timeValues, timesliderTranslations, timestampToPixel, timestampToPixelEdges, useCanvasTarget };