@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.
Files changed (35) hide show
  1. package/package.json +1 -1
  2. package/src/Graph/Gauge/AnimatedPie.tsx +31 -20
  3. package/src/Graph/Gauge/Gauge.stories.tsx +97 -6
  4. package/src/Graph/Gauge/Gauge.tsx +4 -15
  5. package/src/Graph/Gauge/PieData.tsx +8 -24
  6. package/src/Graph/Gauge/ResponsiveGauge.tsx +11 -14
  7. package/src/Graph/Gauge/Thresholds.tsx +109 -56
  8. package/src/Graph/Gauge/models.ts +2 -3
  9. package/src/Graph/LineChart/BasicComponents/ThresholdLine.tsx +64 -0
  10. package/src/Graph/LineChart/BasicComponents/Thresholds.tsx +77 -0
  11. package/src/Graph/LineChart/BasicComponents/useFilterLines.ts +9 -7
  12. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/index.tsx +2 -4
  13. package/src/Graph/LineChart/InteractiveComponents/interactionWithGraphAtoms.ts +1 -0
  14. package/src/Graph/LineChart/Legend/index.tsx +9 -4
  15. package/src/Graph/LineChart/Legend/useInteractiveValues.ts +13 -4
  16. package/src/Graph/LineChart/Legend/useLegend.ts +10 -13
  17. package/src/Graph/LineChart/LineChart.tsx +73 -8
  18. package/src/Graph/LineChart/graphAtoms.ts +0 -3
  19. package/src/Graph/LineChart/index.stories.tsx +101 -6
  20. package/src/Graph/LineChart/index.tsx +13 -3
  21. package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +10 -8
  22. package/src/Graph/SingleBar/SingleBar.stories.tsx +119 -6
  23. package/src/Graph/SingleBar/ThresholdLine.tsx +74 -0
  24. package/src/Graph/SingleBar/Thresholds.tsx +28 -82
  25. package/src/Graph/SingleBar/models.ts +2 -4
  26. package/src/Graph/Text/Text.tsx +20 -16
  27. package/src/Graph/common/models.ts +12 -0
  28. package/src/Graph/common/timeSeries/index.ts +41 -8
  29. package/src/Graph/common/timeSeries/models.ts +3 -1
  30. package/src/Graph/common/utils.ts +59 -6
  31. package/src/api/useGraphQuery/index.ts +52 -21
  32. package/src/components/Modal/Modal.styles.ts +1 -2
  33. package/src/utils/index.ts +1 -0
  34. package/src/utils/useRefreshInterval.ts +21 -0
  35. package/src/utils/useThresholds.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "23.10.61",
3
+ "version": "23.10.63",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -1,17 +1,18 @@
1
1
  import { PieArcDatum, ProvidedProps } from '@visx/shape/lib/shapes/Pie';
2
- import { useTransition, interpolate, animated } from '@react-spring/web';
3
- import { equals } from 'ramda';
2
+ import { useTransition, to, animated } from '@react-spring/web';
3
+ import { equals, includes, pluck } from 'ramda';
4
4
 
5
- import { Metric } from '../common/timeSeries/models';
5
+ import { Typography } from '@mui/material';
6
6
 
7
- import { ThresholdType } from './models';
7
+ import { Metric } from '../common/timeSeries/models';
8
+ import { Thresholds } from '../common/models';
8
9
 
9
10
  type AnimatedStyles = { endAngle: number; opacity: number; startAngle: number };
10
11
 
