@opengeoweb/soundings 14.3.0 → 14.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js CHANGED
@@ -794,7 +794,7 @@ const translateInTestsAndStories = (key, params = undefined) => i18n.t(key, {
794
794
  });
795
795
  const useSoundingsTranslation = () => useTranslation(ns);
796
796
 
797
- const TIMESLIDER_HEIGHT = 176;
797
+ const TIMESLIDER_HEIGHT = 135;
798
798
  const LABEL_MIN_WIDTH = 48;
799
799
  const useMaxLabelCount = ref => {
800
800
  const [width, setWidth] = React.useState(0);
@@ -2251,19 +2251,40 @@ const Soundings = ({
2251
2251
  });
2252
2252
  };
2253
2253
 
2254
+ const ACCORDION_MIN_WIDTH = 24;
2254
2255
  const SoundingsAccordion = React.forwardRef(({
2255
2256
  name,
2256
- minWidth = 24,
2257
+ minWidth = ACCORDION_MIN_WIDTH,
2257
2258
  maxWidth,
2258
2259
  accordionIsOpen,
2259
2260
  diagramTypeButton,
2260
2261
  handleButtonComponent,
2261
- children
2262
+ children,
2263
+ setSoundingsIsClosed,
2264
+ setPreviousHeight,
2265
+ size
2262
2266
  }, aspectRatioRef) => {
2263
2267
  const containerRef = React.useRef(null);
2264
2268
  const widthRef = React.useRef(null);
2265
2269
  const [isOpen, setIsOpen] = React.useState(false);
2266
2270
  const [autoSizing, setAutoSizing] = React.useState(false);
2271
+ const hasWrittenInitialHeightRef = React.useRef(false);
2272
+ // One-time initial write: when component is open and size is available
2273
+ React.useLayoutEffect(() => {
2274
+ if (!hasWrittenInitialHeightRef.current && isOpen && size != null) {
2275
+ size && setPreviousHeight?.(size);
2276
+ if (size > ACCORDION_MIN_WIDTH) {
2277
+ hasWrittenInitialHeightRef.current = true;
2278
+ }
2279
+ }
2280
+ }, [isOpen, size, setPreviousHeight]);
2281
+ React.useEffect(() => {
2282
+ if (!isOpen) {
2283
+ setSoundingsIsClosed?.(true);
2284
+ } else {
2285
+ setSoundingsIsClosed?.(false);
2286
+ }
2287
+ }, [isOpen, setSoundingsIsClosed]);
2267
2288
  const {
2268
2289
  position: containerWidth,
2269
2290
  setPosition: setContainerWidth,
@@ -2276,6 +2297,7 @@ const SoundingsAccordion = React.forwardRef(({
2276
2297
  initial: minWidth,
2277
2298
  onResizeStart: () => {
2278
2299
  setAutoSizing(false);
2300
+ size && setPreviousHeight?.(size);
2279
2301
  },
2280
2302
  onResizeEnd: ({
2281
2303
  position
@@ -2285,6 +2307,7 @@ const SoundingsAccordion = React.forwardRef(({
2285
2307
  return;
2286
2308
  }
2287
2309
  widthRef.current = position;
2310
+ size && setPreviousHeight?.(size);
2288
2311
  }
2289
2312
  });
2290
2313
  const openAccordion = () => {
@@ -2298,10 +2321,14 @@ const SoundingsAccordion = React.forwardRef(({
2298
2321
  setIsOpen(true);
2299
2322
  };
2300
2323
  const closeAccordion = React.useCallback(() => {
2324
+ // Persist the D3 size immediately to avoid render lag downstream
2325
+ size && setPreviousHeight?.(size);
2326
+ // Inform parent it's closing before toggling local state
2327
+ setSoundingsIsClosed?.(true);
2301
2328
  setContainerWidth(minWidth);
2302
2329
  setIsOpen(false);
2303
2330
  setAutoSizing(false);
2304
- }, [minWidth, setContainerWidth]);
2331
+ }, [minWidth, setContainerWidth, setPreviousHeight, setSoundingsIsClosed, size]);
2305
2332
  React.useEffect(() => {
2306
2333
  if (accordionIsOpen) {
2307
2334
  setIsOpen(true);
@@ -2314,13 +2341,15 @@ const SoundingsAccordion = React.forwardRef(({
2314
2341
  }
2315
2342
  if (!isOpen && containerWidth > minWidth) {
2316
2343
  setIsOpen(true);
2344
+ setSoundingsIsClosed?.(false);
2317
2345
  return;
2318
2346
  }
2319
2347
  if (isOpen && containerWidth <= minWidth) {
2320
2348
  setIsOpen(false);
2321
2349
  setAutoSizing(false);
2350
+ setSoundingsIsClosed?.(true);
2322
2351
  }
2323
- }, [autoSizing, containerWidth, isOpen, minWidth, setContainerWidth]);
2352
+ }, [autoSizing, containerWidth, isOpen, minWidth, setContainerWidth, setSoundingsIsClosed]);
2324
2353
  React.useLayoutEffect(() => {
2325
2354
  if (!autoSizing || !containerRef.current) {
2326
2355
  return;
@@ -2895,11 +2924,13 @@ const extendXAxis = (path, horizontalBarbMargin) => {
2895
2924
  };
2896
2925
  const drawWindBarbs = ({
2897
2926
  svgRef,
2927
+ plotGroup,
2898
2928
  yScale,
2899
2929
  data,
2900
2930
  width,
2901
2931
  margin,
2902
- barbColor = 'black'
2932
+ barbColor = 'black',
2933
+ columnOffsetX = 0
2903
2934
  }) => {
2904
2935
  const barbsSize = 40;
2905
2936
  const scalingFactor = 0.5;
@@ -2907,8 +2938,8 @@ const drawWindBarbs = ({
2907
2938
  const visibleItems = removeItemsExponential(data.reverse()).filter(item => item.pressure >= 150);
2908
2939
  // Measure width and height and make extra room for one column
2909
2940
  // of windbarbs
2910
- const svg = d3.select(svgRef.current);
2911
- const currentWidth = svg.node()?.getBoundingClientRect().width;
2941
+ const rootSvg = d3.select(svgRef.current);
2942
+ const currentWidth = rootSvg.node()?.getBoundingClientRect().width;
2912
2943
  if (!currentWidth) {
2913
2944
  return;
2914
2945
  }
@@ -2924,12 +2955,16 @@ const drawWindBarbs = ({
2924
2955
  const newD = extendXAxis(path, horizontalBarbMargin);
2925
2956
  d3.select(nodes[i]).attr('d', newD);
2926
2957
  });
2927
- svg.attr('width', currentWidth + margin.left + horizontalBarbMargin);
2928
- const windBarbColumnX = (currentWidth ?? width) - width + horizontalBarbMargin;
2929
- const barbGroup = svg.append('g').attr('class', 'wind-group').attr('transform',
2958
+ // Expand root SVG width to make room for barbs column at the right
2959
+ rootSvg.attr('width', currentWidth + margin.left + horizontalBarbMargin);
2960
+ // Place the barbs just to the right of the plotting area.
2961
+ // plotGroup's origin is already translated to (margin.left, margin.top),
2962
+ // and its width equals `width`.
2963
+ const windBarbColumnX = width + 5 + columnOffsetX;
2964
+ const barbGroup = plotGroup.append('g').attr('class', 'wind-group').attr('transform',
2930
2965
  // This translation should be revisited when implementing
2931
2966
  // the plotting of several datasets at once
2932
- `translate(${windBarbColumnX}, ${margin.top})`);
2967
+ `translate(${windBarbColumnX}, 0)`);
2933
2968
  barbGroup.selectAll('g').data(visibleItems).enter().append('g').attr('id', 'wind-barb').each(function handleBarb(data) {
2934
2969
  const group = d3.select(this);
2935
2970
  const windSymbol = getWindSymbol(data.windSpeed);
@@ -2992,6 +3027,29 @@ const getWindSymbol = value => {
2992
3027
  return svgNode;
2993
3028
  };
2994
3029
 
3030
+ /* *
3031
+ * Licensed under the Apache License, Version 2.0 (the "License");
3032
+ * you may not use this file except in compliance with the License.
3033
+ * You may obtain a copy of the License at
3034
+ *
3035
+ * http://www.apache.org/licenses/LICENSE-2.0
3036
+ *
3037
+ * Unless required by applicable law or agreed to in writing, software
3038
+ * distributed under the License is distributed on an "AS IS" BASIS,
3039
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3040
+ * See the License for the specific language governing permissions and
3041
+ * limitations under the License.
3042
+ *
3043
+ * Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3044
+ * Copyright 2025 - Finnish Meteorological Institute (FMI)
3045
+ * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
3046
+ * */
3047
+ const animateResizeTransform = (svg, marginLocal, innerHeight, prevInnerHeightRef) => {
3048
+ const prevInnerHeight = typeof prevInnerHeightRef.current === 'number' ? prevInnerHeightRef.current : 0;
3049
+ const scaleYStart = prevInnerHeight > 0 && innerHeight > 0 ? prevInnerHeight / innerHeight : 0;
3050
+ svg.attr('transform', `translate(${marginLocal.left},${marginLocal.top}) scale(1,${scaleYStart})`).transition().duration(300).attr('transform', `translate(${marginLocal.left},${marginLocal.top}) scale(1,1)`);
3051
+ };
3052
+
2995
3053
  const 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)';
2996
3054
  const soundingsStyle = {
2997
3055
  tooltip: {
@@ -3009,16 +3067,19 @@ const soundingsStyle = {
3009
3067
  fontWeight: 'bold'
3010
3068
  }
3011
3069
  };
3070
+ const WIND_BARB_OFFSET_X = 35;
3012
3071
  const WindBarbs = ({
3013
3072
  d3GraphId,
3014
3073
  data,
3015
3074
  svgDimensions,
3016
3075
  showTooltip = true,
3017
- diagramType = 'SKEWT'
3076
+ diagramType = 'SKEWT',
3077
+ animateResize = false
3018
3078
  }) => {
3019
3079
  const svgRef = useRef(null);
3020
3080
  const canvasRef = useRef(null);
3021
3081
  const windRef = useRef(null);
3082
+ const prevInnerHeightRef = useRef(null);
3022
3083
  const svgDimensionsOptions = {
3023
3084
  width: svgDimensions?.width || 812,
3024
3085
  height: svgDimensions?.height || 802,
@@ -3029,7 +3090,6 @@ const WindBarbs = ({
3029
3090
  left: svgDimensions?.margin?.left || 20
3030
3091
  }
3031
3092
  };
3032
- // Set SVG dimensions
3033
3093
  const margin = svgDimensionsOptions?.margin;
3034
3094
  const baseWidth = svgDimensionsOptions?.width;
3035
3095
  const baseHeight = svgDimensionsOptions?.height;
@@ -3050,6 +3110,10 @@ const WindBarbs = ({
3050
3110
  diagramType,
3051
3111
  d3GraphId
3052
3112
  });
3113
+ // When Soundings is dragged close, animate the Wind Barbs to resize back to the height where dragging started
3114
+ if (animateResize) {
3115
+ animateResizeTransform(svg, margin, height, prevInnerHeightRef);
3116
+ }
3053
3117
  const svgRectangle = svgRef.current.getBoundingClientRect();
3054
3118
  const minT = diagramType === 'EMAGRAM' ? minEmagramTemperature : minTemperature;
3055
3119
  const maxT = maxTemperature;
@@ -3072,11 +3136,13 @@ const WindBarbs = ({
3072
3136
  }));
3073
3137
  drawWindBarbs({
3074
3138
  svgRef,
3139
+ plotGroup: svg,
3075
3140
  yScale,
3076
3141
  data: windData,
3077
3142
  width,
3078
3143
  margin: margin,
3079
- barbColor: color
3144
+ barbColor: color,
3145
+ columnOffsetX: index * WIND_BARB_OFFSET_X
3080
3146
  });
3081
3147
  });
3082
3148
  let handleMove = null;
@@ -3098,6 +3164,8 @@ const WindBarbs = ({
3098
3164
  };
3099
3165
  canvasRef.current.addEventListener('mousemove', handleMove);
3100
3166
  }
3167
+ // Update previous inner height after drawing so animation uses the prior value
3168
+ prevInnerHeightRef.current = height;
3101
3169
  // eslint-disable-next-line consistent-return, @typescript-eslint/explicit-function-return-type
3102
3170
  return () => {
3103
3171
  root.selectAll('*').remove();
@@ -3161,6 +3229,8 @@ const SortableAccordions = ({
3161
3229
  }, {
3162
3230
  id: 'windBarbs'
3163
3231
  }]);
3232
+ const [soundingsIsClosed, setSoundingsIsClosed] = React.useState(false);
3233
+ const [previousHeight, setPreviousHeight] = React.useState(size);
3164
3234
  const createPanel = React.useCallback(id => {
3165
3235
  switch (id) {
3166
3236
  case 'soundings':
@@ -3168,6 +3238,9 @@ const SortableAccordions = ({
3168
3238
  ref: viewRef,
3169
3239
  name: "Soundings",
3170
3240
  accordionIsOpen: true,
3241
+ setSoundingsIsClosed: setSoundingsIsClosed,
3242
+ setPreviousHeight: setPreviousHeight,
3243
+ size: size,
3171
3244
  diagramTypeButton: jsx(DiagramTypeButton, {
3172
3245
  diagramType: chosenDiagramType,
3173
3246
  setDiagramType: setChosenDiagramType
@@ -3179,10 +3252,10 @@ const SortableAccordions = ({
3179
3252
  width: size,
3180
3253
  height: size,
3181
3254
  margin: {
3182
- bottom: 0,
3183
- left: 0,
3184
- right: 0,
3185
- top: 0
3255
+ bottom: 25,
3256
+ left: 25,
3257
+ right: 25,
3258
+ top: 25
3186
3259
  }
3187
3260
  },
3188
3261
  diagramType: chosenDiagramType
@@ -3198,20 +3271,21 @@ const SortableAccordions = ({
3198
3271
  diagramType: chosenDiagramType,
3199
3272
  svgDimensions: {
3200
3273
  width: 100,
3201
- height: size,
3202
3274
  margin: {
3203
- bottom: 0,
3204
- left: 0,
3205
- right: 0,
3206
- top: 0
3207
- }
3208
- }
3275
+ bottom: 25,
3276
+ left: 25,
3277
+ right: 25,
3278
+ top: 25
3279
+ },
3280
+ height: soundingsIsClosed ? previousHeight ?? size : size
3281
+ },
3282
+ animateResize: Boolean(soundingsIsClosed && previousHeight)
3209
3283
  })
3210
3284
  });
3211
3285
  default:
3212
3286
  return null;
3213
3287
  }
3214
- }, [data, size, chosenDiagramType, setChosenDiagramType, viewRef]);
3288
+ }, [viewRef, size, chosenDiagramType, setChosenDiagramType, data, soundingsIsClosed, previousHeight]);
3215
3289
  return jsx(Box, {
3216
3290
  sx: {
3217
3291
  display: 'flex',
@@ -3259,32 +3333,31 @@ const SortableAccordions = ({
3259
3333
  });
3260
3334
  };
3261
3335
 
3262
- const DIAGRAM_TYPE_BUTTON_HEIGHT = 28;
3263
- const useGetSize = (viewRef, legendRef) => {
3336
+ const useGetSize = viewRef => {
3264
3337
  const [size, setSize] = React.useState(0);
3265
3338
  React.useLayoutEffect(() => {
3266
- let resizeObserver;
3267
- if (viewRef.current) {
3268
- resizeObserver = new ResizeObserver(entry => {
3269
- const {
3270
- width,
3271
- height
3272
- } = entry[0].target.getBoundingClientRect();
3273
- const availableWidth = width; // currently ignoring the windbarbs as they will be moved to a separate panel
3274
- const legendHeight = legendRef.current?.getBoundingClientRect().height || 0;
3275
- const availableHeight = height - legendHeight - DIAGRAM_TYPE_BUTTON_HEIGHT - TIMESLIDER_HEIGHT;
3276
- // set size to the smallest of available width and height to keep the diagram square
3277
- const newSize = Math.min(availableWidth, availableHeight);
3278
- setSize(newSize);
3279
- });
3280
- resizeObserver.observe(viewRef.current);
3339
+ const container = viewRef.current;
3340
+ if (!container) {
3341
+ return undefined;
3281
3342
  }
3282
- return () => {
3283
- if (resizeObserver) {
3284
- resizeObserver.disconnect();
3343
+ const OFFSET_HEIGHT = 100; // Space reserved in layout
3344
+ const resizeObserver = new ResizeObserver(entries => {
3345
+ if (!entries.length) {
3346
+ return;
3285
3347
  }
3348
+ const {
3349
+ width,
3350
+ height
3351
+ } = entries[0].contentRect;
3352
+ const availableHeight = height - TIMESLIDER_HEIGHT + OFFSET_HEIGHT;
3353
+ const nextSize = Math.floor(Math.min(width, availableHeight));
3354
+ setSize(nextSize > 0 ? nextSize : 0);
3355
+ });
3356
+ resizeObserver.observe(container);
3357
+ return () => {
3358
+ resizeObserver.disconnect();
3286
3359
  };
3287
- }, [legendRef, viewRef]);
3360
+ }, [viewRef]);
3288
3361
  return size;
3289
3362
  };
3290
3363
  const SoundingsConnect = ({
@@ -3292,8 +3365,7 @@ const SoundingsConnect = ({
3292
3365
  diagramType = 'SKEWT'
3293
3366
  }) => {
3294
3367
  const viewRef = React.useRef(null);
3295
- const legendRef = React.useRef(null);
3296
- const size = useGetSize(viewRef, legendRef);
3368
+ const size = useGetSize(viewRef);
3297
3369
  const [chosenDiagramType, setChosenDiagramType] = React.useState(diagramType);
3298
3370
  const geojsonLayerId = React.useRef(webmapUtils.generateLayerId()).current;
3299
3371
  const dispatch = useDispatch();
@@ -3420,44 +3492,52 @@ const SoundingsConnect = ({
3420
3492
  children: jsx(MenuBarConnect, {
3421
3493
  viewId: viewId
3422
3494
  })
3423
- }), jsxs(Card, {
3495
+ }), jsx(Card, {
3424
3496
  sx: {
3425
3497
  width: '100%',
3426
3498
  height: '100%'
3427
3499
  },
3428
- children: [jsx(Box, {
3429
- sx: {
3430
- display: 'flex',
3431
- justifyContent: 'center',
3432
- paddingTop: '2px',
3433
- paddingRight: '2px',
3434
- minHeight: '24px',
3435
- width: '100%'
3436
- },
3437
- ref: legendRef,
3438
- children: jsx(SoundingsLegend, {
3439
- sourceSelections: sourceSelections
3440
- })
3441
- }), jsxs(Stack, {
3500
+ children: jsxs(Stack, {
3442
3501
  sx: {
3443
3502
  width: '100%',
3444
3503
  height: '100%',
3445
3504
  display: 'flex'
3446
3505
  },
3447
3506
  spacing: 1,
3448
- children: [jsx(SortableAccordions, {
3449
- data: data,
3450
- size: size,
3451
- chosenDiagramType: chosenDiagramType,
3452
- setChosenDiagramType: setChosenDiagramType,
3453
- viewRef: viewRef
3507
+ children: [jsx(Box, {
3508
+ sx: {
3509
+ display: 'flex',
3510
+ justifyContent: 'center',
3511
+ paddingTop: '2px',
3512
+ paddingRight: '2px',
3513
+ minHeight: '24px',
3514
+ width: '100%'
3515
+ },
3516
+ children: jsx(SoundingsLegend, {
3517
+ sourceSelections: sourceSelections
3518
+ })
3454
3519
  }), jsx(Box, {
3455
3520
  sx: {
3521
+ flex: 1,
3522
+ minHeight: 0,
3456
3523
  width: '100%'
3457
3524
  },
3525
+ children: jsx(SortableAccordions, {
3526
+ data: data,
3527
+ size: size,
3528
+ chosenDiagramType: chosenDiagramType,
3529
+ setChosenDiagramType: setChosenDiagramType,
3530
+ viewRef: viewRef
3531
+ })
3532
+ }), jsx(Box, {
3533
+ sx: {
3534
+ width: '100%',
3535
+ flex: '0 0 auto',
3536
+ height: `${TIMESLIDER_HEIGHT}px`
3537
+ },
3458
3538
  children: jsx(SoundingsTimeSliderConnect, {})
3459
3539
  })]
3460
- })]
3540
+ })
3461
3541
  })]
3462
3542
  })]
3463
3543
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/soundings",
3
- "version": "14.3.0",
3
+ "version": "14.4.0",
4
4
  "description": "GeoWeb soundings library for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -8,24 +8,24 @@
8
8
  "url": "git@gitlab.com:opengeoweb/opengeoweb.git"
9
9
  },
10
10
  "dependencies": {
11
- "@opengeoweb/api": "14.3.0",
11
+ "@opengeoweb/api": "14.4.0",
12
12
  "@tanstack/react-query": "^5.85.5",
13
13
  "react": "^18.3.1",
14
14
  "d3": "^7.9.0",
15
15
  "react-i18next": "^15.1.1",
16
16
  "i18next": "^25.0.1",
17
- "@opengeoweb/shared": "14.3.0",
17
+ "@opengeoweb/shared": "14.4.0",
18
18
  "@mui/material": "^7.0.1",
19
- "@opengeoweb/store": "14.3.0",
19
+ "@opengeoweb/store": "14.4.0",
20
20
  "react-redux": "^9.2.0",
21
- "@opengeoweb/theme": "14.3.0",
21
+ "@opengeoweb/theme": "14.4.0",
22
22
  "@reduxjs/toolkit": "^2.6.1",
23
- "@opengeoweb/time-slider": "14.3.0",
23
+ "@opengeoweb/time-slider": "14.4.0",
24
24
  "react-window": "^1.8.10",
25
- "@opengeoweb/webmap": "14.3.0",
25
+ "@opengeoweb/webmap": "14.4.0",
26
26
  "lodash": "^4.17.21",
27
27
  "@types/geojson": "^7946.0.14",
28
- "@opengeoweb/webmap-react": "14.3.0",
28
+ "@opengeoweb/webmap-react": "14.4.0",
29
29
  "react-resizable-layout": "^0.7.3",
30
30
  "react-sortablejs": "^6.1.4"
31
31
  },
@@ -8,6 +8,8 @@ export default _default;
8
8
  type Story = StoryObj<typeof SoundingsConnect>;
9
9
  export declare const SoundingsConnectStory: Story;
10
10
  export declare const SoundingsConnectStoryDark: Story;
11
+ export declare const SoundingsClosedWindBarbsOpenStory: Story;
12
+ export declare const SoundingsClosedWindBarbsOpenStoryDark: Story;
11
13
  export declare const SoundingsConnectLoading: {
12
14
  (): React.ReactElement;
13
15
  parameters: {
@@ -11,5 +11,6 @@ export interface WindBarbsProps {
11
11
  };
12
12
  showTooltip?: boolean;
13
13
  diagramType?: SoundingDiagramType;
14
+ animateResize?: boolean;
14
15
  }
15
16
  export declare const WindBarbs: React.FC<WindBarbsProps>;
@@ -0,0 +1,4 @@
1
+ import type { MutableRefObject } from 'react';
2
+ import * as d3 from 'd3';
3
+ import { Margin } from './drawUtils';
4
+ export declare const animateResizeTransform: (svg: d3.Selection<SVGElement, unknown, HTMLElement, unknown>, marginLocal: Margin, innerHeight: number, prevInnerHeightRef: MutableRefObject<number | null>) => void;
@@ -7,5 +7,8 @@ export interface SoundingsAccordionProps {
7
7
  diagramTypeButton?: React.ReactElement;
8
8
  handleButtonComponent?: React.ReactElement;
9
9
  children?: React.ReactNode;
10
+ setSoundingsIsClosed?: (isClosed: boolean) => void;
11
+ setPreviousHeight?: (size: number) => void;
12
+ size?: number;
10
13
  }
11
14
  export declare const SoundingsAccordion: React.ForwardRefExoticComponent<SoundingsAccordionProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- export declare const TIMESLIDER_HEIGHT = 176;
2
+ export declare const TIMESLIDER_HEIGHT = 135;
3
3
  export interface SoundingsTimeSliderProps {
4
4
  timesteps: string[];
5
5
  selectedTime: string;
@@ -1,3 +1,4 @@
1
+ import * as d3 from 'd3';
1
2
  import React from 'react';
2
3
  import { Margin } from '../Soundings/drawUtils';
3
4
  import { ScalesType } from '../Soundings/types';
@@ -8,12 +9,14 @@ export interface WindDataType {
8
9
  }
9
10
  export interface DrawWindBarbsProps {
10
11
  svgRef: React.MutableRefObject<SVGSVGElement | null>;
12
+ plotGroup: d3.Selection<SVGElement, unknown, HTMLElement, unknown>;
11
13
  yScale: ScalesType;
12
14
  data: WindDataType[];
13
15
  width: number;
14
16
  margin: Margin;
15
17
  barbColor?: string;
18
+ columnOffsetX?: number;
16
19
  }
17
- export declare const drawWindBarbs: ({ svgRef, yScale, data, width, margin, barbColor, }: DrawWindBarbsProps) => void;
20
+ export declare const drawWindBarbs: ({ svgRef, plotGroup, yScale, data, width, margin, barbColor, columnOffsetX, }: DrawWindBarbsProps) => void;
18
21
  export declare const removeItemsExponential: (array: WindDataType[]) => WindDataType[];
19
22
  export declare const getWindSymbol: (value: number) => Node | null;