Browse Source

feat(issues): Adjust trace timeline grouping (#64247)

Scott Cooper 1 year ago
parent
commit
33db132fe4

+ 3 - 3
static/app/views/issueDetails/traceTimeline/traceTimeline.tsx

@@ -22,15 +22,15 @@ export function TraceTimeline({event}: TraceTimelineProps) {
   const timelineRef = useRef<HTMLDivElement>(null);
   const {width} = useDimensions({elementRef: timelineRef});
   const hasFeature = hasTraceTimelineFeature(organization, user);
-  const {isError, isLoading} = useTraceTimelineEvents({event}, hasFeature);
+  const {isError, isLoading, data} = useTraceTimelineEvents({event}, hasFeature);
 
   if (!hasFeature) {
     return null;
   }
 
-  if (isError) {
+  if (isError || (!isLoading && data.length === 0)) {
     // display placeholder to reduce layout shift
-    return <div style={{height: 20}} />;
+    return <div style={{height: 45}} />;
   }
 
   return (

+ 12 - 11
static/app/views/issueDetails/traceTimeline/traceTimelineEvents.tsx

@@ -10,12 +10,12 @@ import {TraceTimelineTooltip} from 'sentry/views/issueDetails/traceTimeline/trac
 
 import type {TimelineEvent} from './useTraceTimelineEvents';
 import {useTraceTimelineEvents} from './useTraceTimelineEvents';
-import {getEventsByColumn} from './utils';
+import {getChunkTimeRange, getEventsByColumn} from './utils';
 
 // Adjusting this will change the number of tooltip groups
-const markerWidth = 24;
+const PARENT_WIDTH = 12;
 // Adjusting subwidth changes how many dots to render
-const subWidth = 2;
+const CHILD_WIDTH = 4;
 
 interface TraceTimelineEventsProps {
   event: Event;
@@ -34,7 +34,7 @@ export function TraceTimelineEvents({event, width}: TraceTimelineEventsProps) {
     paddedEndTime = startTimestamp + 1000;
   }
 
-  const totalColumns = Math.floor(width / markerWidth);
+  const totalColumns = Math.floor(width / PARENT_WIDTH);
   const eventsByColumn = getEventsByColumn(
     durationMs,
     data,
@@ -48,10 +48,11 @@ export function TraceTimelineEvents({event, width}: TraceTimelineEventsProps) {
       <TimelineColumns totalColumns={totalColumns}>
         {Array.from(eventsByColumn.entries()).map(([column, colEvents]) => {
           // Calculate the timestamp range that this column represents
-          const columnStartTimestamp =
-            (durationMs / totalColumns) * (column - 1) + paddedStartTime;
-          const columnEndTimestamp =
-            (durationMs / totalColumns) * column + paddedStartTime;
+          const timeRange = getChunkTimeRange(
+            paddedStartTime,
+            column - 1,
+            durationMs / totalColumns
+          );
           return (
             <EventColumn
               key={column}
@@ -61,7 +62,7 @@ export function TraceTimelineEvents({event, width}: TraceTimelineEventsProps) {
                 event={event}
                 colEvents={colEvents}
                 columnSize={columnSize}
-                timeRange={[columnStartTimestamp, columnEndTimestamp]}
+                timeRange={timeRange}
                 currentEventId={event.id}
               />
             </EventColumn>
@@ -133,13 +134,13 @@ function NodeGroup({
   event: Event;
   timeRange: [number, number];
 }) {
-  const totalSubColumns = Math.floor(columnSize / subWidth);
+  const totalSubColumns = Math.floor(columnSize / CHILD_WIDTH);
   const durationMs = timeRange[1] - timeRange[0];
   const eventsByColumn = getEventsByColumn(
     durationMs,
     colEvents,
     totalSubColumns,
-    timeRange[1]
+    timeRange[0]
   );
 
   return (

+ 26 - 0
static/app/views/issueDetails/traceTimeline/utils.spec.tsx

@@ -0,0 +1,26 @@
+import {getChunkTimeRange} from './utils';
+
+describe('getChunkTimeRange', () => {
+  const start = 1000000000; // Easier to understand timestamp
+  const chunkDurationMs = 500000; // Half a minute
+  it('should return correct timestamps for the first chunk', () => {
+    const chunkIndex = 0;
+    expect(getChunkTimeRange(start, chunkIndex, chunkDurationMs)).toEqual([
+      1000000000, 1000500001,
+    ]);
+  });
+
+  it('should return correct timestamps for a chunk in the middle', () => {
+    const chunkIndex = 2;
+    expect(getChunkTimeRange(start, chunkIndex, chunkDurationMs)).toEqual([
+      1001000000, 1001500001,
+    ]);
+  });
+
+  it('should return correct timestamps for the last chunk', () => {
+    const chunkIndex = 10; // Assume 10 chunks total
+    expect(getChunkTimeRange(start, chunkIndex, chunkDurationMs)).toEqual([
+      1005000000, 1005500001,
+    ]);
+  });
+});

+ 18 - 0
static/app/views/issueDetails/traceTimeline/utils.tsx

@@ -30,6 +30,24 @@ export function getEventsByColumn(
   return eventsByColumn;
 }
 
+export function getChunkTimeRange(
+  startTimestamp: number,
+  chunkIndex: number,
+  chunkDurationMs: number
+): [number, number] {
+  // Calculate the absolute start time of the chunk in milliseconds
+  const chunkStartMs = chunkIndex * chunkDurationMs;
+
+  // Add the chunk start time to the overall start timestamp
+  const chunkStartTimestamp = startTimestamp + chunkStartMs;
+
+  // Calculate the end timestamp by adding the chunk duration
+  const chunkEndTimestamp = chunkStartTimestamp + chunkDurationMs;
+
+  // Round up and down to the nearest second
+  return [Math.floor(chunkStartTimestamp), Math.floor(chunkEndTimestamp) + 1];
+}
+
 export function hasTraceTimelineFeature(
   organization: Organization | null,
   user: User | undefined