11
- const fromLeaveTransition = (): AnimatedStyles => ({
12
- endAngle: 0,
12
+ const fromLeaveTransition = ({ endAngle }): AnimatedStyles => ({
13
+ endAngle,
13
14
  opacity: 0,
14
- startAngle: 0
15
+ startAngle: -(Math.PI / 2)
15
16
  });
16
17
  const enterUpdateTransition = <T,>({
17
18
  startAngle,
@@ -30,7 +31,7 @@ type AnimatedPieProps<Datum> = ProvidedProps<Datum> & {
30
31
  hideTooltip?: () => void;
31
32
  metric?: Metric;
32
33
  showTooltip?: (args) => void;
33
- thresholdTooltipLabels?: Array<string>;
34
+ thresholds: Thresholds;
34
35
  };
35
36
 
36
37
  const AnimatedPie = <Datum,>({
@@ -41,7 +42,7 @@ const AnimatedPie = <Datum,>({
41
42
  getColor,
42
43
  showTooltip,
43
44
  hideTooltip,
44
- thresholdTooltipLabels = []
45
+ thresholds
45
46
  }: AnimatedPieProps<Datum>): JSX.Element => {
46
47
  const transitions = useTransition<PieArcDatum<Datum>, AnimatedStyles>(arcs, {
47
48
  enter: enterUpdateTransition,
@@ -54,26 +55,36 @@ const AnimatedPie = <Datum,>({
54
55
  return transitions((props, arc, { key }) => (
55
56
  <g key={key}>
56
57
  <animated.path
57
- d={interpolate(
58
- [props.startAngle, props.endAngle],
59
- (startAngle, endAngle) =>
60
- path({
61
- ...arc,
62
- endAngle,
63
- startAngle
64
- })
58
+ d={to([props.startAngle, props.endAngle], (startAngle, endAngle) =>
59
+ path({
60
+ ...arc,
61
+ endAngle,
62
+ startAngle
63
+ })
65
64
  )}
66
65
  data-testid={`${arc.data?.value || arc.data}-arc`}
66
+ display={
67
+ includes('transparent', arc.data?.name || '') ? 'none' : 'inline'
68
+ }
67
69
  fill={getColor(arc)}
68
70
  onMouseEnter={(event) => {
69
- const thresholdType = arc.data.name;
71
+ const thresholdType = arc.data?.name as string;
70
72
 
71
- if (equals(thresholdType, ThresholdType.Success)) {
73
+ if (equals(thresholdType, 'success')) {
72
74
  return;
73
75
  }
74
76
 
75
77
  showTooltip?.({
76
- tooltipData: thresholdTooltipLabels[thresholdType],
78
+ tooltipData: (
79
+ <div>
80
+ {pluck(
81
+ 'label',
82
+ thresholds[thresholdType as 'warning' | 'critical']
83
+ ).map((label) => (
84
+ <Typography key={label}>{label}</Typography>
85
+ ))}
86
+ </div>
87
+ ),
77
88
  tooltipLeft: event.clientX,
78
89
  tooltipTop: event.clientY
79
90
  });
@@ -20,8 +20,21 @@ const Template = (props): JSX.Element => (
20
20
  export const success: Story = {
21
21
  args: {
22
22
  data: dataLastWeek,
23
- thresholdTooltipLabels: ['Warning', 'Critical'],
24
- thresholds: [0.5, 0.6]
23
+ thresholds: {
24
+ critical: [
25
+ {
26
+ label: 'Critical',
27
+ value: 0.6
28
+ }
29
+ ],
30
+ enabled: true,
31
+ warning: [
32
+ {
33
+ label: 'Warning',
34
+ value: 0.5
35
+ }
36
+ ]
37
+ }
25
38
  },
26
39
  render: Template
27
40
  };
@@ -29,8 +42,21 @@ export const success: Story = {
29
42
  export const warning: Story = {
30
43
  args: {
31
44
  data: dataLastWeek,
32
- thresholdTooltipLabels: ['Warning', 'Critical'],
33
- thresholds: [0.2, 0.5]
45
+ thresholds: {
46
+ critical: [
47
+ {
48
+ label: 'Critical',
49
+ value: 0.6
50
+ }
51
+ ],
52
+ enabled: true,
53
+ warning: [
54
+ {
55
+ label: 'Warning',
56
+ value: 0.2
57
+ }
58
+ ]
59
+ }
34
60
  },
35
61
  render: Template
36
62
  };
@@ -38,8 +64,73 @@ export const warning: Story = {
38
64
  export const critical: Story = {
39
65
  args: {
40
66
  data: dataLastWeek,
41
- thresholdTooltipLabels: ['Warning', 'Critical'],
42
- thresholds: [0.13, 0.35]
67
+ thresholds: {
68
+ critical: [
69
+ {
70
+ label: 'Critical',
71
+ value: 0.35
72
+ }
73
+ ],
74
+ enabled: true,
75
+ warning: [
76
+ {
77
+ label: 'Warning',
78
+ value: 0.13
79
+ }
80
+ ]
81
+ }
82
+ },
83
+ render: Template
84
+ };
85
+
86
+ export const withCriticalLowerThanWarning: Story = {
87
+ args: {
88
+ data: dataLastWeek,
89
+ thresholds: {
90
+ critical: [
91
+ {
92
+ label: 'Critical',
93
+ value: 0.13
94
+ }
95
+ ],
96
+ enabled: true,
97
+ warning: [
98
+ {
99
+ label: 'Warning',
100
+ value: 0.5
101
+ }
102
+ ]
103
+ }
104
+ },
105
+ render: Template
106
+ };
107
+
108
+ export const withRangeThresholds: Story = {
109
+ args: {
110
+ data: dataLastWeek,
111
+ thresholds: {
112
+ critical: [
113
+ {
114
+ label: 'Critical',
115
+ value: 0.55
116
+ },
117
+ {
118
+ label: 'Critical',
119
+ value: 0.65
120
+ }
121
+ ],
122
+ enabled: true,
123
+ warning: [
124
+ {
125
+ label: 'Warning',
126
+ value: 0.13
127
+ },
128
+ {
129
+ label: 'Warning',
130
+ value: 0.5
131
+ }
132
+ ]
133
+ }
43
134
  },
44
135
  render: Template
45
136
  };
@@ -1,7 +1,6 @@
1
1
  import { Responsive } from '@visx/visx';
2
- import { sort, subtract } from 'ramda';
3
2
 
4
- import { LineChartData } from '../common/models';
3
+ import { LineChartData, Thresholds } from '../common/models';
5
4
  import { getMetricWithLatestData } from '../common/timeSeries';
6
5
  import { Metric } from '../common/timeSeries/models';
7
6
 
@@ -9,21 +8,13 @@ import ResponsiveGauge from './ResponsiveGauge';
9
8
 
10
9
  interface Props {
11
10
  data?: LineChartData;
12
- disabledThresholds?: boolean;
13
- thresholdTooltipLabels: Array<string>;
14
- thresholds: Array<number>;
11
+ thresholds: Thresholds;
15
12
  }
16
13
 
17
- export const Gauge = ({
18
- thresholds,
19
- data,
20
- thresholdTooltipLabels,
21
- disabledThresholds
22
- }: Props): JSX.Element | null => {
14
+ export const Gauge = ({ thresholds, data }: Props): JSX.Element | null => {
23
15
  if (!data) {
24
16
  return null;
25
17
  }
26
- const sortedThresholds = sort(subtract, thresholds);
27
18
 
28
19
  const metric = getMetricWithLatestData(data) as Metric;
29
20
 
@@ -31,11 +22,9 @@ export const Gauge = ({
31
22
  <Responsive.ParentSize>
32
23
  {({ width, height }) => (
33
24
  <ResponsiveGauge
34
- disabledThresholds={disabledThresholds}
35
25
  height={height}
36
26
  metric={metric}
37
- thresholdTooltipLabels={thresholdTooltipLabels}
38
- thresholds={sortedThresholds}
27
+ thresholds={thresholds}
39
28
  width={width}
40
29
  />
41
30
  )}
@@ -1,8 +1,10 @@
1
1
  import { scaleOrdinal } from '@visx/scale';
2
2
  import { Pie } from '@visx/shape';
3
- import { T, always, cond, gt, head, identity } from 'ramda';
3
+ import { identity } from 'ramda';
4
4
 
5
- import { Theme, useTheme } from '@mui/material';
5
+ import { useTheme } from '@mui/material';
6
+
7
+ import { getColorFromDataAndTresholds } from '../common/utils';
6
8
 
7
9
  import { thresholdThickness } from './Thresholds';
8
10
  import AnimatedPie from './AnimatedPie';
@@ -10,29 +12,11 @@ import { GaugeProps } from './models';
10
12
 
11
13
  const dataThickness = 45;
12
14
 
13
- interface GetColorFromDataProps {
14
- data: number;
15
- theme: Theme;
16
- thresholds: Array<number>;
17
- }
18
-
19
- const getColorFromData = ({
20
- data,
21
- thresholds,
22
- theme
23
- }: GetColorFromDataProps): string =>
24
- cond([
25
- [gt(head(thresholds) as number), always(theme.palette.success.main)],
26
- [gt(thresholds[1]), always(theme.palette.warning.main)],
27
- [T, always(theme.palette.error.main)]
28
- ])(data);
29
-
30
15
  const PieData = ({
31
16
  metric,
32
17
  adaptedMaxValue,
33
18
  thresholds,
34
- radius,
35
- disabledThresholds
19
+ radius
36
20
  }: Omit<
37
21
  GaugeProps,
38
22
  'width' | 'height' | 'showTooltip' | 'hideTooltip' | 'thresholdTooltipLabels'
@@ -40,9 +24,9 @@ const PieData = ({
40
24
  const theme = useTheme();
41
25
 
42
26
  const pieData = [metric.data[0], adaptedMaxValue - metric.data[0]];
43
- const pieColor = disabledThresholds
27
+ const pieColor = !thresholds.enabled
44
28
  ? theme.palette.success.main
45
- : getColorFromData({
29
+ : getColorFromDataAndTresholds({
46
30
  data: metric.data[0],
47
31
  theme,
48
32
  thresholds
@@ -69,7 +53,7 @@ const PieData = ({
69
53
  animate
70
54
  getColor={(arc) => getDataColor(arc.data)}
71
55
  getKey={(arc) => `${arc.data}`}
72
- thresholdTooltipLabels={[]}
56
+ thresholds={thresholds}
73
57
  />
74
58
  )}
75
59
  </Pie>
@@ -1,7 +1,7 @@
1
1
  import { useRef } from 'react';
2
2
 
3
3
  import { Group } from '@visx/group';
4
- import { head } from 'ramda';
4
+ import { flatten, head, pluck } from 'ramda';
5
5
  import { Tooltip } from '@visx/visx';
6
6
 
7
7
  import { Box, Fade, useTheme } from '@mui/material';
@@ -13,13 +13,11 @@ import { margins } from '../common/margins';
13
13
 
14
14
  import Thresholds from './Thresholds';
15
15
  import PieData from './PieData';
16
+ import { GaugeProps } from './models';
16
17
 
17
- interface Props {
18
- disabledThresholds?: boolean;
18
+ interface Props extends Pick<GaugeProps, 'thresholds'> {
19
19
  height: number;
20
20
  metric: Metric;
21
- thresholdTooltipLabels: Array<string>;
22
- thresholds: Array<number>;
23
21
  width: number;
24
22
  }
25
23
 
@@ -32,9 +30,7 @@ const ResponsiveGauge = ({
32
30
  width,
33
31
  height,
34
32
  thresholds,
35
- metric,
36
- thresholdTooltipLabels,
37
- disabledThresholds
33
+ metric
38
34
  }: Props): JSX.Element => {
39
35
  const svgRef = useRef<SVGSVGElement>(null);
40
36
 
@@ -54,13 +50,17 @@ const ResponsiveGauge = ({
54
50
  const centerY = innerHeight / 2;
55
51
  const centerX = innerWidth / 2;
56
52
  const radius = Math.min(innerWidth, innerHeight) / 2;
53
+ const thresholdValues = flatten([
54
+ pluck('value', thresholds.warning),
55
+ pluck('value', thresholds.critical)
56
+ ]);
57
57
  const adaptedMaxValue = Math.max(
58
58
  metric.maximum_value || 0,
59
- Math.max(...thresholds) * 1.1,
59
+ Math.max(...thresholdValues) * 1.1,
60
60
  head(metric.data) as number
61
61
  );
62
62
 
63
- const pieColor = disabledThresholds
63
+ const pieColor = !thresholds.enabled
64
64
  ? theme.palette.success.main
65
65
  : getColorFromDataAndTresholds({
66
66
  data: metric.data[0],
@@ -79,17 +79,14 @@ const ResponsiveGauge = ({
79
79
  <Group left={centerX + margins.left} top={centerY + height / 6}>
80
80
  <Thresholds
81
81
  adaptedMaxValue={adaptedMaxValue}
82
- disabledThresholds={disabledThresholds}
83
82
  hideTooltip={hideTooltip}
84
83
  metric={metric}
85
84
  radius={radius}
86
85
  showTooltip={showTooltip}
87
- thresholdTooltipLabels={thresholdTooltipLabels}
88
86
  thresholds={thresholds}
89
87
  />
90
88
  <PieData
91
89
  adaptedMaxValue={adaptedMaxValue}
92
- disabledThresholds={disabledThresholds}
93
90
  metric={metric}
94
91
  radius={radius}
95
92
  thresholds={thresholds}
@@ -114,7 +111,7 @@ const ResponsiveGauge = ({
114
111
  {metric.unit}
115
112
  </text>
116
113
  </svg>
117
- <Fade in={tooltipOpen && !disabledThresholds}>
114
+ <Fade in={tooltipOpen && thresholds.enabled}>
118
115
  <Tooltip.Tooltip
119
116
  left={(tooltipLeft || 0) - svgLeft}
120
117
  style={{
@@ -1,11 +1,11 @@
1
1
  import { scaleOrdinal } from '@visx/scale';
2
2
  import { Pie } from '@visx/shape';
3
- import { pluck } from 'ramda';
3
+ import { equals, pluck } from 'ramda';
4
4
 
5
5
  import { useTheme } from '@mui/material';
6
6
 
7
7
  import AnimatedPie from './AnimatedPie';
8
- import { GaugeProps, ThresholdType } from './models';
8
+ import { GaugeProps } from './models';
9
9
 
10
10
  export const thresholdThickness = 12;
11
11
 
@@ -15,72 +15,125 @@ const Thresholds = ({
15
15
  adaptedMaxValue,
16
16
  showTooltip,
17
17
  hideTooltip,
18
- metric,
19
- thresholdTooltipLabels,
20
- disabledThresholds
18
+ metric
21
19
  }: Omit<GaugeProps, 'width' | 'height'>): JSX.Element => {
22
20
  const theme = useTheme();
23
21
 
24
- const namedThresholds = [
22
+ const criticalThresholdValues = pluck('value', thresholds.critical);
23
+ const warningThresholdValues = pluck('value', thresholds.warning);
24
+
25
+ const isCriticalLowerThanWarning =
26
+ criticalThresholdValues[0] < warningThresholdValues[0];
27
+
28
+ const criticalThreshold = isCriticalLowerThanWarning
29
+ ? [0, ...criticalThresholdValues, adaptedMaxValue]
30
+ : [...criticalThresholdValues, adaptedMaxValue];
31
+ const criticalThresholdArc = criticalThreshold.map((value, index) => {
32
+ return {
33
+ name: equals(1, index) ? 'critical' : `transparent-${index}-critical`,
34
+ value: value - (criticalThreshold[index - 1] || 0)
35
+ };
36
+ });
37
+ const criticalThresholdScaleOrdinal = scaleOrdinal({
38
+ domain: pluck('name', criticalThresholdArc),
39
+ range: ['transparent', theme.palette.error.main, 'transparent']
40
+ });
41
+
42
+ const warningThreshold = isCriticalLowerThanWarning
43
+ ? [0, ...warningThresholdValues, adaptedMaxValue]
44
+ : [...warningThresholdValues, adaptedMaxValue];
45
+ const warningThresholdArc = warningThreshold.map((value, index) => {
46
+ return {
47
+ name: equals(1, index) ? 'warning' : `transparent-${index}-warning`,
48
+ value: value - (warningThreshold[index - 1] || 0)
49
+ };
50
+ });
51
+ const warningThresholdScaleOrdinal = scaleOrdinal({
52
+ domain: pluck('name', warningThresholdArc),
53
+ range: ['transparent', theme.palette.warning.main, 'transparent']
54
+ });
55
+
56
+ const successThresholdArc = [adaptedMaxValue].map((value) => {
57
+ return {
58
+ name: 'success',
59
+ value
60
+ };
61
+ });
62
+ const successThresholdScaleOrdinal = scaleOrdinal({
63
+ domain: pluck('name', successThresholdArc),
64
+ range: [theme.palette.success.main]
65
+ });
66
+
67
+ if (!thresholds.enabled) {
68
+ return (
69
+ <Pie
70
+ data={successThresholdArc}
71
+ endAngle={-Math.PI / 2}
72
+ innerRadius={radius - thresholdThickness}
73
+ outerRadius={radius}
74
+ pieSortValues={() => -1}
75
+ pieValue={(d) => d.value}
76
+ startAngle={Math.PI / 2}
77
+ >
78
+ {(pie) => (
79
+ <AnimatedPie<{ name: string; value: number }>
80
+ {...pie}
81
+ animate
82
+ getColor={(arc) => successThresholdScaleOrdinal(arc.data.name)}
83
+ getKey={(arc) => `${arc.data.name}_${arc.data.value}`}
84
+ hideTooltip={hideTooltip}
85
+ metric={metric}
86
+ showTooltip={showTooltip}
87
+ thresholds={thresholds}
88
+ />
89
+ )}
90
+ </Pie>
91
+ );
92
+ }
93
+
94
+ const arcs = [
25
95
  {
26
- name: ThresholdType.Success,
27
- value: thresholds[0]
96
+ thresholdArc: successThresholdArc,
97
+ thresholdScaleOrdinal: successThresholdScaleOrdinal
28
98
  },
29
99
  {
30
- name: ThresholdType.Warning,
31
- value: thresholds[1]
100
+ thresholdArc: warningThresholdArc,
101
+ thresholdScaleOrdinal: warningThresholdScaleOrdinal
32
102
  },
33
103
  {
34
- name: ThresholdType.Error,
35
- value: adaptedMaxValue
104
+ thresholdArc: criticalThresholdArc,
105
+ thresholdScaleOrdinal: criticalThresholdScaleOrdinal
36
106
  }
37
107
  ];
38
108
 
39
- const adaptedThresholds = namedThresholds.map(({ name, value }, index) => {
40
- return {
41
- name,
42
- value: value - (namedThresholds[index - 1]?.value || 0)
43
- };
44
- });
45
-
46
- const getThresholdColor = scaleOrdinal({
47
- domain: pluck('name', adaptedThresholds),
48
- range: disabledThresholds
49
- ? [
50
- theme.palette.success.main,
51
- theme.palette.success.main,
52
- theme.palette.success.main
53
- ]
54
- : [
55
- theme.palette.success.main,
56
- theme.palette.warning.main,
57
- theme.palette.error.main
58
- ]
59
- });
60
-
61
109
  return (
62
- <Pie
63
- data={adaptedThresholds}
64
- endAngle={-Math.PI / 2}
65
- innerRadius={radius - thresholdThickness}
66
- outerRadius={radius}
67
- pieSortValues={() => -1}
68
- pieValue={(d) => d.value}
69
- startAngle={Math.PI / 2}
70
- >
71
- {(pie) => (
72
- <AnimatedPie<{ name: ThresholdType; value: number }>
73
- {...pie}
74
- animate
75
- getColor={(arc) => getThresholdColor(arc.data.name)}
76
- getKey={(arc) => `${arc.data.name}_${arc.data.value}`}
77
- hideTooltip={hideTooltip}
78
- metric={metric}
79
- showTooltip={showTooltip}
80
- thresholdTooltipLabels={thresholdTooltipLabels}
81
- />
82
- )}
83
- </Pie>
110
+ <>
111
+ {arcs.map(({ thresholdArc, thresholdScaleOrdinal }) => (
112
+ <Pie
113
+ data={thresholdArc}
114
+ endAngle={-Math.PI / 2}
115
+ innerRadius={radius - thresholdThickness}
116
+ key={`arc-${thresholdArc[0].name}`}
117
+ outerRadius={radius}
118
+ pieSortValues={() => -1}
119
+ pieValue={(d) => d.value}
120
+ startAngle={Math.PI / 2}
121
+ >
122
+ {(pie) => (
123
+ <AnimatedPie<{ name: string; value: number }>
124
+ {...pie}
125
+ animate
126
+ getColor={(arc) => thresholdScaleOrdinal(arc.data.name)}
127
+ getKey={(arc) => `${arc.data.name}_${arc.data.value}`}
128
+ hideTooltip={hideTooltip}
129
+ metric={metric}
130
+ showTooltip={showTooltip}
131
+ thresholds={thresholds}
132
+ />
133
+ )}
134
+ </Pie>
135
+ ))}
136
+ </>
84
137
  );
85
138
  };
86
139
 
@@ -1,15 +1,14 @@
1
+ import { Thresholds } from '../common/models';
1
2
  import { Metric } from '../common/timeSeries/models';
2
3
 
3
4
  export interface GaugeProps {
4
5
  adaptedMaxValue: number;
5
- disabledThresholds?: boolean;
6
6
  height: number;
7
7
  hideTooltip: () => void;
8
8
  metric: Metric;
9
9
  radius: number;
10
10
  showTooltip: (args) => void;
11
- thresholdTooltipLabels: Array<string>;
12
- thresholds: Array<number>;
11
+ thresholds: Thresholds;
13
12
  width: number;
14
13
  }
15
14
 
@@ -0,0 +1,64 @@
1
+ import { equals } from 'ramda';
2
+
3
+ import { useTheme } from '@mui/material';
4
+
5
+ interface Props {
6
+ hideTooltip: () => void;
7
+ label: string;
8
+ showTooltip: (args) => void;
9
+ thresholdType: string;
10
+ value: number;
11
+ width: number;
12
+ yScale: (value: number) => number;
13
+ }
14
+
15
+ export const ThresholdLine = ({
16
+ value,
17
+ label,
18
+ yScale,
19
+ thresholdType,
20
+ showTooltip,
21
+ hideTooltip,
22
+ width
23
+ }: Props): JSX.Element => {
24
+ const theme = useTheme();
25
+
26
+ const scaledValue = yScale(value);
27
+
28
+ const onMouseEnter = (): void =>
29
+ showTooltip({
30
+ tooltipData: label,
31
+ tooltipLeft: 0,
32
+ tooltipTop: scaledValue
33
+ });
34
+
35
+ const lineColor = equals(thresholdType, 'warning')
36
+ ? theme.palette.warning.main
37
+ : theme.palette.error.main;
38
+
39
+ return (
40
+ <>
41
+ <line
42
+ data-testid={`${thresholdType}-line-${value}`}
43
+ stroke={lineColor}
44
+ strokeDasharray="5,5"
45
+ strokeWidth={2}
46
+ x1={0}
47
+ x2={width}
48
+ y1={scaledValue}
49
+ y2={scaledValue}
50
+ />
51
+ <line
52
+ data-testid={`${thresholdType}-line-${value}-tooltip`}
53
+ stroke="transparent"
54
+ strokeWidth={5}
55
+ x1={0}
56
+ x2={width}
57
+ y1={scaledValue}
58
+ y2={scaledValue}
59
+ onMouseEnter={onMouseEnter}
60
+ onMouseLeave={hideTooltip}
61
+ />
62
+ </>
63
+ );
64
+ };