@@ -25,14 +25,14 @@ module.exports = function(gd, plotinfo, cdheatmaps) {
25
25
}
26
26
} ;
27
27
28
- // From http://www.xarg.org/2010/03/generate-client-side-png-files-using-javascript/
29
28
function plotOne ( gd , plotinfo , cd ) {
30
- var trace = cd [ 0 ] . trace ,
31
- uid = trace . uid ,
32
- xa = plotinfo . xaxis ,
33
- ya = plotinfo . yaxis ,
34
- fullLayout = gd . _fullLayout ,
35
- id = 'hm' + uid ;
29
+ var cd0 = cd [ 0 ] ;
30
+ var trace = cd0 . trace ;
31
+ var uid = trace . uid ;
32
+ var xa = plotinfo . xaxis ;
33
+ var ya = plotinfo . yaxis ;
34
+ var fullLayout = gd . _fullLayout ;
35
+ var id = 'hm' + uid ;
36
36
37
37
// in case this used to be a contour map
38
38
fullLayout . _paper . selectAll ( '.contour' + uid ) . remove ( ) ;
@@ -45,23 +45,21 @@ function plotOne(gd, plotinfo, cd) {
45
45
return ;
46
46
}
47
47
48
- var z = cd [ 0 ] . z ,
49
- x = cd [ 0 ] . x ,
50
- y = cd [ 0 ] . y ,
51
- isContour = Registry . traceIs ( trace , 'contour' ) ,
52
- zsmooth = isContour ? 'best' : trace . zsmooth ,
53
-
54
- // get z dims
55
- m = z . length ,
56
- n = maxRowLength ( z ) ,
57
- xrev = false ,
58
- left ,
59
- right ,
60
- temp ,
61
- yrev = false ,
62
- top ,
63
- bottom ,
64
- i ;
48
+ var z = cd0 . z ;
49
+ var x = cd0 . x ;
50
+ var y = cd0 . y ;
51
+ var xc = cd0 . xCenter ;
52
+ var yc = cd0 . yCenter ;
53
+ var isContour = Registry . traceIs ( trace , 'contour' ) ;
54
+ var zsmooth = isContour ? 'best' : trace . zsmooth ;
55
+
56
+ // get z dims
57
+ var m = z . length ;
58
+ var n = maxRowLength ( z ) ;
59
+ var xrev = false ;
60
+ var yrev = false ;
61
+
62
+ var left , right , temp , top , bottom , i ;
65
63
66
64
// TODO: if there are multiple overlapping categorical heatmaps,
67
65
// or if we allow category sorting, then the categories may not be
@@ -113,11 +111,10 @@ function plotOne(gd, plotinfo, cd) {
113
111
// for contours with heatmap fill, we generate the boundaries based on
114
112
// brick centers but then use the brick edges for drawing the bricks
115
113
if ( isContour ) {
116
- // TODO: for 'best' smoothing, we really should use the given brick
117
- // centers as well as brick bounds in calculating values, in case of
118
- // nonuniform brick sizes
119
- x = cd [ 0 ] . xfill ;
120
- y = cd [ 0 ] . yfill ;
114
+ xc = x ;
115
+ yc = y ;
116
+ x = cd0 . xfill ;
117
+ y = cd0 . yfill ;
121
118
}
122
119
123
120
// make an image that goes at most half a screen off either side, to keep
@@ -201,15 +198,15 @@ function plotOne(gd, plotinfo, cd) {
201
198
202
199
// get interpolated bin value. Returns {bin0:closest bin, frac:fractional dist to next, bin1:next bin}
203
200
function findInterp ( pixel , pixArray ) {
204
- var maxbin = pixArray . length - 2 ,
205
- bin = Lib . constrain ( Lib . findBin ( pixel , pixArray ) , 0 , maxbin ) ,
206
- pix0 = pixArray [ bin ] ,
207
- pix1 = pixArray [ bin + 1 ] ,
208
- interp = Lib . constrain ( bin + ( pixel - pix0 ) / ( pix1 - pix0 ) - 0.5 , 0 , maxbin ) ,
209
- bin0 = Math . round ( interp ) ,
210
- frac = Math . abs ( interp - bin0 ) ;
211
-
212
- if ( ! interp || interp === maxbin || ! frac ) {
201
+ var maxBin = pixArray . length - 2 ;
202
+ var bin = Lib . constrain ( Lib . findBin ( pixel , pixArray ) , 0 , maxBin ) ;
203
+ var pix0 = pixArray [ bin ] ;
204
+ var pix1 = pixArray [ bin + 1 ] ;
205
+ var interp = Lib . constrain ( bin + ( pixel - pix0 ) / ( pix1 - pix0 ) - 0.5 , 0 , maxBin ) ;
206
+ var bin0 = Math . round ( interp ) ;
207
+ var frac = Math . abs ( interp - bin0 ) ;
208
+
209
+ if ( ! interp || interp === maxBin || ! frac ) {
213
210
return {
214
211
bin0 : bin0 ,
215
212
bin1 : bin0 ,
@@ -223,6 +220,36 @@ function plotOne(gd, plotinfo, cd) {
223
220
} ;
224
221
}
225
222
223
+ function findInterpFromCenters ( pixel , centerPixArray ) {
224
+ // if(pixel <= centerPixArray[0]) return {bin0: 0, bin1: 0, frac: 0};
225
+ var maxBin = centerPixArray . length - 1 ;
226
+ // if(pixel >= centerPixArray[lastCenter]) return {bin0: lastCenter, bin1: lastCenter, frac: 0};
227
+
228
+ var bin = Lib . constrain ( Lib . findBin ( pixel , centerPixArray ) , 0 , maxBin ) ;
229
+ var pix0 = centerPixArray [ bin ] ;
230
+ var pix1 = centerPixArray [ bin + 1 ] ;
231
+ var frac = ( ( pixel - pix0 ) / ( pix1 - pix0 ) ) || 0 ;
232
+ if ( frac <= 0 ) {
233
+ return {
234
+ bin0 : bin ,
235
+ bin1 : bin ,
236
+ frac : 0
237
+ } ;
238
+ }
239
+ if ( frac < 0.5 ) {
240
+ return {
241
+ bin0 : bin ,
242
+ bin1 : bin + 1 ,
243
+ frac : frac
244
+ } ;
245
+ }
246
+ return {
247
+ bin0 : bin + 1 ,
248
+ bin1 : bin ,
249
+ frac : 1 - frac
250
+ } ;
251
+ }
252
+
226
253
// build the pixel map brick-by-brick
227
254
// cruise through z-matrix row-by-row
228
255
// build a brick at each z-matrix value
@@ -303,24 +330,26 @@ function plotOne(gd, plotinfo, cd) {
303
330
}
304
331
305
332
if ( zsmooth === 'best' ) {
306
- var xPixArray = new Array ( x . length ) ,
307
- yPixArray = new Array ( y . length ) ,
308
- xinterpArray = new Array ( imageWidth ) ,
309
- yinterp ,
310
- r0 ,
311
- r1 ;
333
+ var xForPx = xc || x ;
334
+ var yForPx = yc || y ;
335
+ var xPixArray = new Array ( xForPx . length ) ;
336
+ var yPixArray = new Array ( xForPx . length ) ;
337
+ var xinterpArray = new Array ( imageWidth ) ;
338
+ var findInterpX = xc ? findInterpFromCenters : findInterp ;
339
+ var findInterpY = yc ? findInterpFromCenters : findInterp ;
340
+ var yinterp , r0 , r1 ;
312
341
313
342
// first make arrays of x and y pixel locations of brick boundaries
314
- for ( i = 0 ; i < x . length ; i ++ ) xPixArray [ i ] = Math . round ( xa . c2p ( x [ i ] ) - left ) ;
315
- for ( i = 0 ; i < y . length ; i ++ ) yPixArray [ i ] = Math . round ( ya . c2p ( y [ i ] ) - top ) ;
343
+ for ( i = 0 ; i < xForPx . length ; i ++ ) xPixArray [ i ] = Math . round ( xa . c2p ( xForPx [ i ] ) - left ) ;
344
+ for ( i = 0 ; i < yForPx . length ; i ++ ) yPixArray [ i ] = Math . round ( ya . c2p ( yForPx [ i ] ) - top ) ;
316
345
317
346
// then make arrays of interpolations
318
347
// (bin0=closest, bin1=next, frac=fractional dist.)
319
- for ( i = 0 ; i < imageWidth ; i ++ ) xinterpArray [ i ] = findInterp ( i , xPixArray ) ;
348
+ for ( i = 0 ; i < imageWidth ; i ++ ) xinterpArray [ i ] = findInterpX ( i , xPixArray ) ;
320
349
321
350
// now do the interpolations and fill the png
322
351
for ( j = 0 ; j < imageHeight ; j ++ ) {
323
- yinterp = findInterp ( j , yPixArray ) ;
352
+ yinterp = findInterpY ( j , yPixArray ) ;
324
353
r0 = z [ yinterp . bin0 ] ;
325
354
r1 = z [ yinterp . bin1 ] ;
326
355
for ( i = 0 ; i < imageWidth ; i ++ , pxIndex += 4 ) {
0 commit comments