@centreon/ui 23.10.61 → 23.10.63
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/Gauge/AnimatedPie.tsx +31 -20
- package/src/Graph/Gauge/Gauge.stories.tsx +97 -6
- package/src/Graph/Gauge/Gauge.tsx +4 -15
- package/src/Graph/Gauge/PieData.tsx +8 -24
- package/src/Graph/Gauge/ResponsiveGauge.tsx +11 -14
- package/src/Graph/Gauge/Thresholds.tsx +109 -56
- package/src/Graph/Gauge/models.ts +2 -3
- package/src/Graph/LineChart/BasicComponents/ThresholdLine.tsx +64 -0
- package/src/Graph/LineChart/BasicComponents/Thresholds.tsx +77 -0
- package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +9 -7
- package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/index.tsx +2 -4
- package/src/Graph/LineChart/InteractiveComponents/interactionWithGraphAtoms.ts +1 -0
- package/src/Graph/LineChart/Legend/index.tsx +9 -4
- package/src/Graph/LineChart/Legend/useInteractiveValues.ts +13 -4
- package/src/Graph/LineChart/Legend/useLegend.ts +10 -13
- package/src/Graph/LineChart/LineChart.tsx +73 -8
- package/src/Graph/LineChart/graphAtoms.ts +0 -3
- package/src/Graph/LineChart/index.stories.tsx +101 -6
- package/src/Graph/LineChart/index.tsx +13 -3
- package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +10 -8
- package/src/Graph/SingleBar/SingleBar.stories.tsx +119 -6
- package/src/Graph/SingleBar/ThresholdLine.tsx +74 -0
- package/src/Graph/SingleBar/Thresholds.tsx +28 -82
- package/src/Graph/SingleBar/models.ts +2 -4
- package/src/Graph/Text/Text.tsx +20 -16
- package/src/Graph/common/models.ts +12 -0
- package/src/Graph/common/timeSeries/index.ts +41 -8
- package/src/Graph/common/timeSeries/models.ts +3 -1
- package/src/Graph/common/utils.ts +59 -6
- package/src/api/useGraphQuery/index.ts +52 -21
- package/src/components/Modal/Modal.styles.ts +1 -2
- package/src/utils/index.ts +1 -0
- package/src/utils/useRefreshInterval.ts +21 -0
- package/src/utils/useThresholds.ts +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { equals, isNil } from 'ramda';
|
|
2
|
+
|
|
3
|
+
import { getUnits, getYScale } from '../../common/timeSeries';
|
|
4
|
+
import { Line } from '../../common/timeSeries/models';
|
|
5
|
+
import { Thresholds } from '../../common/models';
|
|
6
|
+
|
|
7
|
+
import { ThresholdLine } from './ThresholdLine';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
displayedLines: Array<Line>;
|
|
11
|
+
hideTooltip: () => void;
|
|
12
|
+
leftScale: (value: number) => number;
|
|
13
|
+
rightScale: (value: number) => number;
|
|
14
|
+
showTooltip: (props) => void;
|
|
15
|
+
thresholdUnit?: string;
|
|
16
|
+
thresholds: Thresholds;
|
|
17
|
+
width: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const Thresholds = ({
|
|
21
|
+
thresholds,
|
|
22
|
+
leftScale,
|
|
23
|
+
rightScale,
|
|
24
|
+
width,
|
|
25
|
+
displayedLines,
|
|
26
|
+
thresholdUnit,
|
|
27
|
+
showTooltip,
|
|
28
|
+
hideTooltip
|
|
29
|
+
}: Props): JSX.Element => {
|
|
30
|
+
const [firstUnit, secondUnit, thirdUnit] = getUnits(
|
|
31
|
+
displayedLines as Array<Line>
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const shouldUseRightScale = equals(thresholdUnit, secondUnit);
|
|
35
|
+
|
|
36
|
+
const yScale = shouldUseRightScale
|
|
37
|
+
? rightScale
|
|
38
|
+
: getYScale({
|
|
39
|
+
hasMoreThanTwoUnits: !isNil(thirdUnit),
|
|
40
|
+
invert: null,
|
|
41
|
+
leftScale,
|
|
42
|
+
rightScale,
|
|
43
|
+
secondUnit,
|
|
44
|
+
unit: firstUnit
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
{thresholds.warning.map(({ value, label }) => (
|
|
50
|
+
<ThresholdLine
|
|
51
|
+
hideTooltip={hideTooltip}
|
|
52
|
+
key={`warning-${value}`}
|
|
53
|
+
label={label}
|
|
54
|
+
showTooltip={showTooltip}
|
|
55
|
+
thresholdType="warning"
|
|
56
|
+
value={value}
|
|
57
|
+
width={width}
|
|
58
|
+
yScale={yScale}
|
|
59
|
+
/>
|
|
60
|
+
))}
|
|
61
|
+
{thresholds.critical.map(({ value, label }) => (
|
|
62
|
+
<ThresholdLine
|
|
63
|
+
hideTooltip={hideTooltip}
|
|
64
|
+
key={`critical-${value}`}
|
|
65
|
+
label={label}
|
|
66
|
+
showTooltip={showTooltip}
|
|
67
|
+
thresholdType="critical"
|
|
68
|
+
value={value}
|
|
69
|
+
width={width}
|
|
70
|
+
yScale={yScale}
|
|
71
|
+
/>
|
|
72
|
+
))}
|
|
73
|
+
</>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export default Thresholds;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
1
|
+
import { Dispatch, SetStateAction, useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
import { useAtom } from 'jotai';
|
|
4
3
|
import { compose, equals, prop, propEq, reject, sortBy, toLower } from 'ramda';
|
|
5
4
|
|
|
6
|
-
import { linesGraphAtom } from '../graphAtoms';
|
|
7
5
|
import { Line } from '../../common/timeSeries/models';
|
|
8
6
|
|
|
9
7
|
import {
|
|
@@ -15,6 +13,8 @@ import {
|
|
|
15
13
|
interface UseFilterLines {
|
|
16
14
|
displayThreshold?: boolean;
|
|
17
15
|
lines: Array<Line>;
|
|
16
|
+
linesGraph: Array<Line> | null;
|
|
17
|
+
setLinesGraph: Dispatch<SetStateAction<Array<Line> | null>>;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
interface Result {
|
|
@@ -24,10 +24,10 @@ interface Result {
|
|
|
24
24
|
|
|
25
25
|
const useFilterLines = ({
|
|
26
26
|
displayThreshold = false,
|
|
27
|
-
lines
|
|
27
|
+
lines,
|
|
28
|
+
linesGraph,
|
|
29
|
+
setLinesGraph
|
|
28
30
|
}: UseFilterLines): Result => {
|
|
29
|
-
const [linesGraph, setLinesGraph] = useAtom(linesGraphAtom);
|
|
30
|
-
|
|
31
31
|
const displayedLines = reject(propEq('display', false), linesGraph ?? lines);
|
|
32
32
|
const filterLines = (): Array<Line> => {
|
|
33
33
|
const lineOriginMetric = findLineOfOriginMetricThreshold(lines);
|
|
@@ -45,7 +45,9 @@ const useFilterLines = ({
|
|
|
45
45
|
|
|
46
46
|
useEffect(() => {
|
|
47
47
|
const filteredLines = filterLines();
|
|
48
|
-
if (!lines || !displayThreshold
|
|
48
|
+
if (!lines || !displayThreshold) {
|
|
49
|
+
setLinesGraph(lines);
|
|
50
|
+
|
|
49
51
|
return;
|
|
50
52
|
}
|
|
51
53
|
|
|
@@ -8,14 +8,12 @@ interface Props {
|
|
|
8
8
|
|
|
9
9
|
const Point = ({ lineColor, x, y }: Props): JSX.Element => (
|
|
10
10
|
<circle
|
|
11
|
+
cx={x}
|
|
12
|
+
cy={y}
|
|
11
13
|
fill={alpha(lineColor, 0.5)}
|
|
12
14
|
r={4}
|
|
13
15
|
stroke={lineColor}
|
|
14
16
|
strokeWidth={2}
|
|
15
|
-
style={{
|
|
16
|
-
transform: `translate(${x}px, ${y}px)`,
|
|
17
|
-
transition: 'transform 0.08s ease-out'
|
|
18
|
-
}}
|
|
19
17
|
/>
|
|
20
18
|
);
|
|
21
19
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
1
|
+
import { Dispatch, ReactNode, SetStateAction } from 'react';
|
|
2
2
|
|
|
3
3
|
import { slice } from 'ramda';
|
|
4
4
|
import { useAtomValue } from 'jotai';
|
|
@@ -28,8 +28,10 @@ interface Props {
|
|
|
28
28
|
limitLegendRows?: boolean;
|
|
29
29
|
lines: Array<Line>;
|
|
30
30
|
renderExtraComponent?: ReactNode;
|
|
31
|
+
setLinesGraph: Dispatch<SetStateAction<Array<Line> | null>>;
|
|
31
32
|
timeSeries: Array<TimeValue>;
|
|
32
33
|
toggable?: boolean;
|
|
34
|
+
xScale;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
const MainLegend = ({
|
|
@@ -39,18 +41,21 @@ const MainLegend = ({
|
|
|
39
41
|
toggable = true,
|
|
40
42
|
limitLegendRows = true,
|
|
41
43
|
renderExtraComponent,
|
|
42
|
-
displayAnchor = true
|
|
44
|
+
displayAnchor = true,
|
|
45
|
+
setLinesGraph,
|
|
46
|
+
xScale
|
|
43
47
|
}: Props): JSX.Element => {
|
|
44
48
|
const { classes, cx } = useStyles({ limitLegendRows });
|
|
45
49
|
const theme = useTheme();
|
|
46
50
|
|
|
47
51
|
const { selectMetricLine, clearHighlight, highlightLine, toggleMetricLine } =
|
|
48
|
-
useLegend({ lines });
|
|
52
|
+
useLegend({ lines, setLinesGraph });
|
|
49
53
|
|
|
50
54
|
const { getFormattedValue } = useInteractiveValues({
|
|
51
55
|
base,
|
|
52
56
|
lines,
|
|
53
|
-
timeSeries
|
|
57
|
+
timeSeries,
|
|
58
|
+
xScale
|
|
54
59
|
});
|
|
55
60
|
|
|
56
61
|
const displayedLines = limitLegendRows
|
|
@@ -3,11 +3,12 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import { useAtomValue } from 'jotai';
|
|
4
4
|
import { equals, find, isNil } from 'ramda';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { mousePositionAtom } from '../InteractiveComponents/interactionWithGraphAtoms';
|
|
7
7
|
import {
|
|
8
8
|
formatMetricValue,
|
|
9
9
|
getLineForMetric,
|
|
10
|
-
getMetrics
|
|
10
|
+
getMetrics,
|
|
11
|
+
getTimeValue
|
|
11
12
|
} from '../../common/timeSeries';
|
|
12
13
|
import { Line, TimeValue } from '../../common/timeSeries/models';
|
|
13
14
|
|
|
@@ -21,14 +22,22 @@ interface Props {
|
|
|
21
22
|
base: number;
|
|
22
23
|
lines: Array<Line>;
|
|
23
24
|
timeSeries: Array<TimeValue>;
|
|
25
|
+
xScale;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
const useInteractiveValues = ({
|
|
27
29
|
timeSeries,
|
|
28
30
|
lines,
|
|
29
|
-
base
|
|
31
|
+
base,
|
|
32
|
+
xScale
|
|
30
33
|
}: Props): InteractiveValues => {
|
|
31
|
-
const
|
|
34
|
+
const mousePosition = useAtomValue(mousePositionAtom);
|
|
35
|
+
|
|
36
|
+
const timeValue = getTimeValue({
|
|
37
|
+
timeSeries,
|
|
38
|
+
x: mousePosition?.[0],
|
|
39
|
+
xScale
|
|
40
|
+
});
|
|
32
41
|
|
|
33
42
|
const graphTimeValue = timeSeries?.find((item) =>
|
|
34
43
|
equals(item.timeTick, timeValue?.timeTick)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
1
|
+
import { Dispatch, SetStateAction, useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
import { useSetAtom } from 'jotai';
|
|
4
3
|
import {
|
|
5
4
|
equals,
|
|
6
5
|
find,
|
|
@@ -17,7 +16,6 @@ import {
|
|
|
17
16
|
toLower
|
|
18
17
|
} from 'ramda';
|
|
19
18
|
|
|
20
|
-
import { linesGraphAtom } from '../graphAtoms';
|
|
21
19
|
import { Line } from '../../common/timeSeries/models';
|
|
22
20
|
|
|
23
21
|
interface LegendActions {
|
|
@@ -29,11 +27,10 @@ interface LegendActions {
|
|
|
29
27
|
|
|
30
28
|
interface Props {
|
|
31
29
|
lines: Array<Line>;
|
|
30
|
+
setLinesGraph: Dispatch<SetStateAction<Array<Line> | null>>;
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
const useLegend = ({ lines }: Props): LegendActions => {
|
|
35
|
-
const setLines = useSetAtom(linesGraphAtom);
|
|
36
|
-
|
|
33
|
+
const useLegend = ({ lines, setLinesGraph }: Props): LegendActions => {
|
|
37
34
|
const displayedLines = reject(propEq('display', false), lines);
|
|
38
35
|
const getLineByMetric = (metric: string): Line =>
|
|
39
36
|
find(propEq('metric', metric), lines) as Line;
|
|
@@ -41,7 +38,7 @@ const useLegend = ({ lines }: Props): LegendActions => {
|
|
|
41
38
|
const toggleMetricLine = (metric): void => {
|
|
42
39
|
const line = getLineByMetric(metric);
|
|
43
40
|
|
|
44
|
-
|
|
41
|
+
setLinesGraph([
|
|
45
42
|
...reject(propEq('metric', metric), lines),
|
|
46
43
|
{ ...line, display: !line.display }
|
|
47
44
|
]);
|
|
@@ -56,11 +53,11 @@ const useLegend = ({ lines }: Props): LegendActions => {
|
|
|
56
53
|
|
|
57
54
|
const sortedData = sortBy(compose(toLower, prop('name')), data);
|
|
58
55
|
|
|
59
|
-
|
|
56
|
+
setLinesGraph(sortedData);
|
|
60
57
|
};
|
|
61
58
|
|
|
62
59
|
const clearHighlight = (): void => {
|
|
63
|
-
|
|
60
|
+
setLinesGraph(map((line) => ({ ...line, highlight: undefined }), lines));
|
|
64
61
|
};
|
|
65
62
|
|
|
66
63
|
const selectMetricLine = (metric: string): void => {
|
|
@@ -71,7 +68,7 @@ const useLegend = ({ lines }: Props): LegendActions => {
|
|
|
71
68
|
equals(displayedLines.length, 1) && isLineDisplayed;
|
|
72
69
|
|
|
73
70
|
if (isOnlyLineDisplayed || isEmpty(displayedLines)) {
|
|
74
|
-
|
|
71
|
+
setLinesGraph(
|
|
75
72
|
map(
|
|
76
73
|
(line) => ({
|
|
77
74
|
...line,
|
|
@@ -84,7 +81,7 @@ const useLegend = ({ lines }: Props): LegendActions => {
|
|
|
84
81
|
return;
|
|
85
82
|
}
|
|
86
83
|
|
|
87
|
-
|
|
84
|
+
setLinesGraph(
|
|
88
85
|
map(
|
|
89
86
|
(line) => ({
|
|
90
87
|
...line,
|
|
@@ -105,8 +102,8 @@ const useLegend = ({ lines }: Props): LegendActions => {
|
|
|
105
102
|
display: find(propEq('name', line.name), lines)?.display ?? true
|
|
106
103
|
}));
|
|
107
104
|
|
|
108
|
-
|
|
109
|
-
}, []);
|
|
105
|
+
setLinesGraph(newLines);
|
|
106
|
+
}, [lines]);
|
|
110
107
|
|
|
111
108
|
return { clearHighlight, highlightLine, selectMetricLine, toggleMetricLine };
|
|
112
109
|
};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { MutableRefObject, useMemo, useRef } from 'react';
|
|
1
|
+
import { MutableRefObject, useMemo, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import { Group } from '@visx/visx';
|
|
4
|
-
import { isNil } from 'ramda';
|
|
3
|
+
import { Group, Tooltip } from '@visx/visx';
|
|
4
|
+
import { flatten, isNil, pluck } from 'ramda';
|
|
5
5
|
|
|
6
|
-
import { ClickAwayListener, Skeleton } from '@mui/material';
|
|
6
|
+
import { ClickAwayListener, Fade, Skeleton, useTheme } from '@mui/material';
|
|
7
7
|
|
|
8
8
|
import { getLeftScale, getRightScale, getXScale } from '../common/timeSeries';
|
|
9
|
+
import { Line } from '../common/timeSeries/models';
|
|
10
|
+
import { Thresholds as ThresholdsModel } from '../common/models';
|
|
9
11
|
|
|
10
12
|
import Axes from './BasicComponents/Axes';
|
|
11
13
|
import Grids from './BasicComponents/Grids';
|
|
@@ -30,6 +32,7 @@ import {
|
|
|
30
32
|
} from './models';
|
|
31
33
|
import { useIntersection } from './useLineChartIntersection';
|
|
32
34
|
import { CurveType } from './BasicComponents/Lines/models';
|
|
35
|
+
import Thresholds from './BasicComponents/Thresholds';
|
|
33
36
|
|
|
34
37
|
interface Props extends LineChartProps {
|
|
35
38
|
curve: CurveType;
|
|
@@ -39,8 +42,15 @@ interface Props extends LineChartProps {
|
|
|
39
42
|
legend?: LegendModel;
|
|
40
43
|
marginBottom: number;
|
|
41
44
|
shapeLines?: GlobalAreaLines;
|
|
45
|
+
thresholdUnit?: string;
|
|
46
|
+
thresholds?: ThresholdsModel;
|
|
42
47
|
}
|
|
43
48
|
|
|
49
|
+
const baseStyles = {
|
|
50
|
+
...Tooltip.defaultStyles,
|
|
51
|
+
textAlign: 'center'
|
|
52
|
+
};
|
|
53
|
+
|
|
44
54
|
const LineChart = ({
|
|
45
55
|
graphData,
|
|
46
56
|
height = 500,
|
|
@@ -58,15 +68,30 @@ const LineChart = ({
|
|
|
58
68
|
graphRef,
|
|
59
69
|
header,
|
|
60
70
|
curve,
|
|
61
|
-
marginBottom
|
|
71
|
+
marginBottom,
|
|
72
|
+
thresholds,
|
|
73
|
+
thresholdUnit
|
|
62
74
|
}: Props): JSX.Element => {
|
|
75
|
+
const { classes } = useStyles();
|
|
76
|
+
|
|
77
|
+
const theme = useTheme();
|
|
78
|
+
|
|
79
|
+
const [linesGraph, setLinesGraph] = useState<Array<Line> | null>(null);
|
|
63
80
|
const graphSvgRef = useRef<SVGSVGElement | null>(null);
|
|
64
81
|
|
|
65
|
-
const { classes } = useStyles();
|
|
66
82
|
const { isInViewport } = useIntersection({ element: graphRef?.current });
|
|
67
83
|
|
|
68
84
|
const legendRef = useRef<HTMLDivElement | null>(null);
|
|
69
85
|
|
|
86
|
+
const {
|
|
87
|
+
tooltipOpen: thresholdTooltipOpen,
|
|
88
|
+
tooltipLeft: thresholdTooltipLeft,
|
|
89
|
+
tooltipTop: thresholdTooltipTop,
|
|
90
|
+
tooltipData: thresholdTooltipData,
|
|
91
|
+
hideTooltip: hideThresholdTooltip,
|
|
92
|
+
showTooltip: showThresholdTooltip
|
|
93
|
+
} = Tooltip.useTooltip();
|
|
94
|
+
|
|
70
95
|
const graphWidth = width > 0 ? width - margin.left - margin.right : 0;
|
|
71
96
|
const graphHeight =
|
|
72
97
|
(height || 0) > 0
|
|
@@ -79,9 +104,16 @@ const LineChart = ({
|
|
|
79
104
|
|
|
80
105
|
const { title, timeSeries, baseAxis, lines } = graphData;
|
|
81
106
|
|
|
107
|
+
const thresholdValues = flatten([
|
|
108
|
+
pluck('value', thresholds?.warning || []),
|
|
109
|
+
pluck('value', thresholds?.critical || [])
|
|
110
|
+
]);
|
|
111
|
+
|
|
82
112
|
const { displayedLines, newLines } = useFilterLines({
|
|
83
113
|
displayThreshold: canDisplayThreshold(shapeLines?.areaThresholdLines),
|
|
84
|
-
lines
|
|
114
|
+
lines,
|
|
115
|
+
linesGraph,
|
|
116
|
+
setLinesGraph
|
|
85
117
|
});
|
|
86
118
|
|
|
87
119
|
const xScale = useMemo(
|
|
@@ -98,9 +130,11 @@ const LineChart = ({
|
|
|
98
130
|
getLeftScale({
|
|
99
131
|
dataLines: displayedLines,
|
|
100
132
|
dataTimeSeries: timeSeries,
|
|
133
|
+
thresholdUnit,
|
|
134
|
+
thresholds: (thresholds?.enabled && thresholdValues) || [],
|
|
101
135
|
valueGraphHeight: graphHeight - 35
|
|
102
136
|
}),
|
|
103
|
-
[displayedLines, timeSeries, graphHeight]
|
|
137
|
+
[displayedLines, timeSeries, graphHeight, thresholdValues]
|
|
104
138
|
);
|
|
105
139
|
|
|
106
140
|
const rightScale = useMemo(
|
|
@@ -108,6 +142,8 @@ const LineChart = ({
|
|
|
108
142
|
getRightScale({
|
|
109
143
|
dataLines: displayedLines,
|
|
110
144
|
dataTimeSeries: timeSeries,
|
|
145
|
+
thresholdUnit,
|
|
146
|
+
thresholds: (thresholds?.enabled && thresholdValues) || [],
|
|
111
147
|
valueGraphHeight: graphHeight - 35
|
|
112
148
|
}),
|
|
113
149
|
[timeSeries, displayedLines, graphHeight]
|
|
@@ -201,6 +237,19 @@ const LineChart = ({
|
|
|
201
237
|
}}
|
|
202
238
|
zoomData={{ ...zoomPreview }}
|
|
203
239
|
/>
|
|
240
|
+
|
|
241
|
+
{thresholds?.enabled && (
|
|
242
|
+
<Thresholds
|
|
243
|
+
displayedLines={displayedLines}
|
|
244
|
+
hideTooltip={hideThresholdTooltip}
|
|
245
|
+
leftScale={leftScale}
|
|
246
|
+
rightScale={rightScale}
|
|
247
|
+
showTooltip={showThresholdTooltip}
|
|
248
|
+
thresholdUnit={thresholdUnit}
|
|
249
|
+
thresholds={thresholds as ThresholdsModel}
|
|
250
|
+
width={graphWidth}
|
|
251
|
+
/>
|
|
252
|
+
)}
|
|
204
253
|
</Group.Group>
|
|
205
254
|
</svg>
|
|
206
255
|
{displayTooltip && (
|
|
@@ -218,6 +267,20 @@ const LineChart = ({
|
|
|
218
267
|
xScale={xScale}
|
|
219
268
|
/>
|
|
220
269
|
)}
|
|
270
|
+
<Fade in={thresholdTooltipOpen}>
|
|
271
|
+
<Tooltip.Tooltip
|
|
272
|
+
left={thresholdTooltipLeft}
|
|
273
|
+
style={{
|
|
274
|
+
...baseStyles,
|
|
275
|
+
backgroundColor: theme.palette.background.paper,
|
|
276
|
+
color: theme.palette.text.primary,
|
|
277
|
+
transform: `translate(${graphWidth / 2}px, -10px)`
|
|
278
|
+
}}
|
|
279
|
+
top={thresholdTooltipTop}
|
|
280
|
+
>
|
|
281
|
+
{thresholdTooltipData}
|
|
282
|
+
</Tooltip.Tooltip>
|
|
283
|
+
</Fade>
|
|
221
284
|
</div>
|
|
222
285
|
</ClickAwayListener>
|
|
223
286
|
{displayLegend && (
|
|
@@ -227,7 +290,9 @@ const LineChart = ({
|
|
|
227
290
|
displayAnchor={displayAnchor?.displayGuidingLines ?? true}
|
|
228
291
|
lines={newLines}
|
|
229
292
|
renderExtraComponent={legend?.renderExtraComponent}
|
|
293
|
+
setLinesGraph={setLinesGraph}
|
|
230
294
|
timeSeries={timeSeries}
|
|
295
|
+
xScale={xScale}
|
|
231
296
|
/>
|
|
232
297
|
</div>
|
|
233
298
|
)}
|
|
@@ -29,10 +29,11 @@ import exclusionPeriodFirstPeriod from './mockedData/exclusionPeriodFirstPeriod.
|
|
|
29
29
|
import exclusionPeriodSecondPeriod from './mockedData/exclusionPeriodSecondPeriod.json';
|
|
30
30
|
import exclusionPeriodThirdPeriod from './mockedData/exclusionPeriodThirdPeriod.json';
|
|
31
31
|
import dataLastDayForword from './mockedData/lastDayForward.json';
|
|
32
|
-
import
|
|
32
|
+
import dataLastDayThreshold from './mockedData/lastDayThreshold.json';
|
|
33
33
|
import dataLastMonth from './mockedData/lastMonth.json';
|
|
34
34
|
import dataLastWeek from './mockedData/lastWeek.json';
|
|
35
35
|
import dataZoomPreview from './mockedData/zoomPreview.json';
|
|
36
|
+
import dataLastDay from './mockedData/lastDay.json';
|
|
36
37
|
import { Interval, ThresholdType, TooltipData } from './models';
|
|
37
38
|
|
|
38
39
|
import WrapperLineChart from './index';
|
|
@@ -75,7 +76,7 @@ const Threshold = (args): JSX.Element => {
|
|
|
75
76
|
|
|
76
77
|
<WrapperLineChart
|
|
77
78
|
{...args}
|
|
78
|
-
data={
|
|
79
|
+
data={dataLastDayThreshold}
|
|
79
80
|
shapeLines={{
|
|
80
81
|
areaThresholdLines: [
|
|
81
82
|
{ type: ThresholdType.basic },
|
|
@@ -123,7 +124,7 @@ const LineChartAndCLS = (args): JSX.Element => {
|
|
|
123
124
|
useEffect(() => {
|
|
124
125
|
setTimeout(() => {
|
|
125
126
|
setLoading(false);
|
|
126
|
-
setData(
|
|
127
|
+
setData(dataLastDayThreshold as unknown as LineChartData);
|
|
127
128
|
}, 100000);
|
|
128
129
|
}, []);
|
|
129
130
|
|
|
@@ -187,7 +188,7 @@ const LineChartAndTimePeriod = (args): JSX.Element => {
|
|
|
187
188
|
}
|
|
188
189
|
|
|
189
190
|
if (start.includes(`${defaultStart.split('T')[0]}`)) {
|
|
190
|
-
setCurrentData(
|
|
191
|
+
setCurrentData(dataLastDayThreshold as unknown as LineChartData);
|
|
191
192
|
|
|
192
193
|
return;
|
|
193
194
|
}
|
|
@@ -281,7 +282,7 @@ const LineChartAndExclusionPeriod = (args): JSX.Element => {
|
|
|
281
282
|
</ButtonGroup>
|
|
282
283
|
<WrapperLineChart
|
|
283
284
|
{...args}
|
|
284
|
-
data={
|
|
285
|
+
data={dataLastDayThreshold as unknown as LineChartData}
|
|
285
286
|
shapeLines={{
|
|
286
287
|
areaThresholdLines: [
|
|
287
288
|
{
|
|
@@ -303,7 +304,7 @@ const Template: Story = {
|
|
|
303
304
|
render: (args) => (
|
|
304
305
|
<WrapperLineChart
|
|
305
306
|
{...args}
|
|
306
|
-
data={
|
|
307
|
+
data={dataLastDayThreshold as unknown as LineChartData}
|
|
307
308
|
shapeLines={{
|
|
308
309
|
areaThresholdLines: [
|
|
309
310
|
{
|
|
@@ -381,3 +382,97 @@ export const withCLS: Story = {
|
|
|
381
382
|
start: defaultStart
|
|
382
383
|
}
|
|
383
384
|
};
|
|
385
|
+
|
|
386
|
+
export const withThresholds: Story = {
|
|
387
|
+
argTypes,
|
|
388
|
+
args: {
|
|
389
|
+
...argumentsData,
|
|
390
|
+
thresholds: {
|
|
391
|
+
critical: [
|
|
392
|
+
{
|
|
393
|
+
label: 'critical',
|
|
394
|
+
value: 350
|
|
395
|
+
}
|
|
396
|
+
],
|
|
397
|
+
enabled: true,
|
|
398
|
+
warning: [
|
|
399
|
+
{
|
|
400
|
+
label: 'warning',
|
|
401
|
+
value: 300
|
|
402
|
+
}
|
|
403
|
+
]
|
|
404
|
+
}
|
|
405
|
+
},
|
|
406
|
+
render: (args) => (
|
|
407
|
+
<WrapperLineChart
|
|
408
|
+
{...args}
|
|
409
|
+
data={dataLastDay as unknown as LineChartData}
|
|
410
|
+
/>
|
|
411
|
+
)
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
export const withThresholdsAndUnit: Story = {
|
|
415
|
+
argTypes,
|
|
416
|
+
args: {
|
|
417
|
+
...argumentsData,
|
|
418
|
+
thresholdUnit: '%',
|
|
419
|
+
thresholds: {
|
|
420
|
+
critical: [
|
|
421
|
+
{
|
|
422
|
+
label: 'critical',
|
|
423
|
+
value: 79
|
|
424
|
+
}
|
|
425
|
+
],
|
|
426
|
+
enabled: true,
|
|
427
|
+
warning: [
|
|
428
|
+
{
|
|
429
|
+
label: 'warning',
|
|
430
|
+
value: 65
|
|
431
|
+
}
|
|
432
|
+
]
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
render: (args) => (
|
|
436
|
+
<WrapperLineChart
|
|
437
|
+
{...args}
|
|
438
|
+
data={dataLastDay as unknown as LineChartData}
|
|
439
|
+
/>
|
|
440
|
+
)
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
export const thresholdsRange: Story = {
|
|
444
|
+
argTypes,
|
|
445
|
+
args: {
|
|
446
|
+
...argumentsData,
|
|
447
|
+
thresholdUnit: '%',
|
|
448
|
+
thresholds: {
|
|
449
|
+
critical: [
|
|
450
|
+
{
|
|
451
|
+
label: 'critical 1',
|
|
452
|
+
value: 60
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
label: 'critical 2',
|
|
456
|
+
value: 79
|
|
457
|
+
}
|
|
458
|
+
],
|
|
459
|
+
enabled: true,
|
|
460
|
+
warning: [
|
|
461
|
+
{
|
|
462
|
+
label: 'warning 1',
|
|
463
|
+
value: 20
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
label: 'warning 2',
|
|
467
|
+
value: 30
|
|
468
|
+
}
|
|
469
|
+
]
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
render: (args) => (
|
|
473
|
+
<WrapperLineChart
|
|
474
|
+
{...args}
|
|
475
|
+
data={dataLastDay as unknown as LineChartData}
|
|
476
|
+
/>
|
|
477
|
+
)
|
|
478
|
+
};
|
|
@@ -10,7 +10,7 @@ import localizedFormat from 'dayjs/plugin/localizedFormat';
|
|
|
10
10
|
import timezonePlugin from 'dayjs/plugin/timezone';
|
|
11
11
|
import utcPlugin from 'dayjs/plugin/utc';
|
|
12
12
|
|
|
13
|
-
import { LineChartData } from '../common/models';
|
|
13
|
+
import { LineChartData, Thresholds } from '../common/models';
|
|
14
14
|
|
|
15
15
|
import LineChart from './LineChart';
|
|
16
16
|
import LoadingSkeleton from './LoadingSkeleton';
|
|
@@ -31,6 +31,8 @@ interface Props extends Partial<LineChartProps> {
|
|
|
31
31
|
marginBottom?: number;
|
|
32
32
|
shapeLines?: GlobalAreaLines;
|
|
33
33
|
start: string;
|
|
34
|
+
thresholdUnit?: string;
|
|
35
|
+
thresholds?: Thresholds;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
const WrapperLineChart = ({
|
|
@@ -50,12 +52,14 @@ const WrapperLineChart = ({
|
|
|
50
52
|
legend,
|
|
51
53
|
header,
|
|
52
54
|
curve = Curve.curveLinear,
|
|
53
|
-
marginBottom = 0
|
|
55
|
+
marginBottom = 0,
|
|
56
|
+
thresholds,
|
|
57
|
+
thresholdUnit
|
|
54
58
|
}: Props): JSX.Element | null => {
|
|
55
59
|
const { adjustedData } = useLineChartData({ data, end, start });
|
|
56
60
|
const lineChartRef = useRef<HTMLDivElement | null>(null);
|
|
57
61
|
|
|
58
|
-
if (loading
|
|
62
|
+
if (loading && !adjustedData) {
|
|
59
63
|
return (
|
|
60
64
|
<LoadingSkeleton
|
|
61
65
|
displayTitleSkeleton={header?.displayTitle ?? true}
|
|
@@ -64,6 +68,10 @@ const WrapperLineChart = ({
|
|
|
64
68
|
);
|
|
65
69
|
}
|
|
66
70
|
|
|
71
|
+
if (!adjustedData) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
67
75
|
return (
|
|
68
76
|
<div
|
|
69
77
|
ref={lineChartRef as MutableRefObject<HTMLDivElement>}
|
|
@@ -89,6 +97,8 @@ const WrapperLineChart = ({
|
|
|
89
97
|
loading={loading}
|
|
90
98
|
marginBottom={marginBottom}
|
|
91
99
|
shapeLines={shapeLines}
|
|
100
|
+
thresholdUnit={thresholdUnit}
|
|
101
|
+
thresholds={thresholds}
|
|
92
102
|
timeShiftZones={timeShiftZones}
|
|
93
103
|
tooltip={tooltip}
|
|
94
104
|
width={width ?? responsiveWidth}
|