@@ -46,11 +46,17 @@ function LineWithMarkers(scene, uid) {
46
46
this . hoverinfo = 'all' ;
47
47
this . connectgaps = true ;
48
48
49
+ this . index = null ;
49
50
this . idToIndex = [ ] ;
50
51
this . bounds = [ 0 , 0 , 0 , 0 ] ;
51
52
53
+ this . isVisible = false ;
52
54
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 , {
54
60
positions : new Float64Array ( 0 ) ,
55
61
color : [ 0 , 0 , 0 , 1 ] ,
56
62
width : 1 ,
@@ -60,35 +66,26 @@ function LineWithMarkers(scene, uid) {
60
66
[ 0 , 0 , 0 , 1 ] ,
61
67
[ 0 , 0 , 0 , 1 ] ,
62
68
[ 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 ) ;
67
71
68
- this . hasErrorX = false ;
69
- this . errorXOptions = {
72
+ this . errorX = this . initObject ( createError , {
70
73
positions : new Float64Array ( 0 ) ,
71
74
errors : new Float64Array ( 0 ) ,
72
75
lineWidth : 1 ,
73
76
capSize : 0 ,
74
77
color : [ 0 , 0 , 0 , 1 ]
75
- } ;
76
- this . errorX = createError ( scene . glplot , this . errorXOptions ) ;
77
- this . errorX . _trace = this ;
78
+ } , 1 ) ;
78
79
79
- this . hasErrorY = false ;
80
- this . errorYOptions = {
80
+ this . errorY = this . initObject ( createError , {
81
81
positions : new Float64Array ( 0 ) ,
82
82
errors : new Float64Array ( 0 ) ,
83
83
lineWidth : 1 ,
84
84
capSize : 0 ,
85
85
color : [ 0 , 0 , 0 , 1 ]
86
- } ;
87
- this . errorY = createError ( scene . glplot , this . errorYOptions ) ;
88
- this . errorY . _trace = this ;
86
+ } , 2 ) ;
89
87
90
- this . hasMarkers = false ;
91
- this . scatterOptions = {
88
+ var scatterOptions0 = {
92
89
positions : new Float64Array ( 0 ) ,
93
90
sizes : [ ] ,
94
91
colors : [ ] ,
@@ -100,16 +97,44 @@ function LineWithMarkers(scene, uid) {
100
97
borderSize : 1 ,
101
98
borderColor : [ 0 , 0 , 0 , 1 ]
102
99
} ;
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 ;
107
100
108
- this . isVisible = false ;
101
+ this . scatter = this . initObject ( createScatter , scatterOptions0 , 3 ) ;
102
+ this . fancyScatter = this . initObject ( createFancyScatter , scatterOptions0 , 4 ) ;
109
103
}
110
104
111
105
var proto = LineWithMarkers . prototype ;
112
106
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
+
113
138
proto . handlePick = function ( pickResult ) {
114
139
var index = pickResult . pointId ;
115
140
@@ -226,13 +251,8 @@ function _convertColor(colors, opacities, count) {
226
251
return result ;
227
252
}
228
253
229
- /* Order is important here to get the correct laying:
230
- * - lines
231
- * - errorX
232
- * - errorY
233
- * - markers
234
- */
235
254
proto . update = function ( options ) {
255
+
236
256
if ( options . visible !== true ) {
237
257
this . isVisible = false ;
238
258
this . hasLines = false ;
@@ -255,7 +275,11 @@ proto.update = function(options) {
255
275
this . connectgaps = ! ! options . connectgaps ;
256
276
257
277
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 ( ) ;
259
283
}
260
284
else if ( this . isFancy ( options ) ) {
261
285
this . updateFancy ( options ) ;
@@ -264,6 +288,18 @@ proto.update = function(options) {
264
288
this . updateFast ( options ) ;
265
289
}
266
290
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
+
267
303
// not quite on-par with 'scatter', but close enough for now
268
304
// does not handle the colorscale case
269
305
this . color = getTraceColor ( options , { } ) ;
@@ -292,22 +328,6 @@ function allFastTypesLikely(a) {
292
328
return true ;
293
329
}
294
330
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
-
311
331
proto . updateFast = function ( options ) {
312
332
var x = this . xData = this . pickXData = options . x ;
313
333
var y = this . yData = this . pickYData = options . y ;
@@ -363,34 +383,30 @@ proto.updateFast = function(options) {
363
383
var markerSize ;
364
384
365
385
if ( this . hasMarkers ) {
366
- this . scatterOptions . positions = positions ;
386
+ this . scatter . options . positions = positions ;
367
387
368
388
var markerColor = str2RGBArray ( options . marker . color ) ,
369
389
borderColor = str2RGBArray ( options . marker . line . color ) ,
370
390
opacity = ( options . opacity ) * ( options . marker . opacity ) ;
371
391
372
392
markerColor [ 3 ] *= opacity ;
373
- this . scatterOptions . color = markerColor ;
393
+ this . scatter . options . color = markerColor ;
374
394
375
395
borderColor [ 3 ] *= opacity ;
376
- this . scatterOptions . borderColor = borderColor ;
396
+ this . scatter . options . borderColor = borderColor ;
377
397
378
398
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 ;
381
401
382
- this . scatter . update ( this . scatterOptions ) ;
402
+ this . scatter . update ( ) ;
383
403
}
384
404
else {
385
- this . scatterOptions . positions = new Float64Array ( 0 ) ;
386
- this . scatterOptions . glyphs = [ ] ;
387
- this . scatter . update ( this . scatterOptions ) ;
405
+ this . scatter . clear ( ) ;
388
406
}
389
407
390
408
// 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 ( ) ;
394
410
395
411
// add item for autorange routine
396
412
this . expandAxesFast ( bounds , markerSize ) ;
@@ -464,16 +480,16 @@ proto.updateFancy = function(options) {
464
480
var sizes ;
465
481
466
482
if ( this . hasMarkers ) {
467
- this . scatterOptions . positions = positions ;
483
+ this . scatter . options . positions = positions ;
468
484
469
485
// TODO rewrite convert function so that
470
486
// we don't have to loop through the data another time
471
487
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 ) ;
477
493
478
494
var markerSizeFunc = makeBubbleSizeFn ( options ) ,
479
495
markerOpts = options . marker ,
@@ -490,28 +506,24 @@ proto.updateFancy = function(options) {
490
506
for ( i = 0 ; i < pId ; ++ i ) {
491
507
index = idToIndex [ i ] ;
492
508
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 ] ;
496
512
497
513
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 ] ;
500
516
}
501
517
}
502
518
503
- this . fancyScatter . update ( this . scatterOptions ) ;
519
+ this . fancyScatter . update ( ) ;
504
520
}
505
521
else {
506
- this . scatterOptions . positions = new Float64Array ( 0 ) ;
507
- this . scatterOptions . glyphs = [ ] ;
508
- this . fancyScatter . update ( this . scatterOptions ) ;
522
+ this . fancyScatter . clear ( ) ;
509
523
}
510
524
511
525
// 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 ( ) ;
515
527
516
528
// add item for autorange routine
517
529
this . expandAxesFancy ( x , y , sizes ) ;
@@ -535,61 +547,60 @@ proto.updateLines = function(options, positions) {
535
547
}
536
548
}
537
549
538
- this . lineOptions . positions = linePositions ;
550
+ this . line . options . positions = linePositions ;
539
551
540
552
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 ) ,
542
554
dashes = ( DASHES [ options . line . dash ] || [ 1 ] ) . slice ( ) ;
543
555
544
556
for ( i = 0 ; i < dashes . length ; ++ i ) dashes [ i ] *= lineWidth ;
545
557
546
558
switch ( options . fill ) {
547
559
case 'tozeroy' :
548
- this . lineOptions . fill = [ false , true , false , false ] ;
560
+ this . line . options . fill = [ false , true , false , false ] ;
549
561
break ;
550
562
case 'tozerox' :
551
- this . lineOptions . fill = [ true , false , false , false ] ;
563
+ this . line . options . fill = [ true , false , false , false ] ;
552
564
break ;
553
565
default :
554
- this . lineOptions . fill = [ false , false , false , false ] ;
566
+ this . line . options . fill = [ false , false , false , false ] ;
555
567
break ;
556
568
}
557
569
558
570
var fillColor = str2RGBArray ( options . fillcolor ) ;
559
571
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 ( ) ;
564
578
}
565
579
else {
566
- this . lineOptions . positions = new Float64Array ( 0 ) ;
580
+ this . line . clear ( ) ;
567
581
}
568
-
569
- this . line . update ( this . lineOptions ) ;
570
582
} ;
571
583
572
584
proto . updateError = function ( axLetter , options , positions , errors ) {
573
585
var errorObj = this [ 'error' + axLetter ] ,
574
- errorOptions = options [ 'error_' + axLetter . toLowerCase ( ) ] ,
575
- errorObjOptions = this [ 'error' + axLetter + 'Options' ] ;
586
+ errorOptions = options [ 'error_' + axLetter . toLowerCase ( ) ] ;
576
587
577
588
if ( axLetter . toLowerCase ( ) === 'x' && errorOptions . copy_ystyle ) {
578
589
errorOptions = options . error_y ;
579
590
}
580
591
581
592
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 ( ) ;
587
600
}
588
601
else {
589
- errorObjOptions . positions = new Float64Array ( 0 ) ;
602
+ errorObj . clear ( ) ;
590
603
}
591
-
592
- errorObj . update ( errorObjOptions ) ;
593
604
} ;
594
605
595
606
proto . expandAxesFast = function ( bounds , markerSize ) {
0 commit comments