1
+ /* eslint-disable func-names */
2
+ /* eslint-disable react/no-this-in-sfc */
3
+ /* eslint-disable no-shadow */
4
+ /* eslint-disable no-multi-spaces */
5
+ /* eslint-disable newline-per-chained-call */
1
6
/* eslint-disable object-curly-newline */
2
7
/* eslint-disable object-property-newline */
3
8
/* eslint-disable class-methods-use-this */
7
12
/* eslint-disable react/destructuring-assignment */
8
13
/* eslint-disable react/prop-types */
9
14
/* eslint-disable no-console */
10
- import React , { useEffect , useRef } from 'react' ;
15
+
16
+ import React , { useEffect , useState , useRef } from 'react' ;
11
17
import * as d3 from 'd3' ;
12
18
import { addNewSnapshots } from '../actions/actions' ;
13
19
14
- // const chartData = {
15
- // name: 'App',
16
- // children: [
17
- // { name: 'DisplayPanel', componentData: { actualDuration: 5000 } },
18
- // { name: 'AltDisplay', componentData: { actualDuration: 2000 } },
19
- // { name: 'MarketSContainer', componentData: { actualDuration: 4000 } },
20
- // { name: 'MainSlider', componentData: { actualDuration: 3000 } },
21
- // ],
22
- // };
23
-
24
- const moveCompData = node => {
25
- if ( node === null ) return node ;
26
-
27
- if ( node . componentData . actualDuration ) {
28
- node . val = node . componentData . actualDuration ;
29
- }
30
- else {
31
- node . val = 1 ;
32
- }
33
- if ( node . children . length > 0 ) {
34
- node . children . forEach ( elem => copyToProp ( elem ) ) ;
35
- }
36
- else {
37
- return ;
38
- }
39
- } ;
20
+ // const windowRef = useRef(null);
21
+ // const winWidth = null;
22
+ // const winHeight = null;
40
23
41
- const PerfView = ( {
42
- width = 200 ,
43
- height = 200 ,
44
- snapshots
45
- } ) => {
46
- console . log ( 'snapshots' , snapshots ) ;
47
- const chartData = snapshots [ snapshots . length - 1 ] . children [ 0 ] ;
48
- moveCompData ( chartData ) ;
49
- console . log ( 'chartData' , chartData ) ;
24
+ // useEffect(() => {
25
+ // if (windowRef.current) {
26
+ // winWidth = windowRef.current.offsetHeight;
27
+ // winHeight = windowRef.current.offsetWidth;
28
+ // console.log('** SETTING WINDOW SIZES: ', winWidth, winHeight);
29
+ // }
30
+ // }, [windowRef]);
50
31
32
+ const PerfView = ( { snapshots, viewIndex } ) => {
33
+ const [ chartData , setChartData ] = useState ( snapshots [ snapshots . length - 1 ] ) ;
51
34
const svgRef = useRef ( null ) ;
52
35
53
- // returns color scale function
36
+ // Todo: implement update functions...
37
+ const [ curZoom , setZoom ] = useState ( null ) ;
38
+ const [ width , setWidth ] = useState ( 600 ) ;
39
+ const [ height , setHeight ] = useState ( 600 ) ;
40
+
41
+ // set up color scaling function
54
42
const color = d3 . scaleLinear ( )
55
- . domain ( [ 0 , 5 ] )
43
+ . domain ( [ 0 , 7 ] )
56
44
. range ( [ 'hsl(152,80%,80%)' , 'hsl(228,30%,40%)' ] )
57
45
. interpolate ( d3 . interpolateHcl ) ;
58
46
59
- // create a new circle packing layout function
47
+ // set up circle- packing layout function
60
48
const packFunc = data => d3 . pack ( )
61
49
. size ( [ width , height ] )
62
50
. padding ( 3 ) ( d3 . hierarchy ( data )
63
51
. sum ( d => {
64
- console . log ( 'in pack func. d=' , d ) ;
65
- return d . val ;
52
+ // console.log('in pack func. d=', d);
53
+ return d . componentData . actualDuration ;
66
54
} )
67
- . sort ( ( a , b ) => b . val - a . val ) ) ;
55
+ . sort ( ( a , b ) => {
56
+ // console.log('in sort func. a&b=', a, b);
57
+ return b . value - a . value ;
58
+ } ) ) ;
68
59
69
60
console . log ( 'packFunc' , packFunc ) ;
70
61
71
62
useEffect ( ( ) => {
63
+ console . log ( 'PerfView -> snapshots' , snapshots ) ;
64
+ console . log ( 'Current viewIndex: ' , viewIndex ) ;
65
+ for ( let i = 0 ; i < snapshots . length ; i ++ ) {
66
+ console . log ( `SNAPSHOT[${ i } ] App actualDuration:` , snapshots [ i ] . children [ 0 ] . componentData . actualDuration ) ;
67
+ }
68
+
69
+ // empty old tree
70
+ while ( svgRef . current . hasChildNodes ( ) ) {
71
+ svgRef . current . removeChild ( svgRef . current . lastChild ) ;
72
+ }
73
+
74
+ if ( viewIndex < 0 ) {
75
+ setChartData ( snapshots [ snapshots . length - 1 ] ) ;
76
+ console . log ( `Using snapshots[${ snapshots . length - 1 } ]` ) ;
77
+ } else {
78
+ setChartData ( snapshots [ viewIndex ] ) ;
79
+ console . log ( `Using snapshots[${ viewIndex } ]` ) ;
80
+ }
81
+
82
+ console . log ( 'PerfView -> chartData' , chartData ) ;
83
+
84
+ // generate tree with our data
72
85
const packedRoot = packFunc ( chartData ) ;
73
- console . log ( '** PerfView -> packedRoot' , packedRoot ) ;
86
+ // console.log('PerfView -> packedRoot', packedRoot);
87
+
88
+ // initial focus points at root of tree
74
89
let focus = packedRoot ;
75
90
let view ;
76
91
92
+ // set up viewBox dimensions and onClick for parent svg
77
93
const svg = d3 . select ( svgRef . current )
94
+ . attr ( 'viewBox' , `-${ width / 2 } -${ height / 2 } ${ width } ${ height } ` )
78
95
. on ( 'click' , ( ) => zoom ( packedRoot ) ) ;
79
96
97
+ // connect circles below root to data
80
98
const node = svg . append ( 'g' )
81
99
. selectAll ( 'circle' )
82
100
. data ( packedRoot . descendants ( ) . slice ( 1 ) )
83
-
84
- . enter ( )
85
- . append ( 'circle' )
101
+ . enter ( ) . append ( 'circle' )
86
102
. attr ( 'fill' , d => ( d . children ? color ( d . depth ) : 'white' ) )
87
103
. attr ( 'pointer-events' , d => ( ! d . children ? 'none' : null ) )
88
- . on ( 'mouseover' , function ( ) { d3 . select ( this ) . attr ( 'stroke' , '#000' ) ; } )
89
- . on ( 'mouseout' , function ( ) { d3 . select ( this ) . attr ( 'stroke' , null ) ; } )
104
+ . on ( 'mouseover' , ( ) => d3 . select ( this ) . attr ( 'stroke' , '#000' ) )
105
+ . on ( 'mouseout' , ( ) => d3 . select ( this ) . attr ( 'stroke' , null ) )
90
106
. on ( 'click' , d => focus !== d && ( zoom ( d ) , d3 . event . stopPropagation ( ) ) ) ;
91
107
92
- console . log ( 'PerfView -> node' , node ) ;
108
+ // console.log('PerfView -> node', node);
109
+ // console.log('packedRoot.descendants()', packedRoot.descendants());
93
110
111
+ // generate text labels
94
112
const label = svg . append ( 'g' )
95
- . style ( 'font' , '11px sans-serif' )
96
- . attr ( 'pointer-events' , 'none' )
97
- . attr ( 'text-anchor' , 'middle' )
113
+ . attr ( 'class' , 'perf-chart-labels' )
98
114
. selectAll ( 'text' )
99
115
. data ( packedRoot . descendants ( ) )
100
- . enter ( )
101
- . append ( 'text' )
116
+ . enter ( ) . append ( 'text' )
102
117
. style ( 'fill-opacity' , d => ( d . parent === packedRoot ? 1 : 0 ) )
103
118
. style ( 'display' , d => ( d . parent === packedRoot ? 'inline' : 'none' ) )
104
- . text ( d => `${ d . data . name } : ${ Number . parseFloat ( d . data . val ) . toFixed ( 2 ) } ms` ) ;
119
+ . text ( d => {
120
+ console . log ( 'generating text label for d: ' , d ) ;
121
+ return `${ d . data . name } : ${ Number . parseFloat ( d . data . componentData . actualDuration ) . toFixed ( 2 ) } ms` ;
122
+ } ) ;
123
+
124
+ label . exit ( ) . remove ( ) ;
125
+ node . exit ( ) . remove ( ) ;
105
126
127
+ // console.log('PerfView -> label', label);
128
+
129
+ // jump to default zoom state
106
130
zoomTo ( [ packedRoot . x , packedRoot . y , packedRoot . r * 2 ] ) ;
107
131
108
132
function zoomTo ( v ) {
109
133
const k = width / v [ 2 ] ;
110
134
view = v ;
111
-
112
135
label . attr ( 'transform' , d => `translate(${ ( d . x - v [ 0 ] ) * k } ,${ ( d . y - v [ 1 ] ) * k } )` ) ;
113
136
node . attr ( 'transform' , d => `translate(${ ( d . x - v [ 0 ] ) * k } ,${ ( d . y - v [ 1 ] ) * k } )` ) ;
114
137
node . attr ( 'r' , d => d . r * k ) ;
115
138
}
116
139
117
140
function zoom ( d ) {
118
141
const focus0 = focus ;
119
-
120
142
focus = d ;
121
143
122
144
const transition = svg . transition ( )
@@ -127,16 +149,15 @@ const PerfView = ({
127
149
} ) ;
128
150
129
151
label
130
- . filter ( function ( d ) { return d . parent === focus || this . style . display === 'inline' ; } )
131
- . transition ( transition )
132
- . style ( 'fill-opacity' , d => ( d . parent === focus ? 1 : 0 ) )
133
- . on ( 'start' , function ( d ) { if ( d . parent === focus ) this . style . display = 'inline' ; } )
134
- . on ( 'end' , function ( d ) { if ( d . parent !== focus ) this . style . display = 'none' ; } ) ;
152
+ . filter ( function ( d ) { return d . parent === focus || this . style . display === 'inline' ; } )
153
+ . transition ( transition )
154
+ . style ( 'fill-opacity' , d => ( d . parent === focus ? 1 : 0 ) )
155
+ . on ( 'start' , function ( d ) { if ( d . parent === focus ) this . style . display = 'inline' ; } )
156
+ . on ( 'end' , function ( d ) { if ( d . parent !== focus ) this . style . display = 'none' ; } ) ;
135
157
}
136
- } , [ chartData ] ) ;
158
+ } , [ snapshots . length , height , width , viewIndex ] ) ;
137
159
138
- return < svg viewBox = "-250 -250 500 500" className = "perfContainer" ref = { svgRef } /> ;
160
+ return < svg className = "perfContainer" ref = { svgRef } /> ;
139
161
} ;
140
162
141
-
142
163
export default PerfView ;
0 commit comments