thresholdsIndicator.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import {useTheme} from '@emotion/react';
  2. import styled from '@emotion/styled';
  3. import type {Polarity} from 'sentry/components/percentChange';
  4. import {normalizeUnit} from '../../utils';
  5. import {ThresholdsHoverWrapper} from '../../widgetBuilder/buildSteps/thresholdsStep/thresholdsHoverWrapper';
  6. import type {Thresholds} from '../common/types';
  7. interface ThresholdsIndicatorProps {
  8. thresholds: Thresholds;
  9. type: string;
  10. unit: string;
  11. value: number;
  12. preferredPolarity?: Polarity;
  13. }
  14. export function ThresholdsIndicator({
  15. thresholds,
  16. value,
  17. type,
  18. preferredPolarity = '+',
  19. unit: valueUnit,
  20. }: ThresholdsIndicatorProps) {
  21. const theme = useTheme();
  22. const {max_values, unit: thresholdUnit} = thresholds;
  23. const {max1, max2} = max_values;
  24. const normalizedValue = normalizeUnit(value, valueUnit, type);
  25. const normalizedMax1 = normalizeUnit(max1, thresholdUnit, type);
  26. const normalizedMax2 = normalizeUnit(max2, thresholdUnit, type);
  27. const state = getThresholdState(
  28. normalizedValue,
  29. normalizedMax1,
  30. normalizedMax2,
  31. preferredPolarity
  32. );
  33. const colorName = COLOR_NAME_FOR_STATE[state];
  34. return (
  35. <ThresholdsHoverWrapper thresholds={thresholds} type={type}>
  36. <Circle role="status" aria-label={state} color={theme[colorName]} />
  37. </ThresholdsHoverWrapper>
  38. );
  39. }
  40. const Circle = styled('div')<{color: string}>`
  41. display: inline-block;
  42. height: clamp(12px, 20cqh, 50px);
  43. width: clamp(12px, 20cqh, 50px);
  44. position: relative;
  45. align-self: center;
  46. flex-shrink: 0;
  47. border-radius: 50%;
  48. background: ${p => p.color};
  49. `;
  50. type ThresholdState = 'poor' | 'meh' | 'good';
  51. const COLOR_NAME_FOR_STATE: Record<ThresholdState, string> = {
  52. poor: 'red300',
  53. meh: 'yellow300',
  54. good: 'green300',
  55. };
  56. function getThresholdState(
  57. value: number,
  58. max1: number,
  59. max2: number,
  60. preferredPolarity: Polarity
  61. ): string {
  62. const [belowMax1, belowMax2, aboveMax2] =
  63. preferredPolarity === '+' ? ['poor', 'meh', 'good'] : ['good', 'meh', 'poor'];
  64. if (value <= max1) {
  65. return belowMax1;
  66. }
  67. if (value <= max2) {
  68. return belowMax2;
  69. }
  70. return aboveMax2;
  71. }