@centreon/ui 23.10.18-MON-17793-create-graph-component-centreon-ui.7 → 23.10.18-MON-17793-create-graph-component-centreon-ui.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 +7 -1
- package/src/Dashboard/Dashboard.styles.ts +62 -60
- package/src/Dashboard/Grid.tsx +1 -1
- package/src/Dashboard/Item.tsx +9 -6
- package/src/Dialog/Confirm/index.tsx +14 -4
- package/src/Dialog/index.tsx +3 -0
- package/src/Graph/BasicComponents/Lines/RegularLines/index.tsx +3 -9
- package/src/Graph/BasicComponents/Lines/Threshold/BasicThreshold.tsx +14 -10
- package/src/Graph/BasicComponents/Lines/Threshold/Circle.tsx +28 -34
- package/src/Graph/BasicComponents/Lines/Threshold/ThresholdWithPatternLines.tsx +82 -0
- package/src/Graph/BasicComponents/Lines/Threshold/ThresholdWithVariation.tsx +72 -0
- package/src/Graph/BasicComponents/Lines/Threshold/helpers/index.ts +122 -0
- package/src/Graph/BasicComponents/Lines/Threshold/index.tsx +14 -65
- package/src/Graph/BasicComponents/Lines/Threshold/models.ts +42 -2
- package/src/Graph/BasicComponents/Lines/Threshold/useCoordinateCircle.ts +59 -0
- package/src/Graph/BasicComponents/Lines/index.tsx +55 -21
- package/src/Graph/BasicComponents/Lines/models.ts +6 -1
- package/src/Graph/helpers/doc.ts +6 -14
- package/src/Graph/index.stories.tsx +143 -16
- package/src/Graph/mockedData/exclusionPeriodFirstPeriod.json +714 -0
- package/src/Graph/mockedData/exclusionPeriodFourthPeriod.json +588 -0
- package/src/Graph/mockedData/exclusionPeriodSecondPeriod.json +847 -0
- package/src/Graph/mockedData/exclusionPeriodThirdPeriod.json +434 -0
- package/src/Graph/mockedData/lastDayThreshold.json +2037 -2037
- package/src/Graph/models.ts +7 -4
- package/src/Graph/timeSeries/index.test.ts +22 -0
- package/src/Wizard/index.stories.tsx +5 -18
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/DataTable/Item/DataTableItem.tsx +2 -0
- package/src/components/Header/Header.tsx +1 -1
- package/src/components/Modal/ModalActions.tsx +4 -2
- package/src/Graph/BasicComponents/Lines/Threshold/usePointsOnline.ts +0 -50
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@centreon/ui",
|
|
3
|
-
"version": "23.10.18-MON-17793-create-graph-component-centreon-ui.
|
|
3
|
+
"version": "23.10.18-MON-17793-create-graph-component-centreon-ui.8",
|
|
4
4
|
"description": "Centreon UI Components",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
|
|
@@ -92,6 +92,12 @@
|
|
|
92
92
|
"@lexical/react": "0.8.0",
|
|
93
93
|
"@lexical/selection": "0.8.0",
|
|
94
94
|
"@lexical/utils": "0.8.0",
|
|
95
|
+
"@visx/curve": "^2.1.0",
|
|
96
|
+
"@visx/pattern": "^3.0.0",
|
|
97
|
+
"@visx/scale": "^3.0.0",
|
|
98
|
+
"@visx/shape": "^2.12.2",
|
|
99
|
+
"@visx/threshold": "^2.12.2",
|
|
100
|
+
"@visx/visx": "2.16.0",
|
|
95
101
|
"anylogger": "^1.0.11",
|
|
96
102
|
"d3-array": "3.2.0",
|
|
97
103
|
"humanize-duration": "^3.27.3",
|
|
@@ -2,67 +2,69 @@ import { makeStyles } from 'tss-react/mui';
|
|
|
2
2
|
|
|
3
3
|
import { alpha } from '@mui/material';
|
|
4
4
|
|
|
5
|
-
export const useDashboardLayoutStyles = makeStyles()(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
5
|
+
export const useDashboardLayoutStyles = makeStyles<boolean>()(
|
|
6
|
+
(theme, isStatic: boolean) => ({
|
|
7
|
+
container: {
|
|
8
|
+
'& .react-grid-item': {
|
|
9
|
+
borderRadius: theme.shape.borderRadius,
|
|
10
|
+
transition: theme.transitions.create('all', {
|
|
11
|
+
delay: 0,
|
|
12
|
+
duration: 100,
|
|
13
|
+
easing: theme.transitions.easing.easeOut
|
|
14
|
+
})
|
|
15
|
+
},
|
|
16
|
+
'& .react-grid-item.react-draggable-dragging': {
|
|
17
|
+
boxShadow: theme.shadows[3]
|
|
18
|
+
},
|
|
19
|
+
'& .react-grid-item.react-grid-placeholder': {
|
|
20
|
+
backgroundColor: alpha(theme.palette.primary.main, 0.7)
|
|
21
|
+
},
|
|
22
|
+
'& .react-grid-item.resizing': {
|
|
23
|
+
boxShadow: theme.shadows[3]
|
|
24
|
+
},
|
|
25
|
+
'& .react-resizable-handle': {
|
|
26
|
+
backgroundColor: theme.palette.action.focus,
|
|
27
|
+
backgroundImage: 'none',
|
|
28
|
+
borderRadius: theme.shape.borderRadius,
|
|
29
|
+
display: isStatic ? 'none' : 'block',
|
|
30
|
+
opacity: 0,
|
|
31
|
+
position: 'absolute'
|
|
32
|
+
},
|
|
33
|
+
'& .react-resizable-handle.react-resizable-handle-e': {
|
|
34
|
+
cursor: 'ew-resize',
|
|
35
|
+
height: `calc(100% - ${theme.spacing(3)})`,
|
|
36
|
+
marginTop: 0,
|
|
37
|
+
right: 0,
|
|
38
|
+
top: 0,
|
|
39
|
+
transform: 'rotate(0deg)',
|
|
40
|
+
width: theme.spacing(1)
|
|
41
|
+
},
|
|
42
|
+
'& .react-resizable-handle.react-resizable-handle-s': {
|
|
43
|
+
bottom: 0,
|
|
44
|
+
cursor: 'ns-resize',
|
|
45
|
+
height: theme.spacing(1),
|
|
46
|
+
left: 0,
|
|
47
|
+
marginLeft: 0,
|
|
48
|
+
transform: 'rotate(0deg)',
|
|
49
|
+
width: `calc(100% - ${theme.spacing(3)})`
|
|
50
|
+
},
|
|
51
|
+
'& .react-resizable-handle.react-resizable-handle-se': {
|
|
52
|
+
bottom: 0,
|
|
53
|
+
cursor: 'nwse-resize',
|
|
54
|
+
height: theme.spacing(2),
|
|
55
|
+
right: 0,
|
|
56
|
+
transform: 'rotate(0deg)',
|
|
57
|
+
width: theme.spacing(2)
|
|
58
|
+
},
|
|
59
|
+
'& .react-resizable-handle::after': {
|
|
60
|
+
content: 'none'
|
|
61
|
+
},
|
|
62
|
+
'& .react-resizable-handle:hover': {
|
|
63
|
+
opacity: 1
|
|
64
|
+
}
|
|
63
65
|
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
+
})
|
|
67
|
+
);
|
|
66
68
|
|
|
67
69
|
export const useDashboardItemStyles = makeStyles()((theme) => ({
|
|
68
70
|
widgetContainer: {
|
package/src/Dashboard/Grid.tsx
CHANGED
package/src/Dashboard/Item.tsx
CHANGED
|
@@ -18,7 +18,7 @@ interface DashboardItemProps {
|
|
|
18
18
|
children: ReactElement;
|
|
19
19
|
className?: string;
|
|
20
20
|
header?: ReactElement;
|
|
21
|
-
|
|
21
|
+
id: string;
|
|
22
22
|
onMouseDown?: (e: MouseEvent<HTMLDivElement>) => void;
|
|
23
23
|
onMouseUp?: (e: MouseEvent<HTMLDivElement>) => void;
|
|
24
24
|
onTouchEnd?: (e) => void;
|
|
@@ -29,13 +29,13 @@ const Item = forwardRef(
|
|
|
29
29
|
(
|
|
30
30
|
{
|
|
31
31
|
children,
|
|
32
|
-
key,
|
|
33
32
|
style,
|
|
34
33
|
className,
|
|
35
34
|
header,
|
|
36
35
|
onMouseDown,
|
|
37
36
|
onMouseUp,
|
|
38
|
-
onTouchEnd
|
|
37
|
+
onTouchEnd,
|
|
38
|
+
id
|
|
39
39
|
}: DashboardItemProps,
|
|
40
40
|
ref: ForwardedRef<HTMLDivElement>
|
|
41
41
|
): ReactElement => {
|
|
@@ -55,14 +55,17 @@ const Item = forwardRef(
|
|
|
55
55
|
Component: (
|
|
56
56
|
<div
|
|
57
57
|
className={className}
|
|
58
|
-
key={key}
|
|
59
58
|
ref={ref}
|
|
60
59
|
style={style}
|
|
61
60
|
{...cardContainerListeners}
|
|
62
61
|
>
|
|
63
62
|
<Card className={classes.widgetContainer}>
|
|
64
63
|
{header && (
|
|
65
|
-
<div
|
|
64
|
+
<div
|
|
65
|
+
{...listeners}
|
|
66
|
+
className={classes.widgetHeader}
|
|
67
|
+
data-testid={`${id}_move_panel`}
|
|
68
|
+
>
|
|
66
69
|
{header}
|
|
67
70
|
</div>
|
|
68
71
|
)}
|
|
@@ -70,7 +73,7 @@ const Item = forwardRef(
|
|
|
70
73
|
</Card>
|
|
71
74
|
</div>
|
|
72
75
|
),
|
|
73
|
-
memoProps: [
|
|
76
|
+
memoProps: [style, className, header]
|
|
74
77
|
});
|
|
75
78
|
}
|
|
76
79
|
);
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
import DialogContentText from '@mui/material
|
|
1
|
+
import { DialogContentText, Typography } from '@mui/material';
|
|
2
2
|
|
|
3
3
|
import Dialog, { Props as DialogProps } from '..';
|
|
4
4
|
|
|
5
|
-
type Props = DialogProps & {
|
|
5
|
+
type Props = DialogProps & {
|
|
6
|
+
labelMessage?: string | null;
|
|
7
|
+
labelSecondMessage?: string | null;
|
|
8
|
+
};
|
|
6
9
|
|
|
7
|
-
const Confirm = ({
|
|
10
|
+
const Confirm = ({
|
|
11
|
+
labelMessage,
|
|
12
|
+
labelSecondMessage,
|
|
13
|
+
...rest
|
|
14
|
+
}: Props): JSX.Element => (
|
|
8
15
|
<Dialog {...rest}>
|
|
9
|
-
|
|
16
|
+
<DialogContentText>
|
|
17
|
+
{labelMessage && <Typography>{labelMessage}</Typography>}
|
|
18
|
+
{labelSecondMessage && <Typography>{labelSecondMessage}</Typography>}
|
|
19
|
+
</DialogContentText>
|
|
10
20
|
</Dialog>
|
|
11
21
|
);
|
|
12
22
|
|
package/src/Dialog/index.tsx
CHANGED
|
@@ -35,6 +35,7 @@ export type Props = {
|
|
|
35
35
|
confirmDisabled?: boolean;
|
|
36
36
|
contentWidth?: number;
|
|
37
37
|
dialogActionsClassName?: string;
|
|
38
|
+
dialogConfirmButtonClassName?: string;
|
|
38
39
|
dialogContentClassName?: string;
|
|
39
40
|
dialogPaperClassName?: string;
|
|
40
41
|
dialogTitleClassName?: string;
|
|
@@ -65,6 +66,7 @@ const Dialog = ({
|
|
|
65
66
|
dialogTitleClassName,
|
|
66
67
|
dialogContentClassName,
|
|
67
68
|
dialogActionsClassName,
|
|
69
|
+
dialogConfirmButtonClassName,
|
|
68
70
|
...rest
|
|
69
71
|
}: Props): JSX.Element => {
|
|
70
72
|
const { classes, cx } = useStyles({ contentWidth });
|
|
@@ -97,6 +99,7 @@ const Dialog = ({
|
|
|
97
99
|
)}
|
|
98
100
|
<Button
|
|
99
101
|
aria-label={labelConfirm || ''}
|
|
102
|
+
className={dialogConfirmButtonClassName}
|
|
100
103
|
color="primary"
|
|
101
104
|
disabled={confirmDisabled}
|
|
102
105
|
endIcon={submitting && <CircularProgress size={15} />}
|
|
@@ -72,17 +72,13 @@ export default memo(RegularLine, (prevProps, nextProps) => {
|
|
|
72
72
|
timeSeries: prevTimeSeries,
|
|
73
73
|
graphHeight: prevGraphHeight,
|
|
74
74
|
highlight: prevHighlight,
|
|
75
|
-
xScale: prevXScale
|
|
76
|
-
shapeLinePath: prevShapeLinePath,
|
|
77
|
-
shapeAreaClosed: prevShapeAreaClosed
|
|
75
|
+
xScale: prevXScale
|
|
78
76
|
} = prevProps;
|
|
79
77
|
const {
|
|
80
78
|
timeSeries: nextTimeSeries,
|
|
81
79
|
graphHeight: nextGraphHeight,
|
|
82
80
|
highlight: nextHighlight,
|
|
83
|
-
xScale: nextXScale
|
|
84
|
-
shapeLinePath: nextShapeLinePath,
|
|
85
|
-
shapeAreaClosed: nextShapeAreaClosed
|
|
81
|
+
xScale: nextXScale
|
|
86
82
|
} = nextProps;
|
|
87
83
|
|
|
88
84
|
const prevXScaleRange = prevXScale.range();
|
|
@@ -92,8 +88,6 @@ export default memo(RegularLine, (prevProps, nextProps) => {
|
|
|
92
88
|
equals(prevTimeSeries, nextTimeSeries) &&
|
|
93
89
|
equals(prevGraphHeight, nextGraphHeight) &&
|
|
94
90
|
equals(prevHighlight, nextHighlight) &&
|
|
95
|
-
equals(prevXScaleRange, nextXScaleRange)
|
|
96
|
-
equals(prevShapeAreaClosed, nextShapeAreaClosed) &&
|
|
97
|
-
equals(prevShapeLinePath, nextShapeLinePath)
|
|
91
|
+
equals(prevXScaleRange, nextXScaleRange)
|
|
98
92
|
);
|
|
99
93
|
});
|
|
@@ -5,12 +5,14 @@ import { Threshold } from '@visx/threshold';
|
|
|
5
5
|
import { TimeValue } from '../../../timeSeries/models';
|
|
6
6
|
|
|
7
7
|
interface Props {
|
|
8
|
+
fillAboveArea: string;
|
|
9
|
+
fillBelowArea: string;
|
|
10
|
+
fillOpacity?: number;
|
|
8
11
|
getX: ScaleLinear<number, number>;
|
|
9
12
|
getY0: ScaleLinear<number, number>;
|
|
10
13
|
getY1: ScaleLinear<number, number>;
|
|
11
14
|
graphHeight: number;
|
|
12
|
-
|
|
13
|
-
lineColorY1: string;
|
|
15
|
+
id?: string;
|
|
14
16
|
timeSeries: Array<TimeValue>;
|
|
15
17
|
}
|
|
16
18
|
|
|
@@ -18,26 +20,28 @@ const BasicThreshold = ({
|
|
|
18
20
|
getX,
|
|
19
21
|
getY0,
|
|
20
22
|
getY1,
|
|
21
|
-
lineColorY0,
|
|
22
|
-
lineColorY1,
|
|
23
23
|
graphHeight,
|
|
24
|
-
timeSeries
|
|
24
|
+
timeSeries,
|
|
25
|
+
fillOpacity = 0.1,
|
|
26
|
+
id = 'threshold',
|
|
27
|
+
fillAboveArea,
|
|
28
|
+
fillBelowArea
|
|
25
29
|
}: Props): JSX.Element => {
|
|
26
30
|
return (
|
|
27
31
|
<Threshold
|
|
28
32
|
aboveAreaProps={{
|
|
29
|
-
fill:
|
|
30
|
-
fillOpacity
|
|
33
|
+
fill: fillAboveArea,
|
|
34
|
+
fillOpacity
|
|
31
35
|
}}
|
|
32
36
|
belowAreaProps={{
|
|
33
|
-
fill:
|
|
34
|
-
fillOpacity
|
|
37
|
+
fill: fillBelowArea,
|
|
38
|
+
fillOpacity
|
|
35
39
|
}}
|
|
36
40
|
clipAboveTo={0}
|
|
37
41
|
clipBelowTo={graphHeight}
|
|
38
42
|
curve={curveBasis}
|
|
39
43
|
data={timeSeries}
|
|
40
|
-
id=
|
|
44
|
+
id={id}
|
|
41
45
|
x={getX}
|
|
42
46
|
y0={getY0}
|
|
43
47
|
y1={getY1}
|
|
@@ -1,51 +1,45 @@
|
|
|
1
1
|
import { Shape } from '@visx/visx';
|
|
2
|
-
import { isEmpty, isNil
|
|
3
|
-
import { ScaleLinear } from 'd3-scale';
|
|
2
|
+
import { isEmpty, isNil } from 'ramda';
|
|
4
3
|
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
import usePointsOnline from './usePointsOnline';
|
|
9
|
-
import { Data } from './models';
|
|
10
|
-
|
|
11
|
-
interface Circle {
|
|
12
|
-
dataY0: Data;
|
|
13
|
-
dataY1: Data;
|
|
14
|
-
dataYOrigin: Data;
|
|
15
|
-
timeValue: TimeValue;
|
|
16
|
-
variation: number;
|
|
17
|
-
xScale: ScaleLinear<number, number>;
|
|
18
|
-
}
|
|
4
|
+
import { Circle } from './models';
|
|
5
|
+
import useCoordinateCircle from './useCoordinateCircle';
|
|
19
6
|
|
|
20
7
|
const Circle = ({
|
|
21
|
-
timeValue,
|
|
22
8
|
dataY0,
|
|
23
9
|
dataY1,
|
|
24
10
|
dataYOrigin,
|
|
25
11
|
xScale,
|
|
26
|
-
|
|
12
|
+
factors,
|
|
13
|
+
timeSeries,
|
|
14
|
+
getCountDisplayedCircles
|
|
27
15
|
}: Circle): JSX.Element | null => {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const y1 = y1Scale(prop(metricY1, timeValue) - variation);
|
|
38
|
-
const coordinate = usePointsOnline({
|
|
39
|
-
pointLower: { x, y: y0 },
|
|
40
|
-
pointOrigin: { x, y },
|
|
41
|
-
pointUpper: { x, y: y1 }
|
|
16
|
+
const coordinates = useCoordinateCircle({
|
|
17
|
+
dataY0,
|
|
18
|
+
dataY1,
|
|
19
|
+
dataYOrigin,
|
|
20
|
+
factors,
|
|
21
|
+
getCountDisplayedCircles,
|
|
22
|
+
timeSeries,
|
|
23
|
+
xScale
|
|
42
24
|
});
|
|
43
25
|
|
|
44
|
-
if (isEmpty(
|
|
26
|
+
if (isEmpty(coordinates) || isNil(coordinates)) {
|
|
45
27
|
return null;
|
|
46
28
|
}
|
|
47
29
|
|
|
48
|
-
return
|
|
30
|
+
return (
|
|
31
|
+
<g>
|
|
32
|
+
{coordinates.map(({ x, y }) => (
|
|
33
|
+
<Shape.Circle
|
|
34
|
+
cx={x}
|
|
35
|
+
cy={y}
|
|
36
|
+
fill="red"
|
|
37
|
+
key={`${x.toString()}-${y.toString()}`}
|
|
38
|
+
r={2}
|
|
39
|
+
/>
|
|
40
|
+
))}
|
|
41
|
+
</g>
|
|
42
|
+
);
|
|
49
43
|
};
|
|
50
44
|
|
|
51
45
|
export default Circle;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { PatternLines } from '@visx/pattern';
|
|
2
|
+
import { ScaleLinear } from 'd3-scale';
|
|
3
|
+
import { prop } from 'ramda';
|
|
4
|
+
|
|
5
|
+
import { useTheme } from '@mui/material/styles';
|
|
6
|
+
|
|
7
|
+
import { getTime } from '../../../timeSeries/index';
|
|
8
|
+
import { TimeValue } from '../../../timeSeries/models';
|
|
9
|
+
import { adjustGraphData } from '../../../helpers/index';
|
|
10
|
+
import { GraphData } from '../../../models';
|
|
11
|
+
|
|
12
|
+
import BasicThreshold from './BasicThreshold';
|
|
13
|
+
import useDataThreshold from './useDataThreshold';
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
data: GraphData;
|
|
17
|
+
display: boolean;
|
|
18
|
+
graphHeight: number;
|
|
19
|
+
leftScale: ScaleLinear<number, number>;
|
|
20
|
+
rightScale: ScaleLinear<number, number>;
|
|
21
|
+
xScale: ScaleLinear<number, number>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const ThresholdWithPatternLines = ({
|
|
25
|
+
graphHeight,
|
|
26
|
+
data,
|
|
27
|
+
display,
|
|
28
|
+
leftScale,
|
|
29
|
+
rightScale,
|
|
30
|
+
xScale
|
|
31
|
+
}: Props): JSX.Element | null => {
|
|
32
|
+
const theme = useTheme();
|
|
33
|
+
|
|
34
|
+
const { lines, timeSeries } = adjustGraphData(data);
|
|
35
|
+
|
|
36
|
+
const { dataY0, dataY1, displayThreshold } = useDataThreshold({
|
|
37
|
+
display,
|
|
38
|
+
leftScale,
|
|
39
|
+
lines,
|
|
40
|
+
rightScale
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (!dataY0 || !dataY1 || !displayThreshold) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const { metric: metricY0, yScale: y0Scale } = dataY0;
|
|
47
|
+
const { metric: metricY1, yScale: y1Scale } = dataY1;
|
|
48
|
+
|
|
49
|
+
const getX = (timeValue: TimeValue): number => xScale(getTime(timeValue));
|
|
50
|
+
|
|
51
|
+
const getY0 = (timeValue: TimeValue): number =>
|
|
52
|
+
y0Scale(prop(metricY0, timeValue)) ?? null;
|
|
53
|
+
|
|
54
|
+
const getY1 = (timeValue: TimeValue): number =>
|
|
55
|
+
y1Scale(prop(metricY1, timeValue)) ?? null;
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<>
|
|
59
|
+
<BasicThreshold
|
|
60
|
+
fillAboveArea={"url('#lines')"}
|
|
61
|
+
fillBelowArea={"url('#lines')"}
|
|
62
|
+
fillOpacity={0.8}
|
|
63
|
+
getX={getX}
|
|
64
|
+
getY0={getY0}
|
|
65
|
+
getY1={getY1}
|
|
66
|
+
graphHeight={graphHeight}
|
|
67
|
+
timeSeries={timeSeries}
|
|
68
|
+
/>
|
|
69
|
+
<PatternLines
|
|
70
|
+
data-testid="patternLinesExclusionPeriods"
|
|
71
|
+
height={5}
|
|
72
|
+
id="lines"
|
|
73
|
+
orientation={['diagonal']}
|
|
74
|
+
stroke={theme.palette.text.primary}
|
|
75
|
+
strokeWidth={1}
|
|
76
|
+
width={5}
|
|
77
|
+
/>
|
|
78
|
+
</>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export default ThresholdWithPatternLines;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { curveBasis } from '@visx/curve';
|
|
2
|
+
import { LinePath } from '@visx/shape';
|
|
3
|
+
import { ScaleLinear } from 'd3-scale';
|
|
4
|
+
|
|
5
|
+
import { useTheme } from '@mui/material/styles';
|
|
6
|
+
|
|
7
|
+
import { useMemoComponent } from '@centreon/ui';
|
|
8
|
+
|
|
9
|
+
import { TimeValue } from '../../../timeSeries/models';
|
|
10
|
+
|
|
11
|
+
import BasicThreshold from './BasicThreshold';
|
|
12
|
+
import { Data, FactorsVariation } from './models';
|
|
13
|
+
import { getVariationEnvelopThresholdData } from './helpers';
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
dataY0: Data;
|
|
17
|
+
dataY1: Data;
|
|
18
|
+
factors: FactorsVariation;
|
|
19
|
+
graphHeight: number;
|
|
20
|
+
timeSeries: Array<TimeValue>;
|
|
21
|
+
xScale: ScaleLinear<number, number>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const ThresholdWithVariation = ({
|
|
25
|
+
dataY0,
|
|
26
|
+
dataY1,
|
|
27
|
+
timeSeries,
|
|
28
|
+
xScale,
|
|
29
|
+
graphHeight,
|
|
30
|
+
factors
|
|
31
|
+
}: Props): JSX.Element => {
|
|
32
|
+
const theme = useTheme();
|
|
33
|
+
|
|
34
|
+
const { getX, getY0, getY1, lineColorY0, lineColorY1 } =
|
|
35
|
+
getVariationEnvelopThresholdData({
|
|
36
|
+
dataY0,
|
|
37
|
+
dataY1,
|
|
38
|
+
factors,
|
|
39
|
+
xScale
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const props = {
|
|
43
|
+
curve: curveBasis,
|
|
44
|
+
data: timeSeries,
|
|
45
|
+
stroke: theme.palette.secondary.main,
|
|
46
|
+
strokeDasharray: 5,
|
|
47
|
+
strokeOpacity: 0.8,
|
|
48
|
+
x: getX
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return useMemoComponent({
|
|
52
|
+
Component: (
|
|
53
|
+
<>
|
|
54
|
+
<BasicThreshold
|
|
55
|
+
fillAboveArea={lineColorY1}
|
|
56
|
+
fillBelowArea={lineColorY0}
|
|
57
|
+
getX={getX}
|
|
58
|
+
getY0={getY0}
|
|
59
|
+
getY1={getY1}
|
|
60
|
+
graphHeight={graphHeight}
|
|
61
|
+
timeSeries={timeSeries}
|
|
62
|
+
/>
|
|
63
|
+
|
|
64
|
+
<LinePath {...props} y={getY0} />
|
|
65
|
+
<LinePath {...props} y={getY1} />
|
|
66
|
+
</>
|
|
67
|
+
),
|
|
68
|
+
memoProps: [timeSeries, factors]
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default ThresholdWithVariation;
|