diff --git a/static/app/components/events/interfaces/spans/header.tsx b/static/app/components/events/interfaces/spans/header.tsx index e0d40fa5922b07..c42efb71610100 100644 --- a/static/app/components/events/interfaces/spans/header.tsx +++ b/static/app/components/events/interfaces/spans/header.tsx @@ -524,7 +524,10 @@ class TraceViewHeader extends Component { )} {hasProfileMeasurementsChart && ( - + )} {this.renderSecondaryHeader(hasProfileMeasurementsChart)} diff --git a/static/app/components/events/interfaces/spans/profilingMeasurements.tsx b/static/app/components/events/interfaces/spans/profilingMeasurements.tsx index 02854aea9a2511..d2e6af3c6629ca 100644 --- a/static/app/components/events/interfaces/spans/profilingMeasurements.tsx +++ b/static/app/components/events/interfaces/spans/profilingMeasurements.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import {useTheme} from '@emotion/react'; import styled from '@emotion/styled'; import uniqBy from 'lodash/uniqBy'; @@ -22,6 +23,8 @@ import {space} from 'sentry/styles/space'; import {SeriesDataUnit} from 'sentry/types/echarts'; import {defined} from 'sentry/utils'; +import * as CursorGuideHandler from './cursorGuideHandler'; + const NS_PER_MS = 1000000; function toMilliseconds(nanoseconds: number) { @@ -70,11 +73,8 @@ function Chart({data}: ChartProps) { axisLabel: {show: false}, axisTick: {show: false}, axisPointer: { - lineStyle: { - color: theme.red300, - width: 2, - opacity: 0.5, - }, + type: 'none', + triggerOn: 'mousemove', }, boundaryGap: false, }} @@ -99,11 +99,26 @@ function Chart({data}: ChartProps) { ); } +// Memoized to prevent re-rendering when the cursor guide is displayed +const MemoizedChart = React.memo(Chart); + type ProfilingMeasurementsProps = { profileData: Profiling.ProfileInput; + renderCursorGuide?: ({ + cursorGuideHeight, + mouseLeft, + showCursorGuide, + }: { + cursorGuideHeight: number; + mouseLeft: number | undefined; + showCursorGuide: boolean; + }) => void; }; -function ProfilingMeasurements({profileData}: ProfilingMeasurementsProps) { +function ProfilingMeasurements({ + profileData, + renderCursorGuide, +}: ProfilingMeasurementsProps) { const theme = useTheme(); if (!('measurements' in profileData) || !defined(profileData.measurements?.cpu_usage)) { @@ -113,33 +128,50 @@ function ProfilingMeasurements({profileData}: ProfilingMeasurementsProps) { const cpuUsageData = profileData.measurements!.cpu_usage!; return ( - - {dividerHandlerChildrenProps => { - const {dividerPosition} = dividerHandlerChildrenProps; - return ( - - - - - - {t('CPU Usage')} - - - - - - ; - - - ); - }} - + + {({displayCursorGuide, hideCursorGuide, mouseLeft, showCursorGuide}) => ( + + {({dividerPosition}) => ( + + + + + + {t('CPU Usage')} + + + + + { + displayCursorGuide(event.pageX); + }} + onMouseLeave={() => { + hideCursorGuide(); + }} + onMouseMove={event => { + displayCursorGuide(event.pageX); + }} + > + + {renderCursorGuide?.({ + showCursorGuide, + mouseLeft, + cursorGuideHeight: PROFILE_MEASUREMENTS_CHART_HEIGHT, + })} + + + )} + + )} + ); } export {ProfilingMeasurements}; const ChartContainer = styled('div')` + position: relative; flex: 1; border-top: 1px solid ${p => p.theme.border}; `;