@opengeoweb/soundings 19.3.0 → 19.5.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/dist/index.esm.js +1326 -906
- package/dist/src/lib/api/edr-api/queryOptions.d.ts +12 -4
- package/dist/src/lib/components/MenuBar/LocationsMenu.d.ts +16 -1
- package/dist/src/lib/components/MenuBar/MenuBar.d.ts +3 -1
- package/dist/src/lib/components/MenuBar/SoundingsSourceMenu.d.ts +1 -0
- package/dist/src/lib/components/Soundings/SharedMouseYProvider.d.ts +8 -0
- package/dist/src/lib/components/Soundings/Soundings.d.ts +1 -1
- package/dist/src/lib/components/Soundings/constants.d.ts +1 -1
- package/dist/src/lib/components/Soundings/drawUtils.d.ts +2 -1
- package/dist/src/lib/components/Soundings/useSoundingsDiagramSize.d.ts +1 -1
- package/dist/src/lib/components/SoundingsTooltip/utils.d.ts +4 -2
- package/dist/src/lib/components/StaticLines/drawIsotherms.d.ts +2 -1
- package/dist/src/lib/components/StaticLines/utils.d.ts +2 -1
- package/dist/src/lib/components/WindBarbs/utils.d.ts +7 -2
- package/dist/src/lib/store/reducer.d.ts +4 -1
- package/dist/src/lib/store/selectors.d.ts +87 -0
- package/dist/src/lib/store/types.d.ts +30 -0
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -3,8 +3,8 @@ import { Stack, Box, Tooltip, Typography, styled, Card, IconButton, Menu, ListSu
|
|
|
3
3
|
import { range, isEqual } from 'lodash';
|
|
4
4
|
import React, { useMemo, useRef, useEffect, useId, useState, Fragment as Fragment$1, useCallback } from 'react';
|
|
5
5
|
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
|
|
6
|
-
import { dateUtils, referenceTimeUtils, safelyInitI18nForTestsAndStories, sharedTranslations, SHARED_NAMESPACE, SwitchButton, CustomToggleButton, CustomSlider, AlertBanner, ToolContainerDraggable, TooltipSelect, AlertIcon, useResizeObserver, SearchField, CustomAccordion } from '@opengeoweb/shared';
|
|
7
|
-
import { selectorMemoizationOptions, uiSelectors, uiTypes, uiActions, genericActions, useRegisterFeatureSyncSource, genericSelectors,
|
|
6
|
+
import { dateUtils, referenceTimeUtils, safelyInitI18nForTestsAndStories, sharedTranslations, SHARED_NAMESPACE, SwitchButton, CustomToggleButton, LegendToggleButton, CustomSlider, AlertBanner, ToolContainerDraggable, TooltipSelect, AlertIcon, useResizeObserver, SearchField, CustomAccordion } from '@opengeoweb/shared';
|
|
7
|
+
import { selectorMemoizationOptions, uiSelectors, uiTypes, uiActions, genericActions, useSyncgroupTimeState, useRegisterFeatureSyncSource, genericSelectors, mapSelectors, mapActions, useUpdateFeatureSyncLayers, layerActions, useSetupDialog, storeReducerMap, storeMiddlewares } from '@opengeoweb/store';
|
|
8
8
|
import { Layers, Sources, Location, Equalizer, ArrowDropDownDown, DragHandle, Close, Visibility, VisibilityOff } from '@opengeoweb/theme';
|
|
9
9
|
import { ParseISOTimeRangeDuration, parseISO8601IntervalToDateInterval, handleDateUtilsISOString, webmapUtils } from '@opengeoweb/webmap';
|
|
10
10
|
import { MapFeatureClass } from '@opengeoweb/webmap-react';
|
|
@@ -35,6 +35,9 @@ var en = {
|
|
|
35
35
|
"soundings-time-mismatch-title": "Selected time in the sounding view does not match map view time.",
|
|
36
36
|
"soundings-toggle-location-markers-label": "Markers",
|
|
37
37
|
"soundings-toggle-location-markers-tooltip": "Show/hide location markers",
|
|
38
|
+
"soundings-legend": "Legend",
|
|
39
|
+
"soundings-legend-tooltip-show": "Show legend",
|
|
40
|
+
"soundings-legend-tooltip-hide": "Hide legend",
|
|
38
41
|
"no-sounding-data-available": "No sounding data available"
|
|
39
42
|
};
|
|
40
43
|
var no = {
|
|
@@ -52,6 +55,9 @@ var no = {
|
|
|
52
55
|
"soundings-time-mismatch-title": "Selected time in the sounding view does not match map view time.",
|
|
53
56
|
"soundings-toggle-location-markers-label": "Lokasjoner",
|
|
54
57
|
"soundings-toggle-location-markers-tooltip": "Vis/skjul lokasjoner",
|
|
58
|
+
"soundings-legend": "Forklaring",
|
|
59
|
+
"soundings-legend-tooltip-show": "Vis forklaring",
|
|
60
|
+
"soundings-legend-tooltip-hide": "Skjul forklaring",
|
|
55
61
|
"no-sounding-data-available": "No sounding data available"
|
|
56
62
|
};
|
|
57
63
|
var nl = {
|
|
@@ -69,6 +75,9 @@ var nl = {
|
|
|
69
75
|
"soundings-time-mismatch-title": "Selected time in the sounding view does not match map view time.",
|
|
70
76
|
"soundings-toggle-location-markers-label": "Kaart locaties",
|
|
71
77
|
"soundings-toggle-location-markers-tooltip": "Toon/Verberg locatie punten",
|
|
78
|
+
"soundings-legend": "Legenda",
|
|
79
|
+
"soundings-legend-tooltip-show": "Toon legenda",
|
|
80
|
+
"soundings-legend-tooltip-hide": "Verberg legenda",
|
|
72
81
|
"no-sounding-data-available": "No sounding data available"
|
|
73
82
|
};
|
|
74
83
|
var fi = {
|
|
@@ -86,6 +95,9 @@ var fi = {
|
|
|
86
95
|
"soundings-time-mismatch-title": "Valittu aika luotausnäytöllä ei vastaa karttanäytön aikaa",
|
|
87
96
|
"soundings-toggle-location-markers-label": "Kohdemerkit",
|
|
88
97
|
"soundings-toggle-location-markers-tooltip": "Näytä/piilota kohdemerkit",
|
|
98
|
+
"soundings-legend": "Selite",
|
|
99
|
+
"soundings-legend-tooltip-show": "Näytä selite",
|
|
100
|
+
"soundings-legend-tooltip-hide": "Piilota selite",
|
|
89
101
|
"no-sounding-data-available": "Ei luotausdataa saatavilla"
|
|
90
102
|
};
|
|
91
103
|
var soundingsTranslations = {
|
|
@@ -139,7 +151,7 @@ var REFERENCE_PRESSURE = 1000 * 100; // 1000hPa = 100000Pa
|
|
|
139
151
|
var EARTH_MEAN_RADIUS = 6371; // [km]
|
|
140
152
|
var MAX_PROXIMITY_RADIUS = 100; // [km]
|
|
141
153
|
var SAME_POINT_DISTANCE_KM = 0.05;
|
|
142
|
-
var SOUNDINGS_CONTAINER_BREAKPOINT_PX = '
|
|
154
|
+
var SOUNDINGS_CONTAINER_BREAKPOINT_PX = '720px';
|
|
143
155
|
var SOUNDINGS_CONTAINER_NAME = 'soundings-container';
|
|
144
156
|
|
|
145
157
|
/* *
|
|
@@ -200,8 +212,27 @@ var dTdp = function dTdp(pressure, temperature) {
|
|
|
200
212
|
var dTdp2 = dTdp1 / (1.0 + Rs / (7.0 * EPSILON) + Math.pow(Lv / temperature, 2) * Rs * EPSILON / (R_AIR * HEATCP));
|
|
201
213
|
return dTdp2;
|
|
202
214
|
};
|
|
215
|
+
var MAX_THETA_CACHE_SIZE = 50000;
|
|
216
|
+
var thetaFromPressTempCache = new Map();
|
|
217
|
+
var buildThetaCacheKey = function buildThetaCacheKey(pressure, temperature, basePressure) {
|
|
218
|
+
return pressure.toFixed(6) + "|" + temperature.toFixed(6) + "|" + basePressure.toFixed(6);
|
|
219
|
+
};
|
|
220
|
+
var setThetaCacheValue = function setThetaCacheValue(key, value) {
|
|
221
|
+
if (thetaFromPressTempCache.size >= MAX_THETA_CACHE_SIZE) {
|
|
222
|
+
var oldestKey = thetaFromPressTempCache.keys().next().value;
|
|
223
|
+
if (oldestKey !== undefined) {
|
|
224
|
+
thetaFromPressTempCache["delete"](oldestKey);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
thetaFromPressTempCache.set(key, value);
|
|
228
|
+
};
|
|
203
229
|
var calculateThetaFromPressTemp = function calculateThetaFromPressTemp(pressure, temperature, basePressure) {
|
|
204
230
|
var base = basePressure || REFERENCE_PRESSURE;
|
|
231
|
+
var cacheKey = buildThetaCacheKey(pressure, temperature, base);
|
|
232
|
+
var cachedValue = thetaFromPressTempCache.get(cacheKey);
|
|
233
|
+
if (cachedValue !== undefined) {
|
|
234
|
+
return cachedValue;
|
|
235
|
+
}
|
|
205
236
|
var dpPascal = pressure > base ? pressToPascal(-10) : pressToPascal(10); // hPa steps to Pa steps
|
|
206
237
|
var numberOfSteps = Math.round((base - pressure) / dpPascal) < 1 ? 1 : Math.round((base - pressure) / dpPascal);
|
|
207
238
|
var pstep = (base - pressure) / numberOfSteps;
|
|
@@ -215,6 +246,7 @@ var calculateThetaFromPressTemp = function calculateThetaFromPressTemp(pressure,
|
|
|
215
246
|
tempN += k1 / 6.0 + k2 / 3.0 + k3 / 3.0 + k4 / 6.0;
|
|
216
247
|
pressureN += pstep;
|
|
217
248
|
}
|
|
249
|
+
setThetaCacheValue(cacheKey, tempN);
|
|
218
250
|
return tempN;
|
|
219
251
|
};
|
|
220
252
|
|
|
@@ -310,6 +342,14 @@ var initializeSvg$1 = function initializeSvg(_ref) {
|
|
|
310
342
|
// Ensure clipPath uses same coordinate system as the translated group
|
|
311
343
|
// so width/height starting at x=0,y=0 align with axis origin.
|
|
312
344
|
.attr('clipPathUnits', 'userSpaceOnUse').append('rect').attr('width', width).attr('height', height).attr('x', 0).attr('y', 0);
|
|
345
|
+
svg.append('clipPath').attr('id', "clip-" + d3GraphId + "-" + diagramType + "x-axis").attr('clipPathUnits', 'userSpaceOnUse').append('rect')
|
|
346
|
+
// Keep x-axis labels within the horizontal chart band while allowing them
|
|
347
|
+
// to use the reserved left and bottom margin.
|
|
348
|
+
.attr('width', width + margin.left).attr('height', height + margin.bottom).attr('x', -margin.left).attr('y', 0);
|
|
349
|
+
svg.append('clipPath').attr('id', "clip-" + d3GraphId + "-" + diagramType + "y-axis").attr('clipPathUnits', 'userSpaceOnUse').append('rect')
|
|
350
|
+
// Keep y-axis labels within the vertical chart band while allowing them
|
|
351
|
+
// to use the reserved left margin.
|
|
352
|
+
.attr('width', width + margin.left).attr('height', height).attr('x', -margin.left).attr('y', 0);
|
|
313
353
|
svg.append('rect').attr('height', height).attr('width', width).attr('fill', '#ffffff00').attr('opacity', 1).attr('id', d3GraphId + "-" + diagramType + "d3").attr('clip-path', "url(#clip-" + d3GraphId + "-" + diagramType + "d3)");
|
|
314
354
|
return svg;
|
|
315
355
|
};
|
|
@@ -438,6 +478,7 @@ var plotSounding = function plotSounding(_ref7) {
|
|
|
438
478
|
pressureValues = _ref7.pressureValues,
|
|
439
479
|
color = _ref7.color,
|
|
440
480
|
lineStyle = _ref7.lineStyle,
|
|
481
|
+
d3GraphId = _ref7.d3GraphId,
|
|
441
482
|
xScale = _ref7.xScale,
|
|
442
483
|
yScale = _ref7.yScale,
|
|
443
484
|
height = _ref7.height,
|
|
@@ -450,7 +491,7 @@ var plotSounding = function plotSounding(_ref7) {
|
|
|
450
491
|
var Px = mapToPlot(diagramType, filteredPressureValues, filteredTemperatureValues, xScale, yScale, height);
|
|
451
492
|
var lineGenerator = d3.line();
|
|
452
493
|
var pathString = lineGenerator(Px);
|
|
453
|
-
svg.append('path').attr('d', pathString).attr('id', 'dataline').attr('x', 0).attr('y', 0).style('fill', 'none').style('stroke-width', 2).style('stroke', color).style('stroke-opacity', 1).style('stroke-dasharray', lineStyle).attr('clip-path', "url(#clip-" + diagramType + "d3)");
|
|
494
|
+
svg.append('path').attr('d', pathString).attr('id', 'dataline').attr('x', 0).attr('y', 0).style('fill', 'none').style('stroke-width', 2).style('stroke', color).style('stroke-opacity', 1).style('stroke-dasharray', lineStyle).attr('clip-path', "url(#clip-" + d3GraphId + "-" + diagramType + "d3)");
|
|
454
495
|
};
|
|
455
496
|
// Use this function to filter the pressure and parameter array so no NaN or null values are included
|
|
456
497
|
var filterDomainRangeForParameter = function filterDomainRangeForParameter(pressureDomain, parameterDomain) {
|
|
@@ -463,8 +504,16 @@ var filterDomainRangeForParameter = function filterDomainRangeForParameter(press
|
|
|
463
504
|
return [filteredPressureDomain, filteredParameterDomain];
|
|
464
505
|
};
|
|
465
506
|
|
|
507
|
+
var defaultVerticalZoom = {
|
|
508
|
+
scale: 1,
|
|
509
|
+
y: 0,
|
|
510
|
+
sourceId: null
|
|
511
|
+
};
|
|
466
512
|
var MouseYContext = /*#__PURE__*/React.createContext({
|
|
467
|
-
clientY: null
|
|
513
|
+
clientY: null,
|
|
514
|
+
verticalZoom: defaultVerticalZoom,
|
|
515
|
+
publishVerticalZoom: function publishVerticalZoom() {},
|
|
516
|
+
resetVerticalZoom: function resetVerticalZoom() {}
|
|
468
517
|
});
|
|
469
518
|
var useSharedMouseY = function useSharedMouseY() {
|
|
470
519
|
return React.useContext(MouseYContext);
|
|
@@ -479,6 +528,31 @@ var SharedMouseYProvider = function SharedMouseYProvider(_ref) {
|
|
|
479
528
|
var _React$useState = React.useState(null),
|
|
480
529
|
clientY = _React$useState[0],
|
|
481
530
|
setClientY = _React$useState[1];
|
|
531
|
+
var _React$useState2 = React.useState(defaultVerticalZoom),
|
|
532
|
+
verticalZoom = _React$useState2[0],
|
|
533
|
+
setVerticalZoom = _React$useState2[1];
|
|
534
|
+
var publishVerticalZoom = React.useCallback(function (sourceId, scale, y) {
|
|
535
|
+
setVerticalZoom(function (previous) {
|
|
536
|
+
var hasSameValues = previous.sourceId === sourceId && Math.abs(previous.scale - scale) < 1e-6 && Math.abs(previous.y - y) < 1e-3;
|
|
537
|
+
if (hasSameValues) {
|
|
538
|
+
return previous;
|
|
539
|
+
}
|
|
540
|
+
return {
|
|
541
|
+
scale: scale,
|
|
542
|
+
y: y,
|
|
543
|
+
sourceId: sourceId
|
|
544
|
+
};
|
|
545
|
+
});
|
|
546
|
+
}, []);
|
|
547
|
+
var resetVerticalZoom = React.useCallback(function (sourceId) {
|
|
548
|
+
setVerticalZoom(function () {
|
|
549
|
+
return {
|
|
550
|
+
scale: 1,
|
|
551
|
+
y: 0,
|
|
552
|
+
sourceId: sourceId
|
|
553
|
+
};
|
|
554
|
+
});
|
|
555
|
+
}, []);
|
|
482
556
|
React.useEffect(function () {
|
|
483
557
|
var el = wrapperRef.current;
|
|
484
558
|
if (!el) {
|
|
@@ -502,9 +576,12 @@ var SharedMouseYProvider = function SharedMouseYProvider(_ref) {
|
|
|
502
576
|
}, []);
|
|
503
577
|
var contextValue = React.useMemo(function () {
|
|
504
578
|
return {
|
|
505
|
-
clientY: clientY
|
|
579
|
+
clientY: clientY,
|
|
580
|
+
verticalZoom: verticalZoom,
|
|
581
|
+
publishVerticalZoom: publishVerticalZoom,
|
|
582
|
+
resetVerticalZoom: resetVerticalZoom
|
|
506
583
|
};
|
|
507
|
-
}, [clientY]);
|
|
584
|
+
}, [clientY, verticalZoom, publishVerticalZoom, resetVerticalZoom]);
|
|
508
585
|
return jsx("div", {
|
|
509
586
|
"data-testid": "shared-mouse-y-wrapper",
|
|
510
587
|
ref: wrapperRef,
|
|
@@ -1145,6 +1222,25 @@ var soundingsQueryOptions = {
|
|
|
1145
1222
|
}(),
|
|
1146
1223
|
refetchInterval: 5 * 60 * 1000
|
|
1147
1224
|
});
|
|
1225
|
+
},
|
|
1226
|
+
getCollectionDetails: function getCollectionDetails$1(collectionId, url) {
|
|
1227
|
+
return queryOptions({
|
|
1228
|
+
queryKey: ['edr-soundings-collection-details', collectionId, url],
|
|
1229
|
+
queryFn: function () {
|
|
1230
|
+
var _queryFn2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
1231
|
+
return _regenerator().w(function (_context2) {
|
|
1232
|
+
while (1) switch (_context2.n) {
|
|
1233
|
+
case 0:
|
|
1234
|
+
return _context2.a(2, getCollectionDetails(collectionId, url));
|
|
1235
|
+
}
|
|
1236
|
+
}, _callee2);
|
|
1237
|
+
}));
|
|
1238
|
+
function queryFn() {
|
|
1239
|
+
return _queryFn2.apply(this, arguments);
|
|
1240
|
+
}
|
|
1241
|
+
return queryFn;
|
|
1242
|
+
}()
|
|
1243
|
+
});
|
|
1148
1244
|
}
|
|
1149
1245
|
};
|
|
1150
1246
|
|
|
@@ -1702,6 +1798,7 @@ var useResolvedSourceSelections = function useResolvedSourceSelections(sources)
|
|
|
1702
1798
|
}, [sources, instancesBySource]);
|
|
1703
1799
|
};
|
|
1704
1800
|
var useTimesteps = function useTimesteps(sourceSelections) {
|
|
1801
|
+
var queryClient = useQueryClient();
|
|
1705
1802
|
var queries = React.useMemo(function () {
|
|
1706
1803
|
return sourceSelections.map(function (_ref3) {
|
|
1707
1804
|
var collectionId = _ref3.collectionId,
|
|
@@ -1711,12 +1808,12 @@ var useTimesteps = function useTimesteps(sourceSelections) {
|
|
|
1711
1808
|
queryKey: ['edr-soundings-instance', collectionId, instanceId || ''],
|
|
1712
1809
|
queryFn: function () {
|
|
1713
1810
|
var _queryFn3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
|
|
1714
|
-
var _instanceData$extent, instanceData, timeExtentValues,
|
|
1811
|
+
var _instanceData$extent, instanceData, timeExtentValues, collectionData;
|
|
1715
1812
|
return _regenerator().w(function (_context3) {
|
|
1716
1813
|
while (1) switch (_context3.n) {
|
|
1717
1814
|
case 0:
|
|
1718
1815
|
if (!(instanceId && instanceId !== '')) {
|
|
1719
|
-
_context3.n =
|
|
1816
|
+
_context3.n = 3;
|
|
1720
1817
|
break;
|
|
1721
1818
|
}
|
|
1722
1819
|
_context3.n = 1;
|
|
@@ -1725,20 +1822,16 @@ var useTimesteps = function useTimesteps(sourceSelections) {
|
|
|
1725
1822
|
instanceData = _context3.v;
|
|
1726
1823
|
timeExtentValues = instanceData == null || (_instanceData$extent = instanceData.extent) == null || (_instanceData$extent = _instanceData$extent.temporal) == null ? void 0 : _instanceData$extent.values;
|
|
1727
1824
|
if (timeExtentValues) {
|
|
1728
|
-
_context3.n =
|
|
1825
|
+
_context3.n = 2;
|
|
1729
1826
|
break;
|
|
1730
1827
|
}
|
|
1731
|
-
_context3.
|
|
1732
|
-
return getCollectionInstances(collectionId, url);
|
|
1828
|
+
return _context3.a(2, queryClient.fetchQuery(soundingsQueryOptions.getCollectionInstances(collectionId, url)));
|
|
1733
1829
|
case 2:
|
|
1734
|
-
allInstancesData = _context3.v;
|
|
1735
|
-
return _context3.a(2, allInstancesData);
|
|
1736
|
-
case 3:
|
|
1737
1830
|
return _context3.a(2, instanceData);
|
|
1831
|
+
case 3:
|
|
1832
|
+
_context3.n = 4;
|
|
1833
|
+
return queryClient.fetchQuery(soundingsQueryOptions.getCollectionDetails(collectionId, url));
|
|
1738
1834
|
case 4:
|
|
1739
|
-
_context3.n = 5;
|
|
1740
|
-
return getCollectionDetails(collectionId, url);
|
|
1741
|
-
case 5:
|
|
1742
1835
|
collectionData = _context3.v;
|
|
1743
1836
|
return _context3.a(2, collectionData);
|
|
1744
1837
|
}
|
|
@@ -1762,7 +1855,7 @@ var useTimesteps = function useTimesteps(sourceSelections) {
|
|
|
1762
1855
|
refetchInterval: 5 * 60 * 1000
|
|
1763
1856
|
};
|
|
1764
1857
|
});
|
|
1765
|
-
}, [sourceSelections]);
|
|
1858
|
+
}, [sourceSelections, queryClient]);
|
|
1766
1859
|
var results = useQueries({
|
|
1767
1860
|
queries: queries,
|
|
1768
1861
|
combine: function combine(queryResults) {
|
|
@@ -1803,29 +1896,9 @@ var useGetCollectionsInstances = function useGetCollectionsInstances(collections
|
|
|
1803
1896
|
return collectionIds.map(function (_ref4) {
|
|
1804
1897
|
var id = _ref4.id,
|
|
1805
1898
|
url = _ref4.url;
|
|
1806
|
-
return {
|
|
1807
|
-
queryKey: ['edr-soundings-collection-details', id, url],
|
|
1808
|
-
queryFn: function () {
|
|
1809
|
-
var _queryFn4 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
1810
|
-
var data;
|
|
1811
|
-
return _regenerator().w(function (_context4) {
|
|
1812
|
-
while (1) switch (_context4.n) {
|
|
1813
|
-
case 0:
|
|
1814
|
-
_context4.n = 1;
|
|
1815
|
-
return getCollectionDetails(id, url);
|
|
1816
|
-
case 1:
|
|
1817
|
-
data = _context4.v;
|
|
1818
|
-
return _context4.a(2, data);
|
|
1819
|
-
}
|
|
1820
|
-
}, _callee4);
|
|
1821
|
-
}));
|
|
1822
|
-
function queryFn() {
|
|
1823
|
-
return _queryFn4.apply(this, arguments);
|
|
1824
|
-
}
|
|
1825
|
-
return queryFn;
|
|
1826
|
-
}(),
|
|
1899
|
+
return Object.assign({}, soundingsQueryOptions.getCollectionDetails(id, url), {
|
|
1827
1900
|
enabled: isDialogOpen
|
|
1828
|
-
};
|
|
1901
|
+
});
|
|
1829
1902
|
});
|
|
1830
1903
|
}, [collectionIds, isDialogOpen]);
|
|
1831
1904
|
var resultsCollection = useQueries({
|
|
@@ -1834,10 +1907,13 @@ var useGetCollectionsInstances = function useGetCollectionsInstances(collections
|
|
|
1834
1907
|
var _queryResults$find3;
|
|
1835
1908
|
var data = queryResults.map(function (result) {
|
|
1836
1909
|
var _result$data2;
|
|
1837
|
-
return ((_result$data2 = result.data)
|
|
1910
|
+
return !!((_result$data2 = result.data) != null && (_result$data2 = _result$data2.data_queries) != null && _result$data2.instances);
|
|
1838
1911
|
});
|
|
1839
|
-
|
|
1840
|
-
|
|
1912
|
+
// Only enabled queries should contribute to isPending to prevent a
|
|
1913
|
+
// loading indicator that never clears
|
|
1914
|
+
var isPending = queryResults.some(function (result, index) {
|
|
1915
|
+
var _queriesCollection$in;
|
|
1916
|
+
return !!((_queriesCollection$in = queriesCollection[index]) != null && _queriesCollection$in.enabled) && result.isPending;
|
|
1841
1917
|
});
|
|
1842
1918
|
var error = (_queryResults$find3 = queryResults.find(function (result) {
|
|
1843
1919
|
return result == null ? void 0 : result.error;
|
|
@@ -1854,52 +1930,28 @@ var useGetCollectionsInstances = function useGetCollectionsInstances(collections
|
|
|
1854
1930
|
return collectionIds.map(function (_ref5, index) {
|
|
1855
1931
|
var id = _ref5.id,
|
|
1856
1932
|
url = _ref5.url;
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
var data;
|
|
1862
|
-
return _regenerator().w(function (_context5) {
|
|
1863
|
-
while (1) switch (_context5.n) {
|
|
1864
|
-
case 0:
|
|
1865
|
-
if (!resultsCollection.data[index]) {
|
|
1866
|
-
_context5.n = 2;
|
|
1867
|
-
break;
|
|
1868
|
-
}
|
|
1869
|
-
_context5.n = 1;
|
|
1870
|
-
return getCollectionInstances(id, url);
|
|
1871
|
-
case 1:
|
|
1872
|
-
data = _context5.v;
|
|
1873
|
-
return _context5.a(2, data);
|
|
1874
|
-
case 2:
|
|
1875
|
-
return _context5.a(2, {
|
|
1876
|
-
instances: []
|
|
1877
|
-
});
|
|
1878
|
-
}
|
|
1879
|
-
}, _callee5);
|
|
1880
|
-
}));
|
|
1881
|
-
function queryFn() {
|
|
1882
|
-
return _queryFn5.apply(this, arguments);
|
|
1883
|
-
}
|
|
1884
|
-
return queryFn;
|
|
1885
|
-
}(),
|
|
1886
|
-
enabled: isDialogOpen && resultsCollection.data !== undefined
|
|
1887
|
-
};
|
|
1933
|
+
var hasInstances = !!resultsCollection.data[index];
|
|
1934
|
+
return Object.assign({}, soundingsQueryOptions.getCollectionInstances(id, url), {
|
|
1935
|
+
enabled: !!isDialogOpen && hasInstances
|
|
1936
|
+
});
|
|
1888
1937
|
});
|
|
1889
|
-
}, [collectionIds, isDialogOpen, resultsCollection]);
|
|
1938
|
+
}, [collectionIds, isDialogOpen, resultsCollection.data]);
|
|
1890
1939
|
var results = useQueries({
|
|
1891
1940
|
queries: queries,
|
|
1892
1941
|
combine: function combine(queryResults) {
|
|
1893
1942
|
var _queryResults$find4;
|
|
1894
1943
|
var data = queryResults.map(function (result) {
|
|
1895
|
-
var _result$data3;
|
|
1896
|
-
var instances = ((_result$data3 = result.data) == null ? void 0 : _result$data3.instances.sort(function (featureA, featureB) {
|
|
1944
|
+
var _result$data$instance, _result$data3;
|
|
1945
|
+
var instances = [].concat((_result$data$instance = (_result$data3 = result.data) == null ? void 0 : _result$data3.instances) != null ? _result$data$instance : []).sort(function (featureA, featureB) {
|
|
1897
1946
|
return featureB.id.localeCompare(featureA.id);
|
|
1898
|
-
})
|
|
1947
|
+
}); // Sort to get latest first
|
|
1899
1948
|
return instances;
|
|
1900
1949
|
});
|
|
1901
|
-
|
|
1902
|
-
|
|
1950
|
+
// Mirror the collection-details behavior: only enabled instance queries
|
|
1951
|
+
// participate in the loading state.
|
|
1952
|
+
var isPending = queryResults.some(function (result, index) {
|
|
1953
|
+
var _queries$index;
|
|
1954
|
+
return !!((_queries$index = queries[index]) != null && _queries$index.enabled) && result.isPending;
|
|
1903
1955
|
});
|
|
1904
1956
|
var error = (_queryResults$find4 = queryResults.find(function (result) {
|
|
1905
1957
|
return result == null ? void 0 : result.error;
|
|
@@ -1932,61 +1984,61 @@ var useGetLocations = function useGetLocations(collections, enabled) {
|
|
|
1932
1984
|
return {
|
|
1933
1985
|
queryKey: ['edr-locations', collection.id, collection.url, (_collection$instanceI = collection.instanceId) != null ? _collection$instanceI : ''],
|
|
1934
1986
|
queryFn: function () {
|
|
1935
|
-
var
|
|
1987
|
+
var _queryFn4 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
1936
1988
|
var resolvedInstanceId, instances, resolved, locationsExplicitlyUnsupported, _locations, locations;
|
|
1937
|
-
return _regenerator().w(function (
|
|
1938
|
-
while (1) switch (
|
|
1989
|
+
return _regenerator().w(function (_context4) {
|
|
1990
|
+
while (1) switch (_context4.p = _context4.n) {
|
|
1939
1991
|
case 0:
|
|
1940
1992
|
resolvedInstanceId = collection.instanceId;
|
|
1941
1993
|
if (!(resolvedInstanceId && referenceTimeUtils.isRelativeReferenceTime(resolvedInstanceId))) {
|
|
1942
|
-
|
|
1994
|
+
_context4.n = 4;
|
|
1943
1995
|
break;
|
|
1944
1996
|
}
|
|
1945
|
-
|
|
1946
|
-
|
|
1997
|
+
_context4.p = 1;
|
|
1998
|
+
_context4.n = 2;
|
|
1947
1999
|
return queryClient.fetchQuery(soundingsQueryOptions.getCollectionInstances(collection.id, collection.url));
|
|
1948
2000
|
case 2:
|
|
1949
|
-
instances =
|
|
2001
|
+
instances = _context4.v;
|
|
1950
2002
|
resolved = referenceTimeUtils.resolveReferenceTimeInstance(instances.instances, resolvedInstanceId); // Skip instance-level only when data_queries is present but explicitly excludes locations — if data_queries is absent, try instance-level anyway
|
|
1951
2003
|
locationsExplicitlyUnsupported = (resolved == null ? void 0 : resolved.data_queries) !== undefined && !resolved.data_queries.locations;
|
|
1952
2004
|
resolvedInstanceId = locationsExplicitlyUnsupported ? undefined : resolved == null ? void 0 : resolved.id;
|
|
1953
|
-
|
|
2005
|
+
_context4.n = 4;
|
|
1954
2006
|
break;
|
|
1955
2007
|
case 3:
|
|
1956
|
-
|
|
1957
|
-
|
|
2008
|
+
_context4.p = 3;
|
|
2009
|
+
_context4.v;
|
|
1958
2010
|
resolvedInstanceId = undefined;
|
|
1959
2011
|
case 4:
|
|
1960
2012
|
if (!resolvedInstanceId) {
|
|
1961
|
-
|
|
2013
|
+
_context4.n = 8;
|
|
1962
2014
|
break;
|
|
1963
2015
|
}
|
|
1964
|
-
|
|
1965
|
-
|
|
2016
|
+
_context4.p = 5;
|
|
2017
|
+
_context4.n = 6;
|
|
1966
2018
|
return getInstanceLocations(collection.id, resolvedInstanceId, collection.url);
|
|
1967
2019
|
case 6:
|
|
1968
|
-
_locations =
|
|
1969
|
-
return
|
|
2020
|
+
_locations = _context4.v;
|
|
2021
|
+
return _context4.a(2, Object.assign({}, _locations, {
|
|
1970
2022
|
id: collection.id,
|
|
1971
2023
|
name: collection.name
|
|
1972
2024
|
}));
|
|
1973
2025
|
case 7:
|
|
1974
|
-
|
|
1975
|
-
|
|
2026
|
+
_context4.p = 7;
|
|
2027
|
+
_context4.v;
|
|
1976
2028
|
case 8:
|
|
1977
|
-
|
|
2029
|
+
_context4.n = 9;
|
|
1978
2030
|
return getCollectionLocations(collection.id, collection.url);
|
|
1979
2031
|
case 9:
|
|
1980
|
-
locations =
|
|
1981
|
-
return
|
|
2032
|
+
locations = _context4.v;
|
|
2033
|
+
return _context4.a(2, Object.assign({}, locations, {
|
|
1982
2034
|
id: collection.id,
|
|
1983
2035
|
name: collection.name
|
|
1984
2036
|
}));
|
|
1985
2037
|
}
|
|
1986
|
-
},
|
|
2038
|
+
}, _callee4, null, [[5, 7], [1, 3]]);
|
|
1987
2039
|
}));
|
|
1988
2040
|
function queryFn() {
|
|
1989
|
-
return
|
|
2041
|
+
return _queryFn4.apply(this, arguments);
|
|
1990
2042
|
}
|
|
1991
2043
|
return queryFn;
|
|
1992
2044
|
}(),
|
|
@@ -2027,6 +2079,7 @@ var useGetLocations = function useGetLocations(collections, enabled) {
|
|
|
2027
2079
|
var useCheckPositionQuerySupportBySource = function useCheckPositionQuerySupportBySource(sources) {
|
|
2028
2080
|
// Ref to stabilize data object reference when values haven't changed
|
|
2029
2081
|
var dataRef = React.useRef({});
|
|
2082
|
+
var queryClient = useQueryClient();
|
|
2030
2083
|
var queries = useMemo(function () {
|
|
2031
2084
|
return sources.map(function (_ref6) {
|
|
2032
2085
|
var collectionId = _ref6.collectionId,
|
|
@@ -2035,55 +2088,61 @@ var useCheckPositionQuerySupportBySource = function useCheckPositionQuerySupport
|
|
|
2035
2088
|
return {
|
|
2036
2089
|
queryKey: ['edr-position-support', collectionId, instanceId || ''],
|
|
2037
2090
|
queryFn: function () {
|
|
2038
|
-
var
|
|
2091
|
+
var _queryFn5 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
|
|
2039
2092
|
var _details$data_queries, _instance$data_querie, instances, instance, details;
|
|
2040
|
-
return _regenerator().w(function (
|
|
2041
|
-
while (1) switch (
|
|
2093
|
+
return _regenerator().w(function (_context5) {
|
|
2094
|
+
while (1) switch (_context5.p = _context5.n) {
|
|
2042
2095
|
case 0:
|
|
2043
|
-
|
|
2096
|
+
_context5.p = 0;
|
|
2044
2097
|
if (!instanceId) {
|
|
2045
|
-
|
|
2098
|
+
_context5.n = 2;
|
|
2046
2099
|
break;
|
|
2047
2100
|
}
|
|
2048
|
-
|
|
2049
|
-
return getCollectionInstances(collectionId, url);
|
|
2101
|
+
_context5.n = 1;
|
|
2102
|
+
return queryClient.fetchQuery(soundingsQueryOptions.getCollectionInstances(collectionId, url));
|
|
2050
2103
|
case 1:
|
|
2051
|
-
instances =
|
|
2104
|
+
instances = _context5.v;
|
|
2052
2105
|
instance = instances.instances.find(function (i) {
|
|
2053
2106
|
return i.id === instanceId;
|
|
2054
2107
|
});
|
|
2055
|
-
return
|
|
2108
|
+
return _context5.a(2, {
|
|
2056
2109
|
collectionId: collectionId,
|
|
2057
2110
|
supported: !!(instance != null && (_instance$data_querie = instance.data_queries) != null && _instance$data_querie.position)
|
|
2058
2111
|
});
|
|
2059
2112
|
case 2:
|
|
2060
|
-
|
|
2061
|
-
return getCollectionDetails(collectionId, url);
|
|
2113
|
+
_context5.n = 3;
|
|
2114
|
+
return queryClient.fetchQuery(soundingsQueryOptions.getCollectionDetails(collectionId, url));
|
|
2062
2115
|
case 3:
|
|
2063
|
-
details =
|
|
2064
|
-
return
|
|
2116
|
+
details = _context5.v;
|
|
2117
|
+
return _context5.a(2, {
|
|
2065
2118
|
collectionId: collectionId,
|
|
2066
2119
|
supported: !!(details != null && (_details$data_queries = details.data_queries) != null && _details$data_queries.position)
|
|
2067
2120
|
});
|
|
2068
2121
|
case 4:
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
return
|
|
2122
|
+
_context5.p = 4;
|
|
2123
|
+
_context5.v;
|
|
2124
|
+
return _context5.a(2, {
|
|
2072
2125
|
collectionId: collectionId,
|
|
2073
2126
|
supported: false
|
|
2074
2127
|
});
|
|
2075
2128
|
}
|
|
2076
|
-
},
|
|
2129
|
+
}, _callee5, null, [[0, 4]]);
|
|
2077
2130
|
}));
|
|
2078
2131
|
function queryFn() {
|
|
2079
|
-
return
|
|
2132
|
+
return _queryFn5.apply(this, arguments);
|
|
2080
2133
|
}
|
|
2081
2134
|
return queryFn;
|
|
2082
2135
|
}(),
|
|
2083
|
-
|
|
2136
|
+
enabled: !referenceTimeUtils.isRelativeReferenceTime(instanceId),
|
|
2137
|
+
staleTime: 5 * 60 * 1000,
|
|
2138
|
+
// Cache for 5 minutes
|
|
2139
|
+
// Preserve previous result while a new instance check is in-flight to avoid spurious location updates.
|
|
2140
|
+
placeholderData: function placeholderData(prev) {
|
|
2141
|
+
return prev;
|
|
2142
|
+
}
|
|
2084
2143
|
};
|
|
2085
2144
|
});
|
|
2086
|
-
}, [sources]);
|
|
2145
|
+
}, [sources, queryClient]);
|
|
2087
2146
|
return useQueries({
|
|
2088
2147
|
queries: queries,
|
|
2089
2148
|
combine: function combine(queryResults) {
|
|
@@ -2117,6 +2176,7 @@ var useCheckPositionQuerySupportBySource = function useCheckPositionQuerySupport
|
|
|
2117
2176
|
var useCheckRadiusQuerySupportBySource = function useCheckRadiusQuerySupportBySource(sources) {
|
|
2118
2177
|
// Ref to stabilize data object reference when values haven't changed
|
|
2119
2178
|
var dataRef = React.useRef({});
|
|
2179
|
+
var queryClient = useQueryClient();
|
|
2120
2180
|
var queries = useMemo(function () {
|
|
2121
2181
|
return sources.map(function (_ref7) {
|
|
2122
2182
|
var collectionId = _ref7.collectionId,
|
|
@@ -2125,55 +2185,60 @@ var useCheckRadiusQuerySupportBySource = function useCheckRadiusQuerySupportBySo
|
|
|
2125
2185
|
return {
|
|
2126
2186
|
queryKey: ['edr-radius-support', collectionId, instanceId || ''],
|
|
2127
2187
|
queryFn: function () {
|
|
2128
|
-
var
|
|
2188
|
+
var _queryFn6 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
|
|
2129
2189
|
var _details$data_queries2, _instance$data_querie2, instances, instance, details;
|
|
2130
|
-
return _regenerator().w(function (
|
|
2131
|
-
while (1) switch (
|
|
2190
|
+
return _regenerator().w(function (_context6) {
|
|
2191
|
+
while (1) switch (_context6.p = _context6.n) {
|
|
2132
2192
|
case 0:
|
|
2133
|
-
|
|
2193
|
+
_context6.p = 0;
|
|
2134
2194
|
if (!instanceId) {
|
|
2135
|
-
|
|
2195
|
+
_context6.n = 2;
|
|
2136
2196
|
break;
|
|
2137
2197
|
}
|
|
2138
|
-
|
|
2139
|
-
return getCollectionInstances(collectionId, url);
|
|
2198
|
+
_context6.n = 1;
|
|
2199
|
+
return queryClient.fetchQuery(soundingsQueryOptions.getCollectionInstances(collectionId, url));
|
|
2140
2200
|
case 1:
|
|
2141
|
-
instances =
|
|
2201
|
+
instances = _context6.v;
|
|
2142
2202
|
instance = instances.instances.find(function (i) {
|
|
2143
2203
|
return i.id === instanceId;
|
|
2144
2204
|
});
|
|
2145
|
-
return
|
|
2205
|
+
return _context6.a(2, {
|
|
2146
2206
|
collectionId: collectionId,
|
|
2147
2207
|
supported: !!(instance != null && (_instance$data_querie2 = instance.data_queries) != null && _instance$data_querie2.radius)
|
|
2148
2208
|
});
|
|
2149
2209
|
case 2:
|
|
2150
|
-
|
|
2151
|
-
return getCollectionDetails(collectionId, url);
|
|
2210
|
+
_context6.n = 3;
|
|
2211
|
+
return queryClient.fetchQuery(soundingsQueryOptions.getCollectionDetails(collectionId, url));
|
|
2152
2212
|
case 3:
|
|
2153
|
-
details =
|
|
2154
|
-
return
|
|
2213
|
+
details = _context6.v;
|
|
2214
|
+
return _context6.a(2, {
|
|
2155
2215
|
collectionId: collectionId,
|
|
2156
2216
|
supported: !!(details != null && (_details$data_queries2 = details.data_queries) != null && _details$data_queries2.radius)
|
|
2157
2217
|
});
|
|
2158
2218
|
case 4:
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
return
|
|
2219
|
+
_context6.p = 4;
|
|
2220
|
+
_context6.v;
|
|
2221
|
+
return _context6.a(2, {
|
|
2162
2222
|
collectionId: collectionId,
|
|
2163
2223
|
supported: false
|
|
2164
2224
|
});
|
|
2165
2225
|
}
|
|
2166
|
-
},
|
|
2226
|
+
}, _callee6, null, [[0, 4]]);
|
|
2167
2227
|
}));
|
|
2168
2228
|
function queryFn() {
|
|
2169
|
-
return
|
|
2229
|
+
return _queryFn6.apply(this, arguments);
|
|
2170
2230
|
}
|
|
2171
2231
|
return queryFn;
|
|
2172
2232
|
}(),
|
|
2173
|
-
|
|
2233
|
+
enabled: !referenceTimeUtils.isRelativeReferenceTime(instanceId),
|
|
2234
|
+
staleTime: 5 * 60 * 1000,
|
|
2235
|
+
// Cache for 5 minutes
|
|
2236
|
+
placeholderData: function placeholderData(prev) {
|
|
2237
|
+
return prev;
|
|
2238
|
+
}
|
|
2174
2239
|
};
|
|
2175
2240
|
});
|
|
2176
|
-
}, [sources]);
|
|
2241
|
+
}, [sources, queryClient]);
|
|
2177
2242
|
return useQueries({
|
|
2178
2243
|
queries: queries,
|
|
2179
2244
|
combine: function combine(queryResults) {
|
|
@@ -2223,20 +2288,20 @@ var useGridPointsFromRadius = function useGridPointsFromRadius(sources, radiusSu
|
|
|
2223
2288
|
return {
|
|
2224
2289
|
queryKey: ['edr-grid-points-disabled', collectionId],
|
|
2225
2290
|
queryFn: function () {
|
|
2226
|
-
var
|
|
2227
|
-
return _regenerator().w(function (
|
|
2228
|
-
while (1) switch (
|
|
2291
|
+
var _queryFn7 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7() {
|
|
2292
|
+
return _regenerator().w(function (_context7) {
|
|
2293
|
+
while (1) switch (_context7.n) {
|
|
2229
2294
|
case 0:
|
|
2230
|
-
return
|
|
2295
|
+
return _context7.a(2, {
|
|
2231
2296
|
sourceId: collectionId,
|
|
2232
2297
|
gridPoint: undefined,
|
|
2233
2298
|
allGridPoints: []
|
|
2234
2299
|
});
|
|
2235
2300
|
}
|
|
2236
|
-
},
|
|
2301
|
+
}, _callee7);
|
|
2237
2302
|
}));
|
|
2238
2303
|
function queryFn() {
|
|
2239
|
-
return
|
|
2304
|
+
return _queryFn7.apply(this, arguments);
|
|
2240
2305
|
}
|
|
2241
2306
|
return queryFn;
|
|
2242
2307
|
}(),
|
|
@@ -2261,22 +2326,22 @@ var useGridPointsFromRadius = function useGridPointsFromRadius(sources, radiusSu
|
|
|
2261
2326
|
return {
|
|
2262
2327
|
queryKey: ['edr-grid-points-radius', collectionId, instanceId || '', centerCoordinates.join(','), radiusKm.toString(), datetime],
|
|
2263
2328
|
queryFn: function () {
|
|
2264
|
-
var
|
|
2329
|
+
var _queryFn8 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
|
|
2265
2330
|
var minimalParameters, minimalVerticalRange, rawData, allGridPoints, nearestPoint, minSquaredDistance;
|
|
2266
|
-
return _regenerator().w(function (
|
|
2267
|
-
while (1) switch (
|
|
2331
|
+
return _regenerator().w(function (_context8) {
|
|
2332
|
+
while (1) switch (_context8.p = _context8.n) {
|
|
2268
2333
|
case 0:
|
|
2269
2334
|
if (supportsRadius) {
|
|
2270
|
-
|
|
2335
|
+
_context8.n = 1;
|
|
2271
2336
|
break;
|
|
2272
2337
|
}
|
|
2273
|
-
return
|
|
2338
|
+
return _context8.a(2, {
|
|
2274
2339
|
sourceId: collectionId,
|
|
2275
2340
|
gridPoint: undefined,
|
|
2276
2341
|
allGridPoints: []
|
|
2277
2342
|
});
|
|
2278
2343
|
case 1:
|
|
2279
|
-
|
|
2344
|
+
_context8.p = 1;
|
|
2280
2345
|
// Optimization: Only request a single parameter to minimize data transfer
|
|
2281
2346
|
// We only need the grid point coordinates, not the actual sounding data
|
|
2282
2347
|
minimalParameters = parameters.slice(0, 1); // Just one parameter
|
|
@@ -2284,10 +2349,10 @@ var useGridPointsFromRadius = function useGridPointsFromRadius(sources, radiusSu
|
|
|
2284
2349
|
// (Don't hardcode '1000' as that only works for pressure-level sources,
|
|
2285
2350
|
// not for hybrid/model-level sources which use levels 1-65)
|
|
2286
2351
|
minimalVerticalRange = '';
|
|
2287
|
-
|
|
2352
|
+
_context8.n = 2;
|
|
2288
2353
|
return getEdrCollectionForRadius(collectionId, url, instanceId, centerCoordinates, radiusKm, minimalParameters, datetime, minimalVerticalRange);
|
|
2289
2354
|
case 2:
|
|
2290
|
-
rawData =
|
|
2355
|
+
rawData = _context8.v;
|
|
2291
2356
|
allGridPoints = extractGridPointsFromCoverage(rawData); // Find the nearest grid point to the center coordinates
|
|
2292
2357
|
minSquaredDistance = Infinity;
|
|
2293
2358
|
allGridPoints.forEach(function (point) {
|
|
@@ -2302,24 +2367,24 @@ var useGridPointsFromRadius = function useGridPointsFromRadius(sources, radiusSu
|
|
|
2302
2367
|
nearestPoint = point;
|
|
2303
2368
|
}
|
|
2304
2369
|
});
|
|
2305
|
-
return
|
|
2370
|
+
return _context8.a(2, {
|
|
2306
2371
|
sourceId: collectionId,
|
|
2307
2372
|
gridPoint: nearestPoint,
|
|
2308
2373
|
allGridPoints: allGridPoints
|
|
2309
2374
|
});
|
|
2310
2375
|
case 3:
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
return
|
|
2376
|
+
_context8.p = 3;
|
|
2377
|
+
_context8.v;
|
|
2378
|
+
return _context8.a(2, {
|
|
2314
2379
|
sourceId: collectionId,
|
|
2315
2380
|
gridPoint: undefined,
|
|
2316
2381
|
allGridPoints: []
|
|
2317
2382
|
});
|
|
2318
2383
|
}
|
|
2319
|
-
},
|
|
2384
|
+
}, _callee8, null, [[1, 3]]);
|
|
2320
2385
|
}));
|
|
2321
2386
|
function queryFn() {
|
|
2322
|
-
return
|
|
2387
|
+
return _queryFn8.apply(this, arguments);
|
|
2323
2388
|
}
|
|
2324
2389
|
return queryFn;
|
|
2325
2390
|
}(),
|
|
@@ -2627,6 +2692,7 @@ var initialSoundingsViewState = {
|
|
|
2627
2692
|
},
|
|
2628
2693
|
shouldHideLocationMarkers: false,
|
|
2629
2694
|
isTimeSliderVisible: true,
|
|
2695
|
+
isLegendVisible: true,
|
|
2630
2696
|
profileDataPreferences: DEFAULT_PROFILE_DATA_PREFERENCES,
|
|
2631
2697
|
syncGroupsIds: []
|
|
2632
2698
|
};
|
|
@@ -2696,7 +2762,7 @@ var slice = createSlice({
|
|
|
2696
2762
|
}
|
|
2697
2763
|
var preset = payloadAction.payload.preset;
|
|
2698
2764
|
if (preset) {
|
|
2699
|
-
var _preset$selectedSourc, _preset$selectedLocat, _preset$selectedTime, _preset$diagramType, _preset$shouldHideLoc, _preset$isTimeSliderV, _preset$profileDataPr;
|
|
2765
|
+
var _preset$selectedSourc, _preset$selectedLocat, _preset$selectedTime, _preset$diagramType, _preset$shouldHideLoc, _preset$isTimeSliderV, _preset$isLegendVisib, _preset$profileDataPr;
|
|
2700
2766
|
panel.selectedSources = (_preset$selectedSourc = preset.selectedSources) != null ? _preset$selectedSourc : {};
|
|
2701
2767
|
panel.selectedLocations = (_preset$selectedLocat = preset.selectedLocations) != null ? _preset$selectedLocat : {};
|
|
2702
2768
|
panel.selectedTime = (_preset$selectedTime = preset.selectedTime) != null ? _preset$selectedTime : new Date().toISOString();
|
|
@@ -2718,7 +2784,11 @@ var slice = createSlice({
|
|
|
2718
2784
|
}
|
|
2719
2785
|
panel.shouldHideLocationMarkers = (_preset$shouldHideLoc = preset.shouldHideLocationMarkers) != null ? _preset$shouldHideLoc : false;
|
|
2720
2786
|
panel.isTimeSliderVisible = (_preset$isTimeSliderV = preset.isTimeSliderVisible) != null ? _preset$isTimeSliderV : true;
|
|
2787
|
+
panel.isLegendVisible = (_preset$isLegendVisib = preset.isLegendVisible) != null ? _preset$isLegendVisib : true;
|
|
2721
2788
|
panel.profileDataPreferences = (_preset$profileDataPr = preset.profileDataPreferences) != null ? _preset$profileDataPr : DEFAULT_PROFILE_DATA_PREFERENCES;
|
|
2789
|
+
panel.locationMenuSize = preset.locationMenuSize;
|
|
2790
|
+
panel.locationMenuPosition = preset.locationMenuPosition;
|
|
2791
|
+
panel.isLocationsDialogOpen = preset.isLocationsDialogOpen;
|
|
2722
2792
|
}
|
|
2723
2793
|
},
|
|
2724
2794
|
setSoundingsCollections: function setSoundingsCollections(draft, payloadAction) {
|
|
@@ -2776,6 +2846,13 @@ var slice = createSlice({
|
|
|
2776
2846
|
}
|
|
2777
2847
|
panel.isTimeSliderVisible = payloadAction.payload.isTimeSliderVisible;
|
|
2778
2848
|
},
|
|
2849
|
+
toggleLegendVisibility: function toggleLegendVisibility(draft, payloadAction) {
|
|
2850
|
+
var panel = resolveSoundingsView(draft, payloadAction);
|
|
2851
|
+
if (!panel) {
|
|
2852
|
+
return;
|
|
2853
|
+
}
|
|
2854
|
+
panel.isLegendVisible = payloadAction.payload.isLegendVisible;
|
|
2855
|
+
},
|
|
2779
2856
|
updateProfileDataPreferences: function updateProfileDataPreferences(draft, payloadAction) {
|
|
2780
2857
|
var panel = resolveSoundingsView(draft, payloadAction);
|
|
2781
2858
|
if (!panel) {
|
|
@@ -2842,6 +2919,23 @@ var slice = createSlice({
|
|
|
2842
2919
|
customWidth: customWidth
|
|
2843
2920
|
});
|
|
2844
2921
|
},
|
|
2922
|
+
setLocationMenuSizeAndPosition: function setLocationMenuSizeAndPosition(draft, payloadAction) {
|
|
2923
|
+
var panel = resolveSoundingsView(draft, payloadAction);
|
|
2924
|
+
if (!panel) {
|
|
2925
|
+
return;
|
|
2926
|
+
}
|
|
2927
|
+
panel.locationMenuSize = payloadAction.payload.size;
|
|
2928
|
+
if (payloadAction.payload.position !== undefined) {
|
|
2929
|
+
panel.locationMenuPosition = payloadAction.payload.position;
|
|
2930
|
+
}
|
|
2931
|
+
},
|
|
2932
|
+
setLocationsMenuOpen: function setLocationsMenuOpen(draft, payloadAction) {
|
|
2933
|
+
var panel = resolveSoundingsView(draft, payloadAction);
|
|
2934
|
+
if (!panel) {
|
|
2935
|
+
return;
|
|
2936
|
+
}
|
|
2937
|
+
panel.isLocationsDialogOpen = payloadAction.payload.isLocationsDialogOpen;
|
|
2938
|
+
},
|
|
2845
2939
|
notifyViewClosed: function notifyViewClosed(draft) {
|
|
2846
2940
|
var _draft$resizeOnViewCl;
|
|
2847
2941
|
draft.resizeOnViewCloseSignal = ((_draft$resizeOnViewCl = draft.resizeOnViewCloseSignal) != null ? _draft$resizeOnViewCl : 0) + 1;
|
|
@@ -2954,6 +3048,10 @@ var getIsTimeSliderVisible = createSelector(getSoundingsViewState, function (sto
|
|
|
2954
3048
|
var _store$isTimeSliderVi;
|
|
2955
3049
|
return (_store$isTimeSliderVi = store.isTimeSliderVisible) != null ? _store$isTimeSliderVi : true;
|
|
2956
3050
|
}, selectorMemoizationOptions);
|
|
3051
|
+
var getIsLegendVisible = createSelector(getSoundingsViewState, function (store) {
|
|
3052
|
+
var _store$isLegendVisibl;
|
|
3053
|
+
return (_store$isLegendVisibl = store.isLegendVisible) != null ? _store$isLegendVisibl : true;
|
|
3054
|
+
}, selectorMemoizationOptions);
|
|
2957
3055
|
var getProfileDataPreferences = createSelector(getSoundingsViewState, function (store) {
|
|
2958
3056
|
var _store$profileDataPre;
|
|
2959
3057
|
return (_store$profileDataPre = store.profileDataPreferences) != null ? _store$profileDataPre : DEFAULT_PROFILE_DATA_PREFERENCES;
|
|
@@ -2987,6 +3085,12 @@ var getSelectedSourcesIds = createSelector(getSelectedSources, function (activeS
|
|
|
2987
3085
|
return source.collectionId;
|
|
2988
3086
|
});
|
|
2989
3087
|
}, selectorMemoizationOptions);
|
|
3088
|
+
var getLocationMenuSize = createSelector(getSoundingsViewState, function (store) {
|
|
3089
|
+
return store.locationMenuSize;
|
|
3090
|
+
}, selectorMemoizationOptions);
|
|
3091
|
+
var getLocationMenuPosition = createSelector(getSoundingsViewState, function (store) {
|
|
3092
|
+
return store.locationMenuPosition;
|
|
3093
|
+
}, selectorMemoizationOptions);
|
|
2990
3094
|
var getSoundingsPreset = createSelector(getSoundingsViewState, function (soundingsStore) {
|
|
2991
3095
|
return Object.assign({}, soundingsStore);
|
|
2992
3096
|
}, selectorMemoizationOptions);
|
|
@@ -3008,7 +3112,10 @@ var getSoundingPanelsInOrder = createSelector(getSoundingsViewState, function (s
|
|
|
3008
3112
|
var selectors = /*#__PURE__*/Object.freeze({
|
|
3009
3113
|
__proto__: null,
|
|
3010
3114
|
getDiagramType: getDiagramType,
|
|
3115
|
+
getIsLegendVisible: getIsLegendVisible,
|
|
3011
3116
|
getIsTimeSliderVisible: getIsTimeSliderVisible,
|
|
3117
|
+
getLocationMenuPosition: getLocationMenuPosition,
|
|
3118
|
+
getLocationMenuSize: getLocationMenuSize,
|
|
3012
3119
|
getLocationSelections: getLocationSelections,
|
|
3013
3120
|
getPanelCustomWidth: getPanelCustomWidth,
|
|
3014
3121
|
getPanelIsOpen: getPanelIsOpen,
|
|
@@ -3199,13 +3306,15 @@ var MenuOptions;
|
|
|
3199
3306
|
MenuOptions["profileData"] = "profileData";
|
|
3200
3307
|
})(MenuOptions || (MenuOptions = {}));
|
|
3201
3308
|
var SoundingsMenuBar = function SoundingsMenuBar(_ref) {
|
|
3202
|
-
var _sx;
|
|
3309
|
+
var _sx, _sx2;
|
|
3203
3310
|
var handleClick = _ref.handleClick,
|
|
3204
3311
|
isOpen = _ref.isOpen,
|
|
3205
3312
|
_ref$selectedSourcesA = _ref.selectedSourcesAmount,
|
|
3206
3313
|
selectedSourcesAmount = _ref$selectedSourcesA === void 0 ? 0 : _ref$selectedSourcesA,
|
|
3207
3314
|
shouldHideMarkers = _ref.shouldHideMarkers,
|
|
3208
|
-
toggleMarkers = _ref.toggleMarkers
|
|
3315
|
+
toggleMarkers = _ref.toggleMarkers,
|
|
3316
|
+
isLegendVisible = _ref.isLegendVisible,
|
|
3317
|
+
toggleLegend = _ref.toggleLegend;
|
|
3209
3318
|
var _useSoundingsTranslat = useSoundingsTranslation(),
|
|
3210
3319
|
t = _useSoundingsTranslat.t;
|
|
3211
3320
|
return jsxs(Stack, {
|
|
@@ -3260,6 +3369,23 @@ var SoundingsMenuBar = function SoundingsMenuBar(_ref) {
|
|
|
3260
3369
|
}), jsx(SoundingsMarkersSwitch, {
|
|
3261
3370
|
shouldHideMarkers: shouldHideMarkers,
|
|
3262
3371
|
toggleMarkers: toggleMarkers
|
|
3372
|
+
}), jsx(LegendToggleButton, {
|
|
3373
|
+
hideTooltipText: t('soundings-legend-tooltip-hide'),
|
|
3374
|
+
isLegendVisible: isLegendVisible,
|
|
3375
|
+
legendLabel: t('soundings-legend'),
|
|
3376
|
+
onToggle: toggleLegend,
|
|
3377
|
+
showTooltipText: t('soundings-legend-tooltip-show'),
|
|
3378
|
+
sx: (_sx2 = {}, _sx2["@container " + SOUNDINGS_CONTAINER_NAME + " (width < " + SOUNDINGS_CONTAINER_BREAKPOINT_PX + ")"] = {
|
|
3379
|
+
maxWidth: '90px',
|
|
3380
|
+
'& .longText': {
|
|
3381
|
+
display: 'none'
|
|
3382
|
+
},
|
|
3383
|
+
'& svg': {
|
|
3384
|
+
marginRight: '0 !important'
|
|
3385
|
+
}
|
|
3386
|
+
}, _sx2["@container " + SOUNDINGS_CONTAINER_NAME + " (min-width: " + SOUNDINGS_CONTAINER_BREAKPOINT_PX + ")"] = {
|
|
3387
|
+
width: '130px'
|
|
3388
|
+
}, _sx2)
|
|
3263
3389
|
})]
|
|
3264
3390
|
});
|
|
3265
3391
|
};
|
|
@@ -3304,6 +3430,16 @@ var MenuBarConnect = function MenuBarConnect(_ref) {
|
|
|
3304
3430
|
var shouldHideLocationMarkers = useSelector(function (state) {
|
|
3305
3431
|
return getShouldHideLocationMarkers(state, viewId);
|
|
3306
3432
|
});
|
|
3433
|
+
var isLegendVisible = useSelector(function (state) {
|
|
3434
|
+
return getIsLegendVisible(state, viewId);
|
|
3435
|
+
});
|
|
3436
|
+
var toggleLegend = React.useCallback(function () {
|
|
3437
|
+
dispatch(soundingsActions.toggleLegendVisibility({
|
|
3438
|
+
isLegendVisible: !isLegendVisible,
|
|
3439
|
+
viewId: viewId,
|
|
3440
|
+
origin: SoundingsActionOrigin.soundingsComponent
|
|
3441
|
+
}));
|
|
3442
|
+
}, [dispatch, isLegendVisible, viewId]);
|
|
3307
3443
|
var toggleLocationMarkers = React.useCallback(function (shouldHide) {
|
|
3308
3444
|
dispatch(soundingsActions.toggleLocationMarkers({
|
|
3309
3445
|
shouldHideLocationMarkers: shouldHide,
|
|
@@ -3328,19 +3464,29 @@ var MenuBarConnect = function MenuBarConnect(_ref) {
|
|
|
3328
3464
|
dispatchActiveMapId(uiTypes.DialogTypes.SoundingsSources, isSourcesOpenInStore, currentActiveMapIdSources);
|
|
3329
3465
|
break;
|
|
3330
3466
|
case MenuOptions.locations:
|
|
3331
|
-
|
|
3332
|
-
|
|
3467
|
+
{
|
|
3468
|
+
var newIsLocationsOpen = currentActiveMapIdLocations !== viewId ? true : !isLocationsOpenInStore;
|
|
3469
|
+
dispatchActiveMapId(uiTypes.DialogTypes.SoundingsLocations, isLocationsOpenInStore, currentActiveMapIdLocations);
|
|
3470
|
+
dispatch(soundingsActions.setLocationsMenuOpen({
|
|
3471
|
+
viewId: viewId,
|
|
3472
|
+
isLocationsDialogOpen: newIsLocationsOpen,
|
|
3473
|
+
origin: SoundingsActionOrigin.soundingsComponent
|
|
3474
|
+
}));
|
|
3475
|
+
break;
|
|
3476
|
+
}
|
|
3333
3477
|
case MenuOptions.profileData:
|
|
3334
3478
|
dispatchActiveMapId(uiTypes.DialogTypes.SoundingsProfileData, isProfileDataOpenInStore, currentActiveMapIdProfileData);
|
|
3335
3479
|
break;
|
|
3336
3480
|
}
|
|
3337
|
-
}, [dispatchActiveMapId, isSoundingsManagerOpenInStore, currentActiveMapIdsoundingsManager, isSourcesOpenInStore, currentActiveMapIdSources, isLocationsOpenInStore, currentActiveMapIdLocations, isProfileDataOpenInStore, currentActiveMapIdProfileData]);
|
|
3481
|
+
}, [dispatch, dispatchActiveMapId, viewId, isSoundingsManagerOpenInStore, currentActiveMapIdsoundingsManager, isSourcesOpenInStore, currentActiveMapIdSources, isLocationsOpenInStore, currentActiveMapIdLocations, isProfileDataOpenInStore, currentActiveMapIdProfileData]);
|
|
3338
3482
|
var isOpen = (_isOpen = {}, _isOpen[MenuOptions.sources] = currentActiveMapIdSources === viewId && isSourcesOpenInStore, _isOpen[MenuOptions.locations] = currentActiveMapIdLocations === viewId && isLocationsOpenInStore, _isOpen[MenuOptions.soundingsManager] = currentActiveMapIdsoundingsManager === viewId && isSoundingsManagerOpenInStore, _isOpen[MenuOptions.profileData] = currentActiveMapIdProfileData === viewId && isProfileDataOpenInStore, _isOpen);
|
|
3339
3483
|
return jsx(SoundingsMenuBar, {
|
|
3340
3484
|
handleClick: handleClick,
|
|
3485
|
+
isLegendVisible: isLegendVisible,
|
|
3341
3486
|
isOpen: isOpen,
|
|
3342
3487
|
selectedSourcesAmount: sourcesAmount,
|
|
3343
3488
|
shouldHideMarkers: shouldHideLocationMarkers,
|
|
3489
|
+
toggleLegend: toggleLegend,
|
|
3344
3490
|
toggleMarkers: toggleLocationMarkers
|
|
3345
3491
|
});
|
|
3346
3492
|
};
|
|
@@ -3956,7 +4102,7 @@ var Hodograph = function Hodograph(_ref) {
|
|
|
3956
4102
|
});
|
|
3957
4103
|
});
|
|
3958
4104
|
// Allow zooming and panning
|
|
3959
|
-
var zoomBehavior = d3.zoom().scaleExtent([1, 7]).translateExtent([[
|
|
4105
|
+
var zoomBehavior = d3.zoom().scaleExtent([1, 7]).translateExtent([[0, 0], [widthHeight, widthHeight]]).on('zoom', function (event) {
|
|
3960
4106
|
svg.select('g.hodograph').attr('transform', event.transform);
|
|
3961
4107
|
});
|
|
3962
4108
|
svg.call(zoomBehavior);
|
|
@@ -4310,23 +4456,21 @@ var extractPressureFromY = function extractPressureFromY(diagramType, y, yScale)
|
|
|
4310
4456
|
};
|
|
4311
4457
|
var drawSoundingsTooltip = function drawSoundingsTooltip(_ref) {
|
|
4312
4458
|
var event = _ref.event,
|
|
4313
|
-
yScale = _ref.yScale,
|
|
4314
4459
|
svgRectangle = _ref.svgRectangle,
|
|
4460
|
+
hoveredPressure = _ref.hoveredPressure,
|
|
4315
4461
|
pressureRefd3 = _ref.pressureRefd3,
|
|
4316
4462
|
tempRefd3 = _ref.tempRefd3,
|
|
4317
4463
|
dewpointRefd3 = _ref.dewpointRefd3,
|
|
4318
4464
|
windRefd3 = _ref.windRefd3,
|
|
4319
4465
|
margin = _ref.margin,
|
|
4320
4466
|
width = _ref.width,
|
|
4321
|
-
tooltipData = _ref.tooltipData
|
|
4322
|
-
|
|
4467
|
+
tooltipData = _ref.tooltipData;
|
|
4468
|
+
_ref.diagramType;
|
|
4323
4469
|
if (tooltipData.length === 0) {
|
|
4324
4470
|
return;
|
|
4325
4471
|
}
|
|
4326
|
-
var _d3$pointer = d3.pointer(event),
|
|
4327
|
-
y = _d3$pointer[1];
|
|
4328
4472
|
var pressureY = event.clientY - svgRectangle.top - 10;
|
|
4329
|
-
var pressure =
|
|
4473
|
+
var pressure = hoveredPressure;
|
|
4330
4474
|
var interpolatedData = tooltipData.map(function (dataSet) {
|
|
4331
4475
|
return {
|
|
4332
4476
|
hoveredPressure: dataSet.interpolatePressure(pressure),
|
|
@@ -4413,6 +4557,7 @@ var drawDryAdiabatsBijvoet = function drawDryAdiabatsBijvoet(_ref2) {
|
|
|
4413
4557
|
yScale = _ref2.yScale,
|
|
4414
4558
|
svg = _ref2.svg,
|
|
4415
4559
|
d3GraphId = _ref2.d3GraphId;
|
|
4560
|
+
var lineGenerator = d3.line();
|
|
4416
4561
|
for (var Tbase = -20; Tbase < 40; Tbase += 5) {
|
|
4417
4562
|
var Px = [];
|
|
4418
4563
|
var tempKelvin = tempToKelvin(Tbase);
|
|
@@ -4426,7 +4571,6 @@ var drawDryAdiabatsBijvoet = function drawDryAdiabatsBijvoet(_ref2) {
|
|
|
4426
4571
|
var Tpx = xScale(theta);
|
|
4427
4572
|
Px.push([Tpx, Ppx]);
|
|
4428
4573
|
}
|
|
4429
|
-
var lineGenerator = d3.line();
|
|
4430
4574
|
var daPathString = lineGenerator(Px);
|
|
4431
4575
|
var strID = Tbase + "-dryadiabat";
|
|
4432
4576
|
svg.append('path').attr('id', strID).attr('d', daPathString).style('fill', 'none').style('stroke-width', 1).style('stroke', 'green').style('opacity', 0.3).attr('clip-path', "url(#clip-" + d3GraphId + "-BIJVOETd3)");
|
|
@@ -4525,8 +4669,10 @@ var drawIsothermsBijvoet = function drawIsothermsBijvoet(_ref2) {
|
|
|
4525
4669
|
xScale = _ref2.xScale,
|
|
4526
4670
|
yScale = _ref2.yScale,
|
|
4527
4671
|
svg = _ref2.svg,
|
|
4672
|
+
labelSvg = _ref2.labelSvg,
|
|
4528
4673
|
height = _ref2.height,
|
|
4529
4674
|
d3GraphId = _ref2.d3GraphId;
|
|
4675
|
+
var lineGenerator = d3.line();
|
|
4530
4676
|
// lines of constant temperature (2 degree interval from -150...+40C)
|
|
4531
4677
|
for (var temp = -150; temp <= 40; temp += 2) {
|
|
4532
4678
|
var _points$;
|
|
@@ -4537,12 +4683,11 @@ var drawIsothermsBijvoet = function drawIsothermsBijvoet(_ref2) {
|
|
|
4537
4683
|
var theta = calculateThetaFromPressTemp(pressToPascal(pressure), Tiso, REFERENCE_PRESSURE);
|
|
4538
4684
|
points.push([xScale(theta), yScale(pressure)]);
|
|
4539
4685
|
}
|
|
4540
|
-
var lineGenerator = d3.line();
|
|
4541
4686
|
var pathString = lineGenerator(points);
|
|
4542
4687
|
var strID = temp + "-isotherm-BIJVOET";
|
|
4543
4688
|
svg.append('path').attr('id', strID).attr('d', pathString).style('fill', 'none').style('stroke-width', temp % 10 === 0 ? 2 : 1).style('stroke', temp === 0 ? '#D27D2D' : 'orange').style('stroke-opacity', 0.5).attr('clip-path', "url(#clip-" + d3GraphId + "-BIJVOETd3)");
|
|
4544
4689
|
if (temp % 10 === 0 && ((_points$ = points[0]) == null ? void 0 : _points$[1]) === height) {
|
|
4545
|
-
svg.append('text').text(temp).attr('text-anchor', 'middle').attr('x', points[0][0] + "px").attr('y', height + 12 + "px").attr('fill', temp === 0 ? '#D27D2D' : 'orange').attr('font-size', '10px');
|
|
4690
|
+
(labelSvg != null ? labelSvg : svg).append('text').text(temp).attr('text-anchor', 'middle').attr('x', points[0][0] + "px").attr('y', height + 12 + "px").attr('fill', temp === 0 ? '#D27D2D' : 'orange').attr('font-size', '10px');
|
|
4546
4691
|
}
|
|
4547
4692
|
}
|
|
4548
4693
|
};
|
|
@@ -4685,6 +4830,7 @@ var drawStaticLines = function drawStaticLines(_ref) {
|
|
|
4685
4830
|
minPressure = _ref.minPressure,
|
|
4686
4831
|
maxPressure = _ref.maxPressure,
|
|
4687
4832
|
svg = _ref.svg,
|
|
4833
|
+
bijvoetLabelSvg = _ref.bijvoetLabelSvg,
|
|
4688
4834
|
d3GraphId = _ref.d3GraphId;
|
|
4689
4835
|
drawIsobars({
|
|
4690
4836
|
diagramType: diagramType,
|
|
@@ -4708,6 +4854,7 @@ var drawStaticLines = function drawStaticLines(_ref) {
|
|
|
4708
4854
|
xScale: xScale,
|
|
4709
4855
|
yScale: yScale,
|
|
4710
4856
|
svg: svg,
|
|
4857
|
+
labelSvg: bijvoetLabelSvg,
|
|
4711
4858
|
height: height,
|
|
4712
4859
|
d3GraphId: d3GraphId
|
|
4713
4860
|
});
|
|
@@ -4773,105 +4920,503 @@ var drawStaticLines = function drawStaticLines(_ref) {
|
|
|
4773
4920
|
}
|
|
4774
4921
|
};
|
|
4775
4922
|
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4923
|
+
/* *
|
|
4924
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4925
|
+
* you may not use this file except in compliance with the License.
|
|
4926
|
+
* You may obtain a copy of the License at
|
|
4927
|
+
*
|
|
4928
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
4929
|
+
*
|
|
4930
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
4931
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
4932
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
4933
|
+
* See the License for the specific language governing permissions and
|
|
4934
|
+
* limitations under the License.
|
|
4935
|
+
*
|
|
4936
|
+
* Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
4937
|
+
* Copyright 2025 - Finnish Meteorological Institute (FMI)
|
|
4938
|
+
* Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
|
|
4939
|
+
* */
|
|
4940
|
+
var windSymbolDefinitions = {
|
|
4941
|
+
calm: "<svg width=\"50\" height=\"50\" viewBox=\"0 0 50 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M25 45C36.0456 45 45 36.0456 45 25C45 13.9543 36.0456 5 25 5C13.9543 5 5 13.9543 5 25C5 36.0456 13.9543 45 25 45Z\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
|
|
4942
|
+
lightAir: "<svg width=\"14\" height=\"48\" viewBox=\"0 0 14 48\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M7.22656 4.89307V48.0001M7.22656 43.0262V44.6842\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
|
|
4943
|
+
fiveKnots: "<svg width=\"15\" height=\"49\" viewBox=\"0 0 15 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M8.26953 5.57324V48.608M8.26953 40.5757L0.269531 42.2309\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4944
|
+
tenKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17.0781 4.64502V44.9031L1.07812 47.9999\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4945
|
+
fifteenKnots: "<svg width=\"23\" height=\"50\" viewBox=\"0 0 23 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.4727 5.55469V45.8128L0.472656 48.9095M16.4727 38.0708L9.61551 39.6192\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
|
|
4946
|
+
twentyKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.8555 4.71924V44.9773L0.855469 48.0741M16.8555 38.4093L0.855469 41.5061\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4947
|
+
twentyFiveKnots: "<svg width=\"23\" height=\"51\" viewBox=\"0 0 23 51\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.2383 4.94434V46.1541L0.238281 49.3241M16.2383 40.3787L0.238281 43.5486M16.2383 33.9801L9.38114 35.5651\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4948
|
+
thirtyKnots: "<svg width=\"23\" height=\"50\" viewBox=\"0 0 23 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.1914 5.64502V45.9031L0.191406 48.9999M16.1914 40.3459L0.191406 43.4427M16.1914 34.9407L0.191406 38.0375\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4949
|
+
thirtyFiveKnots: "<svg width=\"19\" height=\"50\" viewBox=\"0 0 19 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M12.0028 4.96729V45.2253L1.16406 48.3221M12.0028 39.6443L1.16406 42.7411M12.0028 34.4793L1.16406 37.576M12.0028 29.2735L7.35761 30.8219\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4950
|
+
fortyKnots: "<svg width=\"24\" height=\"50\" viewBox=\"0 0 24 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.5391 5.40311V45.6612L0.539062 48.7579M16.5391 40.4525L0.539062 43.5493M16.5391 35.0449L0.539062 38.1417M16.5391 30.2009L0.539062 33.2976\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4951
|
+
fortyFiveKnots: "<svg width=\"23\" height=\"50\" viewBox=\"0 0 23 50\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.4492 5.4043V45.6624L0.449219 48.7591M16.4492 40.1513L0.449219 43.2481M16.4492 34.7124L0.449219 37.8091M16.4492 29.2013L0.449219 32.2981M16.4492 24.3066L9.59208 25.855\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4952
|
+
fiftyKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.9062 5.27002V45.5281L0.90625 48.6249L16.9062 37.7861\" fill=\"black\"/>\n<path d=\"M16.9053 5.27002V45.5281L4.35132 47.2337L16.9053 37.7861\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
|
|
4953
|
+
fiftyFiveKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.728 5.55371V45.8118L0.894531 48.9085L16.728 38.0698\" fill=\"black\"/>\n<path d=\"M16.73 5.55371V45.8118L4.33984 47.5245L16.73 38.0698\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.7292 32.7358C13.6376 33.3406 8.8125 34.2842 8.8125 34.2842\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4954
|
+
sixtyKnots: "<svg width=\"23\" height=\"49\" viewBox=\"0 0 23 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M16.2891 5.27051V45.5286L0.289062 48.6253L16.2891 37.7866\" fill=\"black\"/>\n<path d=\"M16.2897 5.27051V45.5286L3.7422 47.2478L16.2897 37.7866\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.2891 34.6899L0.289062 37.7867\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4955
|
+
sixtyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L9.5 28.5\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4956
|
+
seventyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>",
|
|
4957
|
+
seventyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 22C13.8251 22.6048 9 23.5484 9 23.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4958
|
+
eightyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4959
|
+
eightyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 17C13.8251 17.6048 9 18.5484 9 18.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
|
|
4960
|
+
ninetyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
|
|
4961
|
+
ninetyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V43.5261L4.35938 45.2985L16.9984 35.7842\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 32.0788L1 35.1756M17 26.8862L1 29.983\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 22C10.7518 23.1718 1 25 1 25\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 12C13.8251 12.6048 9 13.5484 9 13.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4962
|
+
hundredKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>\n",
|
|
4963
|
+
hundredFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 25C13.8251 25.6048 9 26.5484 9 26.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
|
|
4964
|
+
hundredTenKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4965
|
+
hundredFifteenKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 21C13.8251 21.6048 9 22.5484 9 22.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4966
|
+
hundredTwentyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4967
|
+
hundredTwentyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 17C13.8251 17.6048 9 18.5484 9 18.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>\n",
|
|
4968
|
+
hundredThirtyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4969
|
+
hundredThirtyFiveKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M16.9167 13C13.8251 13.6048 9 14.5484 9 14.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4970
|
+
hundredFortyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V28M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M17 25C10.7518 26.1718 1 28 1 28\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 21C10.7518 22.1718 1 24 1 24\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 17C10.7518 18.1718 1 20 1 20\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 13C10.7518 14.1718 1 16 1 16\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4971
|
+
hundredFortyFiveKnots: "<svg width=\"24\" height=\"49\" viewBox=\"0 0 24 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 5.26807V25.3971V45.5261L1 48.6229L17 37.7842\" fill=\"black\"/>\n<path d=\"M16.9984 5.26807V30M16.9984 37.7842L4.35938 47.2985L16.9984 45.5261V37.5M16.9984 30C16.9984 30 5.67406 37.7842 4 39M16.9984 30V31.5M4 39C9.07621 38.4142 16.9984 37.5 16.9984 37.5M4 39C9.07621 36.0711 16.9984 31.5 16.9984 31.5M4 39C9.07682 36.6569 17 33 17 33M4 39C9.07621 37.2426 16.9984 34.5 16.9984 34.5M4 39C9.07621 37.8284 16.9984 36 16.9984 36M16.9984 37.5V36M16.9984 31.5V34.5M16.9984 34.5V36\" stroke=\"black\" stroke-width=\"1.8\"/>\n<path d=\"M16.9167 12C13.8251 12.6048 9 13.5484 9 13.5484\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 27C10.7518 28.1718 1 30 1 30\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 23C10.7518 24.1718 1 26 1 26\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 19C10.7518 20.1718 1 22 1 22\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n<path d=\"M17 15C10.7518 16.1718 1 18 1 18\" stroke=\"black\" stroke-width=\"1.8\" stroke-miterlimit=\"16\"/>\n</svg>",
|
|
4972
|
+
hundredFiftyKnots: "<svg width=\"24\" height=\"47\" viewBox=\"0 0 24 47\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M17 3.26807V23.3971V43.5261L1 46.6229L17 35.7842\" fill=\"black\"/>\n<path d=\"M16.9984 3.26807V19M16.9984 35.7842L4.35938 45.2985L16.9984 43.5261V35.5M16.9984 28C16.9984 28 5.67406 35.7842 4 37M16.9984 28V29.5M16.9984 28V26.5M4 37C9.07621 36.4142 16.9984 35.5 16.9984 35.5M4 37C9.07621 34.0711 16.9984 29.5 16.9984 29.5M4 37C9.07682 34.6569 17 31 17 31M4 37C9.07621 35.2426 16.9984 32.5 16.9984 32.5M4 37C9.07621 35.8284 16.9984 34 16.9984 34M16.9984 35.5V34M16.9984 29.5V32.5M16.9984 32.5V34M16.9984 19C16.9984 19 8 25.5 4 29M16.9984 19V20.5M4 29C9.07621 28.0237 16.9984 26.5 16.9984 26.5M4 29C9.07621 25.6805 16.9984 20.5 16.9984 20.5M4 29C9.07621 26.4616 16.9984 22.5 16.9984 22.5M4 29C9.07621 27.0474 16.9984 24 16.9984 24M4 29C9.07621 27.5355 16.9984 25.25 16.9984 25.25M16.9984 26.5V25.25M16.9984 20.5V22.5M16.9984 22.5V24M16.9984 24V25.25\" stroke=\"black\" stroke-width=\"1.8\"/>\n</svg>"
|
|
4973
|
+
};
|
|
4974
|
+
var windSpeedRanges = [{
|
|
4975
|
+
min: 0,
|
|
4976
|
+
max: 1,
|
|
4977
|
+
symbol: windSymbolDefinitions.calm
|
|
4978
|
+
}, {
|
|
4979
|
+
min: 1,
|
|
4980
|
+
max: 4.5,
|
|
4981
|
+
symbol: windSymbolDefinitions.lightAir
|
|
4982
|
+
}, {
|
|
4983
|
+
min: 4.5,
|
|
4984
|
+
max: 7.5,
|
|
4985
|
+
symbol: windSymbolDefinitions.fiveKnots
|
|
4986
|
+
}, {
|
|
4987
|
+
min: 7.5,
|
|
4988
|
+
max: 12.5,
|
|
4989
|
+
symbol: windSymbolDefinitions.tenKnots
|
|
4990
|
+
}, {
|
|
4991
|
+
min: 12.5,
|
|
4992
|
+
max: 17.5,
|
|
4993
|
+
symbol: windSymbolDefinitions.fifteenKnots
|
|
4994
|
+
}, {
|
|
4995
|
+
min: 17.5,
|
|
4996
|
+
max: 22.5,
|
|
4997
|
+
symbol: windSymbolDefinitions.twentyKnots
|
|
4998
|
+
}, {
|
|
4999
|
+
min: 22.5,
|
|
5000
|
+
max: 27.5,
|
|
5001
|
+
symbol: windSymbolDefinitions.twentyFiveKnots
|
|
5002
|
+
}, {
|
|
5003
|
+
min: 27.5,
|
|
5004
|
+
max: 32.5,
|
|
5005
|
+
symbol: windSymbolDefinitions.thirtyKnots
|
|
5006
|
+
}, {
|
|
5007
|
+
min: 32.5,
|
|
5008
|
+
max: 37.5,
|
|
5009
|
+
symbol: windSymbolDefinitions.thirtyFiveKnots
|
|
5010
|
+
}, {
|
|
5011
|
+
min: 37.5,
|
|
5012
|
+
max: 42.5,
|
|
5013
|
+
symbol: windSymbolDefinitions.fortyKnots
|
|
5014
|
+
}, {
|
|
5015
|
+
min: 42.5,
|
|
5016
|
+
max: 47.5,
|
|
5017
|
+
symbol: windSymbolDefinitions.fortyFiveKnots
|
|
5018
|
+
}, {
|
|
5019
|
+
min: 47.5,
|
|
5020
|
+
max: 52.5,
|
|
5021
|
+
symbol: windSymbolDefinitions.fiftyKnots
|
|
5022
|
+
}, {
|
|
5023
|
+
min: 52.5,
|
|
5024
|
+
max: 57.5,
|
|
5025
|
+
symbol: windSymbolDefinitions.fiftyFiveKnots
|
|
5026
|
+
}, {
|
|
5027
|
+
min: 57.5,
|
|
5028
|
+
max: 62.5,
|
|
5029
|
+
symbol: windSymbolDefinitions.sixtyKnots
|
|
5030
|
+
}, {
|
|
5031
|
+
min: 62.5,
|
|
5032
|
+
max: 67.5,
|
|
5033
|
+
symbol: windSymbolDefinitions.sixtyFiveKnots
|
|
5034
|
+
}, {
|
|
5035
|
+
min: 67.5,
|
|
5036
|
+
max: 72.5,
|
|
5037
|
+
symbol: windSymbolDefinitions.seventyKnots
|
|
5038
|
+
}, {
|
|
5039
|
+
min: 72.5,
|
|
5040
|
+
max: 77.5,
|
|
5041
|
+
symbol: windSymbolDefinitions.seventyFiveKnots
|
|
5042
|
+
}, {
|
|
5043
|
+
min: 77.5,
|
|
5044
|
+
max: 82.5,
|
|
5045
|
+
symbol: windSymbolDefinitions.eightyKnots
|
|
5046
|
+
}, {
|
|
5047
|
+
min: 82.5,
|
|
5048
|
+
max: 87.5,
|
|
5049
|
+
symbol: windSymbolDefinitions.eightyFiveKnots
|
|
5050
|
+
}, {
|
|
5051
|
+
min: 87.5,
|
|
5052
|
+
max: 92.5,
|
|
5053
|
+
symbol: windSymbolDefinitions.ninetyKnots
|
|
5054
|
+
}, {
|
|
5055
|
+
min: 92.5,
|
|
5056
|
+
max: 97.5,
|
|
5057
|
+
symbol: windSymbolDefinitions.ninetyFiveKnots
|
|
5058
|
+
}, {
|
|
5059
|
+
min: 97.5,
|
|
5060
|
+
max: 102.5,
|
|
5061
|
+
symbol: windSymbolDefinitions.hundredKnots
|
|
5062
|
+
}, {
|
|
5063
|
+
min: 102.5,
|
|
5064
|
+
max: 107.5,
|
|
5065
|
+
symbol: windSymbolDefinitions.hundredFiveKnots
|
|
5066
|
+
}, {
|
|
5067
|
+
min: 107.5,
|
|
5068
|
+
max: 112.5,
|
|
5069
|
+
symbol: windSymbolDefinitions.hundredTenKnots
|
|
5070
|
+
}, {
|
|
5071
|
+
min: 112.5,
|
|
5072
|
+
max: 117.5,
|
|
5073
|
+
symbol: windSymbolDefinitions.hundredFifteenKnots
|
|
5074
|
+
}, {
|
|
5075
|
+
min: 117.5,
|
|
5076
|
+
max: 122.5,
|
|
5077
|
+
symbol: windSymbolDefinitions.hundredTwentyKnots
|
|
5078
|
+
}, {
|
|
5079
|
+
min: 122.5,
|
|
5080
|
+
max: 127.5,
|
|
5081
|
+
symbol: windSymbolDefinitions.hundredTwentyFiveKnots
|
|
5082
|
+
}, {
|
|
5083
|
+
min: 127.5,
|
|
5084
|
+
max: 132.5,
|
|
5085
|
+
symbol: windSymbolDefinitions.hundredThirtyKnots
|
|
5086
|
+
}, {
|
|
5087
|
+
min: 132.5,
|
|
5088
|
+
max: 137.5,
|
|
5089
|
+
symbol: windSymbolDefinitions.hundredThirtyFiveKnots
|
|
5090
|
+
}, {
|
|
5091
|
+
min: 137.5,
|
|
5092
|
+
max: 142.5,
|
|
5093
|
+
symbol: windSymbolDefinitions.hundredFortyKnots
|
|
5094
|
+
}, {
|
|
5095
|
+
min: 142.5,
|
|
5096
|
+
max: 147.5,
|
|
5097
|
+
symbol: windSymbolDefinitions.hundredFortyFiveKnots
|
|
5098
|
+
}, {
|
|
5099
|
+
min: 147.5,
|
|
5100
|
+
max: 152,
|
|
5101
|
+
symbol: windSymbolDefinitions.hundredFiftyKnots
|
|
5102
|
+
}];
|
|
5103
|
+
|
|
5104
|
+
/* *
|
|
5105
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5106
|
+
* you may not use this file except in compliance with the License.
|
|
5107
|
+
* You may obtain a copy of the License at
|
|
5108
|
+
*
|
|
5109
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
5110
|
+
*
|
|
5111
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
5112
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
5113
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
5114
|
+
* See the License for the specific language governing permissions and
|
|
5115
|
+
* limitations under the License.
|
|
5116
|
+
*
|
|
5117
|
+
* Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
5118
|
+
* Copyright 2025 - Finnish Meteorological Institute (FMI)
|
|
5119
|
+
* Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
|
|
5120
|
+
* */
|
|
5121
|
+
var MIN_VERTICAL_SCALE = 1;
|
|
5122
|
+
var MAX_VERTICAL_SCALE = 7;
|
|
5123
|
+
var DEFAULT_THINNING_BASE = 1.15;
|
|
5124
|
+
var MIN_THINNING_BASE = 1.08;
|
|
5125
|
+
var EXTRA_REVEAL_EXPONENT = 0.5; // Decrease this number to reveal more barbs earlier as you zoom in
|
|
5126
|
+
var extendIsoBar = function extendIsoBar(path, horizontalBarbMargin) {
|
|
5127
|
+
var match = /^M([\d.-]+),([\d.-]+)\s*L([\d.-]+),([\d.-]+)/.exec(path);
|
|
5128
|
+
if (match) {
|
|
5129
|
+
var startX = parseFloat(match[1]);
|
|
5130
|
+
var startY = parseFloat(match[2]);
|
|
5131
|
+
var endX = parseFloat(match[3]);
|
|
5132
|
+
var endY = parseFloat(match[4]);
|
|
5133
|
+
return "M" + startX + "," + startY + "L" + (endX + horizontalBarbMargin * 3) + "," + endY;
|
|
5134
|
+
}
|
|
5135
|
+
return path;
|
|
5136
|
+
};
|
|
5137
|
+
var extendXAxis = function extendXAxis(path, horizontalBarbMargin) {
|
|
5138
|
+
var match = /^M([\d.-]+),([\d.-]+)H([\d.-]+)/.exec(path);
|
|
5139
|
+
if (match) {
|
|
5140
|
+
var endX = parseFloat(match[3]);
|
|
5141
|
+
return path.replace(/H[\d.-]+/, "H" + (endX + horizontalBarbMargin * 3));
|
|
5142
|
+
}
|
|
5143
|
+
return path;
|
|
5144
|
+
};
|
|
5145
|
+
var drawWindBarbs = function drawWindBarbs(_ref) {
|
|
5146
|
+
var _rootSvg$node;
|
|
5147
|
+
var svgRef = _ref.svgRef,
|
|
5148
|
+
plotGroup = _ref.plotGroup,
|
|
5149
|
+
yScale = _ref.yScale,
|
|
5150
|
+
data = _ref.data,
|
|
5151
|
+
width = _ref.width,
|
|
5152
|
+
margin = _ref.margin,
|
|
5153
|
+
_ref$barbColor = _ref.barbColor,
|
|
5154
|
+
barbColor = _ref$barbColor === void 0 ? 'black' : _ref$barbColor,
|
|
5155
|
+
_ref$columnOffsetX = _ref.columnOffsetX,
|
|
5156
|
+
columnOffsetX = _ref$columnOffsetX === void 0 ? 0 : _ref$columnOffsetX,
|
|
5157
|
+
_ref$verticalScale = _ref.verticalScale,
|
|
5158
|
+
verticalScale = _ref$verticalScale === void 0 ? 1 : _ref$verticalScale;
|
|
5159
|
+
var barbsSize = 40;
|
|
5160
|
+
var scalingFactor = 0.5;
|
|
5161
|
+
var horizontalBarbMargin = barbsSize * scalingFactor + 5;
|
|
5162
|
+
var visibleItems = getVisibleWindItemsForVerticalScale(data, verticalScale).filter(function (item) {
|
|
5163
|
+
return item.pressure >= 150;
|
|
5164
|
+
});
|
|
5165
|
+
// Measure width and height and make extra room for one column
|
|
5166
|
+
// of windbarbs
|
|
5167
|
+
var rootSvg = d3.select(svgRef.current);
|
|
5168
|
+
var currentWidth = (_rootSvg$node = rootSvg.node()) == null ? void 0 : _rootSvg$node.getBoundingClientRect().width;
|
|
5169
|
+
if (!currentWidth) {
|
|
5170
|
+
return;
|
|
5171
|
+
}
|
|
5172
|
+
// Add extra width to isobars in this SVG only.
|
|
5173
|
+
rootSvg.selectAll('path[type="isobar"]').each(function (_d, i, nodes) {
|
|
5174
|
+
var path = d3.select(nodes[i]).attr('d');
|
|
5175
|
+
var newD = extendIsoBar(path, horizontalBarbMargin);
|
|
5176
|
+
d3.select(nodes[i]).attr('d', newD).attr('clip-path', null);
|
|
5177
|
+
});
|
|
5178
|
+
// Add extra width to x-axis in this SVG only.
|
|
5179
|
+
rootSvg.select('g[type="x-axis"] path.domain').each(function (_d, i, nodes) {
|
|
5180
|
+
var path = d3.select(nodes[i]).attr('d');
|
|
5181
|
+
var newD = extendXAxis(path, horizontalBarbMargin);
|
|
5182
|
+
d3.select(nodes[i]).attr('d', newD);
|
|
5183
|
+
});
|
|
5184
|
+
// Expand root SVG width to make room for barbs column at the right
|
|
5185
|
+
rootSvg.attr('width', currentWidth + margin.left + horizontalBarbMargin);
|
|
5186
|
+
// Place the barbs just to the right of the plotting area.
|
|
5187
|
+
// plotGroup's origin is already translated to (margin.left, margin.top),
|
|
5188
|
+
// and its width equals `width`.
|
|
5189
|
+
var windBarbColumnX = width + 5 + columnOffsetX + horizontalBarbMargin;
|
|
5190
|
+
var barbGroup = plotGroup.append('g').attr('class', 'wind-group').attr('transform', // Apply translation and counter-scale to maintain aspect ratio during vertical zoom.
|
|
5191
|
+
// The counter-scale (1, 1/verticalScale) undoes the parent's vertical scaling.
|
|
5192
|
+
"translate(" + windBarbColumnX + ", 0) scale(1, " + 1 / verticalScale + ")");
|
|
5193
|
+
barbGroup.selectAll('g').data(visibleItems).enter().append('g').attr('id', 'wind-barb').each(function handleBarb(data) {
|
|
5194
|
+
var group = d3.select(this);
|
|
5195
|
+
var windSymbol = getWindSymbol(data.windSpeed);
|
|
5196
|
+
if (windSymbol) {
|
|
5197
|
+
var _innerGroup$node;
|
|
5198
|
+
// Inner group will have rotation and scaling applied to it
|
|
5199
|
+
var innerGroup = group.append('g');
|
|
5200
|
+
(_innerGroup$node = innerGroup.node()) == null || _innerGroup$node.appendChild(windSymbol);
|
|
5201
|
+
// Update stroke color
|
|
5202
|
+
innerGroup.selectAll('*').attr('stroke', barbColor);
|
|
5203
|
+
// Only update the fill for the paths that already used a fill
|
|
5204
|
+
// in their original svg form.
|
|
5205
|
+
innerGroup.selectAll('*').each(function (_d, i, nodes) {
|
|
5206
|
+
var el = d3.select(nodes[i]);
|
|
5207
|
+
var currentFill = el.attr('fill');
|
|
5208
|
+
if (currentFill && currentFill !== 'none') {
|
|
5209
|
+
el.attr('fill', barbColor);
|
|
5210
|
+
}
|
|
5211
|
+
});
|
|
5212
|
+
var bbox = windSymbol.getBBox();
|
|
5213
|
+
// Central point
|
|
5214
|
+
var cx = bbox.x + bbox.width / 2;
|
|
5215
|
+
var cy = bbox.y + bbox.height / 2;
|
|
5216
|
+
var rotation = 180 + data.windDirection;
|
|
5217
|
+
var y = yScale(data.pressure);
|
|
5218
|
+
// Place items in the correct vertical position.
|
|
5219
|
+
// Apply verticalScale to compensate for the parent's counter-scale,
|
|
5220
|
+
// ensuring barbs appear at the correct zoomed Y position.
|
|
5221
|
+
group.attr('transform', "translate(0, " + (y - barbsSize * scalingFactor / 8) * verticalScale + ")");
|
|
5222
|
+
// Rotate accordingly, and scale
|
|
5223
|
+
innerGroup.attr('transform', "rotate(" + rotation + ") scale(" + scalingFactor + ") translate(" + -cx + ", " + -cy + ")");
|
|
5224
|
+
}
|
|
5225
|
+
});
|
|
5226
|
+
};
|
|
5227
|
+
var removeItemsExponential = function removeItemsExponential(array, base) {
|
|
5228
|
+
if (base === void 0) {
|
|
5229
|
+
base = DEFAULT_THINNING_BASE;
|
|
5230
|
+
}
|
|
5231
|
+
var indicesToKeep = [];
|
|
5232
|
+
var i = 0;
|
|
5233
|
+
var nextIndex = 0;
|
|
5234
|
+
while (nextIndex < array.length) {
|
|
5235
|
+
nextIndex = Math.floor(Math.pow(base, i));
|
|
5236
|
+
indicesToKeep.push(nextIndex);
|
|
5237
|
+
i += 1;
|
|
5238
|
+
}
|
|
5239
|
+
return array.filter(function (_, index) {
|
|
5240
|
+
return indicesToKeep.includes(index);
|
|
5241
|
+
});
|
|
5242
|
+
};
|
|
5243
|
+
var getVisibleWindItemsForVerticalScale = function getVisibleWindItemsForVerticalScale(data, verticalScale) {
|
|
5244
|
+
var reversedData = [].concat(data).reverse();
|
|
5245
|
+
var baselineItems = removeItemsExponential(reversedData);
|
|
5246
|
+
var maxDetailItems = removeItemsExponential(reversedData, MIN_THINNING_BASE);
|
|
5247
|
+
var baselineSet = new Set(baselineItems);
|
|
5248
|
+
var maxDetailSet = new Set(maxDetailItems);
|
|
5249
|
+
// Candidate additions are fixed and ordered; zooming in reveals a prefix only.
|
|
5250
|
+
var extraCandidates = reversedData.filter(function (item) {
|
|
5251
|
+
return maxDetailSet.has(item) && !baselineSet.has(item);
|
|
5252
|
+
});
|
|
5253
|
+
var clampedScale = Math.max(MIN_VERTICAL_SCALE, Math.min(MAX_VERTICAL_SCALE, verticalScale));
|
|
5254
|
+
var normalizedScale = (clampedScale - MIN_VERTICAL_SCALE) / (MAX_VERTICAL_SCALE - MIN_VERTICAL_SCALE);
|
|
5255
|
+
// Use a front-loaded curve so extra barbs appear earlier when zooming in,
|
|
5256
|
+
// while still keeping zoom level 1 unchanged and monotonic.
|
|
5257
|
+
var revealProgress = Math.pow(normalizedScale, EXTRA_REVEAL_EXPONENT);
|
|
5258
|
+
var extraCount = Math.floor(revealProgress * extraCandidates.length);
|
|
5259
|
+
var extraSet = new Set(extraCandidates.slice(0, extraCount));
|
|
5260
|
+
return reversedData.filter(function (item) {
|
|
5261
|
+
return baselineSet.has(item) || extraSet.has(item);
|
|
5262
|
+
});
|
|
5263
|
+
};
|
|
5264
|
+
var getWindSymbol = function getWindSymbol(value) {
|
|
5265
|
+
var matchedRange = windSpeedRanges.find(function (_ref2) {
|
|
5266
|
+
var min = _ref2.min,
|
|
5267
|
+
max = _ref2.max;
|
|
5268
|
+
return value >= min && value < max;
|
|
5269
|
+
});
|
|
5270
|
+
// Out of range
|
|
5271
|
+
if (!matchedRange) {
|
|
5272
|
+
return null;
|
|
5273
|
+
}
|
|
5274
|
+
// SVG string to actual SVG element
|
|
5275
|
+
var parser = new DOMParser();
|
|
5276
|
+
var svgDoc = parser.parseFromString(matchedRange.symbol, 'image/svg+xml');
|
|
5277
|
+
var svgNode = svgDoc.documentElement;
|
|
5278
|
+
// Return the parsed SVG node
|
|
5279
|
+
return svgNode;
|
|
5280
|
+
};
|
|
5281
|
+
|
|
5282
|
+
var shadow$1 = '0 1px 5px 0 rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.12), 0 2px 4px 0 rgba(0, 0, 0, 0.14)';
|
|
5283
|
+
var soundingsStyle$1 = {
|
|
5284
|
+
tooltip: {
|
|
5285
|
+
display: 'block',
|
|
5286
|
+
position: 'absolute',
|
|
5287
|
+
borderRadius: '1.5px',
|
|
5288
|
+
backgroundColor: 'geowebColors.soundings.tooltip.background',
|
|
5289
|
+
boxShadow: shadow$1,
|
|
5290
|
+
padding: '2px 4px',
|
|
5291
|
+
pointerEvents: 'none',
|
|
5292
|
+
zIndex: 500
|
|
5293
|
+
},
|
|
5294
|
+
pressure: {
|
|
5295
|
+
fontSize: '10px'
|
|
5296
|
+
},
|
|
5297
|
+
temperature: {
|
|
5298
|
+
fontSize: '12px',
|
|
5299
|
+
fontWeight: 'bold'
|
|
5300
|
+
},
|
|
5301
|
+
dewPoint: {
|
|
5302
|
+
fontSize: '12px',
|
|
5303
|
+
fontWeight: 'bold'
|
|
5304
|
+
}};
|
|
5305
|
+
var updateTransformToViewport = function updateTransformToViewport(transform, width, height) {
|
|
5306
|
+
var minX = width * (1 - transform.k);
|
|
5307
|
+
var minY = height * (1 - transform.k);
|
|
5308
|
+
return d3.zoomIdentity.translate(Math.min(0, Math.max(minX, transform.x)), Math.min(0, Math.max(minY, transform.y))).scale(transform.k);
|
|
5309
|
+
};
|
|
5310
|
+
var Soundings = function Soundings(_ref) {
|
|
5311
|
+
var d3GraphId = _ref.d3GraphId,
|
|
5312
|
+
data = _ref.data,
|
|
5313
|
+
svgDimensions = _ref.svgDimensions,
|
|
5314
|
+
_ref$showTooltip = _ref.showTooltip,
|
|
5315
|
+
showTooltip = _ref$showTooltip === void 0 ? true : _ref$showTooltip,
|
|
5316
|
+
_ref$diagramType = _ref.diagramType,
|
|
5317
|
+
diagramType = _ref$diagramType === void 0 ? 'SKEWT' : _ref$diagramType;
|
|
5318
|
+
var instanceId = useId().replace(/:/g, '_');
|
|
5319
|
+
var scopedGraphId = d3GraphId + "-" + instanceId;
|
|
5320
|
+
var svgRef = useRef(null);
|
|
5321
|
+
var canvasRef = useRef(null);
|
|
5322
|
+
var pressureRef = useRef(null);
|
|
5323
|
+
var tempRef = useRef(null);
|
|
5324
|
+
var dewpointRef = useRef(null);
|
|
5325
|
+
// Refs to store current scale/data for shared mouse effect
|
|
5326
|
+
var yScaleRef = useRef(null);
|
|
5327
|
+
var marginRef = useRef(null);
|
|
5328
|
+
var widthRef = useRef(0);
|
|
5329
|
+
var svgRectRef = useRef(null);
|
|
5330
|
+
var tooltipDataRef = useRef(null);
|
|
5331
|
+
var zoomBehaviorRef = useRef(null);
|
|
5332
|
+
// Keep zoom target on the inner translated <g>; Soundings and WindBarbs must
|
|
5333
|
+
// transform the same coordinate space to stay aligned.
|
|
5334
|
+
var zoomTargetRef = useRef(null);
|
|
5335
|
+
var isApplyingSharedZoomRef = useRef(false);
|
|
5336
|
+
// Keep the last applied d3 zoom transform across SVG redraws.
|
|
5337
|
+
// Width/height changes recreate the chart, so this ref prevents zoom snapping
|
|
5338
|
+
// back to identity when panels are closed/resized.
|
|
5339
|
+
var persistedZoomTransformRef = useRef(d3.zoomIdentity);
|
|
5340
|
+
var previousDiagramTypeRef = useRef(null);
|
|
5341
|
+
var _useSharedMouseY = useSharedMouseY(),
|
|
5342
|
+
clientY = _useSharedMouseY.clientY,
|
|
5343
|
+
publishVerticalZoom = _useSharedMouseY.publishVerticalZoom,
|
|
5344
|
+
verticalZoom = _useSharedMouseY.verticalZoom,
|
|
5345
|
+
resetVerticalZoom = _useSharedMouseY.resetVerticalZoom;
|
|
5346
|
+
// Set SVG dimensions (required props; no optional chaining needed)
|
|
5347
|
+
var baseWidth = svgDimensions.width,
|
|
5348
|
+
baseHeight = svgDimensions.height,
|
|
5349
|
+
margin = svgDimensions.margin;
|
|
5350
|
+
var width = baseWidth - (margin.left + margin.right);
|
|
5351
|
+
var height = baseHeight - (margin.top + margin.bottom);
|
|
5352
|
+
useEffect(function () {
|
|
5353
|
+
if (!svgRef.current || width <= 0 || height <= 0) {
|
|
5354
|
+
return;
|
|
5355
|
+
}
|
|
5356
|
+
var isDiagramTypeChange = previousDiagramTypeRef.current !== null && previousDiagramTypeRef.current !== diagramType;
|
|
5357
|
+
if (isDiagramTypeChange) {
|
|
5358
|
+
persistedZoomTransformRef.current = d3.zoomIdentity;
|
|
5359
|
+
resetVerticalZoom(scopedGraphId);
|
|
5360
|
+
}
|
|
5361
|
+
var root = d3.select(svgRef.current);
|
|
5362
|
+
root.selectAll('*').remove();
|
|
5363
|
+
var svg = initializeSvg$1({
|
|
5364
|
+
svgRef: svgRef,
|
|
5365
|
+
width: width,
|
|
5366
|
+
height: height,
|
|
5367
|
+
margin: margin,
|
|
5368
|
+
diagramType: diagramType,
|
|
5369
|
+
d3GraphId: scopedGraphId
|
|
5370
|
+
});
|
|
5371
|
+
// Create a separate layer for axes so they can stay visible above the zoomed content.
|
|
5372
|
+
var axisLayer = svg.append('g').attr('data-layer', 'axis-layer');
|
|
5373
|
+
// Keep a static viewport group for clipping, and transform only the inner
|
|
5374
|
+
// content group during zoom so the visible area stays fixed.
|
|
5375
|
+
var zoomViewport = svg.append('g').attr('data-layer', 'zoom-viewport').attr('clip-path', "url(#clip-" + scopedGraphId + "-" + diagramType + "d3)");
|
|
5376
|
+
var zoomContent = zoomViewport.append('g').attr('data-layer', 'zoom-content');
|
|
5377
|
+
var bijvoetLabelLayer = svg.append('g').attr('data-layer', 'bijvoet-label-layer').style('pointer-events', 'none');
|
|
5378
|
+
var svgRectangle = svgRef.current.getBoundingClientRect();
|
|
5379
|
+
svgRectRef.current = svgRectangle;
|
|
5380
|
+
marginRef.current = margin;
|
|
5381
|
+
widthRef.current = width;
|
|
5382
|
+
var minT = diagramType === 'EMAGRAM' ? minEmagramTemperature : minTemperature;
|
|
5383
|
+
var maxT = maxTemperature;
|
|
5384
|
+
var _createScales = createScales$1(diagramType, width, height, minPressure, maxPressure, minT, maxT),
|
|
5385
|
+
xScale = _createScales[0],
|
|
5386
|
+
yScale = _createScales[1];
|
|
5387
|
+
yScaleRef.current = yScale;
|
|
5388
|
+
var applyAxisClips = function applyAxisClips() {
|
|
5389
|
+
axisLayer.select('g[type="x-axis"] path.domain').attr('d', "M0.5,0.5H" + (width + 0.5));
|
|
5390
|
+
axisLayer.select('g[type="x-axis"]').attr('clip-path', "url(#clip-" + scopedGraphId + "-" + diagramType + "x-axis)");
|
|
5391
|
+
axisLayer.select('g[type="y-axis"]').attr('clip-path', "url(#clip-" + scopedGraphId + "-" + diagramType + "y-axis)");
|
|
5392
|
+
};
|
|
5393
|
+
drawAxes$1({
|
|
5394
|
+
svg: axisLayer,
|
|
5395
|
+
xScale: xScale,
|
|
5396
|
+
yScale: yScale,
|
|
5397
|
+
height: height,
|
|
5398
|
+
diagramType: diagramType
|
|
5399
|
+
});
|
|
5400
|
+
applyAxisClips();
|
|
5401
|
+
drawStaticLines({
|
|
5402
|
+
diagramType: diagramType,
|
|
5403
|
+
dp: dp,
|
|
5404
|
+
staticPressureArray: staticPressureArray,
|
|
5405
|
+
minTemperature: minT,
|
|
5406
|
+
maxTemperature: maxT,
|
|
5407
|
+
height: height,
|
|
5408
|
+
width: width,
|
|
5409
|
+
xScale: xScale,
|
|
5410
|
+
yScale: yScale,
|
|
5411
|
+
minPressure: minPressure,
|
|
5412
|
+
maxPressure: maxPressure,
|
|
5413
|
+
svg: zoomContent,
|
|
5414
|
+
bijvoetLabelSvg: bijvoetLabelLayer,
|
|
5415
|
+
d3GraphId: scopedGraphId
|
|
5416
|
+
});
|
|
5417
|
+
data.forEach(function (features, index) {
|
|
5418
|
+
var color = SOUNDING_COLORS[index] || SOUNDING_COLORS[0];
|
|
5419
|
+
var temperatureValues = features.map(function (feature) {
|
|
4875
5420
|
return feature.properties.temp;
|
|
4876
5421
|
});
|
|
4877
5422
|
var pressureValues = features.map(function (feature) {
|
|
@@ -4882,10 +5427,11 @@ var Soundings = function Soundings(_ref) {
|
|
|
4882
5427
|
pressureValues: pressureValues,
|
|
4883
5428
|
color: color,
|
|
4884
5429
|
lineStyle: 'none',
|
|
5430
|
+
d3GraphId: scopedGraphId,
|
|
4885
5431
|
xScale: xScale,
|
|
4886
5432
|
yScale: yScale,
|
|
4887
5433
|
height: height,
|
|
4888
|
-
svg:
|
|
5434
|
+
svg: zoomContent,
|
|
4889
5435
|
diagramType: diagramType
|
|
4890
5436
|
});
|
|
4891
5437
|
var dewpointValues = features.map(function (feature) {
|
|
@@ -4896,20 +5442,89 @@ var Soundings = function Soundings(_ref) {
|
|
|
4896
5442
|
pressureValues: pressureValues,
|
|
4897
5443
|
color: color,
|
|
4898
5444
|
lineStyle: '8, 2',
|
|
5445
|
+
d3GraphId: scopedGraphId,
|
|
4899
5446
|
xScale: xScale,
|
|
4900
5447
|
yScale: yScale,
|
|
4901
5448
|
height: height,
|
|
4902
|
-
svg:
|
|
5449
|
+
svg: zoomContent,
|
|
4903
5450
|
diagramType: diagramType
|
|
4904
5451
|
});
|
|
4905
5452
|
});
|
|
4906
5453
|
tooltipDataRef.current = constructTooltipData(data);
|
|
4907
|
-
var
|
|
4908
|
-
|
|
5454
|
+
var zoomTarget = zoomContent.node();
|
|
5455
|
+
if (!zoomTarget) {
|
|
5456
|
+
return;
|
|
5457
|
+
}
|
|
5458
|
+
zoomTargetRef.current = zoomTarget;
|
|
5459
|
+
var bijvoetLabelTarget = bijvoetLabelLayer.node();
|
|
5460
|
+
if (!bijvoetLabelTarget) {
|
|
5461
|
+
return;
|
|
5462
|
+
}
|
|
5463
|
+
var applyZoomTransform = function applyZoomTransform(transform) {
|
|
5464
|
+
d3.select(zoomTarget).attr('transform', transform.toString());
|
|
5465
|
+
d3.select(bijvoetLabelTarget).attr('transform', transform.toString());
|
|
5466
|
+
};
|
|
5467
|
+
// Allow zooming and panning
|
|
5468
|
+
var zoomBehavior = d3.zoom().scaleExtent([MIN_VERTICAL_SCALE, MAX_VERTICAL_SCALE]).extent([[0, 0], [width, height]]).translateExtent([[0, 0], [width, height]]).on('zoom', function (event) {
|
|
5469
|
+
// Persist every interactive zoom/pan event so the transform can be
|
|
5470
|
+
// restored after dimension-driven rerenders.
|
|
5471
|
+
persistedZoomTransformRef.current = event.transform;
|
|
5472
|
+
applyZoomTransform(event.transform);
|
|
5473
|
+
var zoomedXScale = event.transform.rescaleX(xScale);
|
|
5474
|
+
var zoomedYScale = event.transform.rescaleY(yScale);
|
|
5475
|
+
var axisXScale = diagramType === 'SKEWT' ? xScale.copy().range(xScale.range().map(function (xValue) {
|
|
5476
|
+
// Skew-T X uses x + (height - y). To keep tick labels tied to
|
|
5477
|
+
// isotherm intersections on the bottom axis, apply the same
|
|
5478
|
+
// transformed bottom-edge offset to the axis scale.
|
|
5479
|
+
var skewBottomOffset = (event.transform.k - 1) * height + event.transform.y;
|
|
5480
|
+
return event.transform.k * xValue + event.transform.x + skewBottomOffset;
|
|
5481
|
+
})) : zoomedXScale;
|
|
5482
|
+
var axisYScale = diagramType === 'BIJVOET' ? yScale.copy().range(yScale.range().map(function (yValue) {
|
|
5483
|
+
return event.transform.k * yValue + event.transform.y;
|
|
5484
|
+
})) : zoomedYScale;
|
|
5485
|
+
axisLayer.selectAll('*').remove();
|
|
5486
|
+
drawAxes$1({
|
|
5487
|
+
svg: axisLayer,
|
|
5488
|
+
xScale: axisXScale,
|
|
5489
|
+
yScale: axisYScale,
|
|
5490
|
+
height: height,
|
|
5491
|
+
diagramType: diagramType
|
|
5492
|
+
});
|
|
5493
|
+
applyAxisClips();
|
|
5494
|
+
if (!isApplyingSharedZoomRef.current) {
|
|
5495
|
+
publishVerticalZoom(scopedGraphId, event.transform.k, event.transform.y);
|
|
5496
|
+
}
|
|
5497
|
+
});
|
|
5498
|
+
zoomBehaviorRef.current = zoomBehavior;
|
|
5499
|
+
svg.call(zoomBehavior);
|
|
5500
|
+
var previousTransform = updateTransformToViewport(persistedZoomTransformRef.current, width, height);
|
|
5501
|
+
var hasPersistedTransform = previousTransform.k > 1 || Math.abs(previousTransform.x) > 1e-3 || Math.abs(previousTransform.y) > 1e-3;
|
|
5502
|
+
// Re-apply the previous transform after rebuilding the SVG so resize
|
|
5503
|
+
// operations preserve the current zoom level/pan offset.
|
|
5504
|
+
if (hasPersistedTransform) {
|
|
5505
|
+
isApplyingSharedZoomRef.current = true;
|
|
5506
|
+
svg.call(zoomBehavior.transform, previousTransform);
|
|
5507
|
+
isApplyingSharedZoomRef.current = false;
|
|
5508
|
+
}
|
|
5509
|
+
// Keep shared zoom state aligned with the effective transform that was
|
|
5510
|
+
// restored after resize so companion panels (WindBarbs) do not wait for the
|
|
5511
|
+
// next interactive zoom event.
|
|
5512
|
+
publishVerticalZoom(scopedGraphId, previousTransform.k, previousTransform.y);
|
|
5513
|
+
previousDiagramTypeRef.current = diagramType;
|
|
5514
|
+
// eslint-disable-next-line consistent-return
|
|
4909
5515
|
return function () {
|
|
4910
|
-
d3
|
|
5516
|
+
// Read the transform directly from d3's internal zoom state before this
|
|
5517
|
+
// chart instance is torn down, then reuse it on the next mount pass.
|
|
5518
|
+
var zoomState = zoomTarget.__zoom;
|
|
5519
|
+
if (zoomState) {
|
|
5520
|
+
persistedZoomTransformRef.current = zoomState;
|
|
5521
|
+
}
|
|
5522
|
+
svg.on('zoom', null);
|
|
5523
|
+
zoomBehaviorRef.current = null;
|
|
5524
|
+
zoomTargetRef.current = null;
|
|
5525
|
+
root.selectAll('*').remove();
|
|
4911
5526
|
};
|
|
4912
|
-
}, [data, diagramType, width, height, scopedGraphId, margin]);
|
|
5527
|
+
}, [data, diagramType, width, height, scopedGraphId, margin, publishVerticalZoom, resetVerticalZoom]);
|
|
4913
5528
|
useEffect(function () {
|
|
4914
5529
|
var _svgRectRef$current;
|
|
4915
5530
|
if (!showTooltip || !svgRef.current) {
|
|
@@ -4925,477 +5540,230 @@ var Soundings = function Soundings(_ref) {
|
|
|
4925
5540
|
dewpointRef.current && (dewpointRef.current.style.display = 'none');
|
|
4926
5541
|
return;
|
|
4927
5542
|
}
|
|
4928
|
-
if (!yScaleRef.current || !marginRef.current || !tooltipDataRef.current) {
|
|
4929
|
-
return;
|
|
4930
|
-
}
|
|
4931
|
-
// Synthetic event with shared clientY
|
|
4932
|
-
var synthetic = {
|
|
4933
|
-
clientX: rect.left + rect.width / 2,
|
|
4934
|
-
clientY: clientY,
|
|
4935
|
-
pageY: clientY + window.scrollY,
|
|
4936
|
-
target: svgRef.current,
|
|
4937
|
-
currentTarget: svgRef.current
|
|
4938
|
-
};
|
|
4939
|
-
var pressureRefd3 = d3.select(pressureRef.current);
|
|
4940
|
-
var tempRefd3 = d3.select(tempRef.current);
|
|
4941
|
-
var dewpointRefd3 = d3.select(dewpointRef.current);
|
|
4942
|
-
var minT = diagramType === 'EMAGRAM' ? minEmagramTemperature : minTemperature;
|
|
4943
|
-
var maxT = maxTemperature;
|
|
4944
|
-
var _createScales2 = createScales$1(diagramType, width, height, minPressure, maxPressure, minT, maxT),
|
|
4945
|
-
yScale = _createScales2[1];
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
}), jsx(Box, {
|
|
4967
|
-
"data-testid": "pressure-tooltip",
|
|
4968
|
-
ref: pressureRef,
|
|
4969
|
-
sx: Object.assign({}, soundingsStyle$1.tooltip, soundingsStyle$1.pressure)
|
|
4970
|
-
}), jsx(Box, {
|
|
4971
|
-
"data-testid": "temperature-tooltip",
|
|
4972
|
-
ref: tempRef,
|
|
4973
|
-
sx: Object.assign({}, soundingsStyle$1.tooltip, soundingsStyle$1.temperature)
|
|
4974
|
-
}), jsx(Box, {
|
|
4975
|
-
"data-testid": "dewpoint-tooltip",
|
|
4976
|
-
ref: dewpointRef,
|
|
4977
|
-
sx: Object.assign({}, soundingsStyle$1.tooltip, soundingsStyle$1.dewPoint)
|
|
4978
|
-
})]
|
|
4979
|
-
});
|
|
4980
|
-
};
|
|
4981
|
-
|
|
4982
|
-
var TIMESLIDER_HEIGHT = 135;
|
|
4983
|
-
var LABEL_MIN_WIDTH = 48;
|
|
4984
|
-
var useMaxLabelCount = function useMaxLabelCount(ref) {
|
|
4985
|
-
var _React$useState = React.useState(0),
|
|
4986
|
-
width = _React$useState[0],
|
|
4987
|
-
setWidth = _React$useState[1];
|
|
4988
|
-
React.useLayoutEffect(function () {
|
|
4989
|
-
var resizeObserver;
|
|
4990
|
-
if (ref.current) {
|
|
4991
|
-
resizeObserver = new ResizeObserver(function (entry) {
|
|
4992
|
-
var _entry$0$target$getBo = entry[0].target.getBoundingClientRect(),
|
|
4993
|
-
width = _entry$0$target$getBo.width;
|
|
4994
|
-
setWidth(width);
|
|
4995
|
-
});
|
|
4996
|
-
resizeObserver.observe(ref.current);
|
|
4997
|
-
}
|
|
4998
|
-
return function () {
|
|
4999
|
-
if (resizeObserver) {
|
|
5000
|
-
resizeObserver.disconnect();
|
|
5001
|
-
}
|
|
5002
|
-
};
|
|
5003
|
-
}, [ref]);
|
|
5004
|
-
var maxLabelCount = Math.max(1, Math.floor(width / LABEL_MIN_WIDTH));
|
|
5005
|
-
return maxLabelCount;
|
|
5006
|
-
};
|
|
5007
|
-
var shouldHideLabel = function shouldHideLabel(nItems, index, maxLabelCount) {
|
|
5008
|
-
var nthLabelsToShow = Math.ceil(nItems / maxLabelCount);
|
|
5009
|
-
return nItems > maxLabelCount &&
|
|
5010
|
-
// hide labels if too many items
|
|
5011
|
-
index !== nItems - 1 && (
|
|
5012
|
-
// not last item (always shown)
|
|
5013
|
-
// only show every nth label, skip label within last n/2 items so end doesn't get cluttered
|
|
5014
|
-
index % nthLabelsToShow !== 0 || nItems - 1 - index < nthLabelsToShow / 2);
|
|
5015
|
-
};
|
|
5016
|
-
var SoundingsTimeSlider = function SoundingsTimeSlider(_ref) {
|
|
5017
|
-
var timesteps = _ref.timesteps,
|
|
5018
|
-
selectedTime = _ref.selectedTime,
|
|
5019
|
-
updateSelectedTime = _ref.updateSelectedTime;
|
|
5020
|
-
var sliderRef = React.useRef(null);
|
|
5021
|
-
var maxLabelCount = useMaxLabelCount(sliderRef);
|
|
5022
|
-
var _useSoundingsTranslat = useSoundingsTranslation(),
|
|
5023
|
-
i18n = _useSoundingsTranslat.i18n;
|
|
5024
|
-
var marks = timesteps.filter(function (date) {
|
|
5025
|
-
return dateUtils.isValidIsoDateString(date);
|
|
5026
|
-
}).map(function (date, index, arr) {
|
|
5027
|
-
return {
|
|
5028
|
-
value: dateUtils.unix(dateUtils.getUtcFromString(date)),
|
|
5029
|
-
label: shouldHideLabel(arr.length, index, maxLabelCount) ? '' : dateUtils.dateToString(dateUtils.getUtcFromString(date), 'iii d. HH:mm', true, i18n.language)
|
|
5030
|
-
};
|
|
5031
|
-
});
|
|
5032
|
-
var currentTimeIndex = React.useMemo(function () {
|
|
5033
|
-
if (timesteps.length === 0) {
|
|
5034
|
-
return -1;
|
|
5035
|
-
}
|
|
5036
|
-
var selectedUtc = dateUtils.getUtcFromString(selectedTime);
|
|
5037
|
-
if (!selectedUtc) {
|
|
5038
|
-
return 0;
|
|
5039
|
-
}
|
|
5040
|
-
var selectedUnix = dateUtils.unix(selectedUtc);
|
|
5041
|
-
var indexByExactTimestamp = timesteps.findIndex(function (time) {
|
|
5042
|
-
var utcTime = dateUtils.getUtcFromString(time);
|
|
5043
|
-
if (!utcTime) {
|
|
5044
|
-
return false;
|
|
5045
|
-
}
|
|
5046
|
-
return dateUtils.unix(utcTime) === selectedUnix;
|
|
5047
|
-
});
|
|
5048
|
-
if (indexByExactTimestamp !== -1) {
|
|
5049
|
-
return indexByExactTimestamp;
|
|
5050
|
-
}
|
|
5051
|
-
var indexByExactString = timesteps.findIndex(function (time) {
|
|
5052
|
-
return time === selectedTime;
|
|
5053
|
-
});
|
|
5054
|
-
if (indexByExactString !== -1) {
|
|
5055
|
-
return indexByExactString;
|
|
5056
|
-
}
|
|
5057
|
-
// If selected time is not a sounding timestep, anchor on the nearest timestep
|
|
5058
|
-
// so forward/backward navigation continues from the expected point in time.
|
|
5059
|
-
return timesteps.reduce(function (nearestIndex, time, index) {
|
|
5060
|
-
var utcTime = dateUtils.getUtcFromString(time);
|
|
5061
|
-
if (!utcTime) {
|
|
5062
|
-
return nearestIndex;
|
|
5063
|
-
}
|
|
5064
|
-
var currentDiff = Math.abs(dateUtils.unix(utcTime) - selectedUnix);
|
|
5065
|
-
var nearestUtc = dateUtils.getUtcFromString(timesteps[nearestIndex]);
|
|
5066
|
-
if (!nearestUtc) {
|
|
5067
|
-
return index;
|
|
5068
|
-
}
|
|
5069
|
-
var nearestDiff = Math.abs(dateUtils.unix(nearestUtc) - selectedUnix);
|
|
5070
|
-
return currentDiff < nearestDiff ? index : nearestIndex;
|
|
5071
|
-
}, 0);
|
|
5072
|
-
}, [selectedTime, timesteps]);
|
|
5073
|
-
var onStepBackward = React.useCallback(function () {
|
|
5074
|
-
var precedingIndex = Math.max(currentTimeIndex - 1, 0);
|
|
5075
|
-
updateSelectedTime(timesteps[precedingIndex]);
|
|
5076
|
-
}, [currentTimeIndex, updateSelectedTime, timesteps]);
|
|
5077
|
-
var onStepForward = React.useCallback(function () {
|
|
5078
|
-
var followingIndex = Math.min(currentTimeIndex + 1, timesteps.length - 1);
|
|
5079
|
-
updateSelectedTime(timesteps[followingIndex]);
|
|
5080
|
-
}, [currentTimeIndex, updateSelectedTime, timesteps]);
|
|
5081
|
-
return jsxs("div", {
|
|
5082
|
-
ref: sliderRef,
|
|
5083
|
-
style: {
|
|
5084
|
-
display: 'flex',
|
|
5085
|
-
paddingTop: '32px',
|
|
5086
|
-
marginRight: '80px',
|
|
5087
|
-
marginLeft: '24px',
|
|
5088
|
-
height: TIMESLIDER_HEIGHT + "px"
|
|
5543
|
+
if (!yScaleRef.current || !marginRef.current || !tooltipDataRef.current) {
|
|
5544
|
+
return;
|
|
5545
|
+
}
|
|
5546
|
+
// Synthetic event with shared clientY
|
|
5547
|
+
var synthetic = {
|
|
5548
|
+
clientX: rect.left + rect.width / 2,
|
|
5549
|
+
clientY: clientY,
|
|
5550
|
+
pageY: clientY + window.scrollY,
|
|
5551
|
+
target: svgRef.current,
|
|
5552
|
+
currentTarget: svgRef.current
|
|
5553
|
+
};
|
|
5554
|
+
var pressureRefd3 = d3.select(pressureRef.current);
|
|
5555
|
+
var tempRefd3 = d3.select(tempRef.current);
|
|
5556
|
+
var dewpointRefd3 = d3.select(dewpointRef.current);
|
|
5557
|
+
var minT = diagramType === 'EMAGRAM' ? minEmagramTemperature : minTemperature;
|
|
5558
|
+
var maxT = maxTemperature;
|
|
5559
|
+
var _createScales2 = createScales$1(diagramType, width, height, minPressure, maxPressure, minT, maxT),
|
|
5560
|
+
yScale = _createScales2[1];
|
|
5561
|
+
var pointerY = clientY - rect.top - marginRef.current.top;
|
|
5562
|
+
var unscaledY = (pointerY - verticalZoom.y) / verticalZoom.scale;
|
|
5563
|
+
var hoveredPressure = extractPressureFromY(diagramType, unscaledY, yScale);
|
|
5564
|
+
drawSoundingsTooltip({
|
|
5565
|
+
event: synthetic,
|
|
5566
|
+
svgRectangle: rect,
|
|
5567
|
+
margin: marginRef.current,
|
|
5568
|
+
width: widthRef.current,
|
|
5569
|
+
hoveredPressure: hoveredPressure,
|
|
5570
|
+
pressureRefd3: pressureRefd3,
|
|
5571
|
+
tempRefd3: tempRefd3,
|
|
5572
|
+
dewpointRefd3: dewpointRefd3,
|
|
5573
|
+
tooltipData: tooltipDataRef.current,
|
|
5574
|
+
diagramType: diagramType
|
|
5575
|
+
});
|
|
5576
|
+
}, [clientY, showTooltip, diagramType, data, width, height, verticalZoom.scale, verticalZoom.y]);
|
|
5577
|
+
return jsxs(Box, {
|
|
5578
|
+
ref: canvasRef,
|
|
5579
|
+
sx: {
|
|
5580
|
+
position: 'relative'
|
|
5089
5581
|
},
|
|
5090
|
-
children: [
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
onClickBFButton: onStepForward
|
|
5105
|
-
})]
|
|
5106
|
-
}), marks.length === 0 ? jsx(CustomSlider, {
|
|
5107
|
-
disabled: true,
|
|
5108
|
-
max: 1,
|
|
5109
|
-
min: 0,
|
|
5110
|
-
orientation: "horizontal",
|
|
5111
|
-
value: 0.5
|
|
5112
|
-
}) : jsx(CustomSlider, {
|
|
5113
|
-
extraStyles: {
|
|
5114
|
-
margin: '0px 20px 0px 20px',
|
|
5115
|
-
'.MuiSlider-markLabel': {
|
|
5116
|
-
transform: 'translate(-90%, 20px) rotate(-45deg)',
|
|
5117
|
-
transformOrigin: 'top center'
|
|
5118
|
-
}
|
|
5119
|
-
},
|
|
5120
|
-
marks: marks,
|
|
5121
|
-
max: marks[marks.length - 1].value,
|
|
5122
|
-
min: marks[0].value,
|
|
5123
|
-
onChange: function onChange(_, value) {
|
|
5124
|
-
updateSelectedTime(dateUtils.fromUnix(value).toISOString());
|
|
5125
|
-
},
|
|
5126
|
-
orientation: "horizontal",
|
|
5127
|
-
slotProps: {
|
|
5128
|
-
// Workaround for MUI bug where labels are just draggable area and clicking on one
|
|
5129
|
-
// does not necessarily select the described timestep
|
|
5130
|
-
markLabel: {
|
|
5131
|
-
onPointerDown: function onPointerDown(event) {
|
|
5132
|
-
event.preventDefault();
|
|
5133
|
-
var markIndex = event.currentTarget.getAttribute('data-index');
|
|
5134
|
-
var mark = marks[Number(markIndex)];
|
|
5135
|
-
var value = mark.value;
|
|
5136
|
-
updateSelectedTime(dateUtils.fromUnix(value).toISOString());
|
|
5137
|
-
}
|
|
5138
|
-
}
|
|
5139
|
-
},
|
|
5140
|
-
step: null,
|
|
5141
|
-
value: dateUtils.unix(dateUtils.getUtcFromString(selectedTime)),
|
|
5142
|
-
valueLabelDisplay: "on",
|
|
5143
|
-
valueLabelFormat: function valueLabelFormat(value) {
|
|
5144
|
-
return dateUtils.dateToString(dateUtils.fromUnix(value), "yyyy iii dd MMM HH:mm 'UTC'", true, i18n.language);
|
|
5145
|
-
}
|
|
5582
|
+
children: [jsx("svg", {
|
|
5583
|
+
ref: svgRef
|
|
5584
|
+
}), jsx(Box, {
|
|
5585
|
+
"data-testid": "pressure-tooltip",
|
|
5586
|
+
ref: pressureRef,
|
|
5587
|
+
sx: Object.assign({}, soundingsStyle$1.tooltip, soundingsStyle$1.pressure)
|
|
5588
|
+
}), jsx(Box, {
|
|
5589
|
+
"data-testid": "temperature-tooltip",
|
|
5590
|
+
ref: tempRef,
|
|
5591
|
+
sx: Object.assign({}, soundingsStyle$1.tooltip, soundingsStyle$1.temperature)
|
|
5592
|
+
}), jsx(Box, {
|
|
5593
|
+
"data-testid": "dewpoint-tooltip",
|
|
5594
|
+
ref: dewpointRef,
|
|
5595
|
+
sx: Object.assign({}, soundingsStyle$1.tooltip, soundingsStyle$1.dewPoint)
|
|
5146
5596
|
})]
|
|
5147
5597
|
});
|
|
5148
5598
|
};
|
|
5149
5599
|
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
* You may obtain a copy of the License at
|
|
5154
|
-
*
|
|
5155
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
5156
|
-
*
|
|
5157
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
5158
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
5159
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
5160
|
-
* See the License for the specific language governing permissions and
|
|
5161
|
-
* limitations under the License.
|
|
5162
|
-
*
|
|
5163
|
-
* Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
5164
|
-
* Copyright 2025 - Finnish Meteorological Institute (FMI)
|
|
5165
|
-
* Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
|
|
5166
|
-
* */
|
|
5167
|
-
var OFFSET_HEIGHT = 100; // Space reserved in layout
|
|
5168
|
-
var useSoundingsDiagramSize = function useSoundingsDiagramSize(ref) {
|
|
5600
|
+
var TIMESLIDER_HEIGHT = 135;
|
|
5601
|
+
var LABEL_MIN_WIDTH = 48;
|
|
5602
|
+
var useMaxLabelCount = function useMaxLabelCount(ref) {
|
|
5169
5603
|
var _React$useState = React.useState(0),
|
|
5170
|
-
|
|
5171
|
-
|
|
5604
|
+
width = _React$useState[0],
|
|
5605
|
+
setWidth = _React$useState[1];
|
|
5172
5606
|
React.useLayoutEffect(function () {
|
|
5173
|
-
var
|
|
5174
|
-
if (
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
return
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5607
|
+
var resizeObserver;
|
|
5608
|
+
if (ref.current) {
|
|
5609
|
+
resizeObserver = new ResizeObserver(function (entry) {
|
|
5610
|
+
var _entry$0$target$getBo = entry[0].target.getBoundingClientRect(),
|
|
5611
|
+
width = _entry$0$target$getBo.width;
|
|
5612
|
+
setWidth(width);
|
|
5613
|
+
});
|
|
5614
|
+
resizeObserver.observe(ref.current);
|
|
5615
|
+
}
|
|
5616
|
+
return function () {
|
|
5617
|
+
if (resizeObserver) {
|
|
5618
|
+
resizeObserver.disconnect();
|
|
5619
|
+
}
|
|
5620
|
+
};
|
|
5621
|
+
}, [ref]);
|
|
5622
|
+
var maxLabelCount = Math.max(1, Math.floor(width / LABEL_MIN_WIDTH));
|
|
5623
|
+
return maxLabelCount;
|
|
5624
|
+
};
|
|
5625
|
+
var shouldHideLabel = function shouldHideLabel(nItems, index, maxLabelCount) {
|
|
5626
|
+
var nthLabelsToShow = Math.ceil(nItems / maxLabelCount);
|
|
5627
|
+
return nItems > maxLabelCount &&
|
|
5628
|
+
// hide labels if too many items
|
|
5629
|
+
index !== nItems - 1 && (
|
|
5630
|
+
// not last item (always shown)
|
|
5631
|
+
// only show every nth label, skip label within last n/2 items so end doesn't get cluttered
|
|
5632
|
+
index % nthLabelsToShow !== 0 || nItems - 1 - index < nthLabelsToShow / 2);
|
|
5633
|
+
};
|
|
5634
|
+
var SoundingsTimeSlider = function SoundingsTimeSlider(_ref) {
|
|
5635
|
+
var timesteps = _ref.timesteps,
|
|
5636
|
+
selectedTime = _ref.selectedTime,
|
|
5637
|
+
updateSelectedTime = _ref.updateSelectedTime;
|
|
5638
|
+
var sliderRef = React.useRef(null);
|
|
5639
|
+
var maxLabelCount = useMaxLabelCount(sliderRef);
|
|
5640
|
+
var _useSoundingsTranslat = useSoundingsTranslation(),
|
|
5641
|
+
i18n = _useSoundingsTranslat.i18n;
|
|
5642
|
+
var marks = timesteps.filter(function (date) {
|
|
5643
|
+
return dateUtils.isValidIsoDateString(date);
|
|
5644
|
+
}).map(function (date, index, arr) {
|
|
5645
|
+
return {
|
|
5646
|
+
value: dateUtils.unix(dateUtils.getUtcFromString(date)),
|
|
5647
|
+
label: shouldHideLabel(arr.length, index, maxLabelCount) ? '' : dateUtils.dateToString(dateUtils.getUtcFromString(date), 'iii d. HH:mm', true, i18n.language)
|
|
5648
|
+
};
|
|
5649
|
+
});
|
|
5650
|
+
var currentTimeIndex = React.useMemo(function () {
|
|
5651
|
+
if (timesteps.length === 0) {
|
|
5652
|
+
return -1;
|
|
5653
|
+
}
|
|
5654
|
+
var selectedUtc = dateUtils.getUtcFromString(selectedTime);
|
|
5655
|
+
if (!selectedUtc) {
|
|
5656
|
+
return 0;
|
|
5657
|
+
}
|
|
5658
|
+
var selectedUnix = dateUtils.unix(selectedUtc);
|
|
5659
|
+
var indexByExactTimestamp = timesteps.findIndex(function (time) {
|
|
5660
|
+
var utcTime = dateUtils.getUtcFromString(time);
|
|
5661
|
+
if (!utcTime) {
|
|
5662
|
+
return false;
|
|
5663
|
+
}
|
|
5664
|
+
return dateUtils.unix(utcTime) === selectedUnix;
|
|
5665
|
+
});
|
|
5666
|
+
if (indexByExactTimestamp !== -1) {
|
|
5667
|
+
return indexByExactTimestamp;
|
|
5668
|
+
}
|
|
5669
|
+
var indexByExactString = timesteps.findIndex(function (time) {
|
|
5670
|
+
return time === selectedTime;
|
|
5671
|
+
});
|
|
5672
|
+
if (indexByExactString !== -1) {
|
|
5673
|
+
return indexByExactString;
|
|
5674
|
+
}
|
|
5675
|
+
// If selected time is not a sounding timestep, anchor on the nearest timestep
|
|
5676
|
+
// so forward/backward navigation continues from the expected point in time.
|
|
5677
|
+
return timesteps.reduce(function (nearestIndex, time, index) {
|
|
5678
|
+
var utcTime = dateUtils.getUtcFromString(time);
|
|
5679
|
+
if (!utcTime) {
|
|
5680
|
+
return nearestIndex;
|
|
5681
|
+
}
|
|
5682
|
+
var currentDiff = Math.abs(dateUtils.unix(utcTime) - selectedUnix);
|
|
5683
|
+
var nearestUtc = dateUtils.getUtcFromString(timesteps[nearestIndex]);
|
|
5684
|
+
if (!nearestUtc) {
|
|
5685
|
+
return index;
|
|
5686
|
+
}
|
|
5687
|
+
var nearestDiff = Math.abs(dateUtils.unix(nearestUtc) - selectedUnix);
|
|
5688
|
+
return currentDiff < nearestDiff ? index : nearestIndex;
|
|
5689
|
+
}, 0);
|
|
5690
|
+
}, [selectedTime, timesteps]);
|
|
5691
|
+
var onStepBackward = React.useCallback(function () {
|
|
5692
|
+
var precedingIndex = Math.max(currentTimeIndex - 1, 0);
|
|
5693
|
+
updateSelectedTime(timesteps[precedingIndex]);
|
|
5694
|
+
}, [currentTimeIndex, updateSelectedTime, timesteps]);
|
|
5695
|
+
var onStepForward = React.useCallback(function () {
|
|
5696
|
+
var followingIndex = Math.min(currentTimeIndex + 1, timesteps.length - 1);
|
|
5697
|
+
updateSelectedTime(timesteps[followingIndex]);
|
|
5698
|
+
}, [currentTimeIndex, updateSelectedTime, timesteps]);
|
|
5699
|
+
return jsxs("div", {
|
|
5700
|
+
ref: sliderRef,
|
|
5701
|
+
style: {
|
|
5702
|
+
display: 'flex',
|
|
5703
|
+
paddingTop: '32px',
|
|
5704
|
+
marginRight: '80px',
|
|
5705
|
+
marginLeft: '24px',
|
|
5706
|
+
height: TIMESLIDER_HEIGHT + "px"
|
|
5707
|
+
},
|
|
5708
|
+
children: [jsxs("div", {
|
|
5709
|
+
style: {
|
|
5710
|
+
minWidth: '60px',
|
|
5711
|
+
marginTop: '2px',
|
|
5712
|
+
display: 'flex',
|
|
5713
|
+
gap: '4px'
|
|
5714
|
+
},
|
|
5715
|
+
children: [jsx(BackwardForwardStepButton, {
|
|
5716
|
+
isDisabled: marks.length === 0,
|
|
5717
|
+
isForwardStep: false,
|
|
5718
|
+
onClickBFButton: onStepBackward
|
|
5719
|
+
}), jsx(BackwardForwardStepButton, {
|
|
5720
|
+
isDisabled: marks.length === 0,
|
|
5721
|
+
isForwardStep: true,
|
|
5722
|
+
onClickBFButton: onStepForward
|
|
5723
|
+
})]
|
|
5724
|
+
}), marks.length === 0 ? jsx(CustomSlider, {
|
|
5725
|
+
disabled: true,
|
|
5726
|
+
max: 1,
|
|
5727
|
+
min: 0,
|
|
5728
|
+
orientation: "horizontal",
|
|
5729
|
+
value: 0.5
|
|
5730
|
+
}) : jsx(CustomSlider, {
|
|
5731
|
+
extraStyles: {
|
|
5732
|
+
margin: '0px 20px 0px 20px',
|
|
5733
|
+
'.MuiSlider-markLabel': {
|
|
5734
|
+
transform: 'translate(-90%, 20px) rotate(-45deg)',
|
|
5735
|
+
transformOrigin: 'top center'
|
|
5736
|
+
}
|
|
5737
|
+
},
|
|
5738
|
+
marks: marks,
|
|
5739
|
+
max: marks[marks.length - 1].value,
|
|
5740
|
+
min: marks[0].value,
|
|
5741
|
+
onChange: function onChange(_, value) {
|
|
5742
|
+
updateSelectedTime(dateUtils.fromUnix(value).toISOString());
|
|
5743
|
+
},
|
|
5744
|
+
orientation: "horizontal",
|
|
5745
|
+
slotProps: {
|
|
5746
|
+
// Workaround for MUI bug where labels are just draggable area and clicking on one
|
|
5747
|
+
// does not necessarily select the described timestep
|
|
5748
|
+
markLabel: {
|
|
5749
|
+
onPointerDown: function onPointerDown(event) {
|
|
5750
|
+
event.preventDefault();
|
|
5751
|
+
var markIndex = event.currentTarget.getAttribute('data-index');
|
|
5752
|
+
var mark = marks[Number(markIndex)];
|
|
5753
|
+
var value = mark.value;
|
|
5754
|
+
updateSelectedTime(dateUtils.fromUnix(value).toISOString());
|
|
5755
|
+
}
|
|
5756
|
+
}
|
|
5757
|
+
},
|
|
5758
|
+
step: null,
|
|
5759
|
+
value: dateUtils.unix(dateUtils.getUtcFromString(selectedTime)),
|
|
5760
|
+
valueLabelDisplay: "on",
|
|
5761
|
+
valueLabelFormat: function valueLabelFormat(value) {
|
|
5762
|
+
return dateUtils.dateToString(dateUtils.fromUnix(value), "yyyy iii dd MMM HH:mm 'UTC'", true, i18n.language);
|
|
5763
|
+
}
|
|
5764
|
+
})]
|
|
5765
|
+
});
|
|
5269
5766
|
};
|
|
5270
|
-
var windSpeedRanges = [{
|
|
5271
|
-
min: 0,
|
|
5272
|
-
max: 1,
|
|
5273
|
-
symbol: windSymbolDefinitions.calm
|
|
5274
|
-
}, {
|
|
5275
|
-
min: 1,
|
|
5276
|
-
max: 4.5,
|
|
5277
|
-
symbol: windSymbolDefinitions.lightAir
|
|
5278
|
-
}, {
|
|
5279
|
-
min: 4.5,
|
|
5280
|
-
max: 7.5,
|
|
5281
|
-
symbol: windSymbolDefinitions.fiveKnots
|
|
5282
|
-
}, {
|
|
5283
|
-
min: 7.5,
|
|
5284
|
-
max: 12.5,
|
|
5285
|
-
symbol: windSymbolDefinitions.tenKnots
|
|
5286
|
-
}, {
|
|
5287
|
-
min: 12.5,
|
|
5288
|
-
max: 17.5,
|
|
5289
|
-
symbol: windSymbolDefinitions.fifteenKnots
|
|
5290
|
-
}, {
|
|
5291
|
-
min: 17.5,
|
|
5292
|
-
max: 22.5,
|
|
5293
|
-
symbol: windSymbolDefinitions.twentyKnots
|
|
5294
|
-
}, {
|
|
5295
|
-
min: 22.5,
|
|
5296
|
-
max: 27.5,
|
|
5297
|
-
symbol: windSymbolDefinitions.twentyFiveKnots
|
|
5298
|
-
}, {
|
|
5299
|
-
min: 27.5,
|
|
5300
|
-
max: 32.5,
|
|
5301
|
-
symbol: windSymbolDefinitions.thirtyKnots
|
|
5302
|
-
}, {
|
|
5303
|
-
min: 32.5,
|
|
5304
|
-
max: 37.5,
|
|
5305
|
-
symbol: windSymbolDefinitions.thirtyFiveKnots
|
|
5306
|
-
}, {
|
|
5307
|
-
min: 37.5,
|
|
5308
|
-
max: 42.5,
|
|
5309
|
-
symbol: windSymbolDefinitions.fortyKnots
|
|
5310
|
-
}, {
|
|
5311
|
-
min: 42.5,
|
|
5312
|
-
max: 47.5,
|
|
5313
|
-
symbol: windSymbolDefinitions.fortyFiveKnots
|
|
5314
|
-
}, {
|
|
5315
|
-
min: 47.5,
|
|
5316
|
-
max: 52.5,
|
|
5317
|
-
symbol: windSymbolDefinitions.fiftyKnots
|
|
5318
|
-
}, {
|
|
5319
|
-
min: 52.5,
|
|
5320
|
-
max: 57.5,
|
|
5321
|
-
symbol: windSymbolDefinitions.fiftyFiveKnots
|
|
5322
|
-
}, {
|
|
5323
|
-
min: 57.5,
|
|
5324
|
-
max: 62.5,
|
|
5325
|
-
symbol: windSymbolDefinitions.sixtyKnots
|
|
5326
|
-
}, {
|
|
5327
|
-
min: 62.5,
|
|
5328
|
-
max: 67.5,
|
|
5329
|
-
symbol: windSymbolDefinitions.sixtyFiveKnots
|
|
5330
|
-
}, {
|
|
5331
|
-
min: 67.5,
|
|
5332
|
-
max: 72.5,
|
|
5333
|
-
symbol: windSymbolDefinitions.seventyKnots
|
|
5334
|
-
}, {
|
|
5335
|
-
min: 72.5,
|
|
5336
|
-
max: 77.5,
|
|
5337
|
-
symbol: windSymbolDefinitions.seventyFiveKnots
|
|
5338
|
-
}, {
|
|
5339
|
-
min: 77.5,
|
|
5340
|
-
max: 82.5,
|
|
5341
|
-
symbol: windSymbolDefinitions.eightyKnots
|
|
5342
|
-
}, {
|
|
5343
|
-
min: 82.5,
|
|
5344
|
-
max: 87.5,
|
|
5345
|
-
symbol: windSymbolDefinitions.eightyFiveKnots
|
|
5346
|
-
}, {
|
|
5347
|
-
min: 87.5,
|
|
5348
|
-
max: 92.5,
|
|
5349
|
-
symbol: windSymbolDefinitions.ninetyKnots
|
|
5350
|
-
}, {
|
|
5351
|
-
min: 92.5,
|
|
5352
|
-
max: 97.5,
|
|
5353
|
-
symbol: windSymbolDefinitions.ninetyFiveKnots
|
|
5354
|
-
}, {
|
|
5355
|
-
min: 97.5,
|
|
5356
|
-
max: 102.5,
|
|
5357
|
-
symbol: windSymbolDefinitions.hundredKnots
|
|
5358
|
-
}, {
|
|
5359
|
-
min: 102.5,
|
|
5360
|
-
max: 107.5,
|
|
5361
|
-
symbol: windSymbolDefinitions.hundredFiveKnots
|
|
5362
|
-
}, {
|
|
5363
|
-
min: 107.5,
|
|
5364
|
-
max: 112.5,
|
|
5365
|
-
symbol: windSymbolDefinitions.hundredTenKnots
|
|
5366
|
-
}, {
|
|
5367
|
-
min: 112.5,
|
|
5368
|
-
max: 117.5,
|
|
5369
|
-
symbol: windSymbolDefinitions.hundredFifteenKnots
|
|
5370
|
-
}, {
|
|
5371
|
-
min: 117.5,
|
|
5372
|
-
max: 122.5,
|
|
5373
|
-
symbol: windSymbolDefinitions.hundredTwentyKnots
|
|
5374
|
-
}, {
|
|
5375
|
-
min: 122.5,
|
|
5376
|
-
max: 127.5,
|
|
5377
|
-
symbol: windSymbolDefinitions.hundredTwentyFiveKnots
|
|
5378
|
-
}, {
|
|
5379
|
-
min: 127.5,
|
|
5380
|
-
max: 132.5,
|
|
5381
|
-
symbol: windSymbolDefinitions.hundredThirtyKnots
|
|
5382
|
-
}, {
|
|
5383
|
-
min: 132.5,
|
|
5384
|
-
max: 137.5,
|
|
5385
|
-
symbol: windSymbolDefinitions.hundredThirtyFiveKnots
|
|
5386
|
-
}, {
|
|
5387
|
-
min: 137.5,
|
|
5388
|
-
max: 142.5,
|
|
5389
|
-
symbol: windSymbolDefinitions.hundredFortyKnots
|
|
5390
|
-
}, {
|
|
5391
|
-
min: 142.5,
|
|
5392
|
-
max: 147.5,
|
|
5393
|
-
symbol: windSymbolDefinitions.hundredFortyFiveKnots
|
|
5394
|
-
}, {
|
|
5395
|
-
min: 147.5,
|
|
5396
|
-
max: 152,
|
|
5397
|
-
symbol: windSymbolDefinitions.hundredFiftyKnots
|
|
5398
|
-
}];
|
|
5399
5767
|
|
|
5400
5768
|
/* *
|
|
5401
5769
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -5414,134 +5782,59 @@ var windSpeedRanges = [{
|
|
|
5414
5782
|
* Copyright 2025 - Finnish Meteorological Institute (FMI)
|
|
5415
5783
|
* Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
|
|
5416
5784
|
* */
|
|
5417
|
-
var
|
|
5418
|
-
|
|
5419
|
-
if (
|
|
5420
|
-
|
|
5421
|
-
var startY = parseFloat(match[2]);
|
|
5422
|
-
var endX = parseFloat(match[3]);
|
|
5423
|
-
var endY = parseFloat(match[4]);
|
|
5424
|
-
return "M" + startX + "," + startY + "L" + (endX + horizontalBarbMargin * 3) + "," + endY;
|
|
5425
|
-
}
|
|
5426
|
-
return path;
|
|
5427
|
-
};
|
|
5428
|
-
var extendXAxis = function extendXAxis(path, horizontalBarbMargin) {
|
|
5429
|
-
var match = /^M([\d.-]+),([\d.-]+)H([\d.-]+)/.exec(path);
|
|
5430
|
-
if (match) {
|
|
5431
|
-
var endX = parseFloat(match[3]);
|
|
5432
|
-
return path.replace(/H[\d.-]+/, "H" + (endX + horizontalBarbMargin * 3));
|
|
5433
|
-
}
|
|
5434
|
-
return path;
|
|
5435
|
-
};
|
|
5436
|
-
var drawWindBarbs = function drawWindBarbs(_ref) {
|
|
5437
|
-
var _rootSvg$node;
|
|
5438
|
-
var svgRef = _ref.svgRef,
|
|
5439
|
-
plotGroup = _ref.plotGroup,
|
|
5440
|
-
yScale = _ref.yScale,
|
|
5441
|
-
data = _ref.data,
|
|
5442
|
-
width = _ref.width,
|
|
5443
|
-
margin = _ref.margin,
|
|
5444
|
-
_ref$barbColor = _ref.barbColor,
|
|
5445
|
-
barbColor = _ref$barbColor === void 0 ? 'black' : _ref$barbColor,
|
|
5446
|
-
_ref$columnOffsetX = _ref.columnOffsetX,
|
|
5447
|
-
columnOffsetX = _ref$columnOffsetX === void 0 ? 0 : _ref$columnOffsetX;
|
|
5448
|
-
var barbsSize = 40;
|
|
5449
|
-
var scalingFactor = 0.5;
|
|
5450
|
-
var horizontalBarbMargin = barbsSize * scalingFactor + 5;
|
|
5451
|
-
var visibleItems = removeItemsExponential(data.reverse()).filter(function (item) {
|
|
5452
|
-
return item.pressure >= 150;
|
|
5453
|
-
});
|
|
5454
|
-
// Measure width and height and make extra room for one column
|
|
5455
|
-
// of windbarbs
|
|
5456
|
-
var rootSvg = d3.select(svgRef.current);
|
|
5457
|
-
var currentWidth = (_rootSvg$node = rootSvg.node()) == null ? void 0 : _rootSvg$node.getBoundingClientRect().width;
|
|
5458
|
-
if (!currentWidth) {
|
|
5459
|
-
return;
|
|
5785
|
+
var OFFSET_HEIGHT = 100; // Space reserved in layout
|
|
5786
|
+
var useSoundingsDiagramSize = function useSoundingsDiagramSize(ref, useWidth) {
|
|
5787
|
+
if (useWidth === void 0) {
|
|
5788
|
+
useWidth = true;
|
|
5460
5789
|
}
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
d3.select('g[type="x-axis"] path.domain').each(function (_d, i, nodes) {
|
|
5469
|
-
var path = d3.select(nodes[i]).attr('d');
|
|
5470
|
-
var newD = extendXAxis(path, horizontalBarbMargin);
|
|
5471
|
-
d3.select(nodes[i]).attr('d', newD);
|
|
5472
|
-
});
|
|
5473
|
-
// Expand root SVG width to make room for barbs column at the right
|
|
5474
|
-
rootSvg.attr('width', currentWidth + margin.left + horizontalBarbMargin);
|
|
5475
|
-
// Place the barbs just to the right of the plotting area.
|
|
5476
|
-
// plotGroup's origin is already translated to (margin.left, margin.top),
|
|
5477
|
-
// and its width equals `width`.
|
|
5478
|
-
var windBarbColumnX = width + 5 + columnOffsetX;
|
|
5479
|
-
var barbGroup = plotGroup.append('g').attr('class', 'wind-group').attr('transform', // This translation should be revisited when implementing
|
|
5480
|
-
// the plotting of several datasets at once
|
|
5481
|
-
"translate(" + windBarbColumnX + ", 0)");
|
|
5482
|
-
barbGroup.selectAll('g').data(visibleItems).enter().append('g').attr('id', 'wind-barb').each(function handleBarb(data) {
|
|
5483
|
-
var group = d3.select(this);
|
|
5484
|
-
var windSymbol = getWindSymbol(data.windSpeed);
|
|
5485
|
-
if (windSymbol) {
|
|
5486
|
-
var _innerGroup$node;
|
|
5487
|
-
// Inner group will have rotation and scaling applied to it
|
|
5488
|
-
var innerGroup = group.append('g');
|
|
5489
|
-
(_innerGroup$node = innerGroup.node()) == null || _innerGroup$node.appendChild(windSymbol);
|
|
5490
|
-
// Update stroke color
|
|
5491
|
-
innerGroup.selectAll('*').attr('stroke', barbColor);
|
|
5492
|
-
// Only update the fill for the paths that already used a fill
|
|
5493
|
-
// in their original svg form.
|
|
5494
|
-
innerGroup.selectAll('*').each(function (_d, i, nodes) {
|
|
5495
|
-
var el = d3.select(nodes[i]);
|
|
5496
|
-
var currentFill = el.attr('fill');
|
|
5497
|
-
if (currentFill && currentFill !== 'none') {
|
|
5498
|
-
el.attr('fill', barbColor);
|
|
5499
|
-
}
|
|
5500
|
-
});
|
|
5501
|
-
var bbox = windSymbol.getBBox();
|
|
5502
|
-
// Central point
|
|
5503
|
-
var cx = bbox.x + bbox.width / 2;
|
|
5504
|
-
var cy = bbox.y + bbox.height / 2;
|
|
5505
|
-
var rotation = 180 + data.windDirection;
|
|
5506
|
-
var y = yScale(data.pressure);
|
|
5507
|
-
// Place items in the correct vertical position
|
|
5508
|
-
// Correcting for barbSize
|
|
5509
|
-
group.attr('transform', "translate(0, " + (y - barbsSize * scalingFactor / 8) + ")");
|
|
5510
|
-
// Rotate accordingly, and scale
|
|
5511
|
-
innerGroup.attr('transform', "rotate(" + rotation + ") scale(" + scalingFactor + ") translate(" + -cx + ", " + -cy + ")");
|
|
5790
|
+
var _React$useState = React.useState(0),
|
|
5791
|
+
size = _React$useState[0],
|
|
5792
|
+
setSize = _React$useState[1];
|
|
5793
|
+
React.useLayoutEffect(function () {
|
|
5794
|
+
var container = ref.current;
|
|
5795
|
+
if (!container) {
|
|
5796
|
+
return undefined;
|
|
5512
5797
|
}
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5798
|
+
var resizeObserver = new ResizeObserver(function (entries) {
|
|
5799
|
+
if (!entries.length) {
|
|
5800
|
+
return;
|
|
5801
|
+
}
|
|
5802
|
+
var _entries$0$contentRec = entries[0].contentRect,
|
|
5803
|
+
width = _entries$0$contentRec.width,
|
|
5804
|
+
height = _entries$0$contentRec.height;
|
|
5805
|
+
var availableHeight = height - TIMESLIDER_HEIGHT + OFFSET_HEIGHT;
|
|
5806
|
+
var nextSize = useWidth ? Math.floor(Math.min(width, availableHeight)) : Math.floor(availableHeight);
|
|
5807
|
+
setSize(nextSize > 0 ? nextSize : 0);
|
|
5808
|
+
});
|
|
5809
|
+
resizeObserver.observe(container);
|
|
5810
|
+
return function () {
|
|
5811
|
+
resizeObserver.disconnect();
|
|
5812
|
+
};
|
|
5813
|
+
}, [ref, useWidth]);
|
|
5814
|
+
return size;
|
|
5528
5815
|
};
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5816
|
+
|
|
5817
|
+
/* *
|
|
5818
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5819
|
+
* you may not use this file except in compliance with the License.
|
|
5820
|
+
* You may obtain a copy of the License at
|
|
5821
|
+
*
|
|
5822
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
5823
|
+
*
|
|
5824
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
5825
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
5826
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
5827
|
+
* See the License for the specific language governing permissions and
|
|
5828
|
+
* limitations under the License.
|
|
5829
|
+
*
|
|
5830
|
+
* Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
5831
|
+
* Copyright 2025 - Finnish Meteorological Institute (FMI)
|
|
5832
|
+
* Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
|
|
5833
|
+
* */
|
|
5834
|
+
var animateResizeTransform = function animateResizeTransform(svg, marginLocal, innerHeight, prevInnerHeightRef) {
|
|
5835
|
+
var prevInnerHeight = typeof prevInnerHeightRef.current === 'number' ? prevInnerHeightRef.current : 0;
|
|
5836
|
+
var scaleYStart = prevInnerHeight > 0 && innerHeight > 0 ? prevInnerHeight / innerHeight : 0;
|
|
5837
|
+
svg.attr('transform', "translate(" + marginLocal.left + "," + marginLocal.top + ") scale(1," + scaleYStart + ")").transition().duration(300).attr('transform', "translate(" + marginLocal.left + "," + marginLocal.top + ") scale(1,1)");
|
|
5545
5838
|
};
|
|
5546
5839
|
|
|
5547
5840
|
var shadow = '0 1px 5px 0 rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.12), 0 2px 4px 0 rgba(0, 0, 0, 0.14)';
|
|
@@ -5562,6 +5855,10 @@ var soundingsStyle = {
|
|
|
5562
5855
|
}
|
|
5563
5856
|
};
|
|
5564
5857
|
var WIND_BARB_OFFSET_X = 35;
|
|
5858
|
+
var getVerticalOnlyTransform = function getVerticalOnlyTransform(scale, yOffset) {
|
|
5859
|
+
// Keep x-axis unchanged, apply shared zoom on y-axis only.
|
|
5860
|
+
return "matrix(1, 0, 0, " + scale + ", 0, " + yOffset + ")";
|
|
5861
|
+
};
|
|
5565
5862
|
/**
|
|
5566
5863
|
* Check if the sounding data is effectively empty.
|
|
5567
5864
|
* Data can be empty in two ways:
|
|
@@ -5597,8 +5894,12 @@ var WindBarbs = function WindBarbs(_ref) {
|
|
|
5597
5894
|
var widthRef = useRef(0);
|
|
5598
5895
|
var svgRectRef = useRef(null);
|
|
5599
5896
|
var tooltipDataRef = useRef(null);
|
|
5897
|
+
// Must point to the inner translated <g> to match Soundings zoom coordinate space.
|
|
5898
|
+
var zoomTargetRef = useRef(null);
|
|
5600
5899
|
var _useSharedMouseY = useSharedMouseY(),
|
|
5601
|
-
clientY = _useSharedMouseY.clientY
|
|
5900
|
+
clientY = _useSharedMouseY.clientY,
|
|
5901
|
+
verticalZoom = _useSharedMouseY.verticalZoom,
|
|
5902
|
+
resetVerticalZoom = _useSharedMouseY.resetVerticalZoom;
|
|
5602
5903
|
// Set SVG dimensions (required props; no optional chaining needed)
|
|
5603
5904
|
var baseWidth = svgDimensions.width,
|
|
5604
5905
|
baseHeight = svgDimensions.height,
|
|
@@ -5606,7 +5907,7 @@ var WindBarbs = function WindBarbs(_ref) {
|
|
|
5606
5907
|
var width = baseWidth - (margin.left + margin.right);
|
|
5607
5908
|
var height = baseHeight - (margin.top + margin.bottom);
|
|
5608
5909
|
useEffect(function () {
|
|
5609
|
-
if (!svgRef.current) {
|
|
5910
|
+
if (!svgRef.current || width <= 0 || height <= 0) {
|
|
5610
5911
|
return;
|
|
5611
5912
|
}
|
|
5612
5913
|
var root = d3.select(svgRef.current);
|
|
@@ -5619,8 +5920,9 @@ var WindBarbs = function WindBarbs(_ref) {
|
|
|
5619
5920
|
diagramType: diagramType,
|
|
5620
5921
|
d3GraphId: d3GraphId
|
|
5621
5922
|
});
|
|
5622
|
-
// When Soundings is dragged
|
|
5923
|
+
// When Soundings is dragged closed, reset the zoom level and animate the Wind Barbs to resize back to the height where dragging started
|
|
5623
5924
|
if (animateResize) {
|
|
5925
|
+
resetVerticalZoom(d3GraphId);
|
|
5624
5926
|
animateResizeTransform(svg, margin, height, prevInnerHeightRef);
|
|
5625
5927
|
}
|
|
5626
5928
|
var svgRectangle = svgRef.current.getBoundingClientRect();
|
|
@@ -5658,18 +5960,33 @@ var WindBarbs = function WindBarbs(_ref) {
|
|
|
5658
5960
|
width: width,
|
|
5659
5961
|
margin: margin,
|
|
5660
5962
|
barbColor: color,
|
|
5661
|
-
columnOffsetX: index * WIND_BARB_OFFSET_X
|
|
5963
|
+
columnOffsetX: index * WIND_BARB_OFFSET_X,
|
|
5964
|
+
verticalScale: verticalZoom.scale
|
|
5662
5965
|
});
|
|
5663
5966
|
});
|
|
5664
5967
|
// Clear or update tooltip data based on whether we have actual data
|
|
5665
5968
|
tooltipDataRef.current = isDataEmpty(data) ? null : constructTooltipData(data);
|
|
5666
5969
|
// Update previous inner height after drawing so animation uses the prior value
|
|
5667
5970
|
prevInnerHeightRef.current = height;
|
|
5971
|
+
var zoomTarget = svg.node();
|
|
5972
|
+
if (!zoomTarget) {
|
|
5973
|
+
return;
|
|
5974
|
+
}
|
|
5975
|
+
zoomTargetRef.current = zoomTarget;
|
|
5976
|
+
// Initialize with shared zoom state from Soundings.
|
|
5977
|
+
d3.select(zoomTarget).attr('transform', getVerticalOnlyTransform(verticalZoom.scale, verticalZoom.y));
|
|
5668
5978
|
// eslint-disable-next-line consistent-return, @typescript-eslint/explicit-function-return-type
|
|
5669
5979
|
return function () {
|
|
5980
|
+
zoomTargetRef.current = null;
|
|
5670
5981
|
root.selectAll('*').remove();
|
|
5671
5982
|
};
|
|
5672
|
-
}, [data, diagramType, width, height, d3GraphId, margin, animateResize]);
|
|
5983
|
+
}, [data, diagramType, width, height, d3GraphId, margin, animateResize, verticalZoom.scale, verticalZoom.y, resetVerticalZoom]);
|
|
5984
|
+
useEffect(function () {
|
|
5985
|
+
if (!zoomTargetRef.current) {
|
|
5986
|
+
return;
|
|
5987
|
+
}
|
|
5988
|
+
d3.select(zoomTargetRef.current).attr('transform', getVerticalOnlyTransform(verticalZoom.scale, verticalZoom.y));
|
|
5989
|
+
}, [verticalZoom]);
|
|
5673
5990
|
useEffect(function () {
|
|
5674
5991
|
var _svgRectRef$current;
|
|
5675
5992
|
if (!showTooltip || !svgRef.current || !windRef.current) {
|
|
@@ -5697,18 +6014,27 @@ var WindBarbs = function WindBarbs(_ref) {
|
|
|
5697
6014
|
target: svgRef.current,
|
|
5698
6015
|
currentTarget: svgRef.current
|
|
5699
6016
|
};
|
|
6017
|
+
var pointerY = clientY - rect.top - marginRef.current.top;
|
|
6018
|
+
var unscaledY = (pointerY - verticalZoom.y) / verticalZoom.scale;
|
|
6019
|
+
var hoveredPressure = extractPressureFromY(diagramType, unscaledY, yScaleRef.current);
|
|
6020
|
+
var transformedY = yScaleRef.current(hoveredPressure) * verticalZoom.scale + verticalZoom.y;
|
|
6021
|
+
var pressureLineY = transformedY + marginRef.current.top;
|
|
5700
6022
|
var windRefd3 = d3.select(windRef.current);
|
|
5701
6023
|
drawSoundingsTooltip({
|
|
5702
6024
|
event: synthetic,
|
|
5703
|
-
yScale: yScaleRef.current,
|
|
5704
6025
|
svgRectangle: rect,
|
|
5705
6026
|
margin: marginRef.current,
|
|
5706
6027
|
width: widthRef.current,
|
|
6028
|
+
hoveredPressure: hoveredPressure,
|
|
5707
6029
|
windRefd3: windRefd3,
|
|
5708
6030
|
tooltipData: tooltipDataRef.current,
|
|
5709
6031
|
diagramType: diagramType
|
|
5710
6032
|
});
|
|
5711
|
-
|
|
6033
|
+
var tooltipHeight = windRef.current.getBoundingClientRect().height;
|
|
6034
|
+
var centeredTop = pressureLineY - tooltipHeight / 2;
|
|
6035
|
+
var clampedTop = Math.max(0, Math.min(centeredTop, rect.height - tooltipHeight));
|
|
6036
|
+
windRef.current.style.top = clampedTop + "px";
|
|
6037
|
+
}, [clientY, showTooltip, diagramType, data, verticalZoom.scale, verticalZoom.y]);
|
|
5712
6038
|
return jsxs(Box, {
|
|
5713
6039
|
ref: canvasRef,
|
|
5714
6040
|
sx: {
|
|
@@ -5972,32 +6298,42 @@ var SoundingsPanels = function SoundingsPanels(_ref) {
|
|
|
5972
6298
|
panelComponent = _ref.panelComponent,
|
|
5973
6299
|
profileDataPreferences = _ref.profileDataPreferences;
|
|
5974
6300
|
var soundingsContentRef = React.useRef(null);
|
|
6301
|
+
var windBarbsContentRef = React.useRef(null);
|
|
5975
6302
|
var diagramSize = useSoundingsDiagramSize(soundingsContentRef);
|
|
5976
|
-
var
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
6303
|
+
var windBarbsDiagramSize = useSoundingsDiagramSize(windBarbsContentRef, false);
|
|
6304
|
+
var soundingsIsOpen = React.useMemo(function () {
|
|
6305
|
+
var _soundingPanelsInOrde;
|
|
6306
|
+
return ((_soundingPanelsInOrde = soundingPanelsInOrder.find(function (panel) {
|
|
6307
|
+
return panel.id === 'soundings';
|
|
6308
|
+
})) == null ? void 0 : _soundingPanelsInOrde.isOpen) || false;
|
|
6309
|
+
}, [soundingPanelsInOrder]);
|
|
6310
|
+
var _React$useState = React.useState(null),
|
|
6311
|
+
previousHeight = _React$useState[0],
|
|
6312
|
+
setPreviousHeight = _React$useState[1];
|
|
5982
6313
|
var firstSelectedSourceData = React.useMemo(function () {
|
|
5983
6314
|
var _data$;
|
|
5984
6315
|
return (_data$ = data[0]) != null ? _data$ : [];
|
|
5985
6316
|
}, [data]);
|
|
6317
|
+
var windBarbsHeight = React.useMemo(function () {
|
|
6318
|
+
if (soundingsIsOpen) {
|
|
6319
|
+
return diagramSize;
|
|
6320
|
+
}
|
|
6321
|
+
return previousHeight != null ? previousHeight : windBarbsDiagramSize;
|
|
6322
|
+
}, [diagramSize, previousHeight, soundingsIsOpen, windBarbsDiagramSize]);
|
|
5986
6323
|
var sizeRef = React.useRef(diagramSize);
|
|
5987
6324
|
var isResizingRef = React.useRef(false);
|
|
5988
6325
|
React.useEffect(function () {
|
|
5989
6326
|
sizeRef.current = diagramSize;
|
|
5990
6327
|
}, [diagramSize]);
|
|
5991
6328
|
React.useEffect(function () {
|
|
5992
|
-
if (previousHeight == null && diagramSize >
|
|
6329
|
+
if (previousHeight == null && diagramSize > 24) {
|
|
5993
6330
|
setPreviousHeight(diagramSize);
|
|
5994
6331
|
}
|
|
5995
6332
|
}, [diagramSize, previousHeight]);
|
|
5996
6333
|
var preserveWindBarbsGrowBackHeight = React.useCallback(function () {
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
}, []);
|
|
6334
|
+
var nextHeight = sizeRef.current > 24 ? sizeRef.current : windBarbsDiagramSize;
|
|
6335
|
+
setPreviousHeight(nextHeight);
|
|
6336
|
+
}, [windBarbsDiagramSize]);
|
|
6001
6337
|
var handleSoundingsResizeStart = React.useCallback(function () {
|
|
6002
6338
|
isResizingRef.current = true;
|
|
6003
6339
|
preserveWindBarbsGrowBackHeight();
|
|
@@ -6010,7 +6346,6 @@ var SoundingsPanels = function SoundingsPanels(_ref) {
|
|
|
6010
6346
|
if (isClosingViaClick) {
|
|
6011
6347
|
preserveWindBarbsGrowBackHeight();
|
|
6012
6348
|
}
|
|
6013
|
-
setSoundingsIsClosed(!isOpen);
|
|
6014
6349
|
}, [preserveWindBarbsGrowBackHeight]);
|
|
6015
6350
|
var panels = soundingPanelsInOrder.flatMap(function (_ref2) {
|
|
6016
6351
|
var id = _ref2.id,
|
|
@@ -6054,9 +6389,10 @@ var SoundingsPanels = function SoundingsPanels(_ref) {
|
|
|
6054
6389
|
name: 'Wind Barbs',
|
|
6055
6390
|
isDisplayed: isDisplayed,
|
|
6056
6391
|
maxWidth: 200,
|
|
6392
|
+
panelRef: windBarbsContentRef,
|
|
6057
6393
|
render: function render() {
|
|
6058
6394
|
return jsx(WindBarbs, {
|
|
6059
|
-
animateResize: Boolean(
|
|
6395
|
+
animateResize: Boolean(!soundingsIsOpen && previousHeight),
|
|
6060
6396
|
d3GraphId: normalizedId,
|
|
6061
6397
|
data: data,
|
|
6062
6398
|
diagramType: chosenDiagramType,
|
|
@@ -6068,7 +6404,7 @@ var SoundingsPanels = function SoundingsPanels(_ref) {
|
|
|
6068
6404
|
right: 25,
|
|
6069
6405
|
top: 0
|
|
6070
6406
|
},
|
|
6071
|
-
height:
|
|
6407
|
+
height: windBarbsHeight
|
|
6072
6408
|
}
|
|
6073
6409
|
});
|
|
6074
6410
|
}
|
|
@@ -6243,6 +6579,7 @@ var SoundingsConnect = function SoundingsConnect(_ref) {
|
|
|
6243
6579
|
// Skip re-registering if the incoming preset already matches the current
|
|
6244
6580
|
// soundings store state (e.g. workspace initialProps updated after a save)
|
|
6245
6581
|
if (!isEqual(soundingsPreset, currentSoundingsPreset)) {
|
|
6582
|
+
var _soundingsPreset$isLo;
|
|
6246
6583
|
presetJustLoadedRef.current = true;
|
|
6247
6584
|
initialLocationsRef.current = soundingsPreset.selectedLocations || {};
|
|
6248
6585
|
previousLocationsRef.current = {};
|
|
@@ -6250,6 +6587,11 @@ var SoundingsConnect = function SoundingsConnect(_ref) {
|
|
|
6250
6587
|
viewId: viewId,
|
|
6251
6588
|
preset: soundingsPreset
|
|
6252
6589
|
}));
|
|
6590
|
+
dispatch(uiActions.setActiveMapIdForDialog({
|
|
6591
|
+
type: uiTypes.DialogTypes.SoundingsLocations,
|
|
6592
|
+
mapId: viewId,
|
|
6593
|
+
setOpen: (_soundingsPreset$isLo = soundingsPreset.isLocationsDialogOpen) != null ? _soundingsPreset$isLo : false
|
|
6594
|
+
}));
|
|
6253
6595
|
setTimeout(function () {
|
|
6254
6596
|
presetJustLoadedRef.current = false;
|
|
6255
6597
|
initialLocationsRef.current = {};
|
|
@@ -6261,6 +6603,26 @@ var SoundingsConnect = function SoundingsConnect(_ref) {
|
|
|
6261
6603
|
previousLocationsRef.current = {};
|
|
6262
6604
|
}
|
|
6263
6605
|
}, [currentSoundingsPreset, dispatch, soundingsPreset, viewId]);
|
|
6606
|
+
var syncgroupTimeState = useSyncgroupTimeState(viewId, 0);
|
|
6607
|
+
var syncgroupSelectedTime = useMemo(function () {
|
|
6608
|
+
if ((syncgroupTimeState == null ? void 0 : syncgroupTimeState.current) === undefined || !Number.isFinite(syncgroupTimeState.current)) {
|
|
6609
|
+
return undefined;
|
|
6610
|
+
}
|
|
6611
|
+
return dateUtils.fromUnix(syncgroupTimeState.current).toISOString();
|
|
6612
|
+
}, [syncgroupTimeState]);
|
|
6613
|
+
var isTimeSynced = !!syncgroupSelectedTime;
|
|
6614
|
+
React.useEffect(function () {
|
|
6615
|
+
if (soundingsPreset != null && soundingsPreset.selectedTime && isTimeSynced) {
|
|
6616
|
+
// trigger sync of time to map when preset has selectedTime
|
|
6617
|
+
dispatch(genericActions.setTime({
|
|
6618
|
+
sourceId: viewId,
|
|
6619
|
+
origin: 'SoundingsConnect',
|
|
6620
|
+
value: {
|
|
6621
|
+
currentTime: handleDateUtilsISOString(soundingsPreset.selectedTime)
|
|
6622
|
+
}
|
|
6623
|
+
}));
|
|
6624
|
+
}
|
|
6625
|
+
}, [dispatch, isTimeSynced, soundingsPreset == null ? void 0 : soundingsPreset.selectedTime, viewId]);
|
|
6264
6626
|
useRegisterFeatureSyncSource(viewId);
|
|
6265
6627
|
var selectedTime = useSelector(function (state) {
|
|
6266
6628
|
return getSelectedTime(state, viewId);
|
|
@@ -6293,6 +6655,9 @@ var SoundingsConnect = function SoundingsConnect(_ref) {
|
|
|
6293
6655
|
var profileDataPreferences = useSelector(function (state) {
|
|
6294
6656
|
return getProfileDataPreferences(state, viewId);
|
|
6295
6657
|
});
|
|
6658
|
+
var isLegendVisible = useSelector(function (state) {
|
|
6659
|
+
return getIsLegendVisible(state, viewId);
|
|
6660
|
+
});
|
|
6296
6661
|
var selectedMapIds = useSelector(function (state) {
|
|
6297
6662
|
return genericSelectors.getLinkedTargetIds(state, viewId);
|
|
6298
6663
|
}, shallowEqual);
|
|
@@ -6307,14 +6672,6 @@ var SoundingsConnect = function SoundingsConnect(_ref) {
|
|
|
6307
6672
|
var firstLinkedMapId = selectedMapIds[0];
|
|
6308
6673
|
var _useTimesteps = useTimesteps(resolvedSourceSelections),
|
|
6309
6674
|
sourceTimesteps = _useTimesteps.data;
|
|
6310
|
-
var syncgroupTimeState = useSyncgroupTimeState(viewId, 0);
|
|
6311
|
-
var syncgroupSelectedTime = useMemo(function () {
|
|
6312
|
-
if ((syncgroupTimeState == null ? void 0 : syncgroupTimeState.current) === undefined || !Number.isFinite(syncgroupTimeState.current)) {
|
|
6313
|
-
return undefined;
|
|
6314
|
-
}
|
|
6315
|
-
return dateUtils.fromUnix(syncgroupTimeState.current).toISOString();
|
|
6316
|
-
}, [syncgroupTimeState]);
|
|
6317
|
-
var isTimeSynced = !!syncgroupSelectedTime;
|
|
6318
6675
|
var selectedTimeInUse = syncgroupSelectedTime || selectedTime;
|
|
6319
6676
|
var timeMismatchInfo = useMemo(function () {
|
|
6320
6677
|
return getTimeMismatchInfo(isTimeSynced, selectedTimeInUse, sourceTimesteps);
|
|
@@ -6973,7 +7330,7 @@ var SoundingsConnect = function SoundingsConnect(_ref) {
|
|
|
6973
7330
|
fontSize: "small"
|
|
6974
7331
|
})
|
|
6975
7332
|
})]
|
|
6976
|
-
}), jsx(Box, {
|
|
7333
|
+
}), isLegendVisible ? jsx(Box, {
|
|
6977
7334
|
sx: {
|
|
6978
7335
|
display: 'flex',
|
|
6979
7336
|
justifyContent: 'center',
|
|
@@ -6989,7 +7346,7 @@ var SoundingsConnect = function SoundingsConnect(_ref) {
|
|
|
6989
7346
|
sourceResolvedInstanceIds: sourceResolvedInstanceIds,
|
|
6990
7347
|
sourceSelections: sourceSelections
|
|
6991
7348
|
})
|
|
6992
|
-
}), jsx(Box, {
|
|
7349
|
+
}) : null, jsx(Box, {
|
|
6993
7350
|
sx: {
|
|
6994
7351
|
flex: 1,
|
|
6995
7352
|
minHeight: 0,
|
|
@@ -7272,6 +7629,28 @@ var SoundingsSourceDialogConnect = function SoundingsSourceDialogConnect(_ref) {
|
|
|
7272
7629
|
data = _useGetCollectionsIns.data,
|
|
7273
7630
|
isPending = _useGetCollectionsIns.isPending,
|
|
7274
7631
|
error = _useGetCollectionsIns.error;
|
|
7632
|
+
// Update checked sources without an instance once instances finish loading.
|
|
7633
|
+
React.useEffect(function () {
|
|
7634
|
+
data == null || data.forEach(function (collection) {
|
|
7635
|
+
var currentSelection = sourceSelections[collection.id];
|
|
7636
|
+
if (!(currentSelection != null && currentSelection.isChecked) || currentSelection.instanceId || collection.instances.length === 0) {
|
|
7637
|
+
return;
|
|
7638
|
+
}
|
|
7639
|
+
var resolvedInstance = referenceTimeUtils.resolveReferenceTimeInstance(collection.instances, defaultInstanceId);
|
|
7640
|
+
if (!resolvedInstance) {
|
|
7641
|
+
return;
|
|
7642
|
+
}
|
|
7643
|
+
dispatch(soundingsActions.updateSelectedSource({
|
|
7644
|
+
sourceId: collection.id,
|
|
7645
|
+
value: {
|
|
7646
|
+
instanceId: defaultInstanceId,
|
|
7647
|
+
verticalRange: getVerticalRangeFromInstance(resolvedInstance)
|
|
7648
|
+
},
|
|
7649
|
+
viewId: viewId,
|
|
7650
|
+
origin: SoundingsActionOrigin.soundingsManager
|
|
7651
|
+
}));
|
|
7652
|
+
});
|
|
7653
|
+
}, [data, dispatch, sourceSelections, viewId]);
|
|
7275
7654
|
return jsx(SoundingsSourceMenu, {
|
|
7276
7655
|
error: error,
|
|
7277
7656
|
handleClose: onCloseDialog,
|
|
@@ -7334,7 +7713,10 @@ var LocationsMenu = function LocationsMenu(_ref2) {
|
|
|
7334
7713
|
_ref2$order = _ref2.order,
|
|
7335
7714
|
order = _ref2$order === void 0 ? 0 : _ref2$order,
|
|
7336
7715
|
isLoading = _ref2.isLoading,
|
|
7337
|
-
error = _ref2.error
|
|
7716
|
+
error = _ref2.error,
|
|
7717
|
+
locationMenuSize = _ref2.locationMenuSize,
|
|
7718
|
+
onSizeChange = _ref2.onSizeChange,
|
|
7719
|
+
locationMenuPosition = _ref2.locationMenuPosition;
|
|
7338
7720
|
var _useState = useState(''),
|
|
7339
7721
|
searchFilter = _useState[0],
|
|
7340
7722
|
setSearchFilter = _useState[1];
|
|
@@ -7361,13 +7743,26 @@ var LocationsMenu = function LocationsMenu(_ref2) {
|
|
|
7361
7743
|
isOpen: isOpen,
|
|
7362
7744
|
minWidth: 264,
|
|
7363
7745
|
onClose: onClose,
|
|
7746
|
+
onDragEnd: function onDragEnd(position, size) {
|
|
7747
|
+
if (typeof size.width === 'number' && typeof size.height === 'number') {
|
|
7748
|
+
onSizeChange == null || onSizeChange({
|
|
7749
|
+
width: size.width,
|
|
7750
|
+
height: size.height
|
|
7751
|
+
}, position);
|
|
7752
|
+
}
|
|
7753
|
+
},
|
|
7364
7754
|
onMouseDown: onMouseDown,
|
|
7365
7755
|
order: order,
|
|
7756
|
+
resetPositionOnOpen: true,
|
|
7757
|
+
startDraggablePosition: locationMenuPosition != null ? locationMenuPosition : {
|
|
7758
|
+
x: 0,
|
|
7759
|
+
y: 0
|
|
7760
|
+
},
|
|
7366
7761
|
startPosition: {
|
|
7367
7762
|
top: 60,
|
|
7368
7763
|
left: 200
|
|
7369
7764
|
},
|
|
7370
|
-
startSize: {
|
|
7765
|
+
startSize: locationMenuSize != null ? locationMenuSize : {
|
|
7371
7766
|
width: 320,
|
|
7372
7767
|
height: 500
|
|
7373
7768
|
},
|
|
@@ -7483,6 +7878,12 @@ var LocationsMenuConnect = function LocationsMenuConnect(_ref) {
|
|
|
7483
7878
|
dispatch(soundingsActions.setSoundingsCollections(soundingsCollections));
|
|
7484
7879
|
}
|
|
7485
7880
|
}, [dispatch, soundingsCollections]);
|
|
7881
|
+
var locationMenuSize = useSelector(function (state) {
|
|
7882
|
+
return getLocationMenuSize(state, viewId);
|
|
7883
|
+
});
|
|
7884
|
+
var locationMenuPosition = useSelector(function (state) {
|
|
7885
|
+
return getLocationMenuPosition(state, viewId);
|
|
7886
|
+
});
|
|
7486
7887
|
var _useGetLocations = useGetLocations(collections, isDialogOpen),
|
|
7487
7888
|
data = _useGetLocations.data,
|
|
7488
7889
|
isPending = _useGetLocations.isPending,
|
|
@@ -7556,12 +7957,31 @@ var LocationsMenuConnect = function LocationsMenuConnect(_ref) {
|
|
|
7556
7957
|
}
|
|
7557
7958
|
}
|
|
7558
7959
|
}, [dispatch, viewId, services, selectedSourceIds, locationSelections, selectedMapIds, ownedFeatureLayerIds]);
|
|
7960
|
+
var handleSizeChange = useCallback(function (size, position) {
|
|
7961
|
+
dispatch(soundingsActions.setLocationMenuSizeAndPosition({
|
|
7962
|
+
size: size,
|
|
7963
|
+
position: position,
|
|
7964
|
+
viewId: viewId,
|
|
7965
|
+
origin: SoundingsActionOrigin.soundingsComponent
|
|
7966
|
+
}));
|
|
7967
|
+
}, [dispatch, viewId]);
|
|
7968
|
+
var handleClose = useCallback(function () {
|
|
7969
|
+
onCloseDialog();
|
|
7970
|
+
dispatch(soundingsActions.setLocationsMenuOpen({
|
|
7971
|
+
viewId: viewId,
|
|
7972
|
+
isLocationsDialogOpen: false,
|
|
7973
|
+
origin: SoundingsActionOrigin.soundingsComponent
|
|
7974
|
+
}));
|
|
7975
|
+
}, [dispatch, onCloseDialog, viewId]);
|
|
7559
7976
|
return jsx(LocationsMenu, {
|
|
7560
7977
|
error: error,
|
|
7561
7978
|
isLoading: isPending,
|
|
7562
7979
|
isOpen: isDialogOpen,
|
|
7563
|
-
|
|
7980
|
+
locationMenuPosition: locationMenuPosition,
|
|
7981
|
+
locationMenuSize: locationMenuSize,
|
|
7982
|
+
onClose: handleClose,
|
|
7564
7983
|
onMouseDown: setDialogOrder,
|
|
7984
|
+
onSizeChange: handleSizeChange,
|
|
7565
7985
|
order: dialogOrder,
|
|
7566
7986
|
selectedLocations: locationSelections,
|
|
7567
7987
|
selectedSourcesAmount: sourcesAmount,
|