6
6
* LICENSE file in the root directory of this source tree.
7
7
*/
8
8
9
-
10
9
'use strict' ;
11
10
12
11
var isNumeric = require ( 'fast-isnumeric' ) ;
13
12
14
13
var Lib = require ( '../../lib' ) ;
14
+ var Registry = require ( '../../registry' ) ;
15
15
var Axes = require ( '../../plots/cartesian/axes' ) ;
16
16
17
17
var arraysToCalcdata = require ( '../bar/arrays_to_calcdata' ) ;
@@ -20,16 +20,10 @@ var normFunctions = require('./norm_functions');
20
20
var doAvg = require ( './average' ) ;
21
21
var getBinSpanLabelRound = require ( './bin_label_vals' ) ;
22
22
23
- module . exports = function calc ( gd , trace ) {
24
- // ignore as much processing as possible (and including in autorange) if not visible
25
- if ( trace . visible !== true ) return ;
26
-
27
- // depending on orientation, set position and size axes and data ranges
28
- // note: this logic for choosing orientation is duplicated in graph_obj->setstyles
23
+ function calc ( gd , trace ) {
29
24
var pos = [ ] ;
30
25
var size = [ ] ;
31
- var pa = Axes . getFromId ( gd , trace . orientation === 'h' ?
32
- ( trace . yaxis || 'y' ) : ( trace . xaxis || 'x' ) ) ;
26
+ var pa = Axes . getFromId ( gd , trace . orientation === 'h' ? trace . yaxis : trace . xaxis ) ;
33
27
var mainData = trace . orientation === 'h' ? 'y' : 'x' ;
34
28
var counterData = { x : 'y' , y : 'x' } [ mainData ] ;
35
29
var calendar = trace [ mainData + 'calendar' ] ;
@@ -143,7 +137,6 @@ module.exports = function calc(gd, trace) {
143
137
// after all normalization etc, now we can accumulate if desired
144
138
if ( cumulativeSpec . enabled ) cdf ( size , cumulativeSpec . direction , cumulativeSpec . currentbin ) ;
145
139
146
-
147
140
var seriesLen = Math . min ( pos . length , size . length ) ;
148
141
var cd = [ ] ;
149
142
var firstNonzero = 0 ;
@@ -201,23 +194,30 @@ module.exports = function calc(gd, trace) {
201
194
}
202
195
203
196
return cd ;
204
- } ;
197
+ }
205
198
206
199
/*
207
- * calcAllAutoBins: we want all histograms on the same axes to share bin specs
208
- * if they're grouped or stacked. If the user has explicitly specified differing
200
+ * calcAllAutoBins: we want all histograms inside the same bingroup
201
+ * (see logic in Histogram.crossTraceDefaults) to share bin specs
202
+ *
203
+ * If the user has explicitly specified differing
209
204
* bin specs, there's nothing we can do, but if possible we will try to use the
210
- * smallest bins of any of the auto values for all histograms grouped/stacked
211
- * together .
205
+ * smallest bins of any of the auto values for all histograms inside the same
206
+ * bingroup .
212
207
*/
213
208
function calcAllAutoBins ( gd , trace , pa , mainData , _overlayEdgeCase ) {
214
209
var binAttr = mainData + 'bins' ;
215
210
var fullLayout = gd . _fullLayout ;
211
+ var groupName = trace [ '_' + mainData + 'bingroup' ] ;
212
+ var binOpts = fullLayout . _histogramBinOpts [ groupName ] ;
216
213
var isOverlay = fullLayout . barmode === 'overlay' ;
217
214
var i , traces , tracei , calendar , pos0 , autoVals , cumulativeSpec ;
218
215
219
- var cleanBound = ( pa . type === 'date' ) ?
220
- function ( v ) { return ( v || v === 0 ) ? Lib . cleanDate ( v , null , pa . calendar ) : null ; } :
216
+ var r2c = function ( v ) { return pa . r2c ( v , 0 , calendar ) ; } ;
217
+ var c2r = function ( v ) { return pa . c2r ( v , 0 , calendar ) ; } ;
218
+
219
+ var cleanBound = pa . type === 'date' ?
220
+ function ( v ) { return ( v || v === 0 ) ? Lib . cleanDate ( v , null , calendar ) : null ; } :
221
221
function ( v ) { return isNumeric ( v ) ? Number ( v ) : null ; } ;
222
222
223
223
function setBound ( attr , bins , newBins ) {
@@ -230,45 +230,73 @@ function calcAllAutoBins(gd, trace, pa, mainData, _overlayEdgeCase) {
230
230
}
231
231
}
232
232
233
- var binOpts = fullLayout . _histogramBinOpts [ trace . _groupName ] ;
234
-
235
233
// all but the first trace in this group has already been marked finished
236
234
// clear this flag, so next time we run calc we will run autobin again
237
235
if ( trace . _autoBinFinished ) {
238
236
delete trace . _autoBinFinished ;
239
237
} else {
240
238
traces = binOpts . traces ;
241
- var sizeFound = binOpts . sizeFound ;
242
239
var allPos = [ ] ;
243
- autoVals = traces [ 0 ] . _autoBin = { } ;
240
+
244
241
// Note: we're including `legendonly` traces here for autobin purposes,
245
242
// so that showing & hiding from the legend won't affect bins.
246
243
// But this complicates things a bit since those traces don't `calc`,
247
244
// hence `isFirstVisible`.
248
245
var isFirstVisible = true ;
246
+ var has2dMap = false ;
247
+ var hasHist2dContour = false ;
249
248
for ( i = 0 ; i < traces . length ; i ++ ) {
250
249
tracei = traces [ i ] ;
250
+
251
251
if ( tracei . visible ) {
252
- pos0 = tracei . _pos0 = pa . makeCalcdata ( tracei , mainData ) ;
252
+ var mainDatai = binOpts . dirs [ i ] ;
253
+ pos0 = tracei [ '_' + mainDatai + 'pos0' ] = pa . makeCalcdata ( tracei , mainDatai ) ;
254
+
253
255
allPos = Lib . concat ( allPos , pos0 ) ;
254
256
delete tracei . _autoBinFinished ;
257
+
255
258
if ( trace . visible === true ) {
256
259
if ( isFirstVisible ) {
257
260
isFirstVisible = false ;
258
261
} else {
259
262
delete tracei . _autoBin ;
260
263
tracei . _autoBinFinished = 1 ;
261
264
}
265
+ if ( Registry . traceIs ( tracei , '2dMap' ) ) {
266
+ has2dMap = true ;
267
+ }
268
+ if ( tracei . type === 'histogram2dcontour' ) {
269
+ hasHist2dContour = true ;
270
+ }
262
271
}
263
272
}
264
273
}
274
+
265
275
calendar = traces [ 0 ] [ mainData + 'calendar' ] ;
266
- var newBinSpec = Axes . autoBin (
267
- allPos , pa , binOpts . nbins , false , calendar , sizeFound && binOpts . size ) ;
276
+ var newBinSpec = Axes . autoBin ( allPos , pa , binOpts . nbins , has2dMap , calendar , binOpts . sizeFound && binOpts . size ) ;
268
277
278
+ var autoBin = traces [ 0 ] . _autoBin = { } ;
279
+ autoVals = autoBin [ binOpts . dirs [ 0 ] ] = { } ;
280
+
281
+ if ( hasHist2dContour ) {
282
+ // the "true" 2nd argument reverses the tick direction (which we can't
283
+ // just do with a minus sign because of month bins)
284
+ if ( ! binOpts . size ) {
285
+ newBinSpec . start = c2r ( Axes . tickIncrement (
286
+ r2c ( newBinSpec . start ) , newBinSpec . size , true , calendar ) ) ;
287
+ }
288
+ if ( binOpts . end === undefined ) {
289
+ newBinSpec . end = c2r ( Axes . tickIncrement (
290
+ r2c ( newBinSpec . end ) , newBinSpec . size , false , calendar ) ) ;
291
+ }
292
+ }
293
+
294
+ // TODO how does work with bingroup ????
295
+ // - https://github.com/plotly/plotly.js/issues/3881
296
+ //
269
297
// Edge case: single-valued histogram overlaying others
270
298
// Use them all together to calculate the bin size for the single-valued one
271
- if ( isOverlay && newBinSpec . _dataSpan === 0 &&
299
+ if ( isOverlay && ! Registry . traceIs ( trace , '2dMap' ) && newBinSpec . _dataSpan === 0 &&
272
300
pa . type !== 'category' && pa . type !== 'multicategory' ) {
273
301
// Several single-valued histograms! Stop infinite recursion,
274
302
// just return an extra flag that tells handleSingleValueOverlays
@@ -279,23 +307,19 @@ function calcAllAutoBins(gd, trace, pa, mainData, _overlayEdgeCase) {
279
307
}
280
308
281
309
// adjust for CDF edge cases
282
- cumulativeSpec = tracei . cumulative ;
310
+ cumulativeSpec = tracei . cumulative || { } ;
283
311
if ( cumulativeSpec . enabled && ( cumulativeSpec . currentbin !== 'include' ) ) {
284
312
if ( cumulativeSpec . direction === 'decreasing' ) {
285
- newBinSpec . start = pa . c2r ( Axes . tickIncrement (
286
- pa . r2c ( newBinSpec . start , 0 , calendar ) ,
287
- newBinSpec . size , true , calendar
288
- ) ) ;
313
+ newBinSpec . start = c2r ( Axes . tickIncrement (
314
+ r2c ( newBinSpec . start ) , newBinSpec . size , true , calendar ) ) ;
289
315
} else {
290
- newBinSpec . end = pa . c2r ( Axes . tickIncrement (
291
- pa . r2c ( newBinSpec . end , 0 , calendar ) ,
292
- newBinSpec . size , false , calendar
293
- ) ) ;
316
+ newBinSpec . end = c2r ( Axes . tickIncrement (
317
+ r2c ( newBinSpec . end ) , newBinSpec . size , false , calendar ) ) ;
294
318
}
295
319
}
296
320
297
321
binOpts . size = newBinSpec . size ;
298
- if ( ! sizeFound ) {
322
+ if ( ! binOpts . sizeFound ) {
299
323
autoVals . size = newBinSpec . size ;
300
324
Lib . nestedProperty ( traces [ 0 ] , binAttr + '.size' ) . set ( newBinSpec . size ) ;
301
325
}
@@ -304,8 +328,8 @@ function calcAllAutoBins(gd, trace, pa, mainData, _overlayEdgeCase) {
304
328
setBound ( 'end' , binOpts , newBinSpec ) ;
305
329
}
306
330
307
- pos0 = trace . _pos0 ;
308
- delete trace . _pos0 ;
331
+ pos0 = trace [ '_' + mainData + 'pos0' ] ;
332
+ delete trace [ '_' + mainData + 'pos0' ] ;
309
333
310
334
// Each trace can specify its own start/end, or if omitted
311
335
// we ensure they're beyond the bounds of this trace's data,
@@ -398,7 +422,7 @@ function handleSingleValueOverlays(gd, trace, pa, mainData, binAttr) {
398
422
// so we can use this result when we get to tracei in the normal
399
423
// course of events, mark it as done and put _pos0 back
400
424
tracei . _autoBinFinished = 1 ;
401
- tracei . _pos0 = resulti [ 1 ] ;
425
+ tracei [ '_' + mainData + 'pos0' ] = resulti [ 1 ] ;
402
426
403
427
if ( isSingleValued ) {
404
428
singleValuedTraces . push ( tracei ) ;
@@ -412,7 +436,7 @@ function handleSingleValueOverlays(gd, trace, pa, mainData, binAttr) {
412
436
// hunt through pos0 for the first valid value
413
437
var dataVals = new Array ( singleValuedTraces . length ) ;
414
438
for ( i = 0 ; i < singleValuedTraces . length ; i ++ ) {
415
- var pos0 = singleValuedTraces [ i ] . _pos0 ;
439
+ var pos0 = singleValuedTraces [ i ] [ '_' + mainData + 'pos0' ] ;
416
440
for ( var j = 0 ; j < pos0 . length ; j ++ ) {
417
441
if ( pos0 [ j ] !== undefined ) {
418
442
dataVals [ i ] = pos0 [ j ] ;
@@ -470,7 +494,6 @@ function getConnectedHistograms(gd, trace) {
470
494
return out ;
471
495
}
472
496
473
-
474
497
function cdf ( size , direction , currentBin ) {
475
498
var i , vi , prevSum ;
476
499
@@ -518,3 +541,8 @@ function cdf(size, direction, currentBin) {
518
541
}
519
542
}
520
543
}
544
+
545
+ module . exports = {
546
+ calc : calc ,
547
+ calcAllAutoBins : calcAllAutoBins
548
+ } ;
0 commit comments