@centreon/ui 25.11.6 → 25.11.8
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 +1 -1
- package/src/Graph/BarChart/ResponsiveBarChart.tsx +11 -5
- package/src/Graph/BarChart/useBarStack.ts +8 -8
- package/src/Graph/Chart/Chart.cypress.spec.tsx +7 -7
- package/src/Graph/Chart/Chart.tsx +10 -5
- package/src/Graph/Chart/InteractiveComponents/ZoomPreview/useZoomPreview.ts +9 -3
- package/src/Graph/Chart/InteractiveComponents/index.tsx +20 -3
- package/src/Graph/Chart/Legend/index.tsx +11 -11
- package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +12 -8
- package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +14 -11
- package/src/Graph/common/useMarginTop.ts +17 -0
package/package.json
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
getYScalePerUnit
|
|
33
33
|
} from '../common/timeSeries';
|
|
34
34
|
import { Line } from '../common/timeSeries/models';
|
|
35
|
+
import { useMarginTop } from '../common/useMarginTop';
|
|
35
36
|
import { useTooltipStyles } from '../common/useTooltipStyles';
|
|
36
37
|
import { computPixelsToShiftMouse } from '../common/utils';
|
|
37
38
|
import BarGroup from './BarGroup';
|
|
@@ -128,7 +129,9 @@ const ResponsiveBarChart = ({
|
|
|
128
129
|
legendDisplay: legend?.display,
|
|
129
130
|
legendPlacement: legend?.placement,
|
|
130
131
|
width,
|
|
131
|
-
maxAxisCharacters: maxRightAxisCharacters || maxLeftAxisCharacters
|
|
132
|
+
maxAxisCharacters: maxRightAxisCharacters || maxLeftAxisCharacters,
|
|
133
|
+
title,
|
|
134
|
+
units: allUnits
|
|
132
135
|
});
|
|
133
136
|
|
|
134
137
|
const thresholdValues = flatten([
|
|
@@ -211,6 +214,8 @@ const ResponsiveBarChart = ({
|
|
|
211
214
|
[axis?.showGridLines]
|
|
212
215
|
);
|
|
213
216
|
|
|
217
|
+
const marginTop = useMarginTop({ title, units: allUnits });
|
|
218
|
+
|
|
214
219
|
if (!isInViewport && !skipIntersectionObserver) {
|
|
215
220
|
return (
|
|
216
221
|
<Skeleton
|
|
@@ -282,6 +287,7 @@ const ResponsiveBarChart = ({
|
|
|
282
287
|
xScale={xScale}
|
|
283
288
|
maxAxisCharacters={maxLeftAxisCharacters}
|
|
284
289
|
hasSecondUnit={Boolean(secondUnit)}
|
|
290
|
+
title={title}
|
|
285
291
|
>
|
|
286
292
|
<>
|
|
287
293
|
{isApplyingZoom && (
|
|
@@ -292,7 +298,7 @@ const ResponsiveBarChart = ({
|
|
|
292
298
|
lines={displayedLines}
|
|
293
299
|
orientation={isHorizontal ? 'horizontal' : 'vertical'}
|
|
294
300
|
size={
|
|
295
|
-
isHorizontal ? graphHeight -
|
|
301
|
+
isHorizontal ? graphHeight - marginTop - 5 : graphWidth
|
|
296
302
|
}
|
|
297
303
|
timeSeries={timeSeries}
|
|
298
304
|
xScale={xScale}
|
|
@@ -312,7 +318,7 @@ const ResponsiveBarChart = ({
|
|
|
312
318
|
thresholdUnit={thresholdUnit}
|
|
313
319
|
thresholds={thresholds as ThresholdsModel}
|
|
314
320
|
width={
|
|
315
|
-
isHorizontal ? graphWidth : graphHeight -
|
|
321
|
+
isHorizontal ? graphWidth : graphHeight - marginTop
|
|
316
322
|
}
|
|
317
323
|
yScalesPerUnit={yScalesPerUnit}
|
|
318
324
|
/>
|
|
@@ -348,7 +354,7 @@ const ResponsiveBarChart = ({
|
|
|
348
354
|
lines={displayedLines}
|
|
349
355
|
orientation={isHorizontal ? 'horizontal' : 'vertical'}
|
|
350
356
|
size={
|
|
351
|
-
isHorizontal ? graphHeight -
|
|
357
|
+
isHorizontal ? graphHeight - marginTop - 5 : graphWidth
|
|
352
358
|
}
|
|
353
359
|
timeSeries={timeSeries}
|
|
354
360
|
xScale={xScale}
|
|
@@ -368,7 +374,7 @@ const ResponsiveBarChart = ({
|
|
|
368
374
|
thresholdUnit={thresholdUnit}
|
|
369
375
|
thresholds={thresholds as ThresholdsModel}
|
|
370
376
|
width={
|
|
371
|
-
isHorizontal ? graphWidth : graphHeight -
|
|
377
|
+
isHorizontal ? graphWidth : graphHeight - marginTop
|
|
372
378
|
}
|
|
373
379
|
yScalesPerUnit={yScalesPerUnit}
|
|
374
380
|
/>
|
|
@@ -72,15 +72,15 @@ export const useBarStack = ({
|
|
|
72
72
|
|
|
73
73
|
const commonBarStackProps = isHorizontal
|
|
74
74
|
? {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
x: (d) => d.timeTick,
|
|
76
|
+
xScale,
|
|
77
|
+
yScale
|
|
78
|
+
}
|
|
79
79
|
: {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
xScale: yScale,
|
|
81
|
+
y: (d) => d.timeTick,
|
|
82
|
+
yScale: xScale
|
|
83
|
+
};
|
|
84
84
|
|
|
85
85
|
const hoverBar = useCallback(
|
|
86
86
|
({ highlightedMetric, barIndex }: HoverBarProps) =>
|
|
@@ -154,7 +154,7 @@ const initializeCustomUnits = ({
|
|
|
154
154
|
const checkGraphWidth = (): void => {
|
|
155
155
|
cy.findByTestId('graph-interaction-zone')
|
|
156
156
|
.should('have.attr', 'height')
|
|
157
|
-
.and('equal', '
|
|
157
|
+
.and('equal', '392');
|
|
158
158
|
|
|
159
159
|
cy.findByTestId('graph-interaction-zone').then((graph) => {
|
|
160
160
|
expect(Number(graph[0].attributes.width.value)).to.be.greaterThan(1170);
|
|
@@ -176,12 +176,12 @@ describe('Line chart', () => {
|
|
|
176
176
|
cy.contains('connTime').should('be.visible');
|
|
177
177
|
cy.contains('Min: 70.31').should('be.visible');
|
|
178
178
|
|
|
179
|
-
cy.findByTestId('graph-interaction-zone').realMouseMove(
|
|
179
|
+
cy.findByTestId('graph-interaction-zone').realMouseMove(240, 70);
|
|
180
180
|
|
|
181
181
|
cy.contains('06/18/2023').should('be.visible');
|
|
182
182
|
|
|
183
183
|
cy.contains('0.4 s').should('be.visible');
|
|
184
|
-
cy.contains('
|
|
184
|
+
cy.contains('73.65%').should('be.visible');
|
|
185
185
|
|
|
186
186
|
cy.makeSnapshot();
|
|
187
187
|
});
|
|
@@ -452,7 +452,7 @@ describe('Line chart', () => {
|
|
|
452
452
|
|
|
453
453
|
cy.contains(':00 AM').should('be.visible');
|
|
454
454
|
|
|
455
|
-
cy.get('text[transform="rotate(-35, -2,
|
|
455
|
+
cy.get('text[transform="rotate(-35, -2, 187.52600691899028)"]').should(
|
|
456
456
|
'be.visible'
|
|
457
457
|
);
|
|
458
458
|
|
|
@@ -534,7 +534,7 @@ describe('Line chart', () => {
|
|
|
534
534
|
checkGraphWidth();
|
|
535
535
|
cy.contains(':00 AM').should('be.visible');
|
|
536
536
|
cy.get('circle[cx="248.33333333333334"]').should('be.visible');
|
|
537
|
-
cy.get('circle[cy="
|
|
537
|
+
cy.get('circle[cy="267.9948393443889"]').should('be.visible');
|
|
538
538
|
|
|
539
539
|
cy.makeSnapshot();
|
|
540
540
|
});
|
|
@@ -748,10 +748,10 @@ describe('Lines and bars', () => {
|
|
|
748
748
|
checkGraphWidth();
|
|
749
749
|
|
|
750
750
|
cy.get(
|
|
751
|
-
'path[d="M7.501377410468319,
|
|
751
|
+
'path[d="M7.501377410468319,289.92398616599974 h56.51239669421488 h1v1 v100.07601383400026 a1,1 0 0 1 -1,1 h-56.51239669421488 a1,1 0 0 1 -1,-1 v-100.07601383400026 v-1h1z"]'
|
|
752
752
|
).should('be.visible');
|
|
753
753
|
cy.get(
|
|
754
|
-
'path[d="M24.05509641873278,
|
|
754
|
+
'path[d="M24.05509641873278,73.57899638721061 h23.404958677685954 a17.553719008264462,17.553719008264462 0 0 1 17.553719008264462,17.553719008264462 v137.44495707537567 v17.553719008264462h-17.553719008264462 h-23.404958677685954 h-17.553719008264462v-17.553719008264462 v-137.44495707537567 a17.553719008264462,17.553719008264462 0 0 1 17.553719008264462,-17.553719008264462z"]'
|
|
755
755
|
).should('be.visible');
|
|
756
756
|
|
|
757
757
|
cy.makeSnapshot();
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
getYScalePerUnit
|
|
28
28
|
} from '../common/timeSeries';
|
|
29
29
|
import type { Line } from '../common/timeSeries/models';
|
|
30
|
+
import { useMarginTop } from '../common/useMarginTop';
|
|
30
31
|
import Lines from './BasicComponents/Lines';
|
|
31
32
|
import {
|
|
32
33
|
canDisplayThreshold,
|
|
@@ -155,6 +156,8 @@ const Chart = ({
|
|
|
155
156
|
secondUnit
|
|
156
157
|
});
|
|
157
158
|
|
|
159
|
+
const allUnits = getUnits(linesGraph);
|
|
160
|
+
|
|
158
161
|
const { legendRef, graphWidth, graphHeight, titleRef } =
|
|
159
162
|
useComputeBaseChartDimensions({
|
|
160
163
|
hasSecondUnit: Boolean(secondUnit),
|
|
@@ -163,7 +166,9 @@ const Chart = ({
|
|
|
163
166
|
legendHeight: legend?.height,
|
|
164
167
|
legendPlacement: legend?.placement,
|
|
165
168
|
width,
|
|
166
|
-
maxAxisCharacters: maxRightAxisCharacters || maxLeftAxisCharacters
|
|
169
|
+
maxAxisCharacters: maxRightAxisCharacters || maxLeftAxisCharacters,
|
|
170
|
+
title,
|
|
171
|
+
units: allUnits
|
|
167
172
|
});
|
|
168
173
|
|
|
169
174
|
const xScale = useMemo(
|
|
@@ -227,8 +232,6 @@ const Chart = ({
|
|
|
227
232
|
[displayedLines]
|
|
228
233
|
);
|
|
229
234
|
|
|
230
|
-
const allUnits = getUnits(linesGraph);
|
|
231
|
-
|
|
232
235
|
useEffect(
|
|
233
236
|
() => {
|
|
234
237
|
setLinesGraph(
|
|
@@ -254,6 +257,8 @@ const Chart = ({
|
|
|
254
257
|
|
|
255
258
|
const hasSecondUnit = useMemo(() => Boolean(secondUnit), [secondUnit]);
|
|
256
259
|
|
|
260
|
+
const marginTop = useMarginTop({ title, units: allUnits });
|
|
261
|
+
|
|
257
262
|
if ((!isInViewport && !skipIntersectionObserver) || !height) {
|
|
258
263
|
return (
|
|
259
264
|
<Skeleton
|
|
@@ -320,7 +325,7 @@ const Chart = ({
|
|
|
320
325
|
isTooltipHidden={false}
|
|
321
326
|
lines={linesDisplayedAsBar}
|
|
322
327
|
orientation="horizontal"
|
|
323
|
-
size={graphHeight -
|
|
328
|
+
size={graphHeight - marginTop - 5}
|
|
324
329
|
timeSeries={timeSeries}
|
|
325
330
|
xScale={xScaleBand}
|
|
326
331
|
yScalesPerUnit={yScalesPerUnit}
|
|
@@ -332,7 +337,7 @@ const Chart = ({
|
|
|
332
337
|
displayAnchor={displayAnchor}
|
|
333
338
|
displayedLines={linesDisplayedAsLine}
|
|
334
339
|
graphSvgRef={graphSvgRef}
|
|
335
|
-
height={graphHeight -
|
|
340
|
+
height={graphHeight - marginTop}
|
|
336
341
|
scale={axis?.scale}
|
|
337
342
|
scaleLogarithmicBase={axis?.scaleLogarithmicBase}
|
|
338
343
|
timeSeries={timeSeries}
|
|
@@ -2,7 +2,7 @@ import { RefObject, useEffect, useState } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { Event } from '@visx/visx';
|
|
4
4
|
import { ScaleTime } from 'd3-scale';
|
|
5
|
-
import {
|
|
5
|
+
import { useAtom, useAtomValue } from 'jotai';
|
|
6
6
|
import { equals, gte, isNil, lt } from 'ramda';
|
|
7
7
|
import { Interval } from '../../models';
|
|
8
8
|
import {
|
|
@@ -37,10 +37,10 @@ const useZoomPreview = ({
|
|
|
37
37
|
graphMarginLeft
|
|
38
38
|
}: Props): ZoomPreview => {
|
|
39
39
|
const [zoomBoundaries, setZoomBoundaries] = useState<Boundaries | null>(null);
|
|
40
|
+
const [isApplyingZoom, setApplyingZoom] = useAtom(applyingZoomAtomAtom);
|
|
40
41
|
const eventMouseDown = useAtomValue(eventMouseDownAtom);
|
|
41
42
|
const eventMouseUp = useAtomValue(eventMouseUpAtom);
|
|
42
43
|
const mousePosition = useAtomValue(mousePositionAtom);
|
|
43
|
-
const setApplyingZoom = useSetAtom(applyingZoomAtomAtom);
|
|
44
44
|
|
|
45
45
|
const mousePointDown =
|
|
46
46
|
eventMouseDown && graphSvgRef.current
|
|
@@ -86,7 +86,6 @@ const useZoomPreview = ({
|
|
|
86
86
|
}
|
|
87
87
|
applyZoom();
|
|
88
88
|
setApplyingZoom(false);
|
|
89
|
-
setZoomBoundaries(null);
|
|
90
89
|
}, [eventMouseUp]);
|
|
91
90
|
|
|
92
91
|
useEffect(() => {
|
|
@@ -99,6 +98,13 @@ const useZoomPreview = ({
|
|
|
99
98
|
setApplyingZoom(true);
|
|
100
99
|
}, [zoomBoundaries]);
|
|
101
100
|
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
if (isApplyingZoom) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
setZoomBoundaries(null);
|
|
106
|
+
}, [isApplyingZoom]);
|
|
107
|
+
|
|
102
108
|
const zoomBarWidth = Math.abs(
|
|
103
109
|
(zoomBoundaries?.end || 0) - (zoomBoundaries?.start || 0)
|
|
104
110
|
);
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
MouseEvent,
|
|
3
|
+
type MutableRefObject,
|
|
4
|
+
ReactElement,
|
|
5
|
+
useMemo
|
|
6
|
+
} from 'react';
|
|
2
7
|
|
|
3
8
|
import { Event } from '@visx/visx';
|
|
4
9
|
import type { ScaleLinear, ScaleTime } from 'd3-scale';
|
|
5
|
-
import { useSetAtom } from 'jotai';
|
|
10
|
+
import { useAtom, useSetAtom } from 'jotai';
|
|
6
11
|
import {
|
|
7
12
|
all,
|
|
8
13
|
equals,
|
|
@@ -48,6 +53,7 @@ import type { TimelineEvent } from './Annotations/models';
|
|
|
48
53
|
import Bar from './Bar';
|
|
49
54
|
import TimeShiftZones from './TimeShiftZones';
|
|
50
55
|
import ZoomPreview from './ZoomPreview';
|
|
56
|
+
import { applyingZoomAtomAtom } from './ZoomPreview/zoomPreviewAtoms';
|
|
51
57
|
import {
|
|
52
58
|
type MousePosition,
|
|
53
59
|
changeMousePositionDerivedAtom,
|
|
@@ -103,6 +109,7 @@ const InteractionWithGraph = ({
|
|
|
103
109
|
}: Props): ReactElement => {
|
|
104
110
|
const { classes } = useStyles();
|
|
105
111
|
|
|
112
|
+
const [isApplyingZoom, setIsApplyingZoom] = useAtom(applyingZoomAtomAtom);
|
|
106
113
|
const setEventMouseDown = useSetAtom(eventMouseDownAtom);
|
|
107
114
|
const setEventMouseUp = useSetAtom(eventMouseUpAtom);
|
|
108
115
|
const setEventMouseLeave = useSetAtom(eventMouseLeaveAtom);
|
|
@@ -136,7 +143,7 @@ const InteractionWithGraph = ({
|
|
|
136
143
|
setEventMouseDown(null);
|
|
137
144
|
};
|
|
138
145
|
|
|
139
|
-
const mouseMove = (event): void => {
|
|
146
|
+
const mouseMove = (event: MouseEvent): void => {
|
|
140
147
|
const mousePoint = Event.localPoint(
|
|
141
148
|
graphSvgRef?.current as SVGSVGElement,
|
|
142
149
|
event
|
|
@@ -150,6 +157,15 @@ const InteractionWithGraph = ({
|
|
|
150
157
|
]);
|
|
151
158
|
};
|
|
152
159
|
|
|
160
|
+
const mouseEnter = (event: MouseEvent): void => {
|
|
161
|
+
if (event.buttons === 1 && isApplyingZoom) {
|
|
162
|
+
mouseDown(event);
|
|
163
|
+
}
|
|
164
|
+
if (event.buttons === 0 && isApplyingZoom) {
|
|
165
|
+
setIsApplyingZoom(false);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
153
169
|
const mouseDown = (event): void => {
|
|
154
170
|
setEventMouseDown(event);
|
|
155
171
|
};
|
|
@@ -336,6 +352,7 @@ const InteractionWithGraph = ({
|
|
|
336
352
|
onMouseLeave={mouseLeave}
|
|
337
353
|
onMouseMove={mouseMove}
|
|
338
354
|
onMouseUp={mouseUp}
|
|
355
|
+
onMouseEnter={mouseEnter}
|
|
339
356
|
/>
|
|
340
357
|
</g>
|
|
341
358
|
);
|
|
@@ -81,17 +81,17 @@ const MainLegend = ({
|
|
|
81
81
|
|
|
82
82
|
const contextMenuClick =
|
|
83
83
|
(metricId: number) =>
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
84
|
+
(event: MouseEvent): void => {
|
|
85
|
+
if (!secondaryClick) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
event.preventDefault();
|
|
89
|
+
secondaryClick({
|
|
90
|
+
element: event.target,
|
|
91
|
+
metricId,
|
|
92
|
+
position: [event.pageX, event.pageY]
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
95
|
|
|
96
96
|
const selectMetric = ({
|
|
97
97
|
event,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { MutableRefObject } from 'react';
|
|
1
|
+
import { MutableRefObject, ReactElement } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Group } from '@visx/visx';
|
|
4
4
|
import { equals } from 'ramda';
|
|
5
|
-
|
|
6
|
-
import { margin } from '../../Chart/common';
|
|
7
5
|
import { ChartAxis } from '../../Chart/models';
|
|
8
6
|
import Axes from '../Axes';
|
|
9
7
|
import Grids from '../Grids';
|
|
10
8
|
import { Line, TimeValue } from '../timeSeries/models';
|
|
9
|
+
import { useMarginTop } from '../useMarginTop';
|
|
11
10
|
import { computeGElementMarginLeft } from '../utils';
|
|
11
|
+
import { margin } from '../../Chart/common';
|
|
12
12
|
|
|
13
13
|
interface Props {
|
|
14
14
|
allUnits: Array<string>;
|
|
@@ -28,6 +28,7 @@ interface Props {
|
|
|
28
28
|
xScale;
|
|
29
29
|
maxAxisCharacters?: number;
|
|
30
30
|
hasSecondUnit?: boolean;
|
|
31
|
+
title?: string;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
const ChartSvgWrapper = ({
|
|
@@ -47,14 +48,17 @@ const ChartSvgWrapper = ({
|
|
|
47
48
|
orientation = 'horizontal',
|
|
48
49
|
allUnits,
|
|
49
50
|
maxAxisCharacters = 0,
|
|
50
|
-
hasSecondUnit
|
|
51
|
-
|
|
51
|
+
hasSecondUnit,
|
|
52
|
+
title
|
|
53
|
+
}: Props): ReactElement => {
|
|
52
54
|
const isHorizontal = equals(orientation, 'horizontal');
|
|
53
55
|
|
|
56
|
+
const marginTop = useMarginTop({ title, units: allUnits });
|
|
57
|
+
|
|
54
58
|
return (
|
|
55
59
|
<svg
|
|
56
60
|
aria-label="graph"
|
|
57
|
-
height={graphHeight +
|
|
61
|
+
height={graphHeight + marginTop}
|
|
58
62
|
ref={svgRef}
|
|
59
63
|
width="100%"
|
|
60
64
|
>
|
|
@@ -63,12 +67,12 @@ const ChartSvgWrapper = ({
|
|
|
63
67
|
maxCharacters: maxAxisCharacters,
|
|
64
68
|
hasSecondUnit
|
|
65
69
|
})}
|
|
66
|
-
top={
|
|
70
|
+
top={marginTop}
|
|
67
71
|
>
|
|
68
72
|
{showGridLines && (
|
|
69
73
|
<Grids
|
|
70
74
|
gridLinesType={gridLinesType}
|
|
71
|
-
height={graphHeight - margin.
|
|
75
|
+
height={graphHeight - margin.bottom}
|
|
72
76
|
leftScale={isHorizontal ? leftScale : xScale}
|
|
73
77
|
width={graphWidth}
|
|
74
78
|
xScale={isHorizontal ? xScale : leftScale}
|
|
@@ -5,6 +5,7 @@ import { equals, isNil } from 'ramda';
|
|
|
5
5
|
import useResizeObserver from 'use-resize-observer';
|
|
6
6
|
import { margin } from '../../Chart/common';
|
|
7
7
|
import { margins } from '../margins';
|
|
8
|
+
import { useMarginTop } from '../useMarginTop';
|
|
8
9
|
|
|
9
10
|
export const extraMargin = 10;
|
|
10
11
|
|
|
@@ -16,6 +17,8 @@ interface UseComputeBaseChartDimensionsProps {
|
|
|
16
17
|
legendPlacement?: string;
|
|
17
18
|
width: number;
|
|
18
19
|
maxAxisCharacters: number;
|
|
20
|
+
title?: string;
|
|
21
|
+
units: Array<string>;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
interface UseComputeBaseChartDimensionsState {
|
|
@@ -32,7 +35,9 @@ export const useComputeBaseChartDimensions = ({
|
|
|
32
35
|
legendPlacement,
|
|
33
36
|
hasSecondUnit,
|
|
34
37
|
legendHeight,
|
|
35
|
-
maxAxisCharacters
|
|
38
|
+
maxAxisCharacters,
|
|
39
|
+
units,
|
|
40
|
+
title
|
|
36
41
|
}: UseComputeBaseChartDimensionsProps): UseComputeBaseChartDimensionsState => {
|
|
37
42
|
const {
|
|
38
43
|
ref: legendRef,
|
|
@@ -43,31 +48,29 @@ export const useComputeBaseChartDimensions = ({
|
|
|
43
48
|
|
|
44
49
|
const currentLegendHeight = legendHeight ?? (legendRefHeight || 0);
|
|
45
50
|
|
|
51
|
+
const marginTop = useMarginTop({ title, units });
|
|
52
|
+
|
|
46
53
|
const legendBoundingHeight =
|
|
47
54
|
!equals(legendDisplay, false) &&
|
|
48
|
-
|
|
55
|
+
(isNil(legendPlacement) || equals(legendPlacement, 'bottom'))
|
|
49
56
|
? currentLegendHeight
|
|
50
57
|
: 0;
|
|
51
58
|
const legendBoundingWidth =
|
|
52
59
|
!equals(legendDisplay, false) &&
|
|
53
|
-
|
|
60
|
+
(equals(legendPlacement, 'left') || equals(legendPlacement, 'right'))
|
|
54
61
|
? legendRefWidth || 0
|
|
55
62
|
: 0;
|
|
56
63
|
|
|
57
64
|
const graphWidth =
|
|
58
65
|
width > 0
|
|
59
66
|
? width -
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
(hasSecondUnit ? maxAxisCharacters * 2 : maxAxisCharacters) * 6 -
|
|
68
|
+
(hasSecondUnit ? margins.left * 0.8 : margin.left) -
|
|
69
|
+
legendBoundingWidth
|
|
63
70
|
: 0;
|
|
64
71
|
const graphHeight =
|
|
65
72
|
(height || 0) > 0
|
|
66
|
-
? (height || 0) -
|
|
67
|
-
margin.top -
|
|
68
|
-
legendBoundingHeight -
|
|
69
|
-
(titleRefHeight || 0) -
|
|
70
|
-
5
|
|
73
|
+
? (height || 0) - marginTop - legendBoundingHeight - (titleRefHeight || 0)
|
|
71
74
|
: 0;
|
|
72
75
|
|
|
73
76
|
return {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { identity } from 'ramda';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { margin } from '../Chart/common';
|
|
4
|
+
|
|
5
|
+
export const useMarginTop = ({
|
|
6
|
+
title,
|
|
7
|
+
units
|
|
8
|
+
}: { title?: string; units: Array<string> }): number => {
|
|
9
|
+
const hasUnits = useMemo(() => units.some(identity), [units]);
|
|
10
|
+
|
|
11
|
+
const marginTop = useMemo(
|
|
12
|
+
() => (title || hasUnits ? margin.top : 4),
|
|
13
|
+
[title, hasUnits]
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
return marginTop;
|
|
17
|
+
};
|