index.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import {Fragment} from 'react';
  2. // eslint-disable-next-line no-restricted-imports
  3. import {withRouter, WithRouterProps} from 'react-router';
  4. import {Location, Query} from 'history';
  5. import EventsRequest from 'sentry/components/charts/eventsRequest';
  6. import {HeaderTitleLegend} from 'sentry/components/charts/styles';
  7. import {getInterval} from 'sentry/components/charts/utils';
  8. import {normalizeDateTimeParams} from 'sentry/components/organizations/pageFilters/parse';
  9. import QuestionTooltip from 'sentry/components/questionTooltip';
  10. import {t} from 'sentry/locale';
  11. import {Organization, OrganizationSummary} from 'sentry/types';
  12. import {Series} from 'sentry/types/echarts';
  13. import {getUtcToLocalDateObject} from 'sentry/utils/dates';
  14. import {useMEPSettingContext} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
  15. import useApi from 'sentry/utils/useApi';
  16. import {getTermHelp, PERFORMANCE_TERM} from 'sentry/views/performance/data';
  17. import {getMEPQueryParams} from 'sentry/views/performance/landing/widgets/utils';
  18. import {DurationChart} from 'sentry/views/performance/landing/widgets/widgets/singleFieldAreaWidget';
  19. import {ViewProps} from 'sentry/views/performance/types';
  20. type Props = WithRouterProps &
  21. ViewProps & {
  22. location: Location;
  23. organization: OrganizationSummary;
  24. queryExtra: Query;
  25. withoutZerofill: boolean;
  26. };
  27. /**
  28. * Fetch and render an area chart that shows user misery over a period
  29. */
  30. function UserMiseryChart({
  31. project,
  32. environment,
  33. location,
  34. organization,
  35. query,
  36. statsPeriod,
  37. withoutZerofill,
  38. start: propsStart,
  39. end: propsEnd,
  40. }: Props) {
  41. const api = useApi();
  42. const mepContext = useMEPSettingContext();
  43. const start = propsStart ? getUtcToLocalDateObject(propsStart) : null;
  44. const end = propsEnd ? getUtcToLocalDateObject(propsEnd) : null;
  45. const utc = normalizeDateTimeParams(location.query).utc === 'true';
  46. const period = statsPeriod;
  47. const datetimeSelection = {start, end, period};
  48. const requestCommonProps = {
  49. api,
  50. start,
  51. end,
  52. project,
  53. environment,
  54. query,
  55. period,
  56. interval: getInterval(datetimeSelection, 'high'),
  57. };
  58. const header = (
  59. <HeaderTitleLegend>
  60. {t('User Misery')}
  61. <QuestionTooltip
  62. size="sm"
  63. position="top"
  64. title={getTermHelp(organization as Organization, PERFORMANCE_TERM.USER_MISERY)}
  65. />
  66. </HeaderTitleLegend>
  67. );
  68. const yAxis = 'user_misery()';
  69. return (
  70. <Fragment>
  71. {header}
  72. <EventsRequest
  73. {...requestCommonProps}
  74. organization={organization}
  75. showLoading={false}
  76. includePrevious={false}
  77. yAxis={yAxis}
  78. partial
  79. withoutZerofill={withoutZerofill}
  80. referrer="api.performance.transaction-summary.user-misery-chart"
  81. queryExtras={getMEPQueryParams(mepContext)}
  82. >
  83. {({loading, reloading, timeseriesData}) => {
  84. const data: Series[] = timeseriesData?.[0]
  85. ? [{...timeseriesData[0], seriesName: yAxis}]
  86. : [];
  87. return (
  88. <DurationChart
  89. grid={{left: '10px', right: '10px', top: '40px', bottom: '0px'}}
  90. data={data}
  91. statsPeriod={statsPeriod}
  92. loading={loading || reloading}
  93. disableMultiAxis
  94. definedAxisTicks={4}
  95. start={start}
  96. end={end}
  97. utc={utc}
  98. />
  99. );
  100. }}
  101. </EventsRequest>
  102. </Fragment>
  103. );
  104. }
  105. export default withRouter(UserMiseryChart);