groupChart.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {useMemo} from 'react';
  2. import MarkLine from 'sentry/components/charts/components/markLine';
  3. import MiniBarChart from 'sentry/components/charts/miniBarChart';
  4. import {LazyRender} from 'sentry/components/lazyRender';
  5. import {t} from 'sentry/locale';
  6. import type {TimeseriesValue} from 'sentry/types';
  7. import type {Series} from 'sentry/types/echarts';
  8. import {formatAbbreviatedNumber} from 'sentry/utils/formatters';
  9. import theme from 'sentry/utils/theme';
  10. function asChartPoint(point: [number, number]): {name: number | string; value: number} {
  11. return {
  12. name: point[0] * 1000,
  13. value: point[1],
  14. };
  15. }
  16. const EMPTY_STATS: ReadonlyArray<TimeseriesValue> = [];
  17. type Props = {
  18. stats: ReadonlyArray<TimeseriesValue>;
  19. height?: number;
  20. secondaryStats?: ReadonlyArray<TimeseriesValue>;
  21. showMarkLine?: boolean;
  22. showSecondaryPoints?: boolean;
  23. };
  24. function GroupChart({
  25. stats,
  26. height = 24,
  27. secondaryStats = EMPTY_STATS,
  28. showSecondaryPoints = false,
  29. showMarkLine = false,
  30. }: Props) {
  31. const graphOptions = useMemo<{
  32. colors: [string] | undefined;
  33. emphasisColors: [string] | undefined;
  34. series: Series[];
  35. }>(() => {
  36. if (!stats || !stats.length) {
  37. return {colors: undefined, emphasisColors: undefined, series: []};
  38. }
  39. const max = Math.max(...stats.map(p => p[1]));
  40. const formattedMarkLine = formatAbbreviatedNumber(max);
  41. if (showSecondaryPoints && secondaryStats && secondaryStats.length) {
  42. const series: Series[] = [
  43. {
  44. seriesName: t('Total Events'),
  45. data: secondaryStats.map(asChartPoint),
  46. },
  47. {
  48. seriesName: t('Matching Events'),
  49. data: stats.map(asChartPoint),
  50. },
  51. ];
  52. return {colors: undefined, emphasisColors: undefined, series};
  53. }
  54. const series: Series[] = [
  55. {
  56. seriesName: t('Events'),
  57. data: stats.map(asChartPoint),
  58. markLine:
  59. showMarkLine && max > 0
  60. ? MarkLine({
  61. silent: true,
  62. lineStyle: {color: theme.gray200, type: 'dotted', width: 1},
  63. data: [
  64. {
  65. type: 'max',
  66. },
  67. ],
  68. label: {
  69. show: true,
  70. position: 'start',
  71. color: `${theme.gray200}`,
  72. fontFamily: 'Rubik',
  73. fontSize: 10,
  74. formatter: `${formattedMarkLine}`,
  75. },
  76. })
  77. : undefined,
  78. },
  79. ];
  80. return {colors: [theme.gray300], emphasisColors: [theme.purple300], series};
  81. }, [showSecondaryPoints, secondaryStats, showMarkLine, stats]);
  82. return (
  83. <LazyRender containerHeight={showMarkLine ? 30 : height}>
  84. <MiniBarChart
  85. height={showMarkLine ? 36 : height}
  86. isGroupedByDate
  87. showTimeInTooltip
  88. series={graphOptions.series}
  89. colors={graphOptions.colors}
  90. emphasisColors={graphOptions.emphasisColors}
  91. hideDelay={50}
  92. showMarkLineLabel={showMarkLine}
  93. />
  94. </LazyRender>
  95. );
  96. }
  97. export default GroupChart;