@centreon/ui 25.2.2 → 25.2.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "25.2.2",
3
+ "version": "25.2.3",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "update:deps": "pnpx npm-check-updates -i --format group",
@@ -1,10 +1,8 @@
1
- import { memo, useMemo } from 'react';
2
-
3
- import { Group } from '@visx/group';
4
1
  import { scaleBand, scaleOrdinal } from '@visx/scale';
5
2
  import { BarGroupHorizontal, BarGroup as VisxBarGroup } from '@visx/shape';
6
3
  import { ScaleLinear } from 'd3-scale';
7
4
  import { difference, equals, keys, omit, pick, pluck, uniq } from 'ramda';
5
+ import { memo, useMemo } from 'react';
8
6
 
9
7
  import { useDeepMemo } from '../../utils';
10
8
  import {
@@ -14,8 +12,7 @@ import {
14
12
  getUnits
15
13
  } from '../common/timeSeries';
16
14
  import { Line, TimeValue } from '../common/timeSeries/models';
17
-
18
- import BarStack from './BarStack';
15
+ import MemoizedGroup from './MemoizedGroup';
19
16
  import { BarStyle } from './models';
20
17
 
21
18
  // Minimum value for logarithmic scale to avoid log(0)
@@ -161,60 +158,23 @@ const BarGroup = ({
161
158
  {...barComponentBaseProps}
162
159
  >
163
160
  {(barGroups) =>
164
- barGroups.map((barGroup) => (
165
- <Group
166
- key={`bar-group-${barGroup.index}-${barGroup.x0}`}
167
- left={barGroup.x0}
168
- top={barGroup.y0}
169
- >
170
- {barGroup.bars.map((bar) => {
171
- const isStackedBar = bar.key.startsWith('stacked-');
172
- const linesBar = isStackedBar
173
- ? stackedLinesTimeSeriesPerUnit[bar.key.replace('stacked-', '')]
174
- .lines
175
- : (notStackedLines.find(({ metric_id }) =>
176
- equals(metric_id, Number(bar.key))
177
- ) as Line);
178
- const timeSeriesBar = isStackedBar
179
- ? stackedLinesTimeSeriesPerUnit[bar.key.replace('stacked-', '')]
180
- .timeSeries
181
- : notStackedTimeSeries.map((timeSerie) => ({
182
- timeTick: timeSerie.timeTick,
183
- [bar.key]: timeSerie[Number(bar.key)]
184
- }));
185
-
186
- return isStackedBar ? (
187
- <BarStack
188
- key={`bar-${barGroup.index}-${bar.width}-${bar.y}-${bar.height}-${bar.x}`}
189
- barIndex={barGroup.index}
190
- barPadding={isHorizontal ? bar.x : bar.y}
191
- barStyle={barStyle}
192
- barWidth={isHorizontal ? bar.width : bar.height}
193
- isHorizontal={isHorizontal}
194
- isTooltipHidden={isTooltipHidden}
195
- lines={linesBar}
196
- timeSeries={timeSeriesBar}
197
- yScale={yScalesPerUnit[bar.key.replace('stacked-', '')]}
198
- neutralValue={neutralValue}
199
- />
200
- ) : (
201
- <BarStack
202
- key={`bar-${barGroup.index}-${bar.width}-${bar.y}-${bar.height}-${bar.x}`}
203
- barIndex={barGroup.index}
204
- barPadding={isHorizontal ? bar.x : bar.y}
205
- barStyle={barStyle}
206
- barWidth={isHorizontal ? bar.width : bar.height}
207
- isHorizontal={isHorizontal}
208
- isTooltipHidden={isTooltipHidden}
209
- lines={[linesBar]}
210
- timeSeries={timeSeriesBar}
211
- yScale={yScalesPerUnit[linesBar.unit]}
212
- neutralValue={neutralValue}
213
- />
214
- );
215
- })}
216
- </Group>
217
- ))
161
+ barGroups.map((barGroup, index) => {
162
+ return (
163
+ <MemoizedGroup
164
+ key={`bar-group-${barGroup.index}-${barGroup.x0}`}
165
+ barGroup={barGroup}
166
+ barStyle={barStyle}
167
+ stackedLinesTimeSeriesPerUnit={stackedLinesTimeSeriesPerUnit}
168
+ notStackedTimeSeries={notStackedTimeSeries}
169
+ notStackedLines={notStackedLines}
170
+ isTooltipHidden={isTooltipHidden}
171
+ isHorizontal={isHorizontal}
172
+ neutralValue={neutralValue}
173
+ yScalesPerUnit={yScalesPerUnit}
174
+ barIndex={index}
175
+ />
176
+ );
177
+ })
218
178
  }
219
179
  </BarComponent>
220
180
  );
@@ -0,0 +1,123 @@
1
+ import { Group } from '@visx/group';
2
+ import { BarGroup } from '@visx/shape/lib/types';
3
+ import { ScaleLinear } from 'd3-scale';
4
+ import { equals, omit } from 'ramda';
5
+ import { memo } from 'react';
6
+ import { Line, TimeValue } from '../common/timeSeries/models';
7
+ import BarStack from './BarStack';
8
+ import { BarStyle } from './models';
9
+
10
+ interface Props {
11
+ neutralValue: number;
12
+ isTooltipHidden: boolean;
13
+ barStyle: BarStyle;
14
+ yScalesPerUnit: Record<string, ScaleLinear<number, number>>;
15
+ stackedLinesTimeSeriesPerUnit: Record<
16
+ string,
17
+ { lines: Array<Line>; timeSeries: Array<TimeValue> }
18
+ >;
19
+ notStackedLines: Array<Line>;
20
+ notStackedTimeSeries: Array<TimeValue>;
21
+ isHorizontal: boolean;
22
+ barGroup: BarGroup<'id'>;
23
+ barIndex: number;
24
+ }
25
+
26
+ const MemoizedGroup = ({
27
+ barGroup,
28
+ stackedLinesTimeSeriesPerUnit,
29
+ notStackedLines,
30
+ notStackedTimeSeries,
31
+ isHorizontal,
32
+ barStyle,
33
+ isTooltipHidden,
34
+ neutralValue,
35
+ yScalesPerUnit,
36
+ barIndex
37
+ }: Props): JSX.Element | null => {
38
+ const hasEmptyValues = barGroup.bars.every(({ key, value }) => {
39
+ if (key.startsWith('stacked-')) {
40
+ const timeValueBar =
41
+ stackedLinesTimeSeriesPerUnit[key.replace('stacked-', '')].timeSeries[
42
+ barIndex
43
+ ];
44
+
45
+ return Object.values(omit(['timeTick'], timeValueBar)).every(
46
+ (value) => !value
47
+ );
48
+ }
49
+
50
+ return !value;
51
+ });
52
+
53
+ if (hasEmptyValues) {
54
+ return null;
55
+ }
56
+
57
+ return (
58
+ <Group left={barGroup.x0} top={barGroup.y0}>
59
+ {barGroup.bars.map((bar) => {
60
+ const isStackedBar = bar.key.startsWith('stacked-');
61
+ const linesBar = isStackedBar
62
+ ? stackedLinesTimeSeriesPerUnit[bar.key.replace('stacked-', '')].lines
63
+ : (notStackedLines.find(({ metric_id }) =>
64
+ equals(metric_id, Number(bar.key))
65
+ ) as Line);
66
+ const timeSeriesBar = isStackedBar
67
+ ? stackedLinesTimeSeriesPerUnit[bar.key.replace('stacked-', '')]
68
+ .timeSeries
69
+ : notStackedTimeSeries.map((timeSerie) => ({
70
+ timeTick: timeSerie.timeTick,
71
+ [bar.key]: timeSerie[Number(bar.key)]
72
+ }));
73
+
74
+ return isStackedBar ? (
75
+ <BarStack
76
+ key={`bar-${barGroup.index}-${bar.width}-${bar.y}-${bar.height}-${bar.x}`}
77
+ barIndex={barGroup.index}
78
+ barPadding={isHorizontal ? bar.x : bar.y}
79
+ barStyle={barStyle}
80
+ barWidth={isHorizontal ? bar.width : bar.height}
81
+ isHorizontal={isHorizontal}
82
+ isTooltipHidden={isTooltipHidden}
83
+ lines={linesBar as Array<Line>}
84
+ timeSeries={timeSeriesBar}
85
+ yScale={yScalesPerUnit[bar.key.replace('stacked-', '')]}
86
+ neutralValue={neutralValue}
87
+ />
88
+ ) : (
89
+ <BarStack
90
+ key={`bar-${barGroup.index}-${bar.width}-${bar.y}-${bar.height}-${bar.x}`}
91
+ barIndex={barGroup.index}
92
+ barPadding={isHorizontal ? bar.x : bar.y}
93
+ barStyle={barStyle}
94
+ barWidth={isHorizontal ? bar.width : bar.height}
95
+ isHorizontal={isHorizontal}
96
+ isTooltipHidden={isTooltipHidden}
97
+ lines={[linesBar as Line]}
98
+ timeSeries={timeSeriesBar}
99
+ yScale={yScalesPerUnit[(linesBar as Line).unit]}
100
+ neutralValue={neutralValue}
101
+ />
102
+ );
103
+ })}
104
+ </Group>
105
+ );
106
+ };
107
+
108
+ export default memo(
109
+ MemoizedGroup,
110
+ (prevProps, nextProps) =>
111
+ equals(prevProps.barGroup, nextProps.barGroup) &&
112
+ equals(
113
+ prevProps.stackedLinesTimeSeriesPerUnit,
114
+ nextProps.stackedLinesTimeSeriesPerUnit
115
+ ) &&
116
+ equals(prevProps.notStackedLines, nextProps.notStackedLines) &&
117
+ equals(prevProps.notStackedTimeSeries, nextProps.notStackedTimeSeries) &&
118
+ equals(prevProps.isHorizontal, nextProps.isHorizontal) &&
119
+ equals(prevProps.barStyle, nextProps.barStyle) &&
120
+ equals(prevProps.isTooltipHidden, nextProps.isTooltipHidden) &&
121
+ equals(prevProps.neutralValue, nextProps.neutralValue) &&
122
+ equals(prevProps.barIndex, nextProps.barIndex)
123
+ );
@@ -362,8 +362,6 @@ describe('Line chart', () => {
362
362
  cy.get('[data-as-list="true"]').should('exist');
363
363
 
364
364
  cy.contains(':00 AM').should('be.visible');
365
-
366
- cy.makeSnapshot();
367
365
  });
368
366
 
369
367
  it('displays the legend on the right side of the graph as list when the corresponding props are set', () => {
@@ -583,7 +581,6 @@ describe('Lines and bars', () => {
583
581
  cy.get('path[data-metric="3"]').should('be.visible');
584
582
  cy.get('path[data-metric="3"]').should('be.visible');
585
583
  cy.findByTestId('stacked-bar-10-0-7650.368581547736').should('be.visible');
586
- cy.findByTestId('stacked-bar-2-0-10').should('be.visible');
587
584
 
588
585
  cy.makeSnapshot();
589
586
  });
@@ -634,7 +631,6 @@ describe('Lines and bars', () => {
634
631
  cy.get('path[data-metric="3"]').should('be.visible');
635
632
  cy.get('path[data-metric="3"]').should('be.visible');
636
633
  cy.findByTestId('stacked-bar-10-0-7650.368581547736').should('be.visible');
637
- cy.findByTestId('stacked-bar-2-0-10').should('be.visible');
638
634
 
639
635
  cy.makeSnapshot();
640
636
  });
@@ -669,7 +669,7 @@ export const linesAndBarsMixedCenteredZero: Story = {
669
669
  )
670
670
  };
671
671
  const CustomYUnits = (props): JSX.Element => {
672
- const [leftUnit, setLeftUnit] = useState('b');
672
+ const [leftUnit, setLeftUnit] = useState('B');
673
673
  const [rightUnit, setRightUnit] = useState('ms');
674
674
 
675
675
  return (
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "global": {
3
3
  "base": 1000,
4
- "title": "ping service"
4
+ "title": "Ping service"
5
5
  },
6
6
  "metrics": [
7
7
  {
8
8
  "metric_id": 2,
9
- "metric": "centreon-server: pl",
10
- "metric_legend": "centreon-server: pl",
11
- "unit": "%",
9
+ "metric": "Centreon-Server: pl",
10
+ "metric_legend": "Centreon-Server: pl",
11
+ "unit": "B",
12
12
  "min": 0.0,
13
13
  "max": 100.0,
14
14
  "ds_data": {
15
- "ds_color_line": "#f30b23",
16
- "ds_color_area": "#f30b23",
15
+ "ds_color_line": "#F30B23",
16
+ "ds_color_area": "#F30B23",
17
17
  "ds_filled": true,
18
18
  "ds_invert": false,
19
19
  "ds_legend": null,
@@ -23,7 +23,7 @@
23
23
  "ds_color_line_mode": 0
24
24
  },
25
25
  "displayAs": "bar",
26
- "legend": "centreon-server: packet loss",
26
+ "legend": "Centreon-Server: Packet Loss",
27
27
  "stack": 0,
28
28
  "warning_high_threshold": 20.0,
29
29
  "critical_high_threshold": 50.0,
@@ -31,17 +31,17 @@
31
31
  "critical_low_threshold": 0.0,
32
32
  "ds_order": 1,
33
33
  "data": [
34
- 0.0,
35
- 0.0,
36
- 0.0,
37
- 0.0,
38
- 0.0,
39
- 0.0,
40
- 0.0,
41
- 0.0,
42
- 0.0,
43
- 10.0,
44
- 20.0,
34
+ 1243.0,
35
+ 3562.0,
36
+ 3532.0,
37
+ 9843.0,
38
+ 3332.0,
39
+ 6576.0,
40
+ 5647.0,
41
+ 8763.0,
42
+ 7487.0,
43
+ 4783.0,
44
+ 6835.0,
45
45
  null,
46
46
  null
47
47
  ],
@@ -52,9 +52,9 @@
52
52
  },
53
53
  {
54
54
  "metric_id": 10,
55
- "metric": "space used",
56
- "metric_legend": "space used",
57
- "unit": "b",
55
+ "metric": "Space used",
56
+ "metric_legend": "Space used",
57
+ "unit": "B",
58
58
  "min": 0.0,
59
59
  "max": 100.0,
60
60
  "ds_data": {
@@ -69,7 +69,7 @@
69
69
  "ds_color_line_mode": 0
70
70
  },
71
71
  "displayAs": "bar",
72
- "legend": "space used",
72
+ "legend": "Space used",
73
73
  "stack": 0,
74
74
  "warning_high_threshold": 20.0,
75
75
  "critical_high_threshold": 50.0,
@@ -90,14 +90,14 @@
90
90
  },
91
91
  {
92
92
  "metric_id": 1,
93
- "metric": "centreon-server: rta",
94
- "metric_legend": "centreon-server: rta",
93
+ "metric": "Centreon-Server: rta",
94
+ "metric_legend": "Centreon-Server: rta",
95
95
  "unit": "ms",
96
96
  "min": 0.0,
97
97
  "max": null,
98
98
  "ds_data": {
99
- "ds_color_line": "#29afee",
100
- "ds_color_area": "#29afee",
99
+ "ds_color_line": "#29AFEE",
100
+ "ds_color_area": "#29AFEE",
101
101
  "ds_filled": true,
102
102
  "ds_invert": false,
103
103
  "ds_legend": null,
@@ -107,7 +107,7 @@
107
107
  "ds_color_line_mode": 0
108
108
  },
109
109
  "displayAs": "line",
110
- "legend": "centreon-server: round-trip average time",
110
+ "legend": "Centreon-Server: Round-Trip Average Time",
111
111
  "stack": 0,
112
112
  "warning_high_threshold": 200.0,
113
113
  "critical_high_threshold": 400.0,
@@ -136,8 +136,8 @@
136
136
  },
137
137
  {
138
138
  "metric_id": 3,
139
- "metric": "centreon-server: rtmax",
140
- "metric_legend": "centreon-server: rtmax",
139
+ "metric": "Centreon-Server: rtmax",
140
+ "metric_legend": "Centreon-Server: rtmax",
141
141
  "unit": "ms",
142
142
  "min": null,
143
143
  "max": null,
@@ -145,7 +145,7 @@
145
145
  "ds_color_line": "#525256",
146
146
  "ds_color_area": "#525256",
147
147
  "ds_filled": false,
148
- "ds_invert": false,
148
+ "ds_invert": true,
149
149
  "ds_legend": null,
150
150
  "ds_stack": false,
151
151
  "ds_order": 2,
@@ -153,7 +153,7 @@
153
153
  "ds_color_line_mode": 0
154
154
  },
155
155
  "displayAs": "line",
156
- "legend": "centreon-server: round-trip maximum time",
156
+ "legend": "Centreon-Server: Round-Trip Maximum Time",
157
157
  "stack": 0,
158
158
  "warning_high_threshold": null,
159
159
  "critical_high_threshold": null,
@@ -182,8 +182,8 @@
182
182
  },
183
183
  {
184
184
  "metric_id": 4,
185
- "metric": "centreon-server: rtmin",
186
- "metric_legend": "centreon-server: rtmin",
185
+ "metric": "Centreon-Server: rtmin",
186
+ "metric_legend": "Centreon-Server: rtmin",
187
187
  "unit": "ms",
188
188
  "min": null,
189
189
  "max": null,
@@ -199,7 +199,7 @@
199
199
  "ds_color_line_mode": 0
200
200
  },
201
201
  "displayAs": "line",
202
- "legend": "centreon-server: round-trip minimum time",
202
+ "legend": "Centreon-Server: Round-Trip Minimum Time",
203
203
  "stack": 0,
204
204
  "warning_high_threshold": null,
205
205
  "critical_high_threshold": null,
@@ -228,18 +228,18 @@
228
228
  }
229
229
  ],
230
230
  "times": [
231
- "2024-06-19t10:50:00+02:00",
232
- "2024-06-19t10:55:00+02:00",
233
- "2024-06-19t11:00:00+02:00",
234
- "2024-06-19t11:05:00+02:00",
235
- "2024-06-19t11:10:00+02:00",
236
- "2024-06-19t11:15:00+02:00",
237
- "2024-06-19t11:20:00+02:00",
238
- "2024-06-19t11:25:00+02:00",
239
- "2024-06-19t11:30:00+02:00",
240
- "2024-06-19t11:35:00+02:00",
241
- "2024-06-19t11:40:00+02:00",
242
- "2024-06-19t11:45:00+02:00",
243
- "2024-06-19t11:50:00+02:00"
231
+ "2024-06-19T10:50:00+02:00",
232
+ "2024-06-19T10:55:00+02:00",
233
+ "2024-06-19T11:00:00+02:00",
234
+ "2024-06-19T11:05:00+02:00",
235
+ "2024-06-19T11:10:00+02:00",
236
+ "2024-06-19T11:15:00+02:00",
237
+ "2024-06-19T11:20:00+02:00",
238
+ "2024-06-19T11:25:00+02:00",
239
+ "2024-06-19T11:30:00+02:00",
240
+ "2024-06-19T11:35:00+02:00",
241
+ "2024-06-19T11:40:00+02:00",
242
+ "2024-06-19T11:45:00+02:00",
243
+ "2024-06-19T11:50:00+02:00"
244
244
  ]
245
245
  }
@@ -1,6 +1,6 @@
1
- import { type MutableRefObject } from 'react';
2
1
  import { Zoom as VisxZoom } from '@visx/zoom';
3
2
  import { TransformMatrix } from '@visx/zoom/lib/types';
3
+ import { type MutableRefObject } from 'react';
4
4
 
5
5
  import { ParentSize } from '../..';
6
6
 
@@ -1,4 +1,11 @@
1
- import { type ForwardedRef, forwardRef, MutableRefObject, useEffect, useRef, useState } from 'react';
1
+ import {
2
+ type ForwardedRef,
3
+ MutableRefObject,
4
+ forwardRef,
5
+ useEffect,
6
+ useRef,
7
+ useState
8
+ } from 'react';
2
9
 
3
10
  import { RectClipPath } from '@visx/clip-path';
4
11
 
@@ -8,11 +15,16 @@ import ReplayIcon from '@mui/icons-material/Replay';
8
15
 
9
16
  import { IconButton } from '../Button';
10
17
 
18
+ import Minimap from './Minimap';
19
+ import { useZoomStyles } from './Zoom.styles';
11
20
  import { minimapScale, radius } from './constants';
21
+ import {
22
+ type Dimension,
23
+ type MinimapPosition,
24
+ ZoomChildren,
25
+ type ZoomInterface
26
+ } from './models';
12
27
  import { useZoom } from './useZoom';
13
- import { useZoomStyles } from './Zoom.styles';
14
- import Minimap from './Minimap';
15
- import { ZoomChildren, type Dimension, type MinimapPosition, type ZoomInterface } from './models';
16
28
 
17
29
  export interface Props extends Dimension, ZoomInterface, ZoomChildren {
18
30
  id?: number | string;
@@ -22,149 +34,144 @@ export interface Props extends Dimension, ZoomInterface, ZoomChildren {
22
34
 
23
35
  const ZoomContent = forwardRef(
24
36
  (
25
- {
26
- zoom,
27
- width,
28
- height,
29
- children,
30
- showMinimap,
31
- minimapPosition,
32
- id
33
- }: Props,
37
+ { zoom, width, height, children, showMinimap, minimapPosition, id }: Props,
34
38
  ref?: ForwardedRef<SVGGElement | null>
35
- ) : JSX.Element => {
36
- const { classes } = useZoomStyles();
39
+ ): JSX.Element => {
40
+ const { classes } = useZoomStyles();
37
41
 
38
- const fallbackRef = useRef<SVGGElement | null>(null)
39
- const contentRef = (ref || fallbackRef) as MutableRefObject<SVGGElement | null>;
40
- const minimapSvgRef = useRef<SVGSVGElement | null>(null);
41
- const minimapContentRef = useRef<SVGSVGElement | null>(null);
42
- const [contentClientRect, setContentClientRect] = useState<Dimension | null>(null);
42
+ const fallbackRef = useRef<SVGGElement | null>(null);
43
+ const contentRef = (ref ||
44
+ fallbackRef) as MutableRefObject<SVGGElement | null>;
45
+ const minimapSvgRef = useRef<SVGSVGElement | null>(null);
46
+ const minimapContentRef = useRef<SVGSVGElement | null>(null);
47
+ const [contentClientRect, setContentClientRect] =
48
+ useState<Dimension | null>(null);
43
49
 
44
- const resizeObserver = new ResizeObserver(() => {
45
- const contentBoundingClientRect = (
46
- contentRef.current as SVGGElement
47
- ).getBoundingClientRect();
50
+ const resizeObserver = new ResizeObserver(() => {
51
+ const contentBoundingClientRect = (
52
+ contentRef.current as SVGGElement
53
+ ).getBoundingClientRect();
48
54
 
49
- setContentClientRect({
50
- height: contentBoundingClientRect.height,
51
- width: contentBoundingClientRect.width
55
+ setContentClientRect({
56
+ height: contentBoundingClientRect.height,
57
+ width: contentBoundingClientRect.width
58
+ });
52
59
  });
53
- });
54
60
 
55
- useEffect(() => {
56
- if (contentRef.current) {
57
- resizeObserver.disconnect();
58
- resizeObserver.observe(contentRef.current);
59
- }
61
+ useEffect(() => {
62
+ if (contentRef.current) {
63
+ resizeObserver.disconnect();
64
+ resizeObserver.observe(contentRef.current);
65
+ }
60
66
 
61
- return () => {
62
- resizeObserver.disconnect();
63
- };
64
- }, [contentRef.current]);
67
+ return () => {
68
+ resizeObserver.disconnect();
69
+ };
70
+ }, [contentRef.current]);
65
71
 
66
- const { move, dragEnd, dragStart, isDragging } = useZoom();
72
+ const { move, dragEnd, dragStart, isDragging } = useZoom();
67
73
 
68
- const diffBetweenContentAndSvg = minimapSvgRef.current &&
69
- minimapContentRef.current && {
70
- left:
71
- minimapContentRef.current.getBoundingClientRect().left -
72
- minimapSvgRef.current.getBoundingClientRect().left,
73
- top:
74
- minimapContentRef.current.getBoundingClientRect().top -
75
- minimapSvgRef.current.getBoundingClientRect().top
76
- };
74
+ const diffBetweenContentAndSvg = minimapSvgRef.current &&
75
+ minimapContentRef.current && {
76
+ left:
77
+ minimapContentRef.current.getBoundingClientRect().left -
78
+ minimapSvgRef.current.getBoundingClientRect().left,
79
+ top:
80
+ minimapContentRef.current.getBoundingClientRect().top -
81
+ minimapSvgRef.current.getBoundingClientRect().top
82
+ };
77
83
 
78
- return (
79
- <div style={{ position: 'relative' }}>
80
- <svg
81
- className={classes.svg}
82
- data-is-grabbing={isDragging}
83
- data-testid="zoom-container"
84
- height={height}
85
- width={width}
86
- onMouseDown={dragStart(zoom)}
87
- onMouseEnter={dragStart(zoom)}
88
- onMouseLeave={dragEnd}
89
- onMouseMove={move(zoom)}
90
- onMouseUp={dragEnd}
91
- onWheel={zoom.handleWheel}
92
- >
93
- <RectClipPath
94
- height={Math.max(contentClientRect?.height || 0, height)}
95
- id={`zoom-clip-${id}`}
96
- rx={radius}
97
- width={Math.max(contentClientRect?.width || 0, width)}
98
- />
99
- <g
100
- data-testid="zoom-content"
101
- ref={contentRef}
102
- transform={zoom.toString()}
84
+ return (
85
+ <div style={{ position: 'relative' }}>
86
+ <svg
87
+ className={classes.svg}
88
+ data-is-grabbing={isDragging}
89
+ data-testid="zoom-container"
90
+ height={height}
91
+ width={width}
92
+ onMouseDown={dragStart(zoom)}
93
+ onMouseEnter={dragStart(zoom)}
94
+ onMouseLeave={dragEnd}
95
+ onMouseMove={move(zoom)}
96
+ onMouseUp={dragEnd}
97
+ onWheel={zoom.handleWheel}
103
98
  >
104
- {children({
105
- contentClientRect,
106
- height,
107
- transformMatrix: zoom.transformMatrix,
108
- width,
109
- zoom
110
- })}
111
- </g>
112
- </svg>
113
- <div className={classes.actionsAndZoom} data-position={minimapPosition}>
114
- {showMinimap && contentClientRect && (
115
- <svg
116
- className={classes.minimapContainer}
117
- data-testid="minimap"
118
- height={height * minimapScale}
119
- ref={minimapSvgRef}
120
- width={width * minimapScale}
99
+ <RectClipPath
100
+ height={Math.max(contentClientRect?.height || 0, height)}
101
+ id={`zoom-clip-${id}`}
102
+ rx={radius}
103
+ width={Math.max(contentClientRect?.width || 0, width)}
104
+ />
105
+ <g
106
+ data-testid="zoom-content"
107
+ ref={contentRef}
108
+ transform={zoom.toString()}
121
109
  >
122
- <Minimap
123
- contentClientRect={contentClientRect}
124
- diffBetweenContentAndSvg={
125
- diffBetweenContentAndSvg || { left: 0, top: 0 }
126
- }
127
- height={height}
128
- id={id}
129
- isDraggingFromContainer={isDragging}
130
- width={width}
131
- zoom={zoom}
110
+ {children({
111
+ contentClientRect,
112
+ height,
113
+ transformMatrix: zoom.transformMatrix,
114
+ width,
115
+ zoom
116
+ })}
117
+ </g>
118
+ </svg>
119
+ <div className={classes.actionsAndZoom} data-position={minimapPosition}>
120
+ {showMinimap && contentClientRect && (
121
+ <svg
122
+ className={classes.minimapContainer}
123
+ data-testid="minimap"
124
+ height={height * minimapScale}
125
+ ref={minimapSvgRef}
126
+ width={width * minimapScale}
132
127
  >
133
- <g ref={minimapContentRef}>
134
- {children({
135
- contentClientRect,
136
- height,
137
- transformMatrix: zoom.transformMatrix,
138
- width,
139
- zoom
140
- })}
141
- </g>
142
- </Minimap>
143
- </svg>
144
- )}
145
- <div className={classes.actions}>
146
- <IconButton
147
- data-testid="zoom in"
148
- icon={<ZoomInIcon />}
149
- size="small"
150
- onClick={() => zoom.scale({ scaleX: 1.2, scaleY: 1.2 })}
151
- />
152
- <IconButton
153
- data-testid="zoom out"
154
- icon={<ZoomOutIcon />}
155
- size="small"
156
- onClick={() => zoom.scale({ scaleX: 0.8, scaleY: 0.8 })}
157
- />
158
- <IconButton
159
- data-testid="clear"
160
- icon={<ReplayIcon />}
161
- size="small"
162
- onClick={zoom.reset}
163
- />
128
+ <Minimap
129
+ contentClientRect={contentClientRect}
130
+ diffBetweenContentAndSvg={
131
+ diffBetweenContentAndSvg || { left: 0, top: 0 }
132
+ }
133
+ height={height}
134
+ id={id}
135
+ isDraggingFromContainer={isDragging}
136
+ width={width}
137
+ zoom={zoom}
138
+ >
139
+ <g ref={minimapContentRef}>
140
+ {children({
141
+ contentClientRect,
142
+ height,
143
+ transformMatrix: zoom.transformMatrix,
144
+ width,
145
+ zoom
146
+ })}
147
+ </g>
148
+ </Minimap>
149
+ </svg>
150
+ )}
151
+ <div className={classes.actions}>
152
+ <IconButton
153
+ data-testid="zoom in"
154
+ icon={<ZoomInIcon />}
155
+ size="small"
156
+ onClick={() => zoom.scale({ scaleX: 1.2, scaleY: 1.2 })}
157
+ />
158
+ <IconButton
159
+ data-testid="zoom out"
160
+ icon={<ZoomOutIcon />}
161
+ size="small"
162
+ onClick={() => zoom.scale({ scaleX: 0.8, scaleY: 0.8 })}
163
+ />
164
+ <IconButton
165
+ data-testid="clear"
166
+ icon={<ReplayIcon />}
167
+ size="small"
168
+ onClick={zoom.reset}
169
+ />
170
+ </div>
164
171
  </div>
165
172
  </div>
166
- </div>
167
- );
168
- });
173
+ );
174
+ }
175
+ );
169
176
 
170
177
  export default ZoomContent;
@@ -26,5 +26,3 @@ export interface ChildrenProps extends ZoomState, Dimension, ZoomInterface {
26
26
  export interface ZoomChildren {
27
27
  children: (args: ChildrenProps) => JSX.Element;
28
28
  }
29
-
30
-