@@ -40,12 +40,9 @@ module.exports = function calc(gd, trace) {
40
40
41
41
cleanBins ( trace , pa , maindata ) ;
42
42
43
- var binspec = calcAllAutoBins ( gd , trace , pa , maindata ) ;
44
-
45
- // the raw data was prepared in calcAllAutoBins (during the first trace in
46
- // this group) and stashed. Pull it out and drop the stash
47
- var pos0 = trace . _pos0 ;
48
- delete trace . _pos0 ;
43
+ var binsAndPos = calcAllAutoBins ( gd , trace , pa , maindata ) ;
44
+ var binspec = binsAndPos [ 0 ] ;
45
+ var pos0 = binsAndPos [ 1 ] ;
49
46
50
47
var nonuniformBins = typeof binspec . size === 'string' ;
51
48
var bins = nonuniformBins ? [ ] : binspec ;
@@ -166,115 +163,116 @@ module.exports = function calc(gd, trace) {
166
163
*/
167
164
function calcAllAutoBins ( gd , trace , pa , maindata ) {
168
165
var binAttr = maindata + 'bins' ;
166
+ var i , tracei , calendar , firstManual , pos0 ;
169
167
170
168
// all but the first trace in this group has already been marked finished
171
169
// clear this flag, so next time we run calc we will run autobin again
172
170
if ( trace . _autoBinFinished ) {
173
171
delete trace . _autoBinFinished ;
174
-
175
- return trace [ binAttr ] ;
176
172
}
173
+ else {
174
+ // must be the first trace in the group - do the autobinning on them all
175
+ var traceGroup = getConnectedHistograms ( gd , trace ) ;
176
+ var autoBinnedTraces = [ ] ;
177
+
178
+ var minSize = Infinity ;
179
+ var minStart = Infinity ;
180
+ var maxEnd = - Infinity ;
181
+
182
+ var autoBinAttr = 'autobin' + maindata ;
183
+
184
+ for ( i = 0 ; i < traceGroup . length ; i ++ ) {
185
+ tracei = traceGroup [ i ] ;
186
+
187
+ // stash pos0 on the trace so we don't need to duplicate this
188
+ // in the main body of calc
189
+ pos0 = tracei . _pos0 = pa . makeCalcdata ( tracei , maindata ) ;
190
+ var binspec = tracei [ binAttr ] ;
191
+
192
+ if ( ( tracei [ autoBinAttr ] ) || ! binspec ||
193
+ binspec . start === null || binspec . end === null ) {
194
+ calendar = tracei [ maindata + 'calendar' ] ;
195
+ var cumulativeSpec = tracei . cumulative ;
196
+
197
+ binspec = Axes . autoBin ( pos0 , pa , tracei [ 'nbins' + maindata ] , false , calendar ) ;
198
+
199
+ // adjust for CDF edge cases
200
+ if ( cumulativeSpec . enabled && ( cumulativeSpec . currentbin !== 'include' ) ) {
201
+ if ( cumulativeSpec . direction === 'decreasing' ) {
202
+ minStart = Math . min ( minStart , pa . r2c ( binspec . start , 0 , calendar ) - binspec . size ) ;
203
+ }
204
+ else {
205
+ maxEnd = Math . max ( maxEnd , pa . r2c ( binspec . end , 0 , calendar ) + binspec . size ) ;
206
+ }
207
+ }
177
208
178
- // must be the first trace in the group - do the autobinning on them all
179
- var traceGroup = getConnectedHistograms ( gd , trace ) ;
180
- var autoBinnedTraces = [ ] ;
181
-
182
- var minSize = Infinity ;
183
- var minStart = Infinity ;
184
- var maxEnd = - Infinity ;
185
-
186
- var autoBinAttr = 'autobin' + maindata ;
187
- var i , tracei , calendar , firstManual ;
188
-
209
+ // note that it's possible to get here with an explicit autobin: false
210
+ // if the bins were not specified. mark this trace for followup
211
+ autoBinnedTraces . push ( tracei ) ;
212
+ }
213
+ else if ( ! firstManual ) {
214
+ // Remember the first manually set binspec. We'll try to be extra
215
+ // accommodating of this one, so other bins line up with these
216
+ // if there's more than one manual bin set and they're mutually inconsistent,
217
+ // then there's not much we can do...
218
+ firstManual = {
219
+ size : binspec . size ,
220
+ start : pa . r2c ( binspec . start , 0 , calendar ) ,
221
+ end : pa . r2c ( binspec . end , 0 , calendar )
222
+ } ;
223
+ }
189
224
190
- for ( i = 0 ; i < traceGroup . length ; i ++ ) {
191
- tracei = traceGroup [ i ] ;
225
+ // Even non-autobinned traces get included here, so we get the greatest extent
226
+ // and minimum bin size of them all.
227
+ // But manually binned traces won't be adjusted, even if the auto values
228
+ // are inconsistent with the manual ones (or the manual ones are inconsistent
229
+ // with each other).
230
+ minSize = getMinSize ( minSize , binspec . size ) ;
231
+ minStart = Math . min ( minStart , pa . r2c ( binspec . start , 0 , calendar ) ) ;
232
+ maxEnd = Math . max ( maxEnd , pa . r2c ( binspec . end , 0 , calendar ) ) ;
233
+
234
+ // add the flag that lets us abort autobin on later traces
235
+ if ( i ) trace . _autoBinFinished = 1 ;
236
+ }
192
237
193
- // stash pos0 on the trace so we don't need to duplicate this
194
- // in the main body of calc
195
- var pos0 = tracei . _pos0 = pa . makeCalcdata ( tracei , maindata ) ;
196
- var binspec = tracei [ binAttr ] ;
238
+ // do what we can to match the auto bins to the first manual bins
239
+ // but only if sizes are all numeric
240
+ if ( firstManual && isNumeric ( firstManual . size ) && isNumeric ( minSize ) ) {
241
+ // first need to ensure the bin size is the same as or an integer fraction
242
+ // of the first manual bin
243
+ // allow the bin size to increase just under the autobin step size to match,
244
+ // (which is a factor of 2 or 2.5) otherwise shrink it
245
+ if ( minSize > firstManual . size / 1.9 ) minSize = firstManual . size ;
246
+ else minSize = firstManual . size / Math . ceil ( firstManual . size / minSize ) ;
247
+
248
+ // now decrease minStart if needed to make the bin centers line up
249
+ var adjustedFirstStart = firstManual . start + ( firstManual . size - minSize ) / 2 ;
250
+ minStart = adjustedFirstStart - minSize * Math . ceil ( ( adjustedFirstStart - minStart ) / minSize ) ;
251
+ }
197
252
198
- if ( ( tracei [ autoBinAttr ] ) || ! binspec ||
199
- binspec . start === null || binspec . end === null ) {
253
+ // now go back to the autobinned traces and update their bin specs with the final values
254
+ for ( i = 0 ; i < autoBinnedTraces . length ; i ++ ) {
255
+ tracei = autoBinnedTraces [ i ] ;
200
256
calendar = tracei [ maindata + 'calendar' ] ;
201
- var cumulativeSpec = tracei . cumulative ;
202
-
203
- binspec = Axes . autoBin ( pos0 , pa , tracei [ 'nbins' + maindata ] , false , calendar ) ;
204
257
205
- // adjust for CDF edge cases
206
- if ( cumulativeSpec . enabled && ( cumulativeSpec . currentbin !== 'include' ) ) {
207
- if ( cumulativeSpec . direction === 'decreasing' ) {
208
- minStart = Math . min ( minStart , pa . r2c ( binspec . start , 0 , calendar ) - binspec . size ) ;
209
- }
210
- else {
211
- maxEnd = Math . max ( maxEnd , pa . r2c ( binspec . end , 0 , calendar ) + binspec . size ) ;
212
- }
213
- }
258
+ tracei . _input [ binAttr ] = tracei [ binAttr ] = {
259
+ start : pa . c2r ( minStart , 0 , calendar ) ,
260
+ end : pa . c2r ( maxEnd , 0 , calendar ) ,
261
+ size : minSize
262
+ } ;
214
263
215
264
// note that it's possible to get here with an explicit autobin: false
216
- // if the bins were not specified. mark this trace for followup
217
- autoBinnedTraces . push ( tracei ) ;
265
+ // if the bins were not specified.
266
+ // in that case this will remain in the trace, so that future updates
267
+ // which would change the autobinning will not do so.
268
+ tracei . _input [ autoBinAttr ] = tracei [ autoBinAttr ] ;
218
269
}
219
- else if ( ! firstManual ) {
220
- // Remember the first manually set binspec. We'll try to be extra
221
- // accommodating of this one, so other bins line up with these
222
- // if there's more than one manual bin set and they're mutually inconsistent,
223
- // then there's not much we can do...
224
- firstManual = {
225
- size : binspec . size ,
226
- start : pa . r2c ( binspec . start , 0 , calendar ) ,
227
- end : pa . r2c ( binspec . end , 0 , calendar )
228
- } ;
229
- }
230
-
231
- // Even non-autobinned traces get included here, so we get the greatest extent
232
- // and minimum bin size of them all.
233
- // But manually binned traces won't be adjusted, even if the auto values
234
- // are inconsistent with the manual ones (or the manual ones are inconsistent
235
- // with each other).
236
- minSize = getMinSize ( minSize , binspec . size ) ;
237
- minStart = Math . min ( minStart , pa . r2c ( binspec . start , 0 , calendar ) ) ;
238
- maxEnd = Math . max ( maxEnd , pa . r2c ( binspec . end , 0 , calendar ) ) ;
239
-
240
- // add the flag that lets us abort autobin on later traces
241
- if ( i ) trace . _autoBinFinished = 1 ;
242
270
}
243
271
244
- // do what we can to match the auto bins to the first manual bins
245
- // but only if sizes are all numeric
246
- if ( firstManual && isNumeric ( firstManual . size ) && isNumeric ( minSize ) ) {
247
- // first need to ensure the bin size is the same as or an integer fraction
248
- // of the first manual bin
249
- // allow the bin size to increase just under the autobin step size to match,
250
- // (which is a factor of 2 or 2.5) otherwise shrink it
251
- if ( minSize > firstManual . size / 1.9 ) minSize = firstManual . size ;
252
- else minSize = firstManual . size / Math . ceil ( firstManual . size / minSize ) ;
253
-
254
- // now decrease minStart if needed to make the bin centers line up
255
- var adjustedFirstStart = firstManual . start + ( firstManual . size - minSize ) / 2 ;
256
- minStart = adjustedFirstStart - minSize * Math . ceil ( ( adjustedFirstStart - minStart ) / minSize ) ;
257
- }
258
-
259
- // now go back to the autobinned traces and update their bin specs with the final values
260
- for ( i = 0 ; i < autoBinnedTraces . length ; i ++ ) {
261
- tracei = autoBinnedTraces [ i ] ;
262
- calendar = tracei [ maindata + 'calendar' ] ;
263
-
264
- tracei . _input [ binAttr ] = tracei [ binAttr ] = {
265
- start : pa . c2r ( minStart , 0 , calendar ) ,
266
- end : pa . c2r ( maxEnd , 0 , calendar ) ,
267
- size : minSize
268
- } ;
269
-
270
- // note that it's possible to get here with an explicit autobin: false
271
- // if the bins were not specified.
272
- // in that case this will remain in the trace, so that future updates
273
- // which would change the autobinning will not do so.
274
- tracei . _input [ autoBinAttr ] = tracei [ autoBinAttr ] ;
275
- }
272
+ pos0 = trace . _pos0 ;
273
+ delete trace . _pos0 ;
276
274
277
- return trace [ binAttr ] ;
275
+ return [ trace [ binAttr ] , pos0 ] ;
278
276
}
279
277
280
278
/*
0 commit comments