@@ -25,59 +25,81 @@ function SurfaceTrace(scene, surface, uid) {
25
25
this . surface = surface ;
26
26
this . data = null ;
27
27
this . showContour = [ false , false , false ] ;
28
+ this . minValues = [ Infinity , Infinity , Infinity ] ;
29
+ this . maxValues = [ - Infinity , - Infinity , - Infinity ] ;
30
+ this . midValues = [ 0 , 0 , 0 ] ;
28
31
this . dataScaleX = 1.0 ;
29
32
this . dataScaleY = 1.0 ;
30
- this . refineData = true ; // this could also be set by user...
33
+ this . refineData = true ;
31
34
}
32
35
33
36
var proto = SurfaceTrace . prototype ;
34
37
35
- proto . getXat = function ( a , b ) {
36
- return ( ! isArrayOrTypedArray ( this . data . x ) ) ?
37
- a :
38
- ( isArrayOrTypedArray ( this . data . x [ 0 ] ) ) ?
39
- this . data . x [ b ] [ a ] :
40
- this . data . x [ a ] ;
38
+ proto . getXat = function ( a , b , calendar , axis ) {
39
+ var v = (
40
+ ( ! isArrayOrTypedArray ( this . data . x ) ) ?
41
+ a :
42
+ ( isArrayOrTypedArray ( this . data . x [ 0 ] ) ) ?
43
+ this . data . x [ b ] [ a ] :
44
+ this . data . x [ a ]
45
+ ) ;
46
+
47
+ return ( calendar === undefined ) ? v : axis . d2l ( v , 0 , calendar ) ;
41
48
} ;
42
49
43
- proto . getYat = function ( a , b ) {
44
- return ( ! isArrayOrTypedArray ( this . data . y ) ) ?
45
- b :
46
- ( isArrayOrTypedArray ( this . data . y [ 0 ] ) ) ?
47
- this . data . y [ b ] [ a ] :
48
- this . data . y [ b ] ;
50
+ proto . getYat = function ( a , b , calendar , axis ) {
51
+ var v = (
52
+ ( ! isArrayOrTypedArray ( this . data . y ) ) ?
53
+ b :
54
+ ( isArrayOrTypedArray ( this . data . y [ 0 ] ) ) ?
55
+ this . data . y [ b ] [ a ] :
56
+ this . data . y [ b ]
57
+ ) ;
58
+
59
+ return ( calendar === undefined ) ? v : axis . d2l ( v , 0 , calendar ) ;
60
+ } ;
61
+
62
+ proto . getZat = function ( a , b , calendar , axis ) {
63
+ var v = (
64
+ this . data . z [ b ] [ a ]
65
+ ) ;
66
+
67
+ return ( calendar === undefined ) ? v : axis . d2l ( v , 0 , calendar ) ;
49
68
} ;
50
69
51
70
proto . handlePick = function ( selection ) {
52
71
if ( selection . object === this . surface ) {
53
- var selectIndex = selection . index = [
54
- Math . min (
55
- Math . floor ( selection . data . index [ 0 ] / this . dataScaleX - 1 ) ,
56
- this . data . z [ 0 ] . length - 1
57
- ) ,
58
- Math . min (
59
- Math . floor ( selection . data . index [ 1 ] / this . dataScaleY - 1 ) ,
60
- this . data . z . length - 1
61
- )
62
- ] ;
63
- var traceCoordinate = [ 0 , 0 , 0 ] ;
64
72
65
- traceCoordinate [ 0 ] = this . getXat ( selectIndex [ 0 ] , selectIndex [ 1 ] ) ;
66
- traceCoordinate [ 1 ] = this . getYat ( selectIndex [ 0 ] , selectIndex [ 1 ] ) ;
73
+ var xRatio = ( selection . data . index [ 0 ] - 1 ) / this . dataScaleX - 1 ;
74
+ var yRatio = ( selection . data . index [ 1 ] - 1 ) / this . dataScaleY - 1 ;
75
+
76
+ var j = Math . max ( Math . min ( Math . round ( xRatio ) , this . data . _xlength - 1 ) , 0 ) ;
77
+ var k = Math . max ( Math . min ( Math . round ( yRatio ) , this . data . _ylength - 1 ) , 0 ) ;
67
78
68
- traceCoordinate [ 2 ] = this . data . z [ selectIndex [ 1 ] ] [ selectIndex [ 0 ] ] ;
69
- selection . traceCoordinate = traceCoordinate ;
79
+ selection . index = [ j , k ] ;
80
+
81
+ selection . traceCoordinate = [
82
+ this . getXat ( j , k ) ,
83
+ this . getYat ( j , k ) ,
84
+ this . getZat ( j , k )
85
+ ] ;
70
86
71
- var sceneLayout = this . scene . fullSceneLayout ;
72
87
selection . dataCoordinate = [
73
- sceneLayout . xaxis . d2l ( traceCoordinate [ 0 ] , 0 , this . data . xcalendar ) * this . scene . dataScale [ 0 ] ,
74
- sceneLayout . yaxis . d2l ( traceCoordinate [ 1 ] , 0 , this . data . ycalendar ) * this . scene . dataScale [ 1 ] ,
75
- sceneLayout . zaxis . d2l ( traceCoordinate [ 2 ] , 0 , this . data . zcalendar ) * this . scene . dataScale [ 2 ]
88
+ this . getXat ( j , k , this . data . xcalendar , this . scene . fullSceneLayout . xaxis ) ,
89
+ this . getYat ( j , k , this . data . ycalendar , this . scene . fullSceneLayout . yaxis ) ,
90
+ this . getZat ( j , k , this . data . zcalendar , this . scene . fullSceneLayout . zaxis )
76
91
] ;
77
92
93
+ for ( var i = 0 ; i < 3 ; i ++ ) {
94
+ var v = selection . dataCoordinate [ i ] ;
95
+ if ( v !== null && v !== undefined ) {
96
+ selection . dataCoordinate [ i ] *= this . scene . dataScale [ i ] ;
97
+ }
98
+ }
99
+
78
100
var text = this . data . text ;
79
- if ( Array . isArray ( text ) && text [ selectIndex [ 1 ] ] && text [ selectIndex [ 1 ] ] [ selectIndex [ 0 ] ] !== undefined ) {
80
- selection . textLabel = text [ selectIndex [ 1 ] ] [ selectIndex [ 0 ] ] ;
101
+ if ( Array . isArray ( text ) && text [ k ] && text [ k ] [ j ] !== undefined ) {
102
+ selection . textLabel = text [ k ] [ j ] ;
81
103
} else if ( text ) {
82
104
selection . textLabel = text ;
83
105
} else {
@@ -318,28 +340,14 @@ proto.setContourLevels = function() {
318
340
} ;
319
341
320
342
proto . update = function ( data ) {
321
- var i ,
322
- scene = this . scene ,
343
+ var scene = this . scene ,
323
344
sceneLayout = scene . fullSceneLayout ,
324
345
surface = this . surface ,
325
346
alpha = data . opacity ,
326
347
colormap = parseColorScale ( data . colorscale , alpha ) ,
327
- z = data . z ,
328
- x = data . x ,
329
- y = data . y ,
330
- xaxis = sceneLayout . xaxis ,
331
- yaxis = sceneLayout . yaxis ,
332
- zaxis = sceneLayout . zaxis ,
333
348
scaleFactor = scene . dataScale ,
334
- xlen = z [ 0 ] . length ,
349
+ xlen = data . _xlength ,
335
350
ylen = data . _ylength ,
336
- coords = [
337
- ndarray ( new Float32Array ( xlen * ylen ) , [ xlen , ylen ] ) ,
338
- ndarray ( new Float32Array ( xlen * ylen ) , [ xlen , ylen ] ) ,
339
- ndarray ( new Float32Array ( xlen * ylen ) , [ xlen , ylen ] )
340
- ] ,
341
- xc = coords [ 0 ] ,
342
- yc = coords [ 1 ] ,
343
351
contourLevels = scene . contourLevels ;
344
352
345
353
// Save data
@@ -353,46 +361,87 @@ proto.update = function(data) {
353
361
* which is the transpose of 'gl-surface-plot'.
354
362
*/
355
363
356
- var xcalendar = data . xcalendar ,
357
- ycalendar = data . ycalendar ,
358
- zcalendar = data . zcalendar ;
364
+ var i , j , k , v ;
365
+ var rawCoords = [ ] ;
366
+ for ( i = 0 ; i < 3 ; i ++ ) {
367
+ rawCoords [ i ] = [ ] ;
368
+ for ( j = 0 ; j < xlen ; j ++ ) {
369
+ rawCoords [ i ] [ j ] = [ ] ;
370
+ /*
371
+ for(k = 0; k < ylen; k++) {
372
+ rawCoords[i][j][k] = undefined;
373
+ }
374
+ */
375
+ }
376
+ }
359
377
360
- fill ( coords [ 2 ] , function ( row , col ) {
361
- return zaxis . d2l ( z [ col ] [ row ] , 0 , zcalendar ) * scaleFactor [ 2 ] ;
362
- } ) ;
378
+ // coords x, y & z
379
+ for ( j = 0 ; j < xlen ; j ++ ) {
380
+ for ( k = 0 ; k < ylen ; k ++ ) {
381
+ rawCoords [ 0 ] [ j ] [ k ] = this . getXat ( j , k , data . xcalendar , sceneLayout . xaxis ) ;
382
+ rawCoords [ 1 ] [ j ] [ k ] = this . getYat ( j , k , data . ycalendar , sceneLayout . yaxis ) ;
383
+ rawCoords [ 2 ] [ j ] [ k ] = this . getZat ( j , k , data . zcalendar , sceneLayout . zaxis ) ;
384
+ }
385
+ }
363
386
364
- // coords x
365
- if ( ! isArrayOrTypedArray ( x ) ) {
366
- fill ( xc , function ( row ) {
367
- return xaxis . d2l ( row , 0 , xcalendar ) * scaleFactor [ 0 ] ;
368
- } ) ;
369
- } else if ( isArrayOrTypedArray ( x [ 0 ] ) ) {
370
- fill ( xc , function ( row , col ) {
371
- return xaxis . d2l ( x [ col ] [ row ] , 0 , xcalendar ) * scaleFactor [ 0 ] ;
372
- } ) ;
373
- } else {
374
- // ticks x
375
- fill ( xc , function ( row ) {
376
- return xaxis . d2l ( x [ row ] , 0 , xcalendar ) * scaleFactor [ 0 ] ;
377
- } ) ;
387
+ // Note: log axes are not defined in surfaces yet.
388
+ // but they could be defined here...
389
+
390
+ for ( i = 0 ; i < 3 ; i ++ ) {
391
+ for ( j = 0 ; j < xlen ; j ++ ) {
392
+ for ( k = 0 ; k < ylen ; k ++ ) {
393
+ v = rawCoords [ i ] [ j ] [ k ] ;
394
+ if ( v === null || v === undefined ) {
395
+ rawCoords [ i ] [ j ] [ k ] = NaN ;
396
+ } else {
397
+ v = rawCoords [ i ] [ j ] [ k ] *= scaleFactor [ i ] ;
398
+ }
399
+ }
400
+ }
378
401
}
379
402
380
- // coords y
381
- if ( ! isArrayOrTypedArray ( x ) ) {
382
- fill ( yc , function ( row , col ) {
383
- return yaxis . d2l ( col , 0 , xcalendar ) * scaleFactor [ 1 ] ;
384
- } ) ;
385
- } else if ( isArrayOrTypedArray ( y [ 0 ] ) ) {
386
- fill ( yc , function ( row , col ) {
387
- return yaxis . d2l ( y [ col ] [ row ] , 0 , ycalendar ) * scaleFactor [ 1 ] ;
388
- } ) ;
389
- } else {
390
- // ticks y
391
- fill ( yc , function ( row , col ) {
392
- return yaxis . d2l ( y [ col ] , 0 , ycalendar ) * scaleFactor [ 1 ] ;
393
- } ) ;
403
+ for ( i = 0 ; i < 3 ; i ++ ) {
404
+ for ( j = 0 ; j < xlen ; j ++ ) {
405
+ for ( k = 0 ; k < ylen ; k ++ ) {
406
+ v = rawCoords [ i ] [ j ] [ k ] ;
407
+ if ( v !== null && v !== undefined ) {
408
+ if ( this . minValues [ i ] > v ) {
409
+ this . minValues [ i ] = v ;
410
+ }
411
+ if ( this . maxValues [ i ] < v ) {
412
+ this . maxValues [ i ] = v ;
413
+ }
414
+ }
415
+ }
416
+ }
417
+ }
418
+
419
+ for ( i = 0 ; i < 3 ; i ++ ) {
420
+ data . _objectOffset [ i ] = this . midValues [ i ] = 0.5 * ( this . minValues [ i ] + this . maxValues [ i ] ) ;
421
+ }
422
+
423
+ for ( i = 0 ; i < 3 ; i ++ ) {
424
+ for ( j = 0 ; j < xlen ; j ++ ) {
425
+ for ( k = 0 ; k < ylen ; k ++ ) {
426
+ v = rawCoords [ i ] [ j ] [ k ] ;
427
+ if ( v !== null && v !== undefined ) {
428
+ rawCoords [ i ] [ j ] [ k ] -= this . midValues [ i ] ;
429
+ }
430
+ }
431
+ }
394
432
}
395
433
434
+ // convert processed raw data to Float32 matrices
435
+ var coords = [
436
+ ndarray ( new Float32Array ( xlen * ylen ) , [ xlen , ylen ] ) ,
437
+ ndarray ( new Float32Array ( xlen * ylen ) , [ xlen , ylen ] ) ,
438
+ ndarray ( new Float32Array ( xlen * ylen ) , [ xlen , ylen ] )
439
+ ] ;
440
+ fill ( coords [ 0 ] , function ( row , col ) { return rawCoords [ 0 ] [ row ] [ col ] ; } ) ;
441
+ fill ( coords [ 1 ] , function ( row , col ) { return rawCoords [ 1 ] [ row ] [ col ] ; } ) ;
442
+ fill ( coords [ 2 ] , function ( row , col ) { return rawCoords [ 2 ] [ row ] [ col ] ; } ) ;
443
+ rawCoords = [ ] ; // free memory
444
+
396
445
var params = {
397
446
colormap : colormap ,
398
447
levels : [ [ ] , [ ] , [ ] ] ,
@@ -491,8 +540,13 @@ proto.update = function(data) {
491
540
params . vertexColor = true ;
492
541
}
493
542
494
- params . coords = coords ;
543
+ params . objectOffset = [
544
+ data . _objectOffset [ 0 ] ,
545
+ data . _objectOffset [ 1 ] ,
546
+ data . _objectOffset [ 2 ]
547
+ ] ;
495
548
549
+ params . coords = coords ;
496
550
surface . update ( params ) ;
497
551
498
552
surface . visible = data . visible ;
0 commit comments