@@ -23,27 +23,45 @@ import * as d3 from 'd3';
23
23
// import { schemeSet1 as colorScheme } from 'd3';
24
24
25
25
interface PerfViewProps {
26
- snapshots :any [ ] ;
27
- viewIndex :number ;
26
+ snapshots : any [ ] ;
27
+ viewIndex : number ;
28
28
width : number ;
29
29
height : number ;
30
30
setNoRenderData : any ;
31
31
}
32
32
33
- const PerfView = ( props :PerfViewProps ) => {
34
- const { snapshots, viewIndex, width, height, setNoRenderData } = props ;
33
+ const PerfView = ( props : PerfViewProps ) => {
34
+ const { viewIndex, width, height, setNoRenderData } = props ;
35
+ let { snapshots } = props ;
35
36
const adjustedSize = Math . min ( width , height ) ;
36
37
const svgRef = useRef ( null ) ;
37
38
39
+ //NEEDS REWRITE FOR RECOIL
40
+ // snapshots.forEach((snapshot) => snapshot.children[0].children.shift());
41
+ // console.log('SNAPSHOTS -------------------------->', snapshots);
38
42
// Figure out which snapshot index to use
39
43
let indexToDisplay : number | null = null ;
40
44
if ( viewIndex < 0 ) indexToDisplay = snapshots . length - 1 ;
41
45
else indexToDisplay = viewIndex ;
42
46
47
+ console . log ( 'SNAPSHOTS IN PERF VIEW' , snapshots ) ;
48
+ console . log ( 'VIEW INDEX' , indexToDisplay ) ;
49
+
43
50
// Set up color scaling function
44
- const colorScale = d3 . scaleOrdinal ( )
51
+ const colorScale = d3
52
+ . scaleOrdinal ( )
45
53
. domain ( [ 0 , 8 ] )
46
- . range ( [ '#4a91c7' , '#5b9bce' , '#6ba6d5' , '#7bb0dc' , '#8abbe3' , '#99c6ea' , '#a8d0f1' , '#b7dbf8' , '#c6e6ff' ] ) ;
54
+ . range ( [
55
+ '#4a91c7' ,
56
+ '#5b9bce' ,
57
+ '#6ba6d5' ,
58
+ '#7bb0dc' ,
59
+ '#8abbe3' ,
60
+ '#99c6ea' ,
61
+ '#a8d0f1' ,
62
+ '#b7dbf8' ,
63
+ '#c6e6ff' ,
64
+ ] ) ;
47
65
48
66
// Alternate color scaling function
49
67
// const colorScale = d3.scaleLinear()
@@ -52,17 +70,21 @@ const PerfView = (props:PerfViewProps) => {
52
70
// .interpolate(d3.interpolateHcl);
53
71
54
72
// Set up circle-packing layout function
55
- const packFunc = useCallback ( ( data :object ) => {
56
- return d3 . pack ( )
57
- . size ( [ adjustedSize , adjustedSize ] )
58
- . padding ( 3 ) ( d3 . hierarchy ( data )
59
- . sum ( ( d :{ componentData ?:{ actualDuration ?:number } } ) => {
60
- return d . componentData . actualDuration || 0 ;
61
- } )
62
- . sort ( ( a :{ value :number } , b :{ value :number } ) => {
63
- return b . value - a . value ;
64
- } ) ) ;
65
- } , [ adjustedSize ] ) ;
73
+ const packFunc = useCallback (
74
+ ( data : object ) => {
75
+ return d3 . pack ( ) . size ( [ adjustedSize , adjustedSize ] ) . padding ( 3 ) (
76
+ d3
77
+ . hierarchy ( data )
78
+ . sum ( ( d : { componentData ?: { actualDuration ?: number } } ) => {
79
+ return d . componentData . actualDuration || 0 ;
80
+ } )
81
+ . sort ( ( a : { value : number } , b : { value : number } ) => {
82
+ return b . value - a . value ;
83
+ } )
84
+ ) ;
85
+ } ,
86
+ [ adjustedSize ]
87
+ ) ;
66
88
67
89
function handleNoRenderData ( isNoRenderData ) {
68
90
setNoRenderData ( isNoRenderData ) ;
@@ -88,87 +110,142 @@ const PerfView = (props:PerfViewProps) => {
88
110
let view ;
89
111
90
112
// Set up viewBox dimensions and onClick for parent svg
91
- const svg = d3 . select ( svgRef . current )
92
- . attr ( 'viewBox' , `-${ adjustedSize / 2 } -${ adjustedSize / 2 } ${ width } ${ height } ` )
113
+ const svg = d3
114
+ . select ( svgRef . current )
115
+ . attr (
116
+ 'viewBox' ,
117
+ `-${ adjustedSize / 2 } -${ adjustedSize / 2 } ${ width } ${ height } `
118
+ )
93
119
. on ( 'click' , ( ) => zoomToNode ( packedRoot ) ) ;
94
120
95
121
// Connect circles below root to data
96
- const node = svg . append ( 'g' )
122
+ const node = svg
123
+ . append ( 'g' )
97
124
. selectAll ( 'circle' )
98
125
. data ( packedRoot . descendants ( ) . slice ( 1 ) )
99
- . enter ( ) . append ( 'circle' )
100
- . attr ( 'fill' , ( d :{ children :[ ] ; depth :number } ) => ( d . children ? colorScale ( d . depth ) : 'white' ) )
101
- . attr ( 'pointer-events' , ( d ?:{ children :[ ] } ) => ( ! d . children ? 'none' : null ) )
102
- . on ( 'mouseover' , function ( ) { d3 . select ( this ) . attr ( 'stroke' , '#000' ) ; } )
103
- . on ( 'mouseout' , function ( ) { d3 . select ( this ) . attr ( 'stroke' , null ) ; } )
104
- . on ( 'click' , ( d :{ x : number ; y : number ; r : number ; } ) => curFocus !== d && ( zoomToNode ( d ) , d3 . event . stopPropagation ( ) ) ) ;
126
+ . enter ( )
127
+ . append ( 'circle' )
128
+ . attr ( 'fill' , ( d : { children : [ ] ; depth : number } ) =>
129
+ d . children ? colorScale ( d . depth ) : 'white'
130
+ )
131
+ . attr ( 'pointer-events' , ( d ?: { children : [ ] } ) =>
132
+ ! d . children ? 'none' : null
133
+ )
134
+ . on ( 'mouseover' , function ( ) {
135
+ d3 . select ( this ) . attr ( 'stroke' , '#000' ) ;
136
+ } )
137
+ . on ( 'mouseout' , function ( ) {
138
+ d3 . select ( this ) . attr ( 'stroke' , null ) ;
139
+ } )
140
+ . on (
141
+ 'click' ,
142
+ ( d : { x : number ; y : number ; r : number } ) =>
143
+ curFocus !== d && ( zoomToNode ( d ) , d3 . event . stopPropagation ( ) )
144
+ ) ;
105
145
106
146
// Generate text labels. Set (only) root to visible initially
107
- const label = svg . append ( 'g' )
108
- . attr ( 'class' , 'perf-chart-labels' )
147
+ const label = svg
148
+ . append ( 'g' )
149
+ . attr ( 'class' , 'perf-chart-labels' )
109
150
. selectAll ( 'text' )
110
151
. data ( packedRoot . descendants ( ) )
111
- . enter ( ) . append ( 'text' )
112
- . style ( 'fill-opacity' , ( d :{ parent :object } ) => ( d . parent === packedRoot ? 1 : 0 ) )
113
- . style ( 'display' , ( d :{ parent ?:object } ) => ( d . parent === packedRoot ? 'inline' : 'none' ) )
114
- . text ( ( d :{ data :{ name :string , componentData ?:{ actualDuration :any } } } ) => {
152
+ . enter ( )
153
+ . append ( 'text' )
154
+ . style ( 'fill-opacity' , ( d : { parent : object } ) =>
155
+ d . parent === packedRoot ? 1 : 0
156
+ )
157
+ . style ( 'display' , ( d : { parent ?: object } ) =>
158
+ d . parent === packedRoot ? 'inline' : 'none'
159
+ )
160
+ . text (
161
+ ( d : {
162
+ data : { name : string ; componentData ?: { actualDuration : any } } ;
163
+ } ) => {
115
164
if ( ! d . data . componentData . actualDuration ) handleNoRenderData ( true ) ;
116
165
else handleNoRenderData ( false ) ;
117
- return `${ d . data . name } : ${ Number . parseFloat ( d . data . componentData . actualDuration || 0 ) . toFixed ( 2 ) } ms` ;
118
- } ) ;
166
+ return `${ d . data . name } : ${ Number . parseFloat (
167
+ d . data . componentData . actualDuration || 0
168
+ ) . toFixed ( 2 ) } ms`;
169
+ }
170
+ ) ;
119
171
120
172
// Remove any unused nodes
121
173
label . exit ( ) . remove ( ) ;
122
174
node . exit ( ) . remove ( ) ;
123
175
124
176
// Zoom size of nodes and labels to focus view on root node
125
- if ( ( ! Number . isNaN ( packedRoot . x ) )
126
- && ( ! Number . isNaN ( packedRoot . y ) )
127
- && ( ! Number . isNaN ( packedRoot . r ) ) ) {
177
+ if (
178
+ ! Number . isNaN ( packedRoot . x ) &&
179
+ ! Number . isNaN ( packedRoot . y ) &&
180
+ ! Number . isNaN ( packedRoot . r )
181
+ ) {
128
182
zoomViewArea ( [ packedRoot . x , packedRoot . y , packedRoot . r * 2 ] ) ;
129
183
}
130
184
131
185
// Zoom/relocated nodes and labels based on dimensions given [x, y, r]
132
186
function zoomViewArea ( newXYR ) {
133
187
const k = width / newXYR [ 2 ] ;
134
188
view = newXYR ;
135
- label . attr ( 'transform' , d => `translate(${ ( d . x - newXYR [ 0 ] ) * k } ,${ ( d . y - newXYR [ 1 ] ) * k } )` ) ;
136
- node . attr ( 'transform' , d => `translate(${ ( d . x - newXYR [ 0 ] ) * k } ,${ ( d . y - newXYR [ 1 ] ) * k } )` ) ;
137
- node . attr ( 'r' , d => d . r * k ) ;
189
+ label . attr (
190
+ 'transform' ,
191
+ ( d ) => `translate(${ ( d . x - newXYR [ 0 ] ) * k } ,${ ( d . y - newXYR [ 1 ] ) * k } )`
192
+ ) ;
193
+ node . attr (
194
+ 'transform' ,
195
+ ( d ) => `translate(${ ( d . x - newXYR [ 0 ] ) * k } ,${ ( d . y - newXYR [ 1 ] ) * k } )`
196
+ ) ;
197
+ node . attr ( 'r' , ( d ) => d . r * k ) ;
138
198
}
139
199
140
200
// Transition visibility of labels
141
- function zoomToNode ( newFocus :{ x :number ; y :number ; r :number } ) {
142
- const transition = svg . transition ( )
143
- . duration ( d3 . event . altKey ? 7500 : 750 )
144
- . tween ( 'zoom' , ( d :object ) => {
145
- const i = d3 . interpolateZoom ( view , [ newFocus . x , newFocus . y , newFocus . r * 2 ] ) ;
146
- return t => zoomViewArea ( i ( t ) ) ;
147
- } ) ;
201
+ function zoomToNode ( newFocus : { x : number ; y : number ; r : number } ) {
202
+ const transition = svg
203
+ . transition ( )
204
+ . duration ( d3 . event . altKey ? 7500 : 750 )
205
+ . tween ( 'zoom' , ( d : object ) => {
206
+ const i = d3 . interpolateZoom ( view , [
207
+ newFocus . x ,
208
+ newFocus . y ,
209
+ newFocus . r * 2 ,
210
+ ] ) ;
211
+ return ( t ) => zoomViewArea ( i ( t ) ) ;
212
+ } ) ;
148
213
149
214
// Grab all nodes that were previously displayed, or who's parent is the new target newFocus
150
215
// Transition their labels to visible or not
151
- label . filter ( function ( d :{ parent :object } ) {
152
- return d . parent === newFocus || this . style . display === 'inline' ;
153
- } )
154
- . transition ( transition )
155
- . style ( 'fill-opacity' , ( d :{ parent :object } ) => ( d . parent === newFocus ? 1 : 0 ) )
156
- . on ( 'start' , function ( d :{ parent :object } ) {
157
- if ( d . parent === newFocus ) this . style . display = 'inline' ;
158
- } )
159
- . on ( 'end' , function ( d :{ parent :object } ) {
160
- if ( d . parent !== newFocus ) this . style . display = 'none' ;
161
- } ) ;
216
+ label
217
+ . filter ( function ( d : { parent : object } ) {
218
+ return d . parent === newFocus || this . style . display === 'inline' ;
219
+ } )
220
+ . transition ( transition )
221
+ . style ( 'fill-opacity' , ( d : { parent : object } ) =>
222
+ d . parent === newFocus ? 1 : 0
223
+ )
224
+ . on ( 'start' , function ( d : { parent : object } ) {
225
+ if ( d . parent === newFocus ) this . style . display = 'inline' ;
226
+ } )
227
+ . on ( 'end' , function ( d : { parent : object } ) {
228
+ if ( d . parent !== newFocus ) this . style . display = 'none' ;
229
+ } ) ;
162
230
163
231
curFocus = newFocus ;
164
232
}
165
- } , [ colorScale , packFunc , width , height , indexToDisplay , snapshots , adjustedSize , handleNoRenderData ] ) ;
233
+ } , [
234
+ colorScale ,
235
+ packFunc ,
236
+ width ,
237
+ height ,
238
+ indexToDisplay ,
239
+ snapshots ,
240
+ adjustedSize ,
241
+ handleNoRenderData ,
242
+ ] ) ;
166
243
167
244
return (
168
245
< div className = "perf-d3-container" >
169
246
< svg className = "perf-d3-svg" ref = { svgRef } />
170
247
</ div >
171
- ) ;
248
+ ) ;
172
249
} ;
173
250
174
251
export default PerfView ;
0 commit comments