@@ -33,7 +33,7 @@ import { getChartThemeSelector } from '../../state/selectors/get_chart_theme';
33
33
import { getSettingsSpecSelector } from '../../state/selectors/get_settings_spec' ;
34
34
import { getTooltipSpecSelector } from '../../state/selectors/get_tooltip_spec' ;
35
35
import { getSpecsFromStore } from '../../state/utils' ;
36
- import { clamp , isFiniteNumber } from '../../utils/common' ;
36
+ import { clamp , isFiniteNumber , isNil } from '../../utils/common' ;
37
37
import { Size } from '../../utils/dimensions' ;
38
38
import { FlamegraphStyle } from '../../utils/themes/theme' ;
39
39
@@ -60,7 +60,7 @@ const WOBBLE_REPEAT_COUNT = 2;
60
60
const WOBBLE_FREQUENCY = SHOULD_DISABLE_WOBBLE ? 0 : 2 * Math . PI * ( WOBBLE_REPEAT_COUNT / WOBBLE_DURATION ) ; // e.g. 1/30 means a cycle of every 30ms
61
61
const NODE_TWEEN_DURATION_MS = 500 ;
62
62
63
- const unitRowPitch = ( position : Float32Array ) => ( position . length >= 4 ? position [ 1 ] - position [ 3 ] : 1 ) ;
63
+ const unitRowPitch = ( position : Float32Array ) => ( position . length >= 4 ? ( position [ 1 ] ?? 0 ) - ( position [ 3 ] ?? 0 ) : 1 ) ;
64
64
const initialPixelRowPitch = ( ) => 16 ;
65
65
const specValueFormatter = ( d : number ) => d ; // fixme use the formatter from the spec
66
66
const browserRootWindow = ( ) => {
@@ -70,10 +70,10 @@ const browserRootWindow = () => {
70
70
} ;
71
71
72
72
const columnToRowPositions = ( { position1, size1 } : FlameSpec [ 'columnarData' ] , i : number ) => ( {
73
- x0 : position1 [ i * 2 ] ,
74
- x1 : position1 [ i * 2 ] + size1 [ i ] ,
75
- y0 : position1 [ i * 2 + 1 ] ,
76
- y1 : position1 [ i * 2 + 1 ] + unitRowPitch ( position1 ) ,
73
+ x0 : position1 [ i * 2 ] ?? 0 ,
74
+ x1 : ( position1 [ i * 2 ] ?? 0 ) + ( size1 [ i ] ?? 0 ) ,
75
+ y0 : position1 [ i * 2 + 1 ] ?? 0 ,
76
+ y1 : ( position1 [ i * 2 + 1 ] ?? 0 ) + unitRowPitch ( position1 ) ,
77
77
} ) ;
78
78
79
79
/** @internal */
@@ -111,17 +111,18 @@ const focusRect = (
111
111
) : FocusRect => focusForArea ( chartHeight , columnToRowPositions ( columnarViewModel , drilldownDatumIndex || 0 ) ) ;
112
112
113
113
const getColor = ( c : Float32Array , i : number ) => {
114
- const r = Math . round ( 255 * c [ 4 * i ] ) ;
115
- const g = Math . round ( 255 * c [ 4 * i + 1 ] ) ;
116
- const b = Math . round ( 255 * c [ 4 * i + 2 ] ) ;
114
+ const r = Math . round ( 255 * ( c [ 4 * i ] ?? 0 ) ) ;
115
+ const g = Math . round ( 255 * ( c [ 4 * i + 1 ] ?? 0 ) ) ;
116
+ const b = Math . round ( 255 * ( c [ 4 * i + 2 ] ?? 0 ) ) ;
117
117
const a = c [ 4 * i + 3 ] ;
118
118
return `rgba(${ r } , ${ g } , ${ b } , ${ a } )` ;
119
119
} ;
120
120
121
121
const colorToDatumIndex = ( pixel : Uint8Array ) => {
122
122
// this is the inverse of what's done via BIT_SHIFTERS in shader code (bijective color/index mapping)
123
- const isEmptyArea = pixel [ 0 ] + pixel [ 1 ] + pixel [ 2 ] + pixel [ 3 ] < GEOM_INDEX_OFFSET ; // ie. zero
124
- return isEmptyArea ? NaN : pixel [ 3 ] + 256 * ( pixel [ 2 ] + 256 * ( pixel [ 1 ] + 256 * pixel [ 0 ] ) ) - GEOM_INDEX_OFFSET ;
123
+ const [ p0 = 0 , p1 = 0 , p2 = 0 , p3 = 0 ] = pixel ;
124
+ const isEmptyArea = p0 + p1 + p2 + p3 < GEOM_INDEX_OFFSET ; // ie. zero
125
+ return isEmptyArea ? NaN : p3 + 256 * ( p2 + 256 * ( p1 + 256 * p0 ) ) - GEOM_INDEX_OFFSET ;
125
126
} ;
126
127
127
128
const getRegExp = ( searchString : string ) : RegExp => {
@@ -473,21 +474,21 @@ class FlameComponent extends React.Component<FlameProps> {
473
474
474
475
if ( prevHoverIndex !== this . hoverIndex ) {
475
476
const columns = this . props . columnarViewModel ;
476
- this . tooltipValues =
477
- this . hoverIndex >= 0
478
- ? [
479
- {
480
- label : columns . label [ this . hoverIndex ] ,
481
- color : getColor ( columns . color , this . hoverIndex ) ,
482
- isHighlighted : false ,
483
- isVisible : true ,
484
- seriesIdentifier : { specId : '' , key : '' } ,
485
- value : columns . value [ this . hoverIndex ] ,
486
- formattedValue : `${ specValueFormatter ( columns . value [ this . hoverIndex ] ) } ` ,
487
- valueAccessor : this . hoverIndex ,
488
- } ,
489
- ]
490
- : [ ] ;
477
+ const hoverValue = this . hoverIndex >= 0 ? columns . value [ this . hoverIndex ] : null ;
478
+ this . tooltipValues = ! isNil ( hoverValue )
479
+ ? [
480
+ {
481
+ label : columns . label [ this . hoverIndex ] ?? '' ,
482
+ color : getColor ( columns . color , this . hoverIndex ) ,
483
+ isHighlighted : false ,
484
+ isVisible : true ,
485
+ seriesIdentifier : { specId : '' , key : '' } ,
486
+ value : hoverValue ,
487
+ formattedValue : `${ specValueFormatter ( hoverValue ) } ` ,
488
+ valueAccessor : this . hoverIndex ,
489
+ } ,
490
+ ]
491
+ : [ ] ;
491
492
}
492
493
this . setState ( { } ) ; // exact tooltip location needs an update
493
494
}
@@ -707,13 +708,13 @@ class FlameComponent extends React.Component<FlameProps> {
707
708
let y1 = - Infinity ;
708
709
// todo unify with matcher loop and setup in focusOnHit
709
710
for ( let i = 0 ; i < datumCount ; i ++ ) {
710
- const label = this . caseSensitive ? labels [ i ] : labels [ i ] . toLowerCase ( ) ;
711
- if ( regex ? label . match ( regex ) : label . includes ( customizedSearchString ) ) {
711
+ const label = this . caseSensitive ? labels [ i ] : labels [ i ] ? .toLowerCase ( ) ;
712
+ if ( regex ? label ? .match ( regex ) : label ? .includes ( customizedSearchString ) ) {
712
713
this . currentSearchHitCount ++ ;
713
- x0 = Math . min ( x0 , position [ 2 * i ] ) ;
714
- x1 = Math . max ( x1 , position [ 2 * i ] + size [ i ] ) ;
715
- y0 = Math . min ( y0 , position [ 2 * i + 1 ] ) ;
716
- y1 = Math . max ( y1 , position [ 2 * i + 1 ] + rowHeight ) ;
714
+ x0 = Math . min ( x0 , position [ 2 * i ] ?? 0 ) ;
715
+ x1 = Math . max ( x1 , ( position [ 2 * i ] ?? 0 ) + ( size [ i ] ?? 0 ) ) ;
716
+ y0 = Math . min ( y0 , position [ 2 * i + 1 ] ?? 0 ) ;
717
+ y1 = Math . max ( y1 , ( position [ 2 * i + 1 ] ?? 0 ) + rowHeight ) ;
717
718
} else {
718
719
this . currentColor [ 4 * i + 3 ] *= 0.25 ; // multiply alpha
719
720
}
@@ -794,8 +795,8 @@ class FlameComponent extends React.Component<FlameProps> {
794
795
const labels = this . props . columnarViewModel . label ;
795
796
// todo unify with matcher loop and setup in focusOnAllMatches
796
797
for ( let i = 0 ; i < labels . length ; i ++ ) {
797
- const label = this . caseSensitive ? labels [ i ] : labels [ i ] . toLowerCase ( ) ;
798
- if ( regex ? label . match ( regex ) : label . includes ( customizedSearchString ) ) {
798
+ const label = this . caseSensitive ? labels [ i ] : labels [ i ] ? .toLowerCase ( ) ;
799
+ if ( regex ? label ? .match ( regex ) : label ? .includes ( customizedSearchString ) ) {
799
800
datumIndex = i ;
800
801
hitEnumerator ++ ;
801
802
if ( hitEnumerator === this . focusedMatchIndex ) break ;
0 commit comments