releaseChart.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import MiniBarChart from 'sentry/components/charts/miniBarChart';
  2. import Count from 'sentry/components/count';
  3. import {t} from 'sentry/locale';
  4. import {Group, Release, TimeseriesValue} from 'sentry/types';
  5. import {Series} from 'sentry/types/echarts';
  6. import {formatVersion} from 'sentry/utils/formatters';
  7. import theme from 'sentry/utils/theme';
  8. import SidebarSection from './sidebarSection';
  9. type Markers = React.ComponentProps<typeof MiniBarChart>['markers'];
  10. /**
  11. * Stats are provided indexed by statsPeriod strings.
  12. */
  13. type StatsGroup = Record<string, TimeseriesValue[]>;
  14. interface Props {
  15. group: Group;
  16. statsPeriod: string;
  17. title: string;
  18. className?: string;
  19. environment?: string;
  20. environmentLabel?: string;
  21. environmentStats?: StatsGroup;
  22. firstSeen?: string;
  23. lastSeen?: string;
  24. release?: Release;
  25. releaseStats?: StatsGroup;
  26. }
  27. function GroupReleaseChart(props: Props) {
  28. const {
  29. className,
  30. group,
  31. lastSeen,
  32. firstSeen,
  33. statsPeriod,
  34. release,
  35. releaseStats,
  36. environment,
  37. environmentLabel,
  38. environmentStats,
  39. title,
  40. } = props;
  41. const stats = group.stats[statsPeriod];
  42. const environmentPeriodStats = environmentStats?.[statsPeriod];
  43. if (!stats || !stats.length || !environmentPeriodStats) {
  44. return null;
  45. }
  46. const series: Series[] = [];
  47. if (environment) {
  48. // Add all events.
  49. series.push({
  50. seriesName: t('Events'),
  51. data: stats.map(point => ({name: point[0] * 1000, value: point[1]})),
  52. });
  53. }
  54. series.push({
  55. seriesName: t('Events in %s', environmentLabel),
  56. data: environmentStats[statsPeriod].map(point => ({
  57. name: point[0] * 1000,
  58. value: point[1],
  59. })),
  60. });
  61. // Get the timestamp of the first point.
  62. const firstTime = series[0].data[0].value;
  63. if (release && releaseStats) {
  64. series.push({
  65. seriesName: t('Events in release %s', formatVersion(release.version)),
  66. data: releaseStats[statsPeriod].map(point => ({
  67. name: point[0] * 1000,
  68. value: point[1],
  69. })),
  70. });
  71. }
  72. const markers: Markers = [];
  73. if (firstSeen) {
  74. const firstSeenX = new Date(firstSeen).getTime();
  75. if (firstSeenX >= firstTime) {
  76. markers.push({
  77. name: t('First seen'),
  78. value: firstSeenX,
  79. color: theme.pink300,
  80. });
  81. }
  82. }
  83. if (lastSeen) {
  84. const lastSeenX = new Date(lastSeen).getTime();
  85. if (lastSeenX >= firstTime) {
  86. markers.push({
  87. name: t('Last seen'),
  88. value: lastSeenX,
  89. color: theme.green300,
  90. });
  91. }
  92. }
  93. const totalSeries =
  94. environment && environmentStats ? environmentStats[statsPeriod] : stats;
  95. const totalEvents = totalSeries.reduce((acc, current) => acc + current[1], 0);
  96. return (
  97. <SidebarSection secondary title={title} className={className}>
  98. <div>
  99. <Count value={totalEvents} />
  100. </div>
  101. <MiniBarChart
  102. isGroupedByDate
  103. showTimeInTooltip
  104. height={42}
  105. colors={environment ? undefined : [theme.purple300, theme.purple300]}
  106. series={series}
  107. markers={markers}
  108. />
  109. </SidebarSection>
  110. );
  111. }
  112. export default GroupReleaseChart;