utils.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import {Location} from 'history';
  2. import {t} from 'app/locale';
  3. import {LightWeightOrganization, Organization, Project} from 'app/types';
  4. import EventView from 'app/utils/discover/eventView';
  5. import {AggregationKey, Column} from 'app/utils/discover/fields';
  6. import {
  7. formatAbbreviatedNumber,
  8. formatFloat,
  9. formatPercentage,
  10. getDuration,
  11. } from 'app/utils/formatters';
  12. import {HistogramData} from 'app/utils/performance/histogram/types';
  13. import {decodeScalar} from 'app/utils/queryString';
  14. import {AxisOption, getTermHelp, PERFORMANCE_TERM} from '../data';
  15. import {Rectangle} from '../transactionSummary/transactionVitals/types';
  16. import {platformToPerformanceType, PROJECT_PERFORMANCE_TYPE} from '../utils';
  17. export const LEFT_AXIS_QUERY_KEY = 'left';
  18. export const RIGHT_AXIS_QUERY_KEY = 'right';
  19. type LandingDisplay = {
  20. label: string;
  21. field: LandingDisplayField;
  22. };
  23. export enum LandingDisplayField {
  24. ALL = 'all',
  25. FRONTEND_PAGELOAD = 'frontend_pageload',
  26. FRONTEND_OTHER = 'frontend_other',
  27. BACKEND = 'backend',
  28. }
  29. export const LANDING_DISPLAYS = [
  30. {
  31. label: 'All Transactions',
  32. field: LandingDisplayField.ALL,
  33. },
  34. {
  35. label: 'Frontend (Pageload)',
  36. field: LandingDisplayField.FRONTEND_PAGELOAD,
  37. },
  38. {
  39. label: 'Frontend (Other)',
  40. field: LandingDisplayField.FRONTEND_OTHER,
  41. },
  42. {
  43. label: 'Backend',
  44. field: LandingDisplayField.BACKEND,
  45. },
  46. ];
  47. export function getCurrentLandingDisplay(
  48. location: Location,
  49. projects: Project[],
  50. eventView?: EventView
  51. ): LandingDisplay {
  52. const landingField = decodeScalar(location?.query?.landingDisplay);
  53. const display = LANDING_DISPLAYS.find(({field}) => field === landingField);
  54. if (display) {
  55. return display;
  56. }
  57. const defaultDisplayField = getDefaultDisplayFieldForPlatform(projects, eventView);
  58. const defaultDisplay = LANDING_DISPLAYS.find(
  59. ({field}) => field === defaultDisplayField
  60. );
  61. return defaultDisplay || LANDING_DISPLAYS[0];
  62. }
  63. export function getChartWidth(chartData: HistogramData, refPixelRect: Rectangle | null) {
  64. const distance = refPixelRect ? refPixelRect.point2.x - refPixelRect.point1.x : 0;
  65. const chartWidth = chartData.length * distance;
  66. return {
  67. chartWidth,
  68. };
  69. }
  70. export function getBackendFunction(
  71. functionName: AggregationKey,
  72. organization: Organization
  73. ): Column {
  74. switch (functionName) {
  75. case 'p75':
  76. return {
  77. kind: 'function',
  78. function: ['p75', 'transaction.duration', undefined, undefined],
  79. };
  80. case 'tpm':
  81. return {kind: 'function', function: ['tpm', '', undefined, undefined]};
  82. case 'failure_rate':
  83. return {kind: 'function', function: ['failure_rate', '', undefined, undefined]};
  84. case 'apdex':
  85. if (organization.features.includes('project-transaction-threshold')) {
  86. return {
  87. kind: 'function',
  88. function: ['apdex' as AggregationKey, '', undefined, undefined],
  89. };
  90. }
  91. return {
  92. kind: 'function',
  93. function: ['apdex', `${organization.apdexThreshold}`, undefined, undefined],
  94. };
  95. default:
  96. throw new Error(`Unsupported backend function: ${functionName}`);
  97. }
  98. }
  99. export function getDefaultDisplayFieldForPlatform(
  100. projects: Project[],
  101. eventView?: EventView
  102. ) {
  103. if (!eventView) {
  104. return LandingDisplayField.ALL;
  105. }
  106. const projectIds = eventView.project;
  107. const performanceTypeToDisplay = {
  108. [PROJECT_PERFORMANCE_TYPE.ANY]: LandingDisplayField.ALL,
  109. [PROJECT_PERFORMANCE_TYPE.FRONTEND]: LandingDisplayField.FRONTEND_PAGELOAD,
  110. [PROJECT_PERFORMANCE_TYPE.BACKEND]: LandingDisplayField.BACKEND,
  111. };
  112. const performanceType = platformToPerformanceType(projects, projectIds);
  113. const landingField =
  114. performanceTypeToDisplay[performanceType] ?? LandingDisplayField.ALL;
  115. return landingField;
  116. }
  117. export const backendCardDetails = (organization: LightWeightOrganization) => {
  118. return {
  119. p75: {
  120. title: t('Duration (p75)'),
  121. tooltip: getTermHelp(organization, PERFORMANCE_TERM.P75),
  122. formatter: value => getDuration(value / 1000, value >= 1000 ? 3 : 0, true),
  123. },
  124. tpm: {
  125. title: t('Throughput'),
  126. tooltip: getTermHelp(organization, PERFORMANCE_TERM.THROUGHPUT),
  127. formatter: formatAbbreviatedNumber,
  128. },
  129. failure_rate: {
  130. title: t('Failure Rate'),
  131. tooltip: getTermHelp(organization, PERFORMANCE_TERM.FAILURE_RATE),
  132. formatter: value => formatPercentage(value, 2),
  133. },
  134. apdex: {
  135. title: t('Apdex'),
  136. tooltip: organization.features.includes('project-transaction-threshold')
  137. ? getTermHelp(organization, PERFORMANCE_TERM.APDEX_NEW)
  138. : getTermHelp(organization, PERFORMANCE_TERM.APDEX),
  139. formatter: value => formatFloat(value, 4),
  140. },
  141. };
  142. };
  143. export function getDisplayAxes(options: AxisOption[], location: Location) {
  144. const leftDefault = options.find(opt => opt.isLeftDefault) || options[0];
  145. const rightDefault = options.find(opt => opt.isRightDefault) || options[1];
  146. const leftAxis =
  147. options.find(opt => opt.value === location.query[LEFT_AXIS_QUERY_KEY]) || leftDefault;
  148. const rightAxis =
  149. options.find(opt => opt.value === location.query[RIGHT_AXIS_QUERY_KEY]) ||
  150. rightDefault;
  151. return {
  152. leftAxis,
  153. rightAxis,
  154. };
  155. }