@@ -105,6 +105,12 @@ class StackChartCanvasImpl extends React.PureComponent<Props> {
105105 _textMeasurement : null | TextMeasurement ;
106106 _textMeasurementCssToDeviceScale : number = 1 ;
107107
108+ // When the user checks the "use same widths for each stack" checkbox, some
109+ // expensive computation happens when the canvas is drawn. These computations
110+ // can be reused for hit testing, and therefore are saved in these variables.
111+ _sameWidthsIndexAtStart : null | number ;
112+ _sameWidthsRangeLength : null | number ;
113+
108114 componentDidUpdate ( prevProps ) {
109115 // We want to scroll the selection into view when this component
110116 // is mounted, but using componentDidMount won't work here as the
@@ -246,17 +252,23 @@ class StackChartCanvasImpl extends React.PureComponent<Props> {
246252 const timeAtEnd : Milliseconds =
247253 timeAtViewportEnd + TIMELINE_MARGIN_RIGHT * timePerCssPixel ;
248254
249- // Compute the range for the "same width" drawing as well.
250- const sameWidthsIndexAtStart = Math . max (
251- 0 ,
252- bisectionRight ( sameWidthsIndexToTimestampMap , timeAtViewportStart ) - 1
253- ) ;
254- const sameWidthsIndexAtEnd = Math . min (
255- sameWidthsIndexToTimestampMap . length - 1 ,
256- bisectionLeft ( sameWidthsIndexToTimestampMap , timeAtViewportEnd )
257- ) ;
255+ // Compute the start index as well as the length for the "same width"
256+ // drawing as well, if needed.
257+ this . _sameWidthsRangeLength = this . _sameWidthsIndexAtStart = null ;
258+ if ( useStackChartSameWidths ) {
259+ const sameWidthsIndexAtStart = Math . max (
260+ 0 ,
261+ bisectionRight ( sameWidthsIndexToTimestampMap , timeAtViewportStart ) - 1
262+ ) ;
263+ const sameWidthsIndexAtEnd = Math . min (
264+ sameWidthsIndexToTimestampMap . length - 1 ,
265+ bisectionLeft ( sameWidthsIndexToTimestampMap , timeAtViewportEnd )
266+ ) ;
258267
259- const sameWidthsRangeLength = sameWidthsIndexAtEnd - sameWidthsIndexAtStart ;
268+ this . _sameWidthsIndexAtStart = sameWidthsIndexAtStart ;
269+ this . _sameWidthsRangeLength =
270+ sameWidthsIndexAtEnd - sameWidthsIndexAtStart ;
271+ }
260272
261273 const pixelAtViewportPosition = (
262274 viewportPosition : UnitIntervalOfProfileRange
@@ -320,19 +332,22 @@ class StackChartCanvasImpl extends React.PureComponent<Props> {
320332 if (
321333 useStackChartSameWidths &&
322334 stackTiming . sameWidthsStart &&
323- stackTiming . sameWidthsEnd
335+ stackTiming . sameWidthsEnd &&
336+ this . _sameWidthsRangeLength !== null &&
337+ this . _sameWidthsIndexAtStart !== null
324338 ) {
325339 floatX =
326340 cssToDeviceScale *
327341 ( marginLeft +
328342 ( innerContainerWidth *
329- ( stackTiming . sameWidthsStart [ i ] - sameWidthsIndexAtStart ) ) /
330- sameWidthsRangeLength ) ;
343+ ( stackTiming . sameWidthsStart [ i ] -
344+ this . _sameWidthsIndexAtStart ) ) /
345+ this . _sameWidthsRangeLength ) ;
331346 floatW =
332347 ( innerDevicePixelsWidth *
333348 ( stackTiming . sameWidthsEnd [ i ] -
334349 stackTiming . sameWidthsStart [ i ] ) ) /
335- sameWidthsRangeLength -
350+ this . _sameWidthsRangeLength -
336351 1 ;
337352 } else {
338353 const viewportAtStartTime : UnitIntervalOfProfileRange =
@@ -632,12 +647,9 @@ class StackChartCanvasImpl extends React.PureComponent<Props> {
632647 y : CssPixels
633648 ) : HoveredStackTiming | null => {
634649 const {
635- rangeStart,
636- rangeEnd,
637650 combinedTimingRows,
638- sameWidthsIndexToTimestampMap,
639651 marginLeft,
640- viewport : { containerWidth, viewportLeft , viewportRight , viewportTop } ,
652+ viewport : { containerWidth, viewportTop } ,
641653 } = this . props ;
642654
643655 const depth = Math . floor ( ( y + viewportTop ) / ROW_CSS_PIXELS_HEIGHT ) ;
@@ -652,28 +664,23 @@ class StackChartCanvasImpl extends React.PureComponent<Props> {
652664 return this . _hitTest ( x , y ) ;
653665 }
654666
655- const rangeLength = rangeEnd - rangeStart ;
667+ if (
668+ this . _sameWidthsRangeLength === null ||
669+ this . _sameWidthsIndexAtStart === null
670+ ) {
671+ console . warn (
672+ 'The local variables sameWidthsRangeLength or samewidthsIndexAtStart are null when they should be present.'
673+ ) ;
674+ return null ;
675+ }
676+
656677 const innerContainerWidth =
657678 containerWidth - marginLeft - TIMELINE_MARGIN_RIGHT ;
658- const timeAtViewportStart : Milliseconds =
659- rangeStart + rangeLength * viewportLeft ;
660- const timeAtViewportEnd : Milliseconds =
661- rangeStart + rangeLength * viewportRight ;
662- const sameWidthsIndexAtStart = Math . max (
663- 0 ,
664- bisectionRight ( sameWidthsIndexToTimestampMap , timeAtViewportStart ) - 1
665- ) ;
666- const sameWidthsIndexAtEnd = Math . min (
667- sameWidthsIndexToTimestampMap . length - 1 ,
668- bisectionLeft ( sameWidthsIndexToTimestampMap , timeAtViewportEnd )
669- ) ;
670-
671- const sameWidthsRangeLength = sameWidthsIndexAtEnd - sameWidthsIndexAtStart ;
672679
673680 const xMinusMargin = x - marginLeft ;
674681 const hoveredBox =
675- ( xMinusMargin / innerContainerWidth ) * sameWidthsRangeLength +
676- sameWidthsIndexAtStart ;
682+ ( xMinusMargin / innerContainerWidth ) * this . _sameWidthsRangeLength +
683+ this . _sameWidthsIndexAtStart ;
677684
678685 for ( let i = 0 ; i < stackTiming . length ; i ++ ) {
679686 const start = stackTiming . sameWidthsStart [ i ] ;
0 commit comments