@@ -33,7 +33,7 @@ module.exports = function plot(gd, plotinfo, cdscatter, transitionOpts, makeOnCo
3333
3434 selection = scatterlayer . selectAll ( 'g.trace' ) ;
3535
36- join = selection . data ( cdscatter , function ( d ) { return d [ 0 ] . trace . uid ; } ) ;
36+ join = selection . data ( cdscatter , function ( d ) { return d [ 0 ] . trace . uid ; } ) ;
3737
3838 // Append new traces:
3939 join . enter ( ) . append ( 'g' )
@@ -197,11 +197,19 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
197197 // revpath is fullpath reversed, for fill-to-next
198198 revpath = '' ,
199199 // functions for converting a point array to a path
200- pathfn , revpathbase , revpathfn ;
200+ pathfn , revpathbase , revpathfn ,
201+ // variables used before and after the data join
202+ pt0 , lastSegment , pt1 , thisPolygons ;
203+
204+ // initialize line join data / method
205+ var segments = [ ] ,
206+ lineSegments = [ ] ,
207+ makeUpdate = Lib . noop ;
201208
202209 ownFillEl3 = trace . _ownFill ;
203210
204211 if ( subTypes . hasLines ( trace ) || trace . fill !== 'none' ) {
212+
205213 if ( tonext ) {
206214 // This tells .style which trace to use for fill information:
207215 tonext . datum ( cdscatter ) ;
@@ -237,7 +245,7 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
237245 return revpathbase ( pts . reverse ( ) ) ;
238246 } ;
239247
240- var segments = linePoints ( cdscatter , {
248+ segments = linePoints ( cdscatter , {
241249 xaxis : xa ,
242250 yaxis : ya ,
243251 connectGaps : trace . connectgaps ,
@@ -250,24 +258,22 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
250258 // polygons for hover on fill
251259 // TODO: can we skip this if hoveron!=fills? That would mean we
252260 // need to redraw when you change hoveron...
253- var thisPolygons = trace . _polygons = new Array ( segments . length ) ;
261+ thisPolygons = trace . _polygons = new Array ( segments . length ) ;
254262 for ( i = 0 ; i < segments . length ; i ++ ) {
255263 trace . _polygons [ i ] = polygonTester ( segments [ i ] ) ;
256264 }
257265
258- var pt0 , lastSegment , pt1 ;
259-
260266 if ( segments . length ) {
261267 pt0 = segments [ 0 ] [ 0 ] ;
262268 lastSegment = segments [ segments . length - 1 ] ;
263269 pt1 = lastSegment [ lastSegment . length - 1 ] ;
264270 }
265271
266- var lineSegments = segments . filter ( function ( s ) {
272+ lineSegments = segments . filter ( function ( s ) {
267273 return s . length > 1 ;
268274 } ) ;
269275
270- var makeUpdate = function ( isEnter ) {
276+ makeUpdate = function ( isEnter ) {
271277 return function ( pts ) {
272278 thispath = pathfn ( pts ) ;
273279 thisrevpath = revpathfn ( pts ) ;
@@ -303,66 +309,66 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
303309 }
304310 } ;
305311 } ;
312+ }
306313
307- var lineJoin = tr . selectAll ( '.js-line' ) . data ( lineSegments ) ;
314+ var lineJoin = tr . selectAll ( '.js-line' ) . data ( lineSegments ) ;
308315
309- transition ( lineJoin . exit ( ) )
310- . style ( 'opacity' , 0 )
311- . remove ( ) ;
316+ transition ( lineJoin . exit ( ) )
317+ . style ( 'opacity' , 0 )
318+ . remove ( ) ;
312319
313- lineJoin . each ( makeUpdate ( false ) ) ;
320+ lineJoin . each ( makeUpdate ( false ) ) ;
314321
315- lineJoin . enter ( ) . append ( 'path' )
316- . classed ( 'js-line' , true )
317- . style ( 'vector-effect' , 'non-scaling-stroke' )
318- . call ( Drawing . lineGroupStyle )
319- . each ( makeUpdate ( true ) ) ;
322+ lineJoin . enter ( ) . append ( 'path' )
323+ . classed ( 'js-line' , true )
324+ . style ( 'vector-effect' , 'non-scaling-stroke' )
325+ . call ( Drawing . lineGroupStyle )
326+ . each ( makeUpdate ( true ) ) ;
320327
321- if ( segments . length ) {
322- if ( ownFillEl3 ) {
323- if ( pt0 && pt1 ) {
324- if ( ownFillDir ) {
325- if ( ownFillDir === 'y' ) {
326- pt0 [ 1 ] = pt1 [ 1 ] = ya . c2p ( 0 , true ) ;
327- }
328- else if ( ownFillDir === 'x' ) {
329- pt0 [ 0 ] = pt1 [ 0 ] = xa . c2p ( 0 , true ) ;
330- }
331-
332- // fill to zero: full trace path, plus extension of
333- // the endpoints to the appropriate axis
334- // For the sake of animations, wrap the points around so that
335- // the points on the axes are the first two points. Otherwise
336- // animations get a little crazy if the number of points changes.
337- transition ( ownFillEl3 ) . attr ( 'd' , 'M' + pt1 + 'L' + pt0 + 'L' + fullpath . substr ( 1 ) ) ;
338- } else {
339- // fill to self: just join the path to itself
340- transition ( ownFillEl3 ) . attr ( 'd' , fullpath + 'Z' ) ;
328+ if ( segments . length ) {
329+ if ( ownFillEl3 ) {
330+ if ( pt0 && pt1 ) {
331+ if ( ownFillDir ) {
332+ if ( ownFillDir === 'y' ) {
333+ pt0 [ 1 ] = pt1 [ 1 ] = ya . c2p ( 0 , true ) ;
334+ }
335+ else if ( ownFillDir === 'x' ) {
336+ pt0 [ 0 ] = pt1 [ 0 ] = xa . c2p ( 0 , true ) ;
341337 }
338+
339+ // fill to zero: full trace path, plus extension of
340+ // the endpoints to the appropriate axis
341+ // For the sake of animations, wrap the points around so that
342+ // the points on the axes are the first two points. Otherwise
343+ // animations get a little crazy if the number of points changes.
344+ transition ( ownFillEl3 ) . attr ( 'd' , 'M' + pt1 + 'L' + pt0 + 'L' + fullpath . substr ( 1 ) ) ;
345+ } else {
346+ // fill to self: just join the path to itself
347+ transition ( ownFillEl3 ) . attr ( 'd' , fullpath + 'Z' ) ;
342348 }
343349 }
344- else if ( trace . fill . substr ( 0 , 6 ) === 'tonext' && fullpath && prevRevpath ) {
345- // fill to next: full trace path, plus the previous path reversed
346- if ( trace . fill === 'tonext' ) {
347- // tonext: for use by concentric shapes, like manually constructed
348- // contours, we just add the two paths closed on themselves.
349- // This makes strange results if one path is *not* entirely
350- // inside the other, but then that is a strange usage.
351- transition ( tonext ) . attr ( 'd' , fullpath + 'Z' + prevRevpath + 'Z' ) ;
352- }
353- else {
354- // tonextx/y: for now just connect endpoints with lines. This is
355- // the correct behavior if the endpoints are at the same value of
356- // y/x, but if they *aren't*, we should ideally do more complicated
357- // things depending on whether the new endpoint projects onto the
358- // existing curve or off the end of it
359- transition ( tonext ) . attr ( 'd' , fullpath + 'L' + prevRevpath . substr ( 1 ) + 'Z' ) ;
360- }
361- trace . _polygons = trace . _polygons . concat ( prevPolygons ) ;
350+ }
351+ else if ( trace . fill . substr ( 0 , 6 ) === 'tonext' && fullpath && prevRevpath ) {
352+ // fill to next: full trace path, plus the previous path reversed
353+ if ( trace . fill === 'tonext' ) {
354+ // tonext: for use by concentric shapes, like manually constructed
355+ // contours, we just add the two paths closed on themselves.
356+ // This makes strange results if one path is *not* entirely
357+ // inside the other, but then that is a strange usage.
358+ transition ( tonext ) . attr ( 'd' , fullpath + 'Z' + prevRevpath + 'Z' ) ;
359+ }
360+ else {
361+ // tonextx/y: for now just connect endpoints with lines. This is
362+ // the correct behavior if the endpoints are at the same value of
363+ // y/x, but if they *aren't*, we should ideally do more complicated
364+ // things depending on whether the new endpoint projects onto the
365+ // existing curve or off the end of it
366+ transition ( tonext ) . attr ( 'd' , fullpath + 'L' + prevRevpath . substr ( 1 ) + 'Z' ) ;
362367 }
363- trace . _prevRevpath = revpath ;
364- trace . _prevPolygons = thisPolygons ;
368+ trace . _polygons = trace . _polygons . concat ( prevPolygons ) ;
365369 }
370+ trace . _prevRevpath = revpath ;
371+ trace . _prevPolygons = thisPolygons ;
366372 }
367373
368374
0 commit comments