content.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import type {InjectedRouter} from 'react-router';
  2. import type {Theme} from '@emotion/react';
  3. import type {Query} from 'history';
  4. import ChartZoom from 'sentry/components/charts/chartZoom';
  5. import ErrorPanel from 'sentry/components/charts/errorPanel';
  6. import type {LineChartProps} from 'sentry/components/charts/lineChart';
  7. import {LineChart} from 'sentry/components/charts/lineChart';
  8. import ReleaseSeries from 'sentry/components/charts/releaseSeries';
  9. import TransitionChart from 'sentry/components/charts/transitionChart';
  10. import TransparentLoadingMask from 'sentry/components/charts/transparentLoadingMask';
  11. import Placeholder from 'sentry/components/placeholder';
  12. import {IconWarning} from 'sentry/icons';
  13. import type {Series} from 'sentry/types/echarts';
  14. import {
  15. axisLabelFormatter,
  16. getDurationUnit,
  17. tooltipFormatter,
  18. } from 'sentry/utils/discover/charts';
  19. import {aggregateOutputType} from 'sentry/utils/discover/fields';
  20. import getDynamicText from 'sentry/utils/getDynamicText';
  21. import {TransactionsListOption} from 'sentry/views/releases/detail/overview';
  22. type Props = {
  23. errored: boolean;
  24. loading: boolean;
  25. queryExtra: Query;
  26. reloading: boolean;
  27. router: InjectedRouter;
  28. theme: Theme;
  29. series?: Series[];
  30. timeFrame?: {
  31. end: number;
  32. start: number;
  33. };
  34. } & Omit<React.ComponentProps<typeof ReleaseSeries>, 'children' | 'queryExtra'> &
  35. Pick<LineChartProps, 'onLegendSelectChanged' | 'legend'>;
  36. function Content({
  37. errored,
  38. theme,
  39. series: data,
  40. timeFrame,
  41. start,
  42. end,
  43. period,
  44. projects,
  45. environments,
  46. loading,
  47. reloading,
  48. legend,
  49. utc,
  50. queryExtra,
  51. router,
  52. onLegendSelectChanged,
  53. }: Props) {
  54. if (errored) {
  55. return (
  56. <ErrorPanel>
  57. <IconWarning color="gray500" size="lg" />
  58. </ErrorPanel>
  59. );
  60. }
  61. const colors = (data && theme.charts.getColorPalette(data.length - 2)) || [];
  62. // Create a list of series based on the order of the fields,
  63. const series = data
  64. ? data.map((values, i: number) => ({
  65. ...values,
  66. color: colors[i],
  67. }))
  68. : [];
  69. const durationUnit = getDurationUnit(series, legend);
  70. const chartOptions: Omit<LineChartProps, 'series'> = {
  71. grid: {
  72. left: '10px',
  73. right: '10px',
  74. top: '40px',
  75. bottom: '0px',
  76. },
  77. seriesOptions: {
  78. showSymbol: false,
  79. },
  80. tooltip: {
  81. trigger: 'axis',
  82. valueFormatter: (value, label) =>
  83. tooltipFormatter(value, aggregateOutputType(label)),
  84. },
  85. xAxis: timeFrame
  86. ? {
  87. min: timeFrame.start,
  88. max: timeFrame.end,
  89. }
  90. : undefined,
  91. yAxis: {
  92. minInterval: durationUnit,
  93. axisLabel: {
  94. color: theme.chartLabel,
  95. // p75(measurements.fcp) coerces the axis to be time based
  96. formatter: (value: number) =>
  97. axisLabelFormatter(value, 'duration', undefined, durationUnit),
  98. },
  99. },
  100. };
  101. return (
  102. <ChartZoom router={router} period={period} start={start} end={end} utc={utc}>
  103. {zoomRenderProps => (
  104. <ReleaseSeries
  105. start={start}
  106. end={end}
  107. queryExtra={{
  108. ...queryExtra,
  109. showTransactions: TransactionsListOption.SLOW_LCP,
  110. }}
  111. period={period}
  112. utc={utc}
  113. projects={projects}
  114. environments={environments}
  115. >
  116. {({releaseSeries}) => (
  117. <TransitionChart loading={loading} reloading={reloading}>
  118. <TransparentLoadingMask visible={reloading} />
  119. {getDynamicText({
  120. value: (
  121. <LineChart
  122. {...zoomRenderProps}
  123. {...chartOptions}
  124. legend={legend}
  125. onLegendSelectChanged={onLegendSelectChanged}
  126. series={[...series, ...releaseSeries]}
  127. />
  128. ),
  129. fixed: <Placeholder height="200px" testId="skeleton-ui" />,
  130. })}
  131. </TransitionChart>
  132. )}
  133. </ReleaseSeries>
  134. )}
  135. </ChartZoom>
  136. );
  137. }
  138. export default Content;