@centreon/ui 24.6.4 → 24.7.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 +3 -3
- package/src/Graph/BarChart/BarChart.tsx +28 -25
- package/src/Graph/BarChart/BarGroup.tsx +2 -0
- package/src/Graph/BarChart/BarStack.tsx +7 -2
- package/src/Graph/BarChart/ResponsiveBarChart.tsx +20 -6
- package/src/Graph/LineChart/LineChart.tsx +48 -17
- package/src/Graph/common/Axes/index.tsx +10 -6
- package/src/Graph/common/Axes/useAxisY.ts +11 -2
- package/src/Graph/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@centreon/ui",
|
|
3
|
-
"version": "24.
|
|
3
|
+
"version": "24.7.0",
|
|
4
4
|
"description": "Centreon UI Components",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"update:deps": "pnpx npm-check-updates -i --format group",
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
"test:storybook:local": "test-storybook --url http://127.0.0.1:9001",
|
|
13
13
|
"test:ci": "jest --silent --reporter=jest-junit",
|
|
14
14
|
"cypress:ui": "cypress open --component --browser=chrome",
|
|
15
|
-
"cypress:
|
|
15
|
+
"cypress:run:updateSnapshot": "pnpm cypress:cli --env updateSnapshots=true",
|
|
16
16
|
"cypress:run:coverage": "cypress run --component --browser=chrome --env codeCoverageTasksRegistered=true",
|
|
17
|
-
"cypress:
|
|
17
|
+
"cypress:run": "cypress run --component --browser=chrome",
|
|
18
18
|
"tokens:transform": "TS_NODE_PROJECT=tsconfig.node.json ts-node style-dictionary.transform.ts"
|
|
19
19
|
},
|
|
20
20
|
"sideEffects": false,
|
|
@@ -8,6 +8,7 @@ import 'dayjs/locale/pt';
|
|
|
8
8
|
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
|
9
9
|
import timezonePlugin from 'dayjs/plugin/timezone';
|
|
10
10
|
import utcPlugin from 'dayjs/plugin/utc';
|
|
11
|
+
import { Provider } from 'jotai';
|
|
11
12
|
|
|
12
13
|
import { Box } from '@mui/material';
|
|
13
14
|
|
|
@@ -33,7 +34,7 @@ export interface BarChartProps
|
|
|
33
34
|
end: string;
|
|
34
35
|
limitLegend?: false | number;
|
|
35
36
|
loading: boolean;
|
|
36
|
-
orientation: 'vertical' | 'horizontal';
|
|
37
|
+
orientation: 'vertical' | 'horizontal' | 'auto';
|
|
37
38
|
start: string;
|
|
38
39
|
thresholdUnit?: string;
|
|
39
40
|
thresholds?: Thresholds;
|
|
@@ -71,30 +72,32 @@ const BarChart = ({
|
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
return (
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
75
|
+
<Provider>
|
|
76
|
+
<Box
|
|
77
|
+
ref={lineChartRef}
|
|
78
|
+
sx={{ height: '100%', overflow: 'hidden', width: '100%' }}
|
|
79
|
+
>
|
|
80
|
+
<ParentSize>
|
|
81
|
+
{({ height: responsiveHeight, width }) => (
|
|
82
|
+
<ResponsiveBarChart
|
|
83
|
+
axis={axis}
|
|
84
|
+
barStyle={barStyle}
|
|
85
|
+
graphData={adjustedData}
|
|
86
|
+
graphRef={lineChartRef}
|
|
87
|
+
header={header}
|
|
88
|
+
height={height || responsiveHeight}
|
|
89
|
+
legend={legend}
|
|
90
|
+
limitLegend={limitLegend}
|
|
91
|
+
orientation={orientation}
|
|
92
|
+
thresholdUnit={thresholdUnit}
|
|
93
|
+
thresholds={thresholds}
|
|
94
|
+
tooltip={tooltip}
|
|
95
|
+
width={width}
|
|
96
|
+
/>
|
|
97
|
+
)}
|
|
98
|
+
</ParentSize>
|
|
99
|
+
</Box>
|
|
100
|
+
</Provider>
|
|
98
101
|
);
|
|
99
102
|
};
|
|
100
103
|
|
|
@@ -171,6 +171,7 @@ const BarGroup = ({
|
|
|
171
171
|
<BarStack
|
|
172
172
|
barIndex={barGroup.index}
|
|
173
173
|
barPadding={isHorizontal ? bar.x : bar.y}
|
|
174
|
+
barStyle={barStyle}
|
|
174
175
|
barWidth={isHorizontal ? bar.width : bar.height}
|
|
175
176
|
isHorizontal={isHorizontal}
|
|
176
177
|
isTooltipHidden={isTooltipHidden}
|
|
@@ -183,6 +184,7 @@ const BarGroup = ({
|
|
|
183
184
|
<BarStack
|
|
184
185
|
barIndex={barGroup.index}
|
|
185
186
|
barPadding={isHorizontal ? bar.x : bar.y}
|
|
187
|
+
barStyle={barStyle}
|
|
186
188
|
barWidth={isHorizontal ? bar.width : bar.height}
|
|
187
189
|
isHorizontal={isHorizontal}
|
|
188
190
|
isTooltipHidden={isTooltipHidden}
|
|
@@ -4,6 +4,7 @@ import { scaleBand } from '@visx/scale';
|
|
|
4
4
|
import { equals, gt, pick } from 'ramda';
|
|
5
5
|
|
|
6
6
|
import { useBarStack, UseBarStackProps } from './useBarStack';
|
|
7
|
+
import { BarStyle } from './models';
|
|
7
8
|
|
|
8
9
|
const xScale = scaleBand<number>({
|
|
9
10
|
domain: [0, 0],
|
|
@@ -14,6 +15,7 @@ const xScale = scaleBand<number>({
|
|
|
14
15
|
interface Props extends Omit<UseBarStackProps, 'xScale'> {
|
|
15
16
|
barIndex: number;
|
|
16
17
|
barPadding: number;
|
|
18
|
+
barStyle: BarStyle;
|
|
17
19
|
barWidth: number;
|
|
18
20
|
isTooltipHidden: boolean;
|
|
19
21
|
}
|
|
@@ -34,7 +36,8 @@ const BarStack = ({
|
|
|
34
36
|
barWidth,
|
|
35
37
|
barPadding,
|
|
36
38
|
barIndex,
|
|
37
|
-
isTooltipHidden
|
|
39
|
+
isTooltipHidden,
|
|
40
|
+
barStyle
|
|
38
41
|
}: Props): JSX.Element => {
|
|
39
42
|
const {
|
|
40
43
|
BarStackComponent,
|
|
@@ -63,6 +66,7 @@ const BarStack = ({
|
|
|
63
66
|
fill={bar.color}
|
|
64
67
|
height={isHorizontal ? Math.abs(bar.height) : barWidth}
|
|
65
68
|
key={`bar-stack-${barStack.index}-${bar.index}`}
|
|
69
|
+
opacity={barStyle.opacity}
|
|
66
70
|
width={isHorizontal ? barWidth : Math.abs(bar.width)}
|
|
67
71
|
x={
|
|
68
72
|
isHorizontal
|
|
@@ -107,7 +111,8 @@ const propsToMemoize = [
|
|
|
107
111
|
'lines',
|
|
108
112
|
'barPadding',
|
|
109
113
|
'barIndex',
|
|
110
|
-
'isTooltipHidden'
|
|
114
|
+
'isTooltipHidden',
|
|
115
|
+
'barStyle'
|
|
111
116
|
];
|
|
112
117
|
|
|
113
118
|
export default memo(BarStack, (prevProps, nextProps) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { MutableRefObject, useMemo, useRef, useState } from 'react';
|
|
1
|
+
import { MutableRefObject, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import { equals, flatten, has, isNil, pluck } from 'ramda';
|
|
3
|
+
import { equals, flatten, gte, has, isNil, pluck } from 'ramda';
|
|
4
4
|
import { useAtom } from 'jotai';
|
|
5
5
|
|
|
6
6
|
import { Skeleton } from '@mui/material';
|
|
@@ -22,6 +22,7 @@ import { useTooltipStyles } from '../common/useTooltipStyles';
|
|
|
22
22
|
import { margin } from '../LineChart/common';
|
|
23
23
|
import { Tooltip } from '../../components';
|
|
24
24
|
import Thresholds from '../common/Thresholds/Thresholds';
|
|
25
|
+
import { useDeepCompare } from '../../utils';
|
|
25
26
|
|
|
26
27
|
import BarGroup from './BarGroup';
|
|
27
28
|
import { tooltipDataAtom } from './atoms';
|
|
@@ -35,7 +36,7 @@ interface Props
|
|
|
35
36
|
graphRef: MutableRefObject<HTMLDivElement | null>;
|
|
36
37
|
height: number;
|
|
37
38
|
limitLegend?: false | number;
|
|
38
|
-
orientation: 'vertical' | 'horizontal';
|
|
39
|
+
orientation: 'vertical' | 'horizontal' | 'auto';
|
|
39
40
|
thresholdUnit?: string;
|
|
40
41
|
thresholds?: ThresholdsModel;
|
|
41
42
|
width: number;
|
|
@@ -82,7 +83,13 @@ const ResponsiveBarChart = ({
|
|
|
82
83
|
pluck('value', thresholds?.critical || [])
|
|
83
84
|
]);
|
|
84
85
|
|
|
85
|
-
const isHorizontal =
|
|
86
|
+
const isHorizontal = useMemo(() => {
|
|
87
|
+
if (!equals(orientation, 'auto')) {
|
|
88
|
+
return equals(orientation, 'horizontal');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return gte(graphWidth, graphHeight + 60);
|
|
92
|
+
}, [orientation, graphWidth, graphHeight]);
|
|
86
93
|
|
|
87
94
|
const xScale = useMemo(
|
|
88
95
|
() =>
|
|
@@ -144,6 +151,13 @@ const ResponsiveBarChart = ({
|
|
|
144
151
|
]
|
|
145
152
|
);
|
|
146
153
|
|
|
154
|
+
useEffect(
|
|
155
|
+
() => {
|
|
156
|
+
setLinesGraph(lines);
|
|
157
|
+
},
|
|
158
|
+
useDeepCompare([lines])
|
|
159
|
+
);
|
|
160
|
+
|
|
147
161
|
const displayLegend = legend?.display ?? true;
|
|
148
162
|
|
|
149
163
|
const displayedLines = useMemo(
|
|
@@ -214,7 +228,7 @@ const ResponsiveBarChart = ({
|
|
|
214
228
|
graphWidth={graphWidth - (isHorizontal ? 0 : margin.left - 15)}
|
|
215
229
|
gridLinesType={axis?.gridLinesType}
|
|
216
230
|
leftScale={leftScale}
|
|
217
|
-
orientation={
|
|
231
|
+
orientation={isHorizontal ? 'horizontal' : 'vertical'}
|
|
218
232
|
rightScale={rightScale}
|
|
219
233
|
showGridLines={showGridLines}
|
|
220
234
|
svgRef={graphSvgRef}
|
|
@@ -228,7 +242,7 @@ const ResponsiveBarChart = ({
|
|
|
228
242
|
isTooltipHidden={isTooltipHidden}
|
|
229
243
|
leftScale={leftScale}
|
|
230
244
|
lines={displayedLines}
|
|
231
|
-
orientation={
|
|
245
|
+
orientation={isHorizontal ? 'horizontal' : 'vertical'}
|
|
232
246
|
rightScale={rightScale}
|
|
233
247
|
secondUnit={secondUnit}
|
|
234
248
|
size={isHorizontal ? graphHeight - margin.top - 5 : graphWidth}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { MutableRefObject, useMemo, useRef, useState } from 'react';
|
|
1
|
+
import { MutableRefObject, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Tooltip } from '@visx/visx';
|
|
4
|
-
import { equals, flatten, isNil, pluck } from 'ramda';
|
|
4
|
+
import { equals, flatten, isNil, pluck, reject } from 'ramda';
|
|
5
5
|
|
|
6
6
|
import { ClickAwayListener, Fade, Skeleton, useTheme } from '@mui/material';
|
|
7
7
|
|
|
@@ -19,10 +19,15 @@ import BaseChart from '../common/BaseChart/BaseChart';
|
|
|
19
19
|
import { useComputeBaseChartDimensions } from '../common/BaseChart/useComputeBaseChartDimensions';
|
|
20
20
|
import ChartSvgWrapper from '../common/BaseChart/ChartSvgWrapper';
|
|
21
21
|
import Thresholds from '../common/Thresholds/Thresholds';
|
|
22
|
+
import { useDeepCompare } from '../../utils';
|
|
22
23
|
|
|
23
24
|
import Lines from './BasicComponents/Lines';
|
|
24
|
-
import {
|
|
25
|
-
|
|
25
|
+
import {
|
|
26
|
+
canDisplayThreshold,
|
|
27
|
+
findLineOfOriginMetricThreshold,
|
|
28
|
+
lowerLineName,
|
|
29
|
+
upperLineName
|
|
30
|
+
} from './BasicComponents/Lines/Threshold/models';
|
|
26
31
|
import InteractionWithGraph from './InteractiveComponents';
|
|
27
32
|
import GraphTooltip from './InteractiveComponents/Tooltip';
|
|
28
33
|
import useGraphTooltip from './InteractiveComponents/Tooltip/useGraphTooltip';
|
|
@@ -47,6 +52,23 @@ const baseStyles = {
|
|
|
47
52
|
textAlign: 'center'
|
|
48
53
|
};
|
|
49
54
|
|
|
55
|
+
const filterLines = (lines: Array<Line>, displayThreshold): Array<Line> => {
|
|
56
|
+
if (!displayThreshold) {
|
|
57
|
+
return lines;
|
|
58
|
+
}
|
|
59
|
+
const lineOriginMetric = findLineOfOriginMetricThreshold(lines);
|
|
60
|
+
|
|
61
|
+
const findLinesUpperLower = lines.map((line) =>
|
|
62
|
+
equals(line.name, lowerLineName) || equals(line.name, upperLineName)
|
|
63
|
+
? line
|
|
64
|
+
: null
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const linesUpperLower = reject((element) => !element, findLinesUpperLower);
|
|
68
|
+
|
|
69
|
+
return [...lineOriginMetric, ...linesUpperLower] as Array<Line>;
|
|
70
|
+
};
|
|
71
|
+
|
|
50
72
|
const LineChart = ({
|
|
51
73
|
graphData,
|
|
52
74
|
height = 500,
|
|
@@ -72,7 +94,11 @@ const LineChart = ({
|
|
|
72
94
|
|
|
73
95
|
const theme = useTheme();
|
|
74
96
|
|
|
75
|
-
const
|
|
97
|
+
const { title, timeSeries, baseAxis, lines } = graphData;
|
|
98
|
+
|
|
99
|
+
const [linesGraph, setLinesGraph] = useState<Array<Line>>(
|
|
100
|
+
filterLines(lines, canDisplayThreshold(shapeLines?.areaThresholdLines))
|
|
101
|
+
);
|
|
76
102
|
const graphSvgRef = useRef<SVGSVGElement | null>(null);
|
|
77
103
|
|
|
78
104
|
const { isInViewport } = useIntersection({ element: graphRef?.current });
|
|
@@ -86,21 +112,12 @@ const LineChart = ({
|
|
|
86
112
|
showTooltip: showThresholdTooltip
|
|
87
113
|
} = Tooltip.useTooltip();
|
|
88
114
|
|
|
89
|
-
const { title, timeSeries, baseAxis, lines } = graphData;
|
|
90
|
-
|
|
91
115
|
const thresholdValues = flatten([
|
|
92
116
|
pluck('value', thresholds?.warning || []),
|
|
93
117
|
pluck('value', thresholds?.critical || [])
|
|
94
118
|
]);
|
|
95
119
|
|
|
96
|
-
const
|
|
97
|
-
displayThreshold: canDisplayThreshold(shapeLines?.areaThresholdLines),
|
|
98
|
-
lines,
|
|
99
|
-
linesGraph,
|
|
100
|
-
setLinesGraph
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
const [, secondUnit] = getUnits(displayedLines);
|
|
120
|
+
const [, secondUnit] = getUnits(linesGraph);
|
|
104
121
|
|
|
105
122
|
const { legendRef, graphWidth, graphHeight } = useComputeBaseChartDimensions({
|
|
106
123
|
hasSecondUnit: Boolean(secondUnit),
|
|
@@ -119,6 +136,11 @@ const LineChart = ({
|
|
|
119
136
|
[timeSeries, graphWidth]
|
|
120
137
|
);
|
|
121
138
|
|
|
139
|
+
const displayedLines = useMemo(
|
|
140
|
+
() => linesGraph.filter(({ display }) => display),
|
|
141
|
+
[linesGraph]
|
|
142
|
+
);
|
|
143
|
+
|
|
122
144
|
const leftScale = useMemo(
|
|
123
145
|
() =>
|
|
124
146
|
getLeftScale({
|
|
@@ -164,6 +186,15 @@ const LineChart = ({
|
|
|
164
186
|
]
|
|
165
187
|
);
|
|
166
188
|
|
|
189
|
+
useEffect(
|
|
190
|
+
() => {
|
|
191
|
+
setLinesGraph(
|
|
192
|
+
filterLines(lines, canDisplayThreshold(shapeLines?.areaThresholdLines))
|
|
193
|
+
);
|
|
194
|
+
},
|
|
195
|
+
useDeepCompare([lines])
|
|
196
|
+
);
|
|
197
|
+
|
|
167
198
|
const graphTooltipData = useGraphTooltip({
|
|
168
199
|
graphWidth,
|
|
169
200
|
timeSeries,
|
|
@@ -204,7 +235,7 @@ const LineChart = ({
|
|
|
204
235
|
}}
|
|
205
236
|
legendRef={legendRef}
|
|
206
237
|
limitLegend={limitLegend}
|
|
207
|
-
lines={
|
|
238
|
+
lines={linesGraph}
|
|
208
239
|
setLines={setLinesGraph}
|
|
209
240
|
title={title}
|
|
210
241
|
>
|
|
@@ -269,7 +300,7 @@ const LineChart = ({
|
|
|
269
300
|
graphSvgRef,
|
|
270
301
|
graphWidth,
|
|
271
302
|
leftScale,
|
|
272
|
-
lines:
|
|
303
|
+
lines: linesGraph,
|
|
273
304
|
rightScale,
|
|
274
305
|
timeSeries,
|
|
275
306
|
xScale
|
|
@@ -32,8 +32,14 @@ const Axes = ({
|
|
|
32
32
|
}: Props): JSX.Element => {
|
|
33
33
|
const { format } = useLocaleDateTimeFormat();
|
|
34
34
|
const { lines, showBorder, yAxisTickLabelRotation } = data;
|
|
35
|
+
const isHorizontal = equals(orientation, 'horizontal');
|
|
35
36
|
|
|
36
|
-
const { axisLeft, axisRight } = useAxisY({
|
|
37
|
+
const { axisLeft, axisRight } = useAxisY({
|
|
38
|
+
data,
|
|
39
|
+
graphHeight: height,
|
|
40
|
+
graphWidth: width,
|
|
41
|
+
isHorizontal
|
|
42
|
+
});
|
|
37
43
|
|
|
38
44
|
const [firstUnit, secondUnit, thirdUnit] = getUnits(lines);
|
|
39
45
|
|
|
@@ -52,8 +58,6 @@ const Axes = ({
|
|
|
52
58
|
const hasMoreThanTwoUnits = !isNil(thirdUnit);
|
|
53
59
|
const displayAxisRight = !isNil(secondUnit) && !hasMoreThanTwoUnits;
|
|
54
60
|
|
|
55
|
-
const isHorizontal = equals(orientation, 'horizontal');
|
|
56
|
-
|
|
57
61
|
const AxisBottom = isHorizontal ? Axis.AxisBottom : Axis.AxisLeft;
|
|
58
62
|
const AxisLeft = isHorizontal ? Axis.AxisLeft : Axis.AxisTop;
|
|
59
63
|
const AxisRight = isHorizontal ? Axis.AxisRight : Axis.AxisBottom;
|
|
@@ -76,7 +80,7 @@ const Axes = ({
|
|
|
76
80
|
<UnitLabel
|
|
77
81
|
unit={firstUnit}
|
|
78
82
|
x={isHorizontal ? -8 : width + 8}
|
|
79
|
-
y={isHorizontal ? 16 :
|
|
83
|
+
y={isHorizontal ? 16 : -2}
|
|
80
84
|
/>
|
|
81
85
|
)}
|
|
82
86
|
|
|
@@ -88,8 +92,8 @@ const Axes = ({
|
|
|
88
92
|
tickLabelProps={() => ({
|
|
89
93
|
...axisLeft.tickLabelProps(),
|
|
90
94
|
angle: yAxisTickLabelRotation,
|
|
91
|
-
dx: isHorizontal ? -8 :
|
|
92
|
-
dy: isHorizontal ? 4 : -
|
|
95
|
+
dx: isHorizontal ? -8 : 16,
|
|
96
|
+
dy: isHorizontal ? 4 : -6
|
|
93
97
|
})}
|
|
94
98
|
tickLength={2}
|
|
95
99
|
/>
|
|
@@ -27,15 +27,24 @@ interface AxisY {
|
|
|
27
27
|
interface Props {
|
|
28
28
|
data: Omit<Data, 'timeSeries'>;
|
|
29
29
|
graphHeight?: number;
|
|
30
|
+
graphWidth?: number;
|
|
31
|
+
isHorizontal: boolean;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
const useAxisY = ({
|
|
34
|
+
const useAxisY = ({
|
|
35
|
+
data,
|
|
36
|
+
graphHeight,
|
|
37
|
+
graphWidth,
|
|
38
|
+
isHorizontal
|
|
39
|
+
}: Props): AxisY => {
|
|
33
40
|
const theme = useTheme();
|
|
34
41
|
|
|
35
42
|
const { lines } = data;
|
|
36
43
|
const [firstUnit, secondUnit, thirdUnit] = getUnits(lines);
|
|
37
44
|
|
|
38
|
-
const numTicks =
|
|
45
|
+
const numTicks = isHorizontal
|
|
46
|
+
? graphHeight && Math.ceil(graphHeight / 30)
|
|
47
|
+
: graphWidth && Math.ceil(graphWidth / 60);
|
|
39
48
|
|
|
40
49
|
const hasMoreThanTwoUnits = !isNil(thirdUnit);
|
|
41
50
|
const hasTwoUnits = !isNil(secondUnit) && !hasMoreThanTwoUnits;
|