@@ -79,6 +79,12 @@ function redraw(svg, vis, data, ancestors, transitionTime, rootCoords) {
79
79
. ___domain ( [ 0 , nodes . length ] )
80
80
. range ( [ 0 , height ] ) ;
81
81
82
+ nodes . forEach ( function ( d , i ) {
83
+ d . x = x ( d . startMillis ) ;
84
+ d . y = y ( i ) ;
85
+ d . deleted = false ;
86
+ } ) ;
87
+
82
88
// Dynamically determine height required to render all tasks and resize the
83
89
// svg canvas if needed.
84
90
var svgHeight = height + MARGIN . top + MARGIN . bottom ;
@@ -96,16 +102,41 @@ function redraw(svg, vis, data, ancestors, transitionTime, rootCoords) {
96
102
. enter ( )
97
103
. append ( 'g' )
98
104
. classed ( 'trace' , true )
99
- . classed ( 'composite' , function ( d ) {
100
- return d . children || d . _children ;
101
- } )
102
- . classed ( 'hidden' , false )
105
+ . classed ( 'component' , function ( d ) { return d . parent . id !== null ; } )
106
+ . classed ( 'composite' , function ( d ) { return d . children || d . _children ; } )
103
107
. style ( 'opacity' , 1e-6 )
104
108
. on ( 'mouseover' , mouseover )
105
109
. on ( 'mouseout' , mouseout ) ;
106
110
107
111
bars . classed ( 'collapsed' , function ( d ) { return d . _children ; } ) ;
108
112
113
+ // Append hierarchy lines before we draw the bars
114
+ barsEnter . each ( function ( d ) {
115
+ if ( d . children || d . _children ) {
116
+ d3 . select ( this ) . append ( 'path' )
117
+ . attr ( 'd' , 'M10 5 L0 10 L0 0 Z' ) ;
118
+ } else if ( d . parent . id !== null ) {
119
+ d3 . select ( this ) . append ( 'circle' )
120
+ . attr ( 'r' , 4 )
121
+ . attr ( 'cx' , - 5 )
122
+ . attr ( 'cy' , BAR_HEIGHT / 2 ) ;
123
+ }
124
+ } ) ;
125
+
126
+ barsEnter . append ( 'line' )
127
+ . classed ( 'vertical' , true )
128
+ . attr ( 'x1' , - 5 )
129
+ . attr ( 'y1' , BAR_HEIGHT / 2 )
130
+ . attr ( 'x2' , - 5 )
131
+ . attr ( 'y2' , BAR_HEIGHT / 2 ) ;
132
+
133
+ barsEnter . append ( 'line' )
134
+ . classed ( 'horizontal' , true )
135
+ . attr ( 'x1' , - 5 )
136
+ . attr ( 'y1' , BAR_HEIGHT / 2 )
137
+ . attr ( 'x2' , - 5 )
138
+ . attr ( 'y2' , BAR_HEIGHT / 2 ) ;
139
+
109
140
barsEnter
110
141
. attr ( 'transform' , 'translate(' + rootCoords . x + ',' + rootCoords . y + ')' )
111
142
. append ( 'rect' )
@@ -127,53 +158,76 @@ function redraw(svg, vis, data, ancestors, transitionTime, rootCoords) {
127
158
var textEnter = barsEnter
128
159
. append ( 'text' )
129
160
. attr ( 'dy' , '1.3em' )
130
- . attr ( 'dx' , '1em ' ) ;
161
+ . attr ( 'dx' , '0.5em ' ) ;
131
162
132
163
textEnter
133
164
. append ( 'tspan' )
134
165
. classed ( 'collapse-toggle' , true )
135
166
. style ( 'font-family' , 'monospace' ) ;
136
167
137
168
bars
138
- . on ( 'click' , toggleCollapse )
139
- . selectAll ( 'text tspan.collapse-toggle' )
140
- . text ( function ( d ) {
141
- if ( d . children ) {
142
- return '[-] ' ;
143
- } else if ( d . _children ) {
144
- return '[+] ' ;
145
- } else {
146
- return '' ;
147
- }
148
- } ) ;
169
+ . on ( 'click' , toggleCollapse ) ;
149
170
150
171
textEnter
151
172
. append ( 'tspan' )
152
173
. text ( function ( d ) { return d . name + ' (' + util . alignMillis ( d . totalMillis ) + ' ms)' ; } ) ;
153
174
154
175
bars
155
- . style ( 'pointer-events' , 'none' )
156
- . transition ( )
157
- . duration ( transitionTime )
158
- . attr ( 'transform' , function ( d , i ) {
159
- return 'translate(' + x ( d . startMillis ) + ',' + y ( i ) + ')' ;
160
- } )
161
- . style ( 'opacity' , alpha )
162
- . each ( 'end' , function ( ) {
163
- d3 . select ( this ) . style ( 'opacity' , alpha ) ;
164
- d3 . select ( this ) . style ( 'pointer-events' , undefined ) ;
176
+ . exit ( )
177
+ . each ( function ( d ) {
178
+ if ( d . parent ) {
179
+ d . x = rootCoords . x ;
180
+ d . y = rootCoords . y ;
181
+ }
182
+ d . deleted = true ;
183
+ } ) ;
184
+
185
+ createTransition ( bars )
186
+ . selectAll ( 'path' )
187
+ . attr ( 'transform' , function ( d ) {
188
+ return 'translate(' + ( d . children ? 0 : - 10 ) + ',' + ( BAR_HEIGHT / 2 - 5 ) + ') ' +
189
+ 'rotate(' + ( d . children ? 90 : 0 ) + ')' ;
165
190
} ) ;
191
+ createTransition ( bars . exit ( ) )
192
+ . each ( 'end' , function ( ) {
193
+ d3 . select ( this . remove ( ) ) ;
194
+ } ) ;
166
195
167
- bars
168
- . exit ( )
196
+ function createTransition ( selection ) {
197
+ var transition = selection
169
198
. style ( 'pointer-events' , 'none' )
170
- . classed ( 'hidden' , true )
171
199
. transition ( )
172
200
. duration ( transitionTime )
173
- . attr ( 'transform' , 'translate(' + rootCoords . x + ',' + rootCoords . y + ')' )
174
- . style ( 'opacity' , 1e-6 )
175
- . each ( 'end' , function ( ) { d3 . select ( this ) . style ( 'pointer-events' , undefined ) ; } )
176
- . remove ( ) ;
201
+ . attr ( 'transform' , function ( d ) { return 'translate(' + d . x + ',' + d . y + ')' ; } )
202
+ . style ( 'opacity' , alpha ) ;
203
+
204
+ transition
205
+ . each ( 'end' , function ( ) {
206
+ d3 . select ( this ) . style ( 'opacity' , alpha ) ;
207
+ d3 . select ( this ) . style ( 'pointer-events' , undefined ) ;
208
+ } ) ;
209
+
210
+ transition . selectAll ( 'line.horizontal' )
211
+ . attr ( 'x2' , function ( d ) {
212
+ var delta = 0 ;
213
+ // Check for id is important since we have a fake node at the root
214
+ if ( d . parent . id !== null ) {
215
+ delta = d . parent . x - d . x ;
216
+ }
217
+ return delta - 4 ;
218
+ } ) ;
219
+
220
+ transition . selectAll ( 'line.vertical' )
221
+ . attr ( 'y2' , function ( d ) {
222
+ var delta = 0 ;
223
+ if ( d . children ) {
224
+ delta = Math . max . apply ( Math , d . children . map ( function ( c ) { return c . y ; } ) ) - d . y ;
225
+ }
226
+ return delta + BAR_HEIGHT / 2 ;
227
+ } ) ;
228
+
229
+ return transition ;
230
+ }
177
231
178
232
function mouseover ( d ) {
179
233
if ( d . children || d . _children ) {
@@ -187,10 +241,8 @@ function redraw(svg, vis, data, ancestors, transitionTime, rootCoords) {
187
241
function mouseout ( ) {
188
242
vis . selectAll ( 'g.trace' )
189
243
. filter ( function ( d ) { return d . waterfallDimmed ; } )
190
- . style ( 'opacity' , function ( ) {
191
- return d3 . select ( this ) . classed ( 'hidden' ) ? 0 : 1 ;
192
- } )
193
- . each ( function ( d ) { delete d . waterfallDimmed ; } ) ;
244
+ . each ( function ( d ) { delete d . waterfallDimmed ; } )
245
+ . style ( 'opacity' , alpha ) ;
194
246
}
195
247
196
248
function toggleCollapse ( d , i ) {
@@ -226,7 +278,7 @@ function redraw(svg, vis, data, ancestors, transitionTime, rootCoords) {
226
278
}
227
279
228
280
function alpha ( d ) {
229
- return d . waterfallDimmed ? DIMMED_ALPHA : 1 ;
281
+ return d . deleted ? 1e-6 : ( d . waterfallDimmed ? DIMMED_ALPHA : 1 ) ;
230
282
}
231
283
232
284
function redrawGrid ( svg , x , transitionTime , height ) {
0 commit comments