@@ -13,6 +13,8 @@ var d3 = require('d3');
1313
1414var Registry = require ( '../../registry' ) ;
1515var Lib = require ( '../../lib' ) ;
16+ var ensureSingle = Lib . ensureSingle ;
17+ var identity = Lib . identity ;
1618var Drawing = require ( '../../components/drawing' ) ;
1719
1820var subTypes = require ( './subtypes' ) ;
@@ -43,7 +45,7 @@ module.exports = function plot(gd, plotinfo, cdscatter, scatterLayer, transition
4345 // the z-order of fill layers is correct.
4446 linkTraces ( gd , plotinfo , cdscatter ) ;
4547
46- createFills ( gd , scatterLayer , plotinfo ) ;
48+ createFills ( gd , join , plotinfo ) ;
4749
4850 // Sort the traces, once created, so that the ordering is preserved even when traces
4951 // are shown and hidden. This is needed since we're not just wiping everything out
@@ -52,10 +54,10 @@ module.exports = function plot(gd, plotinfo, cdscatter, scatterLayer, transition
5254 uids [ cdscatter [ i ] [ 0 ] . trace . uid ] = i ;
5355 }
5456
55- scatterLayer . selectAll ( 'g.trace' ) . sort ( function ( a , b ) {
57+ join . sort ( function ( a , b ) {
5658 var idx1 = uids [ a [ 0 ] . trace . uid ] ;
5759 var idx2 = uids [ b [ 0 ] . trace . uid ] ;
58- return idx1 > idx2 ? 1 : - 1 ;
60+ return idx1 - idx2 ;
5961 } ) ;
6062
6163 if ( hasTransition ) {
@@ -97,51 +99,45 @@ module.exports = function plot(gd, plotinfo, cdscatter, scatterLayer, transition
9799 scatterLayer . selectAll ( 'path:not([d])' ) . remove ( ) ;
98100} ;
99101
100- function createFills ( gd , scatterLayer , plotinfo ) {
101- var trace ;
102+ function createFills ( gd , traceJoin , plotinfo ) {
103+ traceJoin . each ( function ( d ) {
104+ var fills = ensureSingle ( d3 . select ( this ) , 'g' , 'fills' ) ;
105+ Drawing . setClipUrl ( fills , plotinfo . layerClipId ) ;
102106
103- scatterLayer . selectAll ( 'g.trace' ) . each ( function ( d ) {
104- var tr = d3 . select ( this ) ;
105-
106- // Loop only over the traces being redrawn:
107- trace = d [ 0 ] . trace ;
107+ var trace = d [ 0 ] . trace ;
108108
109- // make the fill-to-next path now for the NEXT trace, so it shows
110- // behind both lines.
109+ var fillData = [ ] ;
110+ if ( trace . fill && ( trace . fill . substr ( 0 , 6 ) === 'tozero' || trace . fill === 'toself' ||
111+ ( trace . fill . substr ( 0 , 2 ) === 'to' && ! trace . _prevtrace ) )
112+ ) {
113+ fillData = [ '_ownFill' ] ;
114+ }
111115 if ( trace . _nexttrace ) {
112- trace . _nextFill = tr . select ( '.js-fill.js-tonext' ) ;
113- if ( ! trace . _nextFill . size ( ) ) {
116+ // make the fill-to-next path now for the NEXT trace, so it shows
117+ // behind both lines.
118+ fillData . push ( '_nextFill' ) ;
119+ }
114120
115- // If there is an existing tozero fill, we must insert this *after* that fill:
116- var loc = ':first-child' ;
117- if ( tr . select ( '.js-fill.js-tozero' ) . size ( ) ) {
118- loc += ' + *' ;
119- }
121+ var fillJoin = fills . selectAll ( 'g' )
122+ . data ( fillData , identity ) ;
120123
121- trace . _nextFill = tr . insert ( 'path' , loc ) . attr ( 'class' , 'js-fill js-tonext' ) ;
122- }
123- } else {
124- tr . selectAll ( '.js-fill.js-tonext' ) . remove ( ) ;
125- trace . _nextFill = null ;
126- }
124+ fillJoin . enter ( ) . append ( 'g' ) ;
127125
128- if ( trace . fill && ( trace . fill . substr ( 0 , 6 ) === 'tozero' || trace . fill === 'toself' ||
129- ( trace . fill . substr ( 0 , 2 ) === 'to' && ! trace . _prevtrace ) ) ) {
130- trace . _ownFill = tr . select ( '.js-fill.js-tozero' ) ;
131- if ( ! trace . _ownFill . size ( ) ) {
132- trace . _ownFill = tr . insert ( 'path' , ':first-child' ) . attr ( 'class' , 'js-fill js-tozero' ) ;
133- }
134- } else {
135- tr . selectAll ( '.js-fill.js-tozero' ) . remove ( ) ;
136- trace . _ownFill = null ;
137- }
126+ fillJoin . exit ( )
127+ . each ( function ( d ) { trace [ d ] = null ; } )
128+ . remove ( ) ;
138129
139- tr . selectAll ( '.js-fill' ) . call ( Drawing . setClipUrl , plotinfo . layerClipId ) ;
130+ fillJoin . order ( ) . each ( function ( d ) {
131+ // make a path element inside the fill group, just so
132+ // we can give it its own data later on and the group can
133+ // keep its simple '_*Fill' data
134+ trace [ d ] = ensureSingle ( d3 . select ( this ) , 'path' , 'js-fill' ) ;
135+ } ) ;
140136 } ) ;
141137}
142138
143139function plotOne ( gd , idx , plotinfo , cdscatter , cdscatterAll , element , transitionOpts ) {
144- var join , i ;
140+ var i ;
145141
146142 // Since this has been reorganized and we're executing this on individual traces,
147143 // we need to pass it the full list of cdscatter as well as this trace's index (idx)
@@ -157,12 +153,17 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
157153 var xa = plotinfo . xaxis ,
158154 ya = plotinfo . yaxis ;
159155
160- var trace = cdscatter [ 0 ] . trace ,
161- line = trace . line ,
162- tr = d3 . select ( element ) ;
156+ var trace = cdscatter [ 0 ] . trace ;
157+ var line = trace . line ;
158+ var tr = d3 . select ( element ) ;
159+
160+ var errorBarGroup = ensureSingle ( tr , 'g' , 'errorbars' ) ;
161+ var lines = ensureSingle ( tr , 'g' , 'lines' ) ;
162+ var points = ensureSingle ( tr , 'g' , 'points' ) ;
163+ var text = ensureSingle ( tr , 'g' , 'text' ) ;
163164
164165 // error bars are at the bottom
165- Registry . getComponentMethod ( 'errorbars' , 'plot' ) ( tr , plotinfo , transitionOpts ) ;
166+ Registry . getComponentMethod ( 'errorbars' , 'plot' ) ( errorBarGroup , plotinfo , transitionOpts ) ;
166167
167168 if ( trace . visible !== true ) return ;
168169
@@ -303,7 +304,7 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
303304 } ;
304305 }
305306
306- var lineJoin = tr . selectAll ( '.js-line' ) . data ( segments ) ;
307+ var lineJoin = lines . selectAll ( '.js-line' ) . data ( segments ) ;
307308
308309 transition ( lineJoin . exit ( ) )
309310 . style ( 'opacity' , 0 )
@@ -325,6 +326,7 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
325326
326327 if ( segments . length ) {
327328 if ( ownFillEl3 ) {
329+ ownFillEl3 . datum ( cdscatter ) ;
328330 if ( pt0 && pt1 ) {
329331 if ( ownFillDir ) {
330332 if ( ownFillDir === 'y' ) {
@@ -412,11 +414,10 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
412414 return false ;
413415 }
414416
415- function makePoints ( d ) {
417+ function makePoints ( points , text , cdscatter ) {
416418 var join , selection , hasNode ;
417419
418- var trace = d [ 0 ] . trace ;
419- var s = d3 . select ( this ) ;
420+ var trace = cdscatter [ 0 ] . trace ;
420421 var showMarkers = subTypes . hasMarkers ( trace ) ;
421422 var showText = subTypes . hasText ( trace ) ;
422423
@@ -425,7 +426,7 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
425426 var textFilter = hideFilter ;
426427
427428 if ( showMarkers || showText ) {
428- var showFilter = Lib . identity ;
429+ var showFilter = identity ;
429430 // if we're stacking, "infer zero" gap mode gets markers in the
430431 // gap points - because we've inferred a zero there - but other
431432 // modes (currently "interpolate", later "interrupt" hopefully)
@@ -446,7 +447,7 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
446447
447448 // marker points
448449
449- selection = s . selectAll ( 'path.point' ) ;
450+ selection = points . selectAll ( 'path.point' ) ;
450451
451452 join = selection . data ( markerFilter , keyFunc ) ;
452453
@@ -498,7 +499,7 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
498499 }
499500
500501 // text points
501- selection = s . selectAll ( 'g' ) ;
502+ selection = text . selectAll ( 'g' ) ;
502503 join = selection . data ( textFilter , keyFunc ) ;
503504
504505 // each text needs to go in its own 'g' in case
@@ -537,28 +538,16 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
537538 join . exit ( ) . remove ( ) ;
538539 }
539540
540- // NB: selectAll is evaluated on instantiation:
541- var pointSelection = tr . selectAll ( '.points' ) ;
542-
543- // Join with new data
544- join = pointSelection . data ( [ cdscatter ] ) ;
545-
546- // Transition existing, but don't defer this to an async .transition since
547- // there's no timing involved:
548- pointSelection . each ( makePoints ) ;
549-
550- join . enter ( ) . append ( 'g' )
551- . classed ( 'points' , true )
552- . each ( makePoints ) ;
553-
554- join . exit ( ) . remove ( ) ;
541+ points . datum ( cdscatter ) ;
542+ text . datum ( cdscatter ) ;
543+ makePoints ( points , text , cdscatter ) ;
555544
556545 // lastly, clip points groups of `cliponaxis !== false` traces
557546 // on `plotinfo._hasClipOnAxisFalse === true` subplots
558- join . each ( function ( d ) {
559- var hasClipOnAxisFalse = d [ 0 ] . trace . cliponaxis === false ;
560- Drawing . setClipUrl ( d3 . select ( this ) , hasClipOnAxisFalse ? null : plotinfo . layerClipId ) ;
561- } ) ;
547+ var hasClipOnAxisFalse = trace . cliponaxis === false ;
548+ var clipUrl = hasClipOnAxisFalse ? null : plotinfo . layerClipId ;
549+ Drawing . setClipUrl ( points , clipUrl ) ;
550+ Drawing . setClipUrl ( text , clipUrl ) ;
562551}
563552
564553function selectMarkers ( gd , idx , plotinfo , cdscatter , cdscatterAll ) {
0 commit comments