content.tsx 4.1 KB

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