@@ -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
@@ -381,64 +387,78 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
381387        } 
382388    } 
383389
390+     function  hideFilter ( )  { 
391+         return  false ; 
392+     } 
393+ 
384394    function  makePoints ( d )  { 
385395        var  join ,  selection ; 
396+ 
386397        var  trace  =  d [ 0 ] . trace , 
387398            s  =  d3 . select ( this ) , 
388399            showMarkers  =  subTypes . hasMarkers ( trace ) , 
389400            showText  =  subTypes . hasText ( trace ) ; 
390401
391-         if ( ( ! showMarkers  &&  ! showText )  ||  trace . visible  !==  true )  s . remove ( ) ; 
392-         else  { 
393-             if ( showMarkers )  { 
394-                 selection  =  s . selectAll ( 'path.point' ) ; 
402+         var  keyFunc  =  getKeyFunc ( trace ) , 
403+             markerFilter  =  hideFilter , 
404+             textFilter  =  hideFilter ; 
395405
396-                 join  =  selection 
397-                     . data ( trace . marker . maxdisplayed  ? visFilter  : Lib . identity ,  getKeyFunc ( trace ) ) ; 
406+         if ( showMarkers )  { 
407+             markerFilter  =  trace . marker . maxdisplayed  ? visFilter  : Lib . identity ; 
408+         } 
398409
399-                 var  enter  =  join . enter ( ) . append ( 'path' ) 
400-                     . classed ( 'point' ,  true ) ; 
410+         if ( showText )  { 
411+             textFilter  =  trace . marker . maxdisplayed  ? visFilter  : Lib . identity ; 
412+         } 
401413
402-                 enter . call ( Drawing . pointStyle ,  trace ) 
403-                     . call ( Drawing . translatePoints ,  xa ,  ya ,  trace ) ; 
414+         // marker points 
404415
405-                 if ( hasTransition )  { 
406-                     enter . style ( 'opacity' ,  0 ) . transition ( ) 
407-                         . style ( 'opacity' ,  1 ) ; 
408-                 } 
416+         selection  =  s . selectAll ( 'path.point' ) ; 
409417
410-                 join . each ( function ( d )  { 
411-                     var  sel  =  transition ( d3 . select ( this ) ) ; 
412-                     Drawing . translatePoint ( d ,  sel ,  xa ,  ya ) ; 
413-                     Drawing . singlePointStyle ( d ,  sel ,  trace ) ; 
414-                 } ) ; 
418+         join  =  selection . data ( markerFilter ,  keyFunc ) ; 
415419
416-                 if ( hasTransition )  { 
417-                     join . exit ( ) . transition ( ) 
418-                         . style ( 'opacity' ,  0 ) 
419-                         . remove ( ) ; 
420-                 }  else  { 
421-                     join . exit ( ) . remove ( ) ; 
422-                 } 
423-             } 
424-             if ( showText )  { 
425-                 selection  =  s . selectAll ( 'g' ) ; 
420+         var  enter  =  join . enter ( ) . append ( 'path' ) 
421+             . classed ( 'point' ,  true ) ; 
426422
427-                  join   =   selection 
428-                      . data ( trace . marker . maxdisplayed  ?  visFilter  :  Lib . identity ) ; 
423+         enter . call ( Drawing . pointStyle ,   trace ) 
424+             . call ( Drawing . translatePoints ,   xa ,   ya ,   trace ) ; 
429425
430-                     // each text needs to go in its own 'g' in case 
431-                     // it gets converted to mathjax 
432-                 join . enter ( ) . append ( 'g' ) 
433-                     . append ( 'text' ) 
434-                     . call ( Drawing . translatePoints ,  xa ,  ya ) ; 
426+         if ( hasTransition )  { 
427+             enter . style ( 'opacity' ,  0 ) . transition ( ) 
428+                 . style ( 'opacity' ,  1 ) ; 
429+         } 
435430
436-                 selection 
437-                     . call ( Drawing . translatePoints ,  xa ,  ya ) ; 
431+         join . each ( function ( d )  { 
432+             var  sel  =  transition ( d3 . select ( this ) ) ; 
433+             Drawing . translatePoint ( d ,  sel ,  xa ,  ya ) ; 
434+             Drawing . singlePointStyle ( d ,  sel ,  trace ) ; 
435+         } ) ; 
438436
439-                 join . exit ( ) . remove ( ) ; 
440-             } 
437+         if ( hasTransition )  { 
438+             join . exit ( ) . transition ( ) 
439+                 . style ( 'opacity' ,  0 ) 
440+                 . remove ( ) ; 
441+         }  else  { 
442+             join . exit ( ) . remove ( ) ; 
441443        } 
444+ 
445+         // text points 
446+ 
447+         selection  =  s . selectAll ( 'g' ) ; 
448+ 
449+         join  =  selection . data ( textFilter ,  keyFunc ) ; 
450+ 
451+         // each text needs to go in its own 'g' in case 
452+         // it gets converted to mathjax 
453+         join . enter ( ) . append ( 'g' ) 
454+             . append ( 'text' ) ; 
455+ 
456+         join . each ( function ( d )  { 
457+             var  sel  =  d3 . select ( this ) . select ( 'text' ) ; 
458+             Drawing . translatePoint ( d ,  sel ,  xa ,  ya ) ; 
459+         } ) ; 
460+ 
461+         join . exit ( ) . remove ( ) ; 
442462    } 
443463
444464    // NB: selectAll is evaluated on instantiation: 
0 commit comments