averageComparisonChart.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import {useMemo} from 'react';
  2. import {t} from 'sentry/locale';
  3. import type {NewQuery} from 'sentry/types/organization';
  4. import {defined} from 'sentry/utils';
  5. import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
  6. import EventView from 'sentry/utils/discover/eventView';
  7. import {DiscoverDatasets} from 'sentry/utils/discover/types';
  8. import {decodeScalar} from 'sentry/utils/queryString';
  9. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  10. import {useLocation} from 'sentry/utils/useLocation';
  11. import usePageFilters from 'sentry/utils/usePageFilters';
  12. import {formatVersion} from 'sentry/utils/versions/formatVersion';
  13. import {PRIMARY_RELEASE_COLOR} from 'sentry/views/insights/colors';
  14. import {useReleaseSelection} from 'sentry/views/insights/common/queries/useReleases';
  15. import {appendReleaseFilters} from 'sentry/views/insights/common/utils/releaseComparison';
  16. import {COLD_START_TYPE} from 'sentry/views/insights/mobile/appStarts/components/startTypeSelector';
  17. import useCrossPlatformProject from 'sentry/views/insights/mobile/common/queries/useCrossPlatformProject';
  18. import useTruncatedReleaseNames from 'sentry/views/insights/mobile/common/queries/useTruncatedRelease';
  19. import {ScreensBarChart} from 'sentry/views/insights/mobile/screenload/components/charts/screenBarChart';
  20. import {useTableQuery} from 'sentry/views/insights/mobile/screenload/components/tables/screensTable';
  21. import {YAxis, YAXIS_COLUMNS} from 'sentry/views/insights/mobile/screenload/constants';
  22. import {SpanMetricsField} from 'sentry/views/insights/types';
  23. interface Props {
  24. chartHeight?: number;
  25. }
  26. function transformData(data: TableDataRow[] | undefined, appStartType: string) {
  27. if (!defined(data)) {
  28. return [];
  29. }
  30. return [
  31. {
  32. seriesName: t('Average Duration'),
  33. data:
  34. data?.map(row => ({
  35. name: formatVersion(row.release as string),
  36. value:
  37. (row[
  38. YAXIS_COLUMNS[
  39. appStartType === COLD_START_TYPE ? YAxis.COLD_START : YAxis.WARM_START
  40. ]
  41. ] as number) ?? 0,
  42. })) ?? [],
  43. itemStyle: {
  44. color: PRIMARY_RELEASE_COLOR,
  45. },
  46. },
  47. ];
  48. }
  49. export function AverageComparisonChart({chartHeight}: Props) {
  50. const location = useLocation();
  51. const {
  52. primaryRelease,
  53. secondaryRelease,
  54. isLoading: isReleasesLoading,
  55. } = useReleaseSelection();
  56. const {selection} = usePageFilters();
  57. const {isProjectCrossPlatform, selectedPlatform} = useCrossPlatformProject();
  58. const appStartType =
  59. decodeScalar(location.query[SpanMetricsField.APP_START_TYPE]) ?? COLD_START_TYPE;
  60. const query = new MutableSearch([
  61. 'event.type:transaction',
  62. 'transaction.op:ui.load',
  63. `count_starts(measurements.app_start_${appStartType}):>0`,
  64. ]);
  65. if (isProjectCrossPlatform) {
  66. query.addFilterValue('os.name', selectedPlatform);
  67. }
  68. const queryString = appendReleaseFilters(query, primaryRelease, secondaryRelease);
  69. const newQuery: NewQuery = {
  70. name: '',
  71. fields: ['release', `avg(measurements.app_start_${appStartType})`],
  72. dataset: DiscoverDatasets.METRICS,
  73. query: queryString,
  74. version: 2,
  75. projects: selection.projects,
  76. };
  77. const tableEventView = EventView.fromNewQueryWithLocation(newQuery, location);
  78. const {data, isPending} = useTableQuery({
  79. eventView: tableEventView,
  80. enabled: !isReleasesLoading,
  81. referrer: 'api.starfish.mobile-startup-bar-chart',
  82. });
  83. const transformedData = useMemo(() => {
  84. return transformData(data?.data, appStartType);
  85. }, [data, appStartType]);
  86. const {truncatedPrimaryRelease, truncatedSecondaryRelease} = useTruncatedReleaseNames();
  87. return (
  88. <ScreensBarChart
  89. chartOptions={[
  90. {
  91. title:
  92. appStartType === COLD_START_TYPE
  93. ? t('Average Cold Start')
  94. : t('Average Warm Start'),
  95. yAxis: `avg(measurements.app_start_${appStartType})`,
  96. xAxisLabel: [
  97. ...(primaryRelease ? [formatVersion(primaryRelease)] : []),
  98. ...(secondaryRelease ? [formatVersion(secondaryRelease)] : []),
  99. ],
  100. series: transformedData,
  101. subtitle: primaryRelease
  102. ? t(
  103. '%s v. %s',
  104. truncatedPrimaryRelease,
  105. secondaryRelease ? truncatedSecondaryRelease : ''
  106. )
  107. : '',
  108. },
  109. ]}
  110. chartHeight={chartHeight}
  111. isLoading={isPending || isReleasesLoading}
  112. chartKey={`averageStart`}
  113. />
  114. );
  115. }