@@ -46,11 +46,17 @@ function LineWithMarkers(scene, uid) {
4646 this . hoverinfo = 'all' ;
4747 this . connectgaps = true ;
4848
49+ this . index = null ;
4950 this . idToIndex = [ ] ;
5051 this . bounds = [ 0 , 0 , 0 , 0 ] ;
5152
53+ this . isVisible = false ;
5254 this . hasLines = false ;
53- this . lineOptions = {
55+ this . hasErrorX = false ;
56+ this . hasErrorY = false ;
57+ this . hasMarkers = false ;
58+
59+ this . line = this . initObject ( createLine , {
5460 positions : new Float64Array ( 0 ) ,
5561 color : [ 0 , 0 , 0 , 1 ] ,
5662 width : 1 ,
@@ -60,35 +66,26 @@ function LineWithMarkers(scene, uid) {
6066 [ 0 , 0 , 0 , 1 ] ,
6167 [ 0 , 0 , 0 , 1 ] ,
6268 [ 0 , 0 , 0 , 1 ] ] ,
63- dashes : [ 1 ]
64- } ;
65- this . line = createLine ( scene . glplot , this . lineOptions ) ;
66- this . line . _trace = this ;
69+ dashes : [ 1 ] ,
70+ } , 0 ) ;
6771
68- this . hasErrorX = false ;
69- this . errorXOptions = {
72+ this . errorX = this . initObject ( createError , {
7073 positions : new Float64Array ( 0 ) ,
7174 errors : new Float64Array ( 0 ) ,
7275 lineWidth : 1 ,
7376 capSize : 0 ,
7477 color : [ 0 , 0 , 0 , 1 ]
75- } ;
76- this . errorX = createError ( scene . glplot , this . errorXOptions ) ;
77- this . errorX . _trace = this ;
78+ } , 1 ) ;
7879
79- this . hasErrorY = false ;
80- this . errorYOptions = {
80+ this . errorY = this . initObject ( createError , {
8181 positions : new Float64Array ( 0 ) ,
8282 errors : new Float64Array ( 0 ) ,
8383 lineWidth : 1 ,
8484 capSize : 0 ,
8585 color : [ 0 , 0 , 0 , 1 ]
86- } ;
87- this . errorY = createError ( scene . glplot , this . errorYOptions ) ;
88- this . errorY . _trace = this ;
86+ } , 2 ) ;
8987
90- this . hasMarkers = false ;
91- this . scatterOptions = {
88+ var scatterOptions0 = {
9289 positions : new Float64Array ( 0 ) ,
9390 sizes : [ ] ,
9491 colors : [ ] ,
@@ -100,16 +97,44 @@ function LineWithMarkers(scene, uid) {
10097 borderSize : 1 ,
10198 borderColor : [ 0 , 0 , 0 , 1 ]
10299 } ;
103- this . scatter = createScatter ( scene . glplot , this . scatterOptions ) ;
104- this . scatter . _trace = this ;
105- this . fancyScatter = createFancyScatter ( scene . glplot , this . scatterOptions ) ;
106- this . fancyScatter . _trace = this ;
107100
108- this . isVisible = false ;
101+ this . scatter = this . initObject ( createScatter , scatterOptions0 , 3 ) ;
102+ this . fancyScatter = this . initObject ( createFancyScatter , scatterOptions0 , 4 ) ;
109103}
110104
111105var proto = LineWithMarkers . prototype ;
112106
107+ proto . initObject = function ( createFn , options , objIndex ) {
108+ var _this = this ;
109+ var glplot = _this . scene . glplot ;
110+ var options0 = Lib . extendFlat ( { } , options ) ;
111+ var obj = null ;
112+
113+ function update ( ) {
114+ if ( ! obj ) {
115+ obj = createFn ( glplot , options ) ;
116+ obj . _trace = _this ;
117+ obj . _index = objIndex ;
118+ }
119+ obj . update ( options ) ;
120+ }
121+
122+ function clear ( ) {
123+ if ( obj ) obj . update ( options0 ) ;
124+ }
125+
126+ function dispose ( ) {
127+ if ( obj ) obj . dispose ( ) ;
128+ }
129+
130+ return {
131+ options : options ,
132+ update : update ,
133+ clear : clear ,
134+ dispose : dispose
135+ } ;
136+ } ;
137+
113138proto . handlePick = function ( pickResult ) {
114139 var index = pickResult . pointId ;
115140
@@ -226,13 +251,8 @@ function _convertColor(colors, opacities, count) {
226251 return result ;
227252}
228253
229- /* Order is important here to get the correct laying:
230- * - lines
231- * - errorX
232- * - errorY
233- * - markers
234- */
235254proto . update = function ( options ) {
255+
236256 if ( options . visible !== true ) {
237257 this . isVisible = false ;
238258 this . hasLines = false ;
@@ -255,7 +275,11 @@ proto.update = function(options) {
255275 this . connectgaps = ! ! options . connectgaps ;
256276
257277 if ( ! this . isVisible ) {
258- this . clear ( ) ;
278+ this . line . clear ( ) ;
279+ this . errorX . clear ( ) ;
280+ this . errorY . clear ( ) ;
281+ this . scatter . clear ( ) ;
282+ this . fancyScatter . clear ( ) ;
259283 }
260284 else if ( this . isFancy ( options ) ) {
261285 this . updateFancy ( options ) ;
@@ -264,6 +288,18 @@ proto.update = function(options) {
264288 this . updateFast ( options ) ;
265289 }
266290
291+ // sort objects so that order is preserve on updates:
292+ // - lines
293+ // - errorX
294+ // - errorY
295+ // - markers
296+ this . scene . glplot . objects . sort ( function ( a , b ) {
297+ return a . _index - b . _index ;
298+ } ) ;
299+
300+ // set trace index so that scene2d can sort object per traces
301+ this . index = options . index ;
302+
267303 // not quite on-par with 'scatter', but close enough for now
268304 // does not handle the colorscale case
269305 this . color = getTraceColor ( options , { } ) ;
@@ -292,22 +328,6 @@ function allFastTypesLikely(a) {
292328 return true ;
293329}
294330
295- proto . clear = function ( ) {
296- this . lineOptions . positions = new Float64Array ( 0 ) ;
297- this . line . update ( this . lineOptions ) ;
298-
299- this . errorXOptions . positions = new Float64Array ( 0 ) ;
300- this . errorX . update ( this . errorXOptions ) ;
301-
302- this . errorYOptions . positions = new Float64Array ( 0 ) ;
303- this . errorY . update ( this . errorYOptions ) ;
304-
305- this . scatterOptions . positions = new Float64Array ( 0 ) ;
306- this . scatterOptions . glyphs = [ ] ;
307- this . scatter . update ( this . scatterOptions ) ;
308- this . fancyScatter . update ( this . scatterOptions ) ;
309- } ;
310-
311331proto . updateFast = function ( options ) {
312332 var x = this . xData = this . pickXData = options . x ;
313333 var y = this . yData = this . pickYData = options . y ;
@@ -363,34 +383,30 @@ proto.updateFast = function(options) {
363383 var markerSize ;
364384
365385 if ( this . hasMarkers ) {
366- this . scatterOptions . positions = positions ;
386+ this . scatter . options . positions = positions ;
367387
368388 var markerColor = str2RGBArray ( options . marker . color ) ,
369389 borderColor = str2RGBArray ( options . marker . line . color ) ,
370390 opacity = ( options . opacity ) * ( options . marker . opacity ) ;
371391
372392 markerColor [ 3 ] *= opacity ;
373- this . scatterOptions . color = markerColor ;
393+ this . scatter . options . color = markerColor ;
374394
375395 borderColor [ 3 ] *= opacity ;
376- this . scatterOptions . borderColor = borderColor ;
396+ this . scatter . options . borderColor = borderColor ;
377397
378398 markerSize = options . marker . size ;
379- this . scatterOptions . size = markerSize ;
380- this . scatterOptions . borderSize = options . marker . line . width ;
399+ this . scatter . options . size = markerSize ;
400+ this . scatter . options . borderSize = options . marker . line . width ;
381401
382- this . scatter . update ( this . scatterOptions ) ;
402+ this . scatter . update ( ) ;
383403 }
384404 else {
385- this . scatterOptions . positions = new Float64Array ( 0 ) ;
386- this . scatterOptions . glyphs = [ ] ;
387- this . scatter . update ( this . scatterOptions ) ;
405+ this . scatter . clear ( ) ;
388406 }
389407
390408 // turn off fancy scatter plot
391- this . scatterOptions . positions = new Float64Array ( 0 ) ;
392- this . scatterOptions . glyphs = [ ] ;
393- this . fancyScatter . update ( this . scatterOptions ) ;
409+ this . fancyScatter . clear ( ) ;
394410
395411 // add item for autorange routine
396412 this . expandAxesFast ( bounds , markerSize ) ;
@@ -464,16 +480,16 @@ proto.updateFancy = function(options) {
464480 var sizes ;
465481
466482 if ( this . hasMarkers ) {
467- this . scatterOptions . positions = positions ;
483+ this . scatter . options . positions = positions ;
468484
469485 // TODO rewrite convert function so that
470486 // we don't have to loop through the data another time
471487
472- this . scatterOptions . sizes = new Array ( pId ) ;
473- this . scatterOptions . glyphs = new Array ( pId ) ;
474- this . scatterOptions . borderWidths = new Array ( pId ) ;
475- this . scatterOptions . colors = new Array ( pId * 4 ) ;
476- this . scatterOptions . borderColors = new Array ( pId * 4 ) ;
488+ this . scatter . options . sizes = new Array ( pId ) ;
489+ this . scatter . options . glyphs = new Array ( pId ) ;
490+ this . scatter . options . borderWidths = new Array ( pId ) ;
491+ this . scatter . options . colors = new Array ( pId * 4 ) ;
492+ this . scatter . options . borderColors = new Array ( pId * 4 ) ;
477493
478494 var markerSizeFunc = makeBubbleSizeFn ( options ) ,
479495 markerOpts = options . marker ,
@@ -490,28 +506,24 @@ proto.updateFancy = function(options) {
490506 for ( i = 0 ; i < pId ; ++ i ) {
491507 index = idToIndex [ i ] ;
492508
493- this . scatterOptions . sizes [ i ] = 4.0 * sizes [ index ] ;
494- this . scatterOptions . glyphs [ i ] = glyphs [ index ] ;
495- this . scatterOptions . borderWidths [ i ] = 0.5 * borderWidths [ index ] ;
509+ this . scatter . options . sizes [ i ] = 4.0 * sizes [ index ] ;
510+ this . scatter . options . glyphs [ i ] = glyphs [ index ] ;
511+ this . scatter . options . borderWidths [ i ] = 0.5 * borderWidths [ index ] ;
496512
497513 for ( j = 0 ; j < 4 ; ++ j ) {
498- this . scatterOptions . colors [ 4 * i + j ] = colors [ 4 * index + j ] ;
499- this . scatterOptions . borderColors [ 4 * i + j ] = borderColors [ 4 * index + j ] ;
514+ this . scatter . options . colors [ 4 * i + j ] = colors [ 4 * index + j ] ;
515+ this . scatter . options . borderColors [ 4 * i + j ] = borderColors [ 4 * index + j ] ;
500516 }
501517 }
502518
503- this . fancyScatter . update ( this . scatterOptions ) ;
519+ this . fancyScatter . update ( ) ;
504520 }
505521 else {
506- this . scatterOptions . positions = new Float64Array ( 0 ) ;
507- this . scatterOptions . glyphs = [ ] ;
508- this . fancyScatter . update ( this . scatterOptions ) ;
522+ this . fancyScatter . clear ( ) ;
509523 }
510524
511525 // turn off fast scatter plot
512- this . scatterOptions . positions = new Float64Array ( 0 ) ;
513- this . scatterOptions . glyphs = [ ] ;
514- this . scatter . update ( this . scatterOptions ) ;
526+ this . scatter . clear ( ) ;
515527
516528 // add item for autorange routine
517529 this . expandAxesFancy ( x , y , sizes ) ;
@@ -535,61 +547,60 @@ proto.updateLines = function(options, positions) {
535547 }
536548 }
537549
538- this . lineOptions . positions = linePositions ;
550+ this . line . options . positions = linePositions ;
539551
540552 var lineColor = convertColor ( options . line . color , options . opacity , 1 ) ,
541- lineWidth = Math . round ( 0.5 * this . lineOptions . width ) ,
553+ lineWidth = Math . round ( 0.5 * this . line . options . width ) ,
542554 dashes = ( DASHES [ options . line . dash ] || [ 1 ] ) . slice ( ) ;
543555
544556 for ( i = 0 ; i < dashes . length ; ++ i ) dashes [ i ] *= lineWidth ;
545557
546558 switch ( options . fill ) {
547559 case 'tozeroy' :
548- this . lineOptions . fill = [ false , true , false , false ] ;
560+ this . line . options . fill = [ false , true , false , false ] ;
549561 break ;
550562 case 'tozerox' :
551- this . lineOptions . fill = [ true , false , false , false ] ;
563+ this . line . options . fill = [ true , false , false , false ] ;
552564 break ;
553565 default :
554- this . lineOptions . fill = [ false , false , false , false ] ;
566+ this . line . options . fill = [ false , false , false , false ] ;
555567 break ;
556568 }
557569
558570 var fillColor = str2RGBArray ( options . fillcolor ) ;
559571
560- this . lineOptions . color = lineColor ;
561- this . lineOptions . width = 2.0 * options . line . width ;
562- this . lineOptions . dashes = dashes ;
563- this . lineOptions . fillColor = [ fillColor , fillColor , fillColor , fillColor ] ;
572+ this . line . options . color = lineColor ;
573+ this . line . options . width = 2.0 * options . line . width ;
574+ this . line . options . dashes = dashes ;
575+ this . line . options . fillColor = [ fillColor , fillColor , fillColor , fillColor ] ;
576+
577+ this . line . update ( ) ;
564578 }
565579 else {
566- this . lineOptions . positions = new Float64Array ( 0 ) ;
580+ this . line . clear ( ) ;
567581 }
568-
569- this . line . update ( this . lineOptions ) ;
570582} ;
571583
572584proto . updateError = function ( axLetter , options , positions , errors ) {
573585 var errorObj = this [ 'error' + axLetter ] ,
574- errorOptions = options [ 'error_' + axLetter . toLowerCase ( ) ] ,
575- errorObjOptions = this [ 'error' + axLetter + 'Options' ] ;
586+ errorOptions = options [ 'error_' + axLetter . toLowerCase ( ) ] ;
576587
577588 if ( axLetter . toLowerCase ( ) === 'x' && errorOptions . copy_ystyle ) {
578589 errorOptions = options . error_y ;
579590 }
580591
581592 if ( this [ 'hasError' + axLetter ] ) {
582- errorObjOptions . positions = positions ;
583- errorObjOptions . errors = errors ;
584- errorObjOptions . capSize = errorOptions . width ;
585- errorObjOptions . lineWidth = errorOptions . thickness / 2 ; // ballpark rescaling
586- errorObjOptions . color = convertColor ( errorOptions . color , 1 , 1 ) ;
593+ errorObj . options . positions = positions ;
594+ errorObj . options . errors = errors ;
595+ errorObj . options . capSize = errorOptions . width ;
596+ errorObj . options . lineWidth = errorOptions . thickness / 2 ; // ballpark rescaling
597+ errorObj . options . color = convertColor ( errorOptions . color , 1 , 1 ) ;
598+
599+ errorObj . update ( ) ;
587600 }
588601 else {
589- errorObjOptions . positions = new Float64Array ( 0 ) ;
602+ errorObj . clear ( ) ;
590603 }
591-
592- errorObj . update ( errorObjOptions ) ;
593604} ;
594605
595606proto . expandAxesFast = function ( bounds , markerSize ) {
0 commit comments