-
-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Expand file tree
/
Copy paththresholdsIndicator.tsx
More file actions
107 lines (88 loc) · 2.58 KB
/
Copy paththresholdsIndicator.tsx
File metadata and controls
107 lines (88 loc) · 2.58 KB
1
2
3
4
5
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import {useTheme} from '@emotion/react';
import styled from '@emotion/styled';
import type {Polarity} from 'sentry/components/percentChange';
import {normalizeUnit} from 'sentry/views/dashboards/utils';
import type {ThresholdsConfig} from 'sentry/views/dashboards/widgetBuilder/buildSteps/thresholdsStep/thresholds';
import {ThresholdsHoverWrapper} from 'sentry/views/dashboards/widgetBuilder/buildSteps/thresholdsStep/thresholdsHoverWrapper';
type ValidThresholds = {
max_values: {
max1: number;
max2: number;
};
unit?: string;
};
interface ThresholdsIndicatorProps {
thresholds: ValidThresholds;
type: string;
unit: string;
value: number;
preferredPolarity?: Polarity;
}
export function ThresholdsIndicator({
thresholds,
value,
type,
preferredPolarity = '+',
unit: valueUnit,
}: ThresholdsIndicatorProps) {
const theme = useTheme();
const {max_values, unit: thresholdUnit} = thresholds;
const {max1, max2} = max_values;
const normalizedValue = normalizeUnit(value, valueUnit, type);
const normalizedMax1 = thresholdUnit ? normalizeUnit(max1, thresholdUnit, type) : max1;
const normalizedMax2 = thresholdUnit ? normalizeUnit(max2, thresholdUnit, type) : max2;
const state = getThresholdState(
normalizedValue,
normalizedMax1,
normalizedMax2,
preferredPolarity
);
const colorName = COLOR_NAME_FOR_STATE[state];
const thresholdsConfig: ThresholdsConfig = {
unit: thresholdUnit ?? null,
max_values: {
max1: max1 ?? null,
max2: max2 ?? null,
},
preferredPolarity,
};
return (
<ThresholdsHoverWrapper thresholds={thresholdsConfig} type={type}>
<Circle role="status" aria-label={state} color={theme.colors[colorName]} />
</ThresholdsHoverWrapper>
);
}
const Circle = styled('div')<{color: string}>`
display: inline-block;
height: clamp(12px, 20cqh, 50px);
width: clamp(12px, 20cqh, 50px);
position: relative;
align-self: center;
flex-shrink: 0;
border-radius: 50%;
background: ${p => p.color};
`;
type ThresholdState = 'poor' | 'meh' | 'good';
const COLOR_NAME_FOR_STATE = {
poor: 'red400',
meh: 'yellow400',
good: 'green400',
} as const satisfies Record<ThresholdState, string>;
function getThresholdState(
value: number,
max1: number,
max2: number,
preferredPolarity: Polarity
): ThresholdState {
const [belowMax1, belowMax2, aboveMax2] =
preferredPolarity === '+'
? (['poor', 'meh', 'good'] as const)
: (['good', 'meh', 'poor'] as const);
if (value <= max1) {
return belowMax1;
}
if (value <= max2) {
return belowMax2;
}
return aboveMax2;
}