@centreon/ui 26.9.1 → 26.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "26.9.1",
3
+ "version": "26.10.0",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "update:deps": "pnpx npm-check-updates -i --format group",
@@ -162,7 +162,7 @@
162
162
  "ramda": "0.30.1",
163
163
  "react-grid-layout": "^2.2.2",
164
164
  "react-resizable": "^3.0.5",
165
- "react-router": "7.12.0",
165
+ "react-router": "7.14.2",
166
166
  "react-transition-group": "^4.4.5",
167
167
  "sanitize-html": "^2.14.0",
168
168
  "ulog": "^2.0.0-beta.19"
@@ -70,8 +70,19 @@ const initialize = ({
70
70
  cy.viewport('macbook-13');
71
71
  };
72
72
 
73
- const checkWidth = (): void => {
74
- cy.get('g[class*="visx-rows"] > line').eq(0).should('have.attr', 'x2');
73
+ const checkWidth = (orientation): void => {
74
+ if (orientation === 'vertical') {
75
+ cy.get('g[class*="visx-rows"] > line')
76
+ .eq(0)
77
+ .should('have.attr', 'x2')
78
+ .and('equal', '1133');
79
+
80
+ return;
81
+ }
82
+ cy.get('g[class*="visx-rows"] > line')
83
+ .eq(0)
84
+ .should('have.attr', 'x2')
85
+ .and('equal', '1168');
75
86
  };
76
87
 
77
88
  describe('Bar chart', () => {
@@ -80,7 +91,7 @@ describe('Bar chart', () => {
80
91
  orientation: 'horizontal'
81
92
  });
82
93
 
83
- checkWidth();
94
+ checkWidth('horizontal');
84
95
  cy.contains('0 ms').should('be.visible');
85
96
  cy.contains('20').should('be.visible');
86
97
  cy.contains(':40 AM').should('be.visible');
@@ -106,7 +117,7 @@ describe('Bar chart', () => {
106
117
  }
107
118
  });
108
119
 
109
- checkWidth();
120
+ checkWidth('horizontal');
110
121
  cy.contains('0 ms').should('be.visible');
111
122
  cy.contains('20').should('be.visible');
112
123
  cy.contains(':40 AM').should('be.visible');
@@ -136,7 +147,7 @@ describe('Bar chart', () => {
136
147
  const userData = renderHook(() => useAtomValue(userAtom));
137
148
  userData.result.current.locale = 'en';
138
149
 
139
- checkWidth();
150
+ checkWidth(orientation);
140
151
  cy.contains('0 ms').should('be.visible');
141
152
  cy.contains('20').should('be.visible');
142
153
  cy.contains(':40 AM').should('be.visible');
@@ -149,7 +160,7 @@ describe('Bar chart', () => {
149
160
  it(`displays the bar chart ${orientation}ly centered in zero`, () => {
150
161
  initialize({ axis: { isCenteredZero: true }, orientation });
151
162
 
152
- checkWidth();
163
+ checkWidth(orientation);
153
164
  cy.contains('0 ms').should('be.visible');
154
165
  cy.contains('20').should('be.visible');
155
166
  cy.contains(':40 AM').should('be.visible');
@@ -162,7 +173,7 @@ describe('Bar chart', () => {
162
173
  it(`displays the stacked bar chart ${orientation}ly`, () => {
163
174
  initialize({ data: dataPingServiceStacked, orientation });
164
175
 
165
- checkWidth();
176
+ checkWidth(orientation);
166
177
  cy.contains('0 ms').should('be.visible');
167
178
  cy.contains('20').should('be.visible');
168
179
  cy.contains(':40 AM').should('be.visible');
@@ -175,7 +186,7 @@ describe('Bar chart', () => {
175
186
  it(`displays bar chart ${orientation}ly with a mix of stacked and non-stacked data`, () => {
176
187
  initialize({ data: dataPingServiceMixedStacked, orientation });
177
188
 
178
- checkWidth();
189
+ checkWidth(orientation);
179
190
  cy.contains('0 ms').should('be.visible');
180
191
  cy.contains('20').should('be.visible');
181
192
  cy.contains(':40 AM').should('be.visible');
@@ -190,7 +201,7 @@ describe('Bar chart', () => {
190
201
  orientation
191
202
  });
192
203
 
193
- checkWidth();
204
+ checkWidth(orientation);
194
205
  cy.contains('0 ms').should('be.visible');
195
206
  cy.contains('20').should('be.visible');
196
207
  cy.contains(':40 AM').should('be.visible');
@@ -205,7 +216,7 @@ describe('Bar chart', () => {
205
216
  orientation
206
217
  });
207
218
 
208
- checkWidth();
219
+ checkWidth(orientation);
209
220
  cy.contains('0 ms').should('be.visible');
210
221
  cy.contains('20').should('be.visible');
211
222
  cy.contains(':40 AM').should('be.visible');
@@ -220,7 +231,7 @@ describe('Bar chart', () => {
220
231
  orientation
221
232
  });
222
233
 
223
- checkWidth();
234
+ checkWidth(orientation);
224
235
  cy.contains('0 ms').should('be.visible');
225
236
  cy.contains('20').should('be.visible');
226
237
  cy.contains(':40 AM').should('be.visible');
@@ -239,7 +250,7 @@ describe('Bar chart', () => {
239
250
  }
240
251
  });
241
252
 
242
- checkWidth();
253
+ checkWidth('horizontal');
243
254
  cy.contains('0 ms').should('be.visible');
244
255
  cy.contains('20').should('be.visible');
245
256
  cy.contains(':40 AM').should('be.visible');
@@ -91,9 +91,6 @@ const ResponsiveBarChart = ({
91
91
  zoomPreview,
92
92
  annotationEvent
93
93
  }: Props): ReactElement => {
94
- const maxLeftAxisCharactersRef = useRef(0);
95
- const maxRightAxisCharactersRef = useRef(0);
96
-
97
94
  const { title, timeSeries, baseAxis, lines } = graphData || {};
98
95
 
99
96
  const { classes, cx } = useTooltipStyles();
@@ -114,14 +111,23 @@ const ResponsiveBarChart = ({
114
111
  const [firstUnit, secondUnit] = getUnits(displayedLines);
115
112
  const allUnits = getUnits(lines || []);
116
113
 
114
+ const { maxLeftAxisCharacters, maxRightAxisCharacters } =
115
+ useComputeYAxisMaxCharacters({
116
+ axis,
117
+ firstUnit,
118
+ graphData,
119
+ secondUnit,
120
+ thresholds,
121
+ thresholdUnit
122
+ });
123
+
117
124
  const { legendRef, graphWidth, graphHeight, titleRef } =
118
125
  useComputeBaseChartDimensions({
119
126
  hasSecondUnit: Boolean(secondUnit),
120
127
  height,
121
128
  legendDisplay: legend?.display,
122
129
  legendPlacement: legend?.placement,
123
- maxLeftAxisCharacters: maxLeftAxisCharactersRef.current,
124
- maxRightAxisCharacters: maxRightAxisCharactersRef.current,
130
+ maxAxisCharacters: maxRightAxisCharacters || maxLeftAxisCharacters,
125
131
  title,
126
132
  units: allUnits,
127
133
  width
@@ -196,22 +202,6 @@ const ResponsiveBarChart = ({
196
202
 
197
203
  const leftScale = yScalesPerUnit[firstUnit ?? allUnits[0]];
198
204
  const rightScale = yScalesPerUnit[secondUnit ?? allUnits[1]];
199
-
200
- const { maxLeftAxisCharacters, maxRightAxisCharacters } =
201
- useComputeYAxisMaxCharacters({
202
- axis,
203
- base: baseAxis,
204
- displayedLines,
205
- graphHeight,
206
- graphWidth,
207
- isHorizontal,
208
- leftScale,
209
- rightScale
210
- });
211
-
212
- maxRightAxisCharactersRef.current = maxRightAxisCharacters;
213
- maxLeftAxisCharactersRef.current = maxLeftAxisCharacters;
214
-
215
205
  const pixelsToShift = computPixelsToShiftMouse(xScaleLinear);
216
206
 
217
207
  useEffect(
@@ -296,8 +286,9 @@ const ResponsiveBarChart = ({
296
286
  graphHeight={graphHeight}
297
287
  graphWidth={graphWidth - (isHorizontal ? 0 : margin.left - 15)}
298
288
  gridLinesType={axis?.gridLinesType}
289
+ hasSecondUnit={Boolean(secondUnit)}
299
290
  leftScale={leftScale}
300
- maxLeftAxisCharacters={maxLeftAxisCharacters}
291
+ maxAxisCharacters={maxLeftAxisCharacters}
301
292
  orientation={isHorizontal ? 'horizontal' : 'vertical'}
302
293
  rightScale={rightScale}
303
294
  showGridLines={showGridLines}
@@ -112,6 +112,7 @@ const Lines = ({
112
112
  <GuidingLines
113
113
  graphHeight={height}
114
114
  graphWidth={width}
115
+ hasSecondUnit={hasSecondUnit}
115
116
  hasUnit={hasUnitDisplayed}
116
117
  leftScale={leftScale}
117
118
  lines={displayedLines}
@@ -234,6 +235,7 @@ const Lines = ({
234
235
  <g key={metric_id}>
235
236
  {displayGuidingLines && (
236
237
  <RegularAnchorPoint
238
+ hasSecondUnit={hasSecondUnit}
237
239
  lineColor={lineColor}
238
240
  maxLeftAxisCharacters={maxLeftAxisCharacters}
239
241
  metric_id={metric_id}
@@ -177,8 +177,8 @@ describe('Line chart', () => {
177
177
 
178
178
  cy.contains('06/18/2023').should('be.visible');
179
179
 
180
- cy.contains('0.56 s').should('be.visible');
181
- cy.contains('73.25%').should('be.visible');
180
+ cy.contains('0.44 s').should('be.visible');
181
+ cy.contains('75.19%').should('be.visible');
182
182
 
183
183
  cy.makeSnapshot();
184
184
  });
@@ -218,7 +218,7 @@ describe('Line chart', () => {
218
218
 
219
219
  cy.contains('Min: 70.31').should('be.visible');
220
220
 
221
- cy.findByTestId('graph-interaction-zone').realMouseMove(1205, 100);
221
+ cy.findByTestId('graph-interaction-zone').realMouseMove(1198, 100);
222
222
 
223
223
  cy.get('[data-metric="querytime"]').should('not.exist');
224
224
 
@@ -291,7 +291,7 @@ describe('Line chart', () => {
291
291
 
292
292
  cy.findByTestId('graph-interaction-zone')
293
293
  .should('have.attr', 'width')
294
- .and('equal', '1230');
294
+ .and('equal', '1200');
295
295
 
296
296
  cy.get('[data-icon="true"]')
297
297
  .eq(0)
@@ -530,7 +530,8 @@ describe('Line chart', () => {
530
530
 
531
531
  checkGraphWidth();
532
532
  cy.contains(':00 AM').should('be.visible');
533
- cy.get('circle').should('have.length', 864);
533
+ cy.get('circle[cx="245.83333333333334"]').should('be.visible');
534
+ cy.get('circle[cy="256.7205013298516"]').should('be.visible');
534
535
 
535
536
  cy.makeSnapshot();
536
537
  });
@@ -588,7 +589,7 @@ describe('Line chart', () => {
588
589
  cy.get('path.visx-area-closed')
589
590
  .should('have.attr', 'stroke-dasharray')
590
591
  .and('equals', '5 4');
591
- cy.get('circle').should('have.length', 288);
592
+ cy.get('circle[cx="32.77777777777778"]').should('be.visible');
592
593
 
593
594
  cy.makeSnapshot();
594
595
  });
@@ -744,10 +745,10 @@ describe('Lines and bars', () => {
744
745
  checkGraphWidth();
745
746
 
746
747
  cy.get(
747
- 'path[d="M7.473829201101932,289.92398616599974 h56.26446280991734 h1v1 v100.07601383400026 a1,1 0 0 1 -1,1 h-56.26446280991734 a1,1 0 0 1 -1,-1 v-100.07601383400026 v-1h1z"]'
748
+ 'path[d="M7.435261707988982,289.92398616599974 h55.91735537190083 h1v1 v100.07601383400026 a1,1 0 0 1 -1,1 h-55.91735537190083 a1,1 0 0 1 -1,-1 v-100.07601383400026 v-1h1z"]'
748
749
  ).should('be.visible');
749
750
  cy.get(
750
- 'path[d="M23.953168044077135,235.36727985204413 h23.305785123966935 a17.479338842975203,17.479338842975203 0 0 1 17.479338842975203,17.479338842975203 v19.598028628005196 v17.479338842975203h-17.479338842975203 h-23.305785123966935 h-17.479338842975203v-17.479338842975203 v-19.598028628005196 a17.479338842975203,17.479338842975203 0 0 1 17.479338842975203,-17.479338842975203z"]'
751
+ 'path[d="M23.81046831955923,235.36727985204413 h23.166942148760334 a17.37520661157025,17.37520661157025 0 0 1 17.37520661157025,17.37520661157025 v19.806293090815103 v17.37520661157025h-17.37520661157025 h-23.166942148760334 h-17.37520661157025v-17.37520661157025 v-19.806293090815103 a17.37520661157025,17.37520661157025 0 0 1 17.37520661157025,-17.37520661157025z"]'
751
752
  ).should('be.visible');
752
753
 
753
754
  cy.makeSnapshot();
@@ -119,8 +119,6 @@ const Chart = ({
119
119
  boundariesUnit
120
120
  }: Props): ReactElement => {
121
121
  const { classes } = useChartStyles();
122
- const maxLeftAxisCharactersRef = useRef(0);
123
- const maxRightAxisCharactersRef = useRef(0);
124
122
 
125
123
  const { title, timeSeries, baseAxis, lines } = graphData;
126
124
 
@@ -148,6 +146,16 @@ const Chart = ({
148
146
  [displayedLines]
149
147
  );
150
148
 
149
+ const { maxLeftAxisCharacters, maxRightAxisCharacters } =
150
+ useComputeYAxisMaxCharacters({
151
+ axis,
152
+ firstUnit,
153
+ graphData,
154
+ secondUnit,
155
+ thresholds,
156
+ thresholdUnit
157
+ });
158
+
151
159
  const allUnits = getUnits(linesGraph);
152
160
 
153
161
  const { legendRef, graphWidth, graphHeight, titleRef } =
@@ -157,8 +165,7 @@ const Chart = ({
157
165
  legendDisplay: legend?.display,
158
166
  legendHeight: legend?.height,
159
167
  legendPlacement: legend?.placement,
160
- maxLeftAxisCharacters: maxLeftAxisCharactersRef.current,
161
- maxRightAxisCharacters: maxRightAxisCharactersRef.current,
168
+ maxAxisCharacters: maxRightAxisCharacters || maxLeftAxisCharacters,
162
169
  title,
163
170
  units: allUnits,
164
171
  width
@@ -223,21 +230,6 @@ const Chart = ({
223
230
  const leftScale = yScalesPerUnit[fallbackLeftUnit];
224
231
  const rightScale = yScalesPerUnit[fallbackRightUnit];
225
232
 
226
- const { maxLeftAxisCharacters, maxRightAxisCharacters } =
227
- useComputeYAxisMaxCharacters({
228
- axis,
229
- base: baseAxis,
230
- displayedLines,
231
- graphHeight,
232
- graphWidth,
233
- isHorizontal: false,
234
- leftScale,
235
- rightScale
236
- });
237
-
238
- maxRightAxisCharactersRef.current = maxRightAxisCharacters;
239
- maxLeftAxisCharactersRef.current = maxLeftAxisCharacters;
240
-
241
233
  const linesDisplayedAsLine = useMemo(
242
234
  () =>
243
235
  displayedLines.filter(
@@ -333,8 +325,9 @@ const Chart = ({
333
325
  graphHeight={graphHeight}
334
326
  graphWidth={graphWidth}
335
327
  gridLinesType={axis?.gridLinesType}
328
+ hasSecondUnit={hasSecondUnit}
336
329
  leftScale={leftScale}
337
- maxLeftAxisCharacters={maxLeftAxisCharacters}
330
+ maxAxisCharacters={maxLeftAxisCharacters}
338
331
  rightScale={rightScale}
339
332
  showGridLines={showGridLines}
340
333
  svgRef={graphSvgRef}
@@ -395,6 +388,7 @@ const Chart = ({
395
388
  xScale,
396
389
  yScalesPerUnit
397
390
  }}
391
+ hasSecondUnit={hasSecondUnit}
398
392
  maxLeftAxisCharacters={maxLeftAxisCharacters}
399
393
  timeShiftZonesData={{
400
394
  ...timeShiftZones,
@@ -12,12 +12,14 @@ const GuidingLines = ({
12
12
  graphHeight,
13
13
  graphWidth,
14
14
  maxLeftAxisCharacters,
15
+ hasSecondUnit,
15
16
  lines,
16
17
  leftScale,
17
18
  rightScale,
18
19
  hasUnit
19
20
  }: GuidingLinesModel): ReactElement | null => {
20
21
  const { positionX, positionY } = useTickGraph({
22
+ hasSecondUnit,
21
23
  hasUnit,
22
24
  leftScale,
23
25
  lines,
@@ -13,6 +13,7 @@ interface Props {
13
13
  timeSeries: Array<TimeValue>;
14
14
  xScale: ScaleTime<number, number>;
15
15
  yScale: ScaleLinear<number, number>;
16
+ hasSecondUnit?: boolean;
16
17
  maxLeftAxisCharacters: number;
17
18
  }
18
19
 
@@ -38,9 +39,11 @@ const RegularAnchorPoint = ({
38
39
  metric_id,
39
40
  timeSeries,
40
41
  lineColor,
41
- maxLeftAxisCharacters
42
+ maxLeftAxisCharacters,
43
+ hasSecondUnit
42
44
  }: Props): JSX.Element | null => {
43
45
  const { tickAxisBottom: timeTick } = useTickGraph({
46
+ hasSecondUnit,
44
47
  maxLeftAxisCharacters,
45
48
  timeSeries,
46
49
  xScale
@@ -13,6 +13,7 @@ interface Props {
13
13
  timeSeries: Array<TimeValue>;
14
14
  xScale: ScaleTime<number, number>;
15
15
  yScale: ScaleLinear<number, number>;
16
+ hasSecondUnit?: boolean;
16
17
  maxLeftAxisCharacters: number;
17
18
  }
18
19
 
@@ -58,9 +59,11 @@ const StackedAnchorPoint = ({
58
59
  stackValues,
59
60
  timeSeries,
60
61
  lineColor,
62
+ hasSecondUnit,
61
63
  maxLeftAxisCharacters
62
64
  }: Props): JSX.Element | null => {
63
65
  const { tickAxisBottom: timeTick } = useTickGraph({
66
+ hasSecondUnit,
64
67
  maxLeftAxisCharacters,
65
68
  timeSeries,
66
69
  xScale
@@ -30,6 +30,7 @@ export interface GuidingLines {
30
30
  timeSeries: Array<TimeValue>;
31
31
  xScale: ScaleTime<number, number>;
32
32
  maxLeftAxisCharacters: number;
33
+ hasSecondUnit?: boolean;
33
34
  leftScale?: ScaleLinear<number, number>;
34
35
  lines: Array<Line>;
35
36
  rightScale?: ScaleLinear<number, number>;
@@ -27,6 +27,7 @@ interface Props {
27
27
  rightScale?: ScaleLinear<number, number>;
28
28
  timeSeries: Array<TimeValue>;
29
29
  xScale: ScaleTime<number, number>;
30
+ hasSecondUnit?: boolean;
30
31
  maxLeftAxisCharacters: number;
31
32
  hasUnit?: boolean;
32
33
  }
@@ -38,6 +39,7 @@ const useTickGraph = ({
38
39
  rightScale,
39
40
  lines = [],
40
41
  baseAxis = 1000,
42
+ hasSecondUnit,
41
43
  maxLeftAxisCharacters,
42
44
  hasUnit
43
45
  }: Props): AnchorPointResult => {
@@ -51,7 +53,11 @@ const useTickGraph = ({
51
53
  const mousePosition = useAtomValue(mousePositionAtom);
52
54
 
53
55
  const positionX = mousePosition
54
- ? mousePosition[0] - computeGElementMarginLeft(maxLeftAxisCharacters)
56
+ ? mousePosition[0] -
57
+ computeGElementMarginLeft({
58
+ hasSecondUnit,
59
+ maxCharacters: maxLeftAxisCharacters
60
+ })
55
61
  : undefined;
56
62
  const positionY = mousePosition
57
63
  ? mousePosition[1] - (hasUnit ? 29 : 4)
@@ -68,7 +74,10 @@ const useTickGraph = ({
68
74
  const pixelToShift = computPixelsToShiftMouse(xScale);
69
75
  const mousePositionTimeTick = mousePosition
70
76
  ? getTimeValue({
71
- marginLeft: computeGElementMarginLeft(maxLeftAxisCharacters),
77
+ marginLeft: computeGElementMarginLeft({
78
+ hasSecondUnit,
79
+ maxCharacters: maxLeftAxisCharacters
80
+ }),
72
81
  timeSeries,
73
82
  x: mousePosition[0] - pixelToShift,
74
83
  xScale
@@ -90,6 +90,7 @@ interface Props {
90
90
  fx?: (pointX: number) => number;
91
91
  fy?: (pointY: number) => number;
92
92
  };
93
+ hasSecondUnit?: boolean;
93
94
  maxLeftAxisCharacters: number;
94
95
  additionalZoomMargin?: number;
95
96
  }
@@ -100,6 +101,7 @@ const InteractionWithGraph = ({
100
101
  annotationData,
101
102
  timeShiftZonesData,
102
103
  transformMatrix,
104
+ hasSecondUnit,
103
105
  maxLeftAxisCharacters,
104
106
  additionalZoomMargin = 0
105
107
  }: Props): ReactElement => {
@@ -168,8 +170,11 @@ const InteractionWithGraph = ({
168
170
 
169
171
  const graphMarginLeft = useMemo(
170
172
  () =>
171
- computeGElementMarginLeft(maxLeftAxisCharacters) + additionalZoomMargin,
172
- [additionalZoomMargin, maxLeftAxisCharacters]
173
+ computeGElementMarginLeft({
174
+ hasSecondUnit,
175
+ maxCharacters: maxLeftAxisCharacters
176
+ }) + additionalZoomMargin,
177
+ [additionalZoomMargin, maxLeftAxisCharacters, hasSecondUnit]
173
178
  );
174
179
 
175
180
  const updateMousePosition = (pointPosition: MousePosition): void => {
@@ -73,10 +73,6 @@ const Axes = ({
73
73
  const AxisLeft = isHorizontal ? Axis.AxisLeft : Axis.AxisTop;
74
74
  const AxisRight = isHorizontal ? Axis.AxisRight : Axis.AxisBottom;
75
75
 
76
- const axisBottomProps = isHorizontal
77
- ? {}
78
- : ({ angle: 90, textAnchor: 'middle' } as const);
79
-
80
76
  return (
81
77
  <g>
82
78
  <AxisBottom
@@ -86,8 +82,7 @@ const Axes = ({
86
82
  tickFormat={formatAxisTick}
87
83
  tickLabelProps={() => ({
88
84
  ...(axisLeft.tickLabelProps as () => Record<string, unknown>)(),
89
- dx: data?.axisX?.dx ?? (isHorizontal ? 16 : -12),
90
- ...axisBottomProps
85
+ dx: data?.axisX?.dx ?? (isHorizontal ? 16 : -4)
91
86
  })}
92
87
  top={isHorizontal ? height - margin.bottom : 0}
93
88
  />
@@ -30,7 +30,8 @@ interface Props {
30
30
  | ScaleTime<number, number>
31
31
  | ScaleLinear<number, number>
32
32
  | ScaleBand<number>;
33
- maxLeftAxisCharacters?: number;
33
+ maxAxisCharacters?: number;
34
+ hasSecondUnit?: boolean;
34
35
  title?: string;
35
36
  }
36
37
 
@@ -50,7 +51,8 @@ const ChartSvgWrapper = ({
50
51
  children,
51
52
  orientation = 'horizontal',
52
53
  allUnits,
53
- maxLeftAxisCharacters = 0,
54
+ maxAxisCharacters = 0,
55
+ hasSecondUnit,
54
56
  title
55
57
  }: Props): ReactElement => {
56
58
  const isHorizontal = equals(orientation, 'horizontal');
@@ -71,7 +73,10 @@ const ChartSvgWrapper = ({
71
73
  >
72
74
  <title>chart</title>
73
75
  <Group.Group
74
- left={computeGElementMarginLeft(maxLeftAxisCharacters)}
76
+ left={computeGElementMarginLeft({
77
+ hasSecondUnit,
78
+ maxCharacters: maxAxisCharacters
79
+ })}
75
80
  top={marginTop}
76
81
  >
77
82
  {showGridLines && (canRenderGridRows || canRenderGridColumns) && (
@@ -2,6 +2,7 @@ import { equals, isNil } from 'ramda';
2
2
  import type { RefCallback } from 'react';
3
3
  import useResizeObserver from 'use-resize-observer';
4
4
 
5
+ import { margin } from '../../Chart/common';
5
6
  import { margins } from '../margins';
6
7
  import { useMarginTop } from '../useMarginTop';
7
8
 
@@ -14,8 +15,7 @@ interface UseComputeBaseChartDimensionsProps {
14
15
  legendHeight?: number;
15
16
  legendPlacement?: string;
16
17
  width: number;
17
- maxLeftAxisCharacters: number;
18
- maxRightAxisCharacters: number;
18
+ maxAxisCharacters: number;
19
19
  title?: string;
20
20
  units: Array<string>;
21
21
  }
@@ -32,9 +32,9 @@ export const useComputeBaseChartDimensions = ({
32
32
  height,
33
33
  legendDisplay,
34
34
  legendPlacement,
35
+ hasSecondUnit,
35
36
  legendHeight,
36
- maxLeftAxisCharacters,
37
- maxRightAxisCharacters,
37
+ maxAxisCharacters,
38
38
  units,
39
39
  title
40
40
  }: UseComputeBaseChartDimensionsProps): UseComputeBaseChartDimensionsState => {
@@ -63,8 +63,8 @@ export const useComputeBaseChartDimensions = ({
63
63
  const graphWidth =
64
64
  width > 0
65
65
  ? width -
66
- (maxLeftAxisCharacters * 5 + maxRightAxisCharacters * 5) -
67
- margins.left / 2 -
66
+ (hasSecondUnit ? maxAxisCharacters * 2 : maxAxisCharacters) * 6 -
67
+ (hasSecondUnit ? margins.left * 0.8 : margin.left) -
68
68
  legendBoundingWidth
69
69
  : 0;
70
70
  const graphHeight =
@@ -1,21 +1,18 @@
1
- import { getTicks } from '@visx/scale';
2
- import { ScaleLinear } from 'd3-scale';
3
1
  import { isEmpty } from 'ramda';
4
2
  import { useMemo } from 'react';
5
3
 
6
4
  import type { ChartAxis } from '../../Chart/models';
7
- import useAxisY from '../Axes/useAxisY';
8
- import { Line } from '../timeSeries/models';
5
+ import type { Data } from '../Axes/models';
6
+ import type { Thresholds } from '../models';
7
+ import { getFormattedAxisValues } from '../utils';
9
8
 
10
9
  interface UseComputeYAxisMaxCharactersProps {
10
+ firstUnit: string;
11
+ secondUnit: string;
12
+ thresholdUnit?: string;
13
+ thresholds?: Thresholds;
14
+ graphData: Data;
11
15
  axis?: ChartAxis;
12
- base: number;
13
- displayedLines: Array<Line>;
14
- graphWidth: number;
15
- graphHeight: number;
16
- isHorizontal: boolean;
17
- leftScale: ScaleLinear<number, number, never>;
18
- rightScale: ScaleLinear<number, number, never>;
19
16
  }
20
17
 
21
18
  interface UseComputteYAxisMaxCharactersState {
@@ -24,52 +21,71 @@ interface UseComputteYAxisMaxCharactersState {
24
21
  }
25
22
 
26
23
  export const useComputeYAxisMaxCharacters = ({
24
+ thresholds,
25
+ firstUnit,
26
+ secondUnit,
27
+ graphData,
27
28
  axis,
28
- base,
29
- displayedLines,
30
- graphWidth,
31
- graphHeight,
32
- isHorizontal,
33
- leftScale,
34
- rightScale
29
+ thresholdUnit
35
30
  }: UseComputeYAxisMaxCharactersProps): UseComputteYAxisMaxCharactersState => {
36
- const { axisLeft, axisRight } = useAxisY({
37
- data: {
38
- baseAxis: base,
39
- lines: displayedLines,
40
- ...axis
41
- },
42
- graphHeight,
43
- graphWidth,
44
- isHorizontal
45
- });
31
+ const maxLeftValue = useMemo(
32
+ () =>
33
+ getFormattedAxisValues({
34
+ axisUnit: axis?.axisYLeft?.unit ?? firstUnit,
35
+ base: graphData?.baseAxis,
36
+ lines: graphData?.lines ?? [],
37
+ threshold: thresholds?.critical ?? [],
38
+ thresholdUnit,
39
+ timeSeries: graphData?.timeSeries ?? []
40
+ }),
41
+ [
42
+ thresholds?.critical,
43
+ axis?.axisYLeft?.unit,
44
+ firstUnit,
45
+ graphData?.timeSeries,
46
+ thresholdUnit,
47
+ graphData?.lines,
48
+ graphData?.baseAxis
49
+ ]
50
+ );
46
51
 
47
- // Always add a character space in case the algorithm does not compute the displayed value in axis.
48
- const maxLeftAxisCharacters = useMemo(() => {
49
- if (!leftScale) {
50
- return 0;
51
- }
52
-
53
- const ticks = getTicks(leftScale, axisLeft.numTicks);
54
- const formattedTicks = ticks.map(axisLeft.tickFormat);
55
-
56
- return isEmpty(formattedTicks)
57
- ? 2
58
- : Math.max(...formattedTicks.map((value) => value.length), 2) + 1;
59
- }, [leftScale, axisLeft]);
52
+ const maxRightValue = useMemo(
53
+ () =>
54
+ getFormattedAxisValues({
55
+ axisUnit: axis?.axisYRight?.unit ?? secondUnit,
56
+ base: graphData.baseAxis,
57
+ lines: graphData.lines ?? [],
58
+ threshold: thresholds?.critical ?? [],
59
+ thresholdUnit,
60
+ timeSeries: graphData.timeSeries ?? []
61
+ }),
62
+ [
63
+ thresholds?.critical,
64
+ axis?.axisYRight?.unit,
65
+ secondUnit,
66
+ graphData.timeSeries,
67
+ thresholdUnit,
68
+ graphData.lines,
69
+ graphData.baseAxis
70
+ ]
71
+ );
60
72
 
61
- const maxRightAxisCharacters = useMemo(() => {
62
- if (!rightScale) {
63
- return 0;
64
- }
65
-
66
- const ticks = getTicks(rightScale, axisRight.numTicks);
67
- const formattedTicks = ticks.map(axisRight.tickFormat);
73
+ // Always add a character space in case the algorithm does not compute the displayed value in axis.
74
+ const maxLeftAxisCharacters = useMemo(
75
+ () =>
76
+ isEmpty(maxLeftValue)
77
+ ? 2
78
+ : Math.max(...maxLeftValue.map((value) => value.length), 2) + 1,
79
+ [maxLeftValue]
80
+ );
68
81
 
69
- return isEmpty(formattedTicks)
70
- ? 2
71
- : Math.max(...formattedTicks.map((value) => value.length), 2) + 1;
72
- }, [rightScale, axisRight]);
82
+ const maxRightAxisCharacters = useMemo(
83
+ () =>
84
+ isEmpty(maxRightValue)
85
+ ? 5
86
+ : Math.max(...maxRightValue.map((value) => value.length), 5) + 1,
87
+ [maxRightValue]
88
+ );
73
89
 
74
90
  return {
75
91
  maxLeftAxisCharacters,
@@ -22,6 +22,7 @@ import {
22
22
  } from 'ramda';
23
23
 
24
24
  import type { BarStyle } from '../BarChart/models';
25
+ import { margin } from '../Chart/common';
25
26
  import type { LineStyle } from '../Chart/models';
26
27
  import type { Threshold, Thresholds } from './models';
27
28
  import { formatMetricValueWithUnit } from './timeSeries';
@@ -262,8 +263,16 @@ export const getFormattedAxisValues = ({
262
263
  .filter((v) => v) as Array<string>;
263
264
  };
264
265
 
265
- export const computeGElementMarginLeft = (maxLeftCharacters: number): number =>
266
- maxLeftCharacters * 5;
266
+ interface ComputeGElementMarginLeftProps {
267
+ maxCharacters: number;
268
+ hasSecondUnit?: boolean;
269
+ }
270
+
271
+ export const computeGElementMarginLeft = ({
272
+ maxCharacters,
273
+ hasSecondUnit
274
+ }: ComputeGElementMarginLeftProps): number =>
275
+ maxCharacters * 5 + (hasSecondUnit ? margin.top * 0.8 : margin.top * 0.6);
267
276
 
268
277
  export const computPixelsToShiftMouse = (
269
278
  xScale: import('d3-scale').ScaleTime<number, number>