@centreon/ui 25.2.2 → 25.2.4

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.
@@ -1,14 +1,14 @@
1
1
  import { useMemo } from 'react';
2
2
 
3
- import { Axis } from '@visx/visx';
3
+ import type { Axis } from '@visx/visx';
4
4
  import { isNil } from 'ramda';
5
5
 
6
6
  import { useTheme } from '@mui/material';
7
7
 
8
- import { formatMetricValue, getUnits } from '../timeSeries';
8
+ import { formatMetricValueWithUnit, getUnits } from '../timeSeries';
9
9
  import { commonTickLabelProps } from '../utils';
10
10
 
11
- import { Data, LabelProps } from './models';
11
+ import type { Data, LabelProps } from './models';
12
12
 
13
13
  interface AxisYData {
14
14
  displayUnit: boolean;
@@ -69,7 +69,11 @@ const useAxisY = ({
69
69
  return '';
70
70
  }
71
71
 
72
- return formatMetricValue({ base: data.baseAxis, unit, value }) as string;
72
+ return formatMetricValueWithUnit({
73
+ base: data.baseAxis,
74
+ unit,
75
+ value
76
+ }) as string;
73
77
  };
74
78
 
75
79
  const labelProps = ({
@@ -9,8 +9,6 @@ import Axes from '../Axes';
9
9
  import Grids from '../Grids';
10
10
  import { Line, TimeValue } from '../timeSeries/models';
11
11
 
12
- import { extraMargin } from './useComputeBaseChartDimensions';
13
-
14
12
  interface Props {
15
13
  allUnits: Array<string>;
16
14
  axis?: ChartAxis;
@@ -27,6 +25,8 @@ interface Props {
27
25
  svgRef: MutableRefObject<SVGSVGElement | null>;
28
26
  timeSeries: Array<TimeValue>;
29
27
  xScale;
28
+ maxAxisCharacters?: number;
29
+ hasSecondUnit?: boolean;
30
30
  }
31
31
 
32
32
  const ChartSvgWrapper = ({
@@ -44,7 +44,9 @@ const ChartSvgWrapper = ({
44
44
  axis,
45
45
  children,
46
46
  orientation = 'horizontal',
47
- allUnits
47
+ allUnits,
48
+ maxAxisCharacters = 0,
49
+ hasSecondUnit
48
50
  }: Props): JSX.Element => {
49
51
  const isHorizontal = equals(orientation, 'horizontal');
50
52
 
@@ -55,7 +57,13 @@ const ChartSvgWrapper = ({
55
57
  ref={svgRef}
56
58
  width="100%"
57
59
  >
58
- <Group.Group left={margin.left + extraMargin / 2} top={margin.top}>
60
+ <Group.Group
61
+ left={
62
+ maxAxisCharacters * 5 +
63
+ (hasSecondUnit ? margin.top * 0.8 : margin.top * 0.6)
64
+ }
65
+ top={margin.top}
66
+ >
59
67
  {showGridLines && (
60
68
  <Grids
61
69
  gridLinesType={gridLinesType}
@@ -3,6 +3,7 @@ import { MutableRefObject, useRef } from 'react';
3
3
  import { equals, isNil } from 'ramda';
4
4
 
5
5
  import { margin } from '../../Chart/common';
6
+ import { margins } from '../margins';
6
7
 
7
8
  export const extraMargin = 10;
8
9
 
@@ -13,6 +14,7 @@ interface UseComputeBaseChartDimensionsProps {
13
14
  legendHeight?: number;
14
15
  legendPlacement?: string;
15
16
  width: number;
17
+ maxAxisCharacters: number;
16
18
  }
17
19
 
18
20
  interface UseComputeBaseChartDimensionsState {
@@ -27,7 +29,8 @@ export const useComputeBaseChartDimensions = ({
27
29
  legendDisplay,
28
30
  legendPlacement,
29
31
  hasSecondUnit,
30
- legendHeight
32
+ legendHeight,
33
+ maxAxisCharacters
31
34
  }: UseComputeBaseChartDimensionsProps): UseComputeBaseChartDimensionsState => {
32
35
  const legendRef = useRef<HTMLDivElement | null>(null);
33
36
 
@@ -48,9 +51,8 @@ export const useComputeBaseChartDimensions = ({
48
51
  const graphWidth =
49
52
  width > 0
50
53
  ? width -
51
- margin.left -
52
- (hasSecondUnit ? margin.right : 8) -
53
- extraMargin -
54
+ (hasSecondUnit ? maxAxisCharacters * 2 : maxAxisCharacters) * 6 -
55
+ (hasSecondUnit ? margins.left * 0.8 : margin.left) -
54
56
  legendBoundingWidth
55
57
  : 0;
56
58
  const graphHeight =
@@ -0,0 +1,92 @@
1
+ import { isEmpty } from 'ramda';
2
+ import { useMemo } from 'react';
3
+ import { ChartAxis } from '../../Chart/models';
4
+ import { Data } from '../Axes/models';
5
+ import { Thresholds } from '../models';
6
+ import { getFormattedAxisValues } from '../utils';
7
+
8
+ interface UseComputeYAxisMaxCharactersProps {
9
+ firstUnit: string;
10
+ secondUnit: string;
11
+ thresholdUnit?: string;
12
+ thresholds?: Thresholds;
13
+ graphData: Data;
14
+ axis?: ChartAxis;
15
+ }
16
+
17
+ interface UseComputteYAxisMaxCharactersState {
18
+ maxLeftAxisCharacters: number;
19
+ maxRightAxisCharacters: number;
20
+ }
21
+
22
+ export const useComputeYAxisMaxCharacters = ({
23
+ thresholds,
24
+ firstUnit,
25
+ secondUnit,
26
+ graphData,
27
+ axis,
28
+ thresholdUnit
29
+ }: UseComputeYAxisMaxCharactersProps): UseComputteYAxisMaxCharactersState => {
30
+ const maxLeftValue = useMemo(
31
+ () =>
32
+ getFormattedAxisValues({
33
+ threshold: thresholds?.critical ?? [],
34
+ axisUnit: axis?.axisYLeft?.unit ?? firstUnit,
35
+ timeSeries: graphData?.timeSeries ?? [],
36
+ thresholdUnit,
37
+ lines: graphData?.lines ?? [],
38
+ base: graphData?.baseAxis
39
+ }),
40
+ [
41
+ thresholds?.critical,
42
+ axis?.axisYLeft?.unit,
43
+ firstUnit,
44
+ graphData?.timeSeries,
45
+ thresholdUnit,
46
+ graphData?.lines,
47
+ graphData?.baseAxis
48
+ ]
49
+ );
50
+
51
+ const maxRightValue = useMemo(
52
+ () =>
53
+ getFormattedAxisValues({
54
+ threshold: thresholds?.critical ?? [],
55
+ axisUnit: axis?.axisYRight?.unit ?? secondUnit,
56
+ timeSeries: graphData.timeSeries ?? [],
57
+ thresholdUnit,
58
+ lines: graphData.lines ?? [],
59
+ base: graphData.baseAxis
60
+ }),
61
+ [
62
+ thresholds?.critical,
63
+ axis?.axisYRight?.unit,
64
+ secondUnit,
65
+ graphData.timeSeries,
66
+ thresholdUnit,
67
+ graphData.lines,
68
+ graphData.baseAxis
69
+ ]
70
+ );
71
+
72
+ const maxLeftAxisCharacters = useMemo(
73
+ () =>
74
+ isEmpty(maxLeftValue)
75
+ ? 2
76
+ : Math.max(...maxLeftValue.map((value) => value.length), 2),
77
+ [maxLeftValue]
78
+ );
79
+
80
+ const maxRightAxisCharacters = useMemo(
81
+ () =>
82
+ isEmpty(maxRightValue)
83
+ ? 5
84
+ : Math.max(...maxRightValue.map((value) => value.length), 5),
85
+ [maxRightValue]
86
+ );
87
+
88
+ return {
89
+ maxLeftAxisCharacters,
90
+ maxRightAxisCharacters
91
+ };
92
+ };
@@ -6,14 +6,13 @@ export interface LineChartData {
6
6
  times: Array<string>;
7
7
  }
8
8
 
9
+ export interface Threshold {
10
+ label: string;
11
+ value: number;
12
+ }
13
+
9
14
  export interface Thresholds {
10
- critical: Array<{
11
- label: string;
12
- value: number;
13
- }>;
15
+ critical: Array<Threshold>;
14
16
  enabled: boolean;
15
- warning: Array<{
16
- label: string;
17
- value: number;
18
- }>;
17
+ warning: Array<Threshold>;
19
18
  }
@@ -567,7 +567,7 @@ describe('Format value with unit', () => {
567
567
 
568
568
  if (unit === 'ms') {
569
569
  return {
570
- expectedResult: '34.23 seconds',
570
+ expectedResult: '34.23k ms',
571
571
  unit,
572
572
  value: 34232
573
573
  };
@@ -523,13 +523,7 @@ const getYScalePerUnit = ({
523
523
  };
524
524
 
525
525
  const formatTime = (value: number): string => {
526
- if (value < 1000) {
527
- return `${numeral(value).format('0.[00]a')} ms`;
528
- }
529
-
530
- const t = numeral(value / 1000).format('0.[00]a');
531
-
532
- return `${t} seconds`;
526
+ return `${numeral(value).format('0.[00]a')} ms`;
533
527
  };
534
528
 
535
529
  const registerMsUnitToNumeral = (): null => {
@@ -17,7 +17,9 @@ import {
17
17
 
18
18
  import { Theme, darken, getLuminance, lighten } from '@mui/material';
19
19
 
20
- import { Thresholds } from './models';
20
+ import { Threshold, Thresholds } from './models';
21
+ import { formatMetricValue } from './timeSeries';
22
+ import { Line, TimeValue } from './timeSeries/models';
21
23
 
22
24
  interface GetColorFromDataAndThresholdsProps {
23
25
  baseColor?: string;
@@ -179,3 +181,49 @@ export const commonTickLabelProps = {
179
181
  fontSize: 10,
180
182
  textAnchor: 'middle'
181
183
  };
184
+
185
+ interface GetFormattedAxisValuesProps {
186
+ thresholdUnit?: string;
187
+ axisUnit: string;
188
+ base?: number;
189
+ timeSeries: Array<TimeValue>;
190
+ threshold: Array<Threshold>;
191
+ lines: Array<Line>;
192
+ }
193
+
194
+ export const getFormattedAxisValues = ({
195
+ thresholdUnit,
196
+ axisUnit,
197
+ timeSeries,
198
+ base = 1000,
199
+ lines,
200
+ threshold
201
+ }: GetFormattedAxisValuesProps): Array<string> => {
202
+ const metricId = (lines.find(({ unit }) => equals(unit, axisUnit)) as Line)
203
+ ?.metric_id;
204
+
205
+ if (isNil(metricId)) {
206
+ return [];
207
+ }
208
+ const formattedData = timeSeries.map((data) =>
209
+ formatMetricValue({
210
+ value: data[metricId],
211
+ unit: axisUnit,
212
+ base
213
+ })
214
+ );
215
+
216
+ const formattedThresholdValues = equals(thresholdUnit, axisUnit)
217
+ ? threshold.map(({ value }) =>
218
+ formatMetricValue({
219
+ value,
220
+ unit: axisUnit,
221
+ base
222
+ })
223
+ ) || []
224
+ : [];
225
+
226
+ return formattedData
227
+ .concat(formattedThresholdValues)
228
+ .filter((v) => v) as Array<string>;
229
+ };
@@ -329,7 +329,20 @@
329
329
  0.32339333333,
330
330
  null
331
331
  ],
332
- "prints": [["Last:0.32"], ["Min:0.03"], ["Max:0.97"], ["Average:0.51"]],
332
+ "prints": [
333
+ [
334
+ "Last:0.32"
335
+ ],
336
+ [
337
+ "Min:0.03"
338
+ ],
339
+ [
340
+ "Max:0.97"
341
+ ],
342
+ [
343
+ "Average:0.51"
344
+ ]
345
+ ],
333
346
  "last_value": 0.32,
334
347
  "minimum_value": 0.03,
335
348
  "maximum_value": 0.97,
@@ -654,10 +667,18 @@
654
667
  null
655
668
  ],
656
669
  "prints": [
657
- ["Last:87.27"],
658
- ["Min:70.31"],
659
- ["Max:88.03"],
660
- ["Average:78.07"]
670
+ [
671
+ "Last:87.27"
672
+ ],
673
+ [
674
+ "Min:70.31"
675
+ ],
676
+ [
677
+ "Max:88.03"
678
+ ],
679
+ [
680
+ "Average:78.07"
681
+ ]
661
682
  ],
662
683
  "last_value": 87.27,
663
684
  "minimum_value": 70.31,
@@ -974,15 +995,28 @@
974
995
  0.32092,
975
996
  0.23609333333,
976
997
  0.45102333333,
977
- 0.75873,
978
- 0.23588666667,
979
- 0.41906666667,
980
- 0.357,
981
- 0.32246333333,
982
- 0.64624666667,
998
+ null,
999
+ null,
1000
+ null,
1001
+ null,
1002
+ null,
1003
+ null,
983
1004
  null
984
1005
  ],
985
- "prints": [["Last:0.65"], ["Min:0.03"], ["Max:0.98"], ["Average:0.50"]],
1006
+ "prints": [
1007
+ [
1008
+ "Last:0.65"
1009
+ ],
1010
+ [
1011
+ "Min:0.03"
1012
+ ],
1013
+ [
1014
+ "Max:0.98"
1015
+ ],
1016
+ [
1017
+ "Average:0.50"
1018
+ ]
1019
+ ],
986
1020
  "last_value": 0.65,
987
1021
  "minimum_value": 0.03,
988
1022
  "maximum_value": 0.98,
@@ -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