responseRateChart.tsx 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import type {Series} from 'sentry/types/echarts';
  2. import {formatPercentage} from 'sentry/utils/formatters';
  3. import {CHART_HEIGHT} from 'sentry/views/performance/database/settings';
  4. import {
  5. HTTP_RESPONSE_3XX_COLOR,
  6. HTTP_RESPONSE_4XX_COLOR,
  7. HTTP_RESPONSE_5XX_COLOR,
  8. } from 'sentry/views/starfish/colours';
  9. import Chart, {ChartType} from 'sentry/views/starfish/components/chart';
  10. import ChartPanel from 'sentry/views/starfish/components/chartPanel';
  11. import {DataTitles} from 'sentry/views/starfish/views/spans/types';
  12. interface Props {
  13. isLoading: boolean;
  14. series: [Series, Series, Series];
  15. error?: Error | null;
  16. }
  17. export function ResponseRateChart({series, isLoading, error}: Props) {
  18. return (
  19. <ChartPanel title={DataTitles.unsuccessfulHTTPCodes}>
  20. <Chart
  21. showLegend
  22. height={CHART_HEIGHT}
  23. grid={{
  24. left: '4px',
  25. right: '0',
  26. top: '8px',
  27. bottom: '0',
  28. }}
  29. data={series}
  30. loading={isLoading}
  31. error={error}
  32. chartColors={[
  33. HTTP_RESPONSE_3XX_COLOR,
  34. HTTP_RESPONSE_4XX_COLOR,
  35. HTTP_RESPONSE_5XX_COLOR,
  36. ]}
  37. type={ChartType.LINE}
  38. aggregateOutputFormat="percentage"
  39. dataMax={getAxisMaxForPercentageSeries(series)}
  40. tooltipFormatterOptions={{
  41. valueFormatter: value => formatPercentage(value),
  42. }}
  43. />
  44. </ChartPanel>
  45. );
  46. }
  47. /**
  48. * Given a set of `Series` objects that contain percentage data (i.e., every item in `data` has a `value` between 0 and 1) return an appropriate max value.
  49. *
  50. * e.g., for series with very low values (like 5xx rates), it rounds to the nearest significant digit. For other cases, it limits it to 100
  51. */
  52. export function getAxisMaxForPercentageSeries(series: Series[]): number {
  53. const maxValue = Math.max(
  54. ...series.map(serie => Math.max(...serie.data.map(datum => datum.value)))
  55. );
  56. const maxNumberOfDecimalPlaces = Math.ceil(Math.min(0, Math.log10(maxValue)));
  57. return Math.pow(10, maxNumberOfDecimalPlaces);
  58. }