Browse Source

ref(charts): Use `GranularityLadder` class to get chart intervals (#60374)

A lil refactor to replace long conditionals with the class I wrote for
another PR. This has a few benefits:

- less code
- much clearer to see how the interval sizes change with the time range,
and how they compare to other ladders
- impossible to create an invalid ladder
- ladder can be created with elements out of order, if someone wants to
George Gritsouk 1 year ago
parent
commit
6afd9e2ec2
1 changed files with 62 additions and 128 deletions
  1. 62 128
      static/app/components/charts/utils.tsx

+ 62 - 128
static/app/components/charts/utils.tsx

@@ -58,134 +58,6 @@ export function useShortInterval(datetimeObj: DateTimeObject): boolean {
   return computeShortInterval(datetimeObj);
 }
 
-export type Fidelity = 'high' | 'medium' | 'low' | 'metrics';
-
-export function getInterval(datetimeObj: DateTimeObject, fidelity: Fidelity = 'medium') {
-  const diffInMinutes = getDiffInMinutes(datetimeObj);
-
-  if (diffInMinutes >= SIXTY_DAYS) {
-    // Greater than or equal to 60 days
-    if (fidelity === 'high') {
-      return '4h';
-    }
-    if (fidelity === 'medium') {
-      return '1d';
-    }
-    if (fidelity === 'metrics') {
-      return '1d';
-    }
-    return '2d';
-  }
-
-  if (diffInMinutes >= THIRTY_DAYS) {
-    // Greater than or equal to 30 days
-    if (fidelity === 'high') {
-      return '1h';
-    }
-    if (fidelity === 'medium') {
-      return '4h';
-    }
-    if (fidelity === 'metrics') {
-      return '12h';
-    }
-    return '1d';
-  }
-
-  if (diffInMinutes >= TWO_WEEKS) {
-    if (fidelity === 'high') {
-      return '30m';
-    }
-    if (fidelity === 'medium') {
-      return '1h';
-    }
-    if (fidelity === 'metrics') {
-      return '4h';
-    }
-    return '12h';
-  }
-
-  if (diffInMinutes > TWENTY_FOUR_HOURS) {
-    // Between 24 hours and 14 days
-    if (fidelity === 'high') {
-      return '30m';
-    }
-    if (fidelity === 'medium') {
-      return '1h';
-    }
-    if (fidelity === 'metrics') {
-      return '30m';
-    }
-    return '6h';
-  }
-
-  if (diffInMinutes > SIX_HOURS) {
-    // Between six hours and 24 hours
-    if (fidelity === 'high') {
-      return '5m';
-    }
-
-    if (fidelity === 'medium') {
-      return '15m';
-    }
-
-    if (fidelity === 'metrics') {
-      return '5m';
-    }
-    return '1h';
-  }
-
-  if (diffInMinutes > ONE_HOUR) {
-    // Between 1 hour and 6 hours
-    if (fidelity === 'high') {
-      return '5m';
-    }
-    if (fidelity === 'medium') {
-      return '15m';
-    }
-    if (fidelity === 'metrics') {
-      return '1m';
-    }
-    return '1h';
-  }
-
-  // Less than or equal to 1 hour
-  if (fidelity === 'high') {
-    return '1m';
-  }
-  if (fidelity === 'medium') {
-    return '5m';
-  }
-  if (fidelity === 'metrics') {
-    return '1m';
-  }
-  return '10m';
-}
-
-/**
- * Duplicate of getInterval, except that we do not support <1h granularity
- * Used by OrgStatsV2 API
- */
-export function getSeriesApiInterval(datetimeObj: DateTimeObject) {
-  const diffInMinutes = getDiffInMinutes(datetimeObj);
-
-  if (diffInMinutes >= SIXTY_DAYS) {
-    // Greater than or equal to 60 days
-    return '1d';
-  }
-
-  if (diffInMinutes >= THIRTY_DAYS) {
-    // Greater than or equal to 30 days
-    return '4h';
-  }
-
-  if (diffInMinutes < SIX_HOURS) {
-    // Less than 6 hours
-    return '5m';
-  }
-
-  return '1h';
-}
-
 export type GranularityStep = [timeDiff: number, interval: string];
 
 export class GranularityLadder {
@@ -221,6 +93,68 @@ export class GranularityLadder {
   }
 }
 
+export type Fidelity = 'high' | 'medium' | 'low' | 'metrics';
+
+export function getInterval(datetimeObj: DateTimeObject, fidelity: Fidelity = 'medium') {
+  const diffInMinutes = getDiffInMinutes(datetimeObj);
+
+  return {
+    high: highFidelityLadder,
+    medium: mediumFidelityLadder,
+    low: lowFidelityLadder,
+    metrics: metricsFidelityLadder,
+  }[fidelity].getInterval(diffInMinutes);
+}
+
+const highFidelityLadder = new GranularityLadder([
+  [SIXTY_DAYS, '4h'],
+  [THIRTY_DAYS, '1h'],
+  [TWENTY_FOUR_HOURS + 1, '30m'],
+  [ONE_HOUR + 1, '5m'],
+  [0, '1m'],
+]);
+
+const mediumFidelityLadder = new GranularityLadder([
+  [SIXTY_DAYS, '1d'],
+  [THIRTY_DAYS, '4h'],
+  [TWENTY_FOUR_HOURS + 1, '1h'],
+  [ONE_HOUR + 1, '15m'],
+  [0, '5m'],
+]);
+
+const lowFidelityLadder = new GranularityLadder([
+  [SIXTY_DAYS, '2d'],
+  [THIRTY_DAYS, '1d'],
+  [TWO_WEEKS, '12h'],
+  [TWENTY_FOUR_HOURS + 1, '6h'],
+  [ONE_HOUR + 1, '1h'],
+  [0, '10m'],
+]);
+
+const metricsFidelityLadder = new GranularityLadder([
+  [SIXTY_DAYS, '1d'],
+  [THIRTY_DAYS, '12h'],
+  [TWO_WEEKS, '4h'],
+  [TWENTY_FOUR_HOURS, '30m'],
+  [SIX_HOURS, '5m'],
+  [ONE_HOUR, '1m'],
+  [0, '1m'],
+]);
+
+/**
+ * Duplicate of getInterval, except that we do not support <1h granularity
+ * Used by OrgStatsV2 API
+ */
+const seriesAPILadder = new GranularityLadder([
+  [SIXTY_DAYS, '1d'],
+  [THIRTY_DAYS, '4h'],
+  [SIX_HOURS, '1h'],
+  [0, '5m'],
+]);
+export function getSeriesApiInterval(datetimeObj: DateTimeObject) {
+  return seriesAPILadder.getInterval(getDiffInMinutes(datetimeObj));
+}
+
 export function getDiffInMinutes(datetimeObj: DateTimeObject): number {
   const {period, start, end} = datetimeObj;