chart.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // eslint-disable-next-line no-restricted-imports
  2. import {browserHistory, withRouter, WithRouterProps} from 'react-router';
  3. import {Location} from 'history';
  4. import Feature from 'sentry/components/acl/feature';
  5. import OptionSelector from 'sentry/components/charts/optionSelector';
  6. import {
  7. ChartContainer,
  8. ChartControls,
  9. InlineContainer,
  10. SectionHeading,
  11. SectionValue,
  12. } from 'sentry/components/charts/styles';
  13. import Count from 'sentry/components/count';
  14. import {Panel} from 'sentry/components/panels';
  15. import {t} from 'sentry/locale';
  16. import {Organization} from 'sentry/types';
  17. import {defined} from 'sentry/utils';
  18. import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
  19. import EventView from 'sentry/utils/discover/eventView';
  20. import {SpanSlug} from 'sentry/utils/performance/suspectSpans/types';
  21. import {decodeScalar} from 'sentry/utils/queryString';
  22. import ExclusiveTimeHistogram from './exclusiveTimeHistogram';
  23. import ExclusiveTimeTimeSeries from './exclusiveTimeTimeSeries';
  24. type Props = WithRouterProps & {
  25. eventView: EventView;
  26. location: Location;
  27. organization: Organization;
  28. spanSlug: SpanSlug;
  29. totalCount?: number;
  30. };
  31. enum DisplayModes {
  32. TIMESERIES = 'timeseries',
  33. HISTOGRAM = 'histogram',
  34. }
  35. function Chart(props: Props) {
  36. const {location} = props;
  37. const display = decodeScalar(props.location.query.display, DisplayModes.TIMESERIES);
  38. function generateDisplayOptions() {
  39. return [
  40. {value: DisplayModes.TIMESERIES, label: t('Self Time Breakdown')},
  41. {value: DisplayModes.HISTOGRAM, label: t('Self Time Distribution')},
  42. ];
  43. }
  44. function handleDisplayChange(value: string) {
  45. trackAdvancedAnalyticsEvent('performance_views.span_summary.change_chart', {
  46. organization: props.organization,
  47. change_to_display: value,
  48. });
  49. browserHistory.push({
  50. pathname: location.pathname,
  51. query: {
  52. ...location.query,
  53. display: value,
  54. },
  55. });
  56. }
  57. return (
  58. <Panel>
  59. <ChartContainer>
  60. <Feature features={['performance-span-histogram-view']}>
  61. {({hasFeature}) => {
  62. if (hasFeature) {
  63. if (display === DisplayModes.TIMESERIES) {
  64. return <ExclusiveTimeTimeSeries {...props} withoutZerofill={false} />;
  65. }
  66. return <ExclusiveTimeHistogram {...props} />;
  67. }
  68. return <ExclusiveTimeTimeSeries {...props} withoutZerofill={false} />;
  69. }}
  70. </Feature>
  71. </ChartContainer>
  72. <Feature features={['performance-span-histogram-view']}>
  73. <ChartControls>
  74. <InlineContainer>
  75. <SectionHeading>{t('Total Events')}</SectionHeading>
  76. <SectionValue data-test-id="total-value">
  77. {defined(props.totalCount) ? <Count value={props.totalCount} /> : '\u2014'}
  78. </SectionValue>
  79. </InlineContainer>
  80. <InlineContainer data-test-id="display-toggle">
  81. <OptionSelector
  82. title={t('Display')}
  83. selected={display}
  84. options={generateDisplayOptions()}
  85. onChange={handleDisplayChange}
  86. />
  87. </InlineContainer>
  88. </ChartControls>
  89. </Feature>
  90. </Panel>
  91. );
  92. }
  93. export default withRouter(Chart);