@@ -186,6 +186,280 @@ describe('Test histogram', function() {
186
186
} ) ;
187
187
} ) ;
188
188
189
+ describe ( 'cross-trace bingroup logic:' , function ( ) {
190
+ var gd ;
191
+
192
+ beforeEach ( function ( ) {
193
+ spyOn ( Lib , 'warn' ) ;
194
+ } ) ;
195
+
196
+ function _assert ( msg , exp , warnMsg ) {
197
+ var allBinOpts = gd . _fullLayout . _histogramBinOpts ;
198
+ var groups = Object . keys ( allBinOpts ) ;
199
+
200
+ expect ( groups . length ) . toBe ( exp . length , 'same # of bin groups| ' + msg ) ;
201
+
202
+ var eGroups = exp . map ( function ( expi ) { return expi [ 0 ] ; } ) ;
203
+ expect ( groups ) . toEqual ( eGroups , 'same bin groups| ' + msg ) ;
204
+
205
+ exp . forEach ( function ( expi ) {
206
+ var k = expi [ 0 ] ;
207
+ var binOpts = allBinOpts [ k ] ;
208
+
209
+ if ( ! binOpts ) {
210
+ return fail ( 'bingroup ' + k + ' does NOT exist| ' + msg ) ;
211
+ }
212
+
213
+ var traces = binOpts . traces || [ ] ;
214
+
215
+ if ( ! traces . length ) {
216
+ return fail ( 'traces list for bingroup ' + k + ' is empty| ' + msg ) ;
217
+ }
218
+
219
+ expect ( traces . length ) . toBe ( expi [ 1 ] . length , 'same # of tracked traces|' + msg ) ;
220
+
221
+ traces . forEach ( function ( t , i ) {
222
+ expect ( t . index )
223
+ . toBe ( expi [ 1 ] [ i ] , 'tracks same traces[' + i + ']|' + msg ) ;
224
+ expect ( t [ '_' + binOpts . dirs [ i ] + 'bingroup' ] )
225
+ . toBe ( k , '_(x|y)bingroup key in trace' + i + '| ' + msg ) ;
226
+ } ) ;
227
+ } ) ;
228
+
229
+ if ( warnMsg ) {
230
+ expect ( Lib . warn ) . toHaveBeenCalledWith ( warnMsg ) ;
231
+ } else {
232
+ expect ( Lib . warn ) . toHaveBeenCalledTimes ( 0 ) ;
233
+ }
234
+ }
235
+
236
+ it ( 'should group traces w/ same axes and w/ same orientation' , function ( ) {
237
+ var barModes = [ 'group' , 'stack' ] ;
238
+
239
+ barModes . forEach ( function ( mode ) {
240
+ gd = {
241
+ data : [
242
+ { type : 'histogram' , y : [ 1 ] } ,
243
+ { type : 'histogram' , y : [ 2 ] } ,
244
+
245
+ { type : 'histogram' , y : [ 1 ] , xaxis : 'x2' } ,
246
+ { type : 'histogram' , y : [ 3 ] , xaxis : 'x2' } ,
247
+
248
+ { type : 'histogram' , y : [ 3 ] } ,
249
+ { type : 'histogram' , y : [ 2 ] , xaxis : 'x2' } ,
250
+
251
+ { type : 'histogram' , x : [ 1 ] } ,
252
+ { uid : 'solo' , type : 'histogram' , x : [ 2 ] , yaxis : 'y2' } ,
253
+ { type : 'histogram' , x : [ 2 ] }
254
+ ] ,
255
+ layout : { barmode : mode }
256
+ } ;
257
+ supplyAllDefaults ( gd ) ;
258
+ _assert ( 'under barmode:' + mode , [
259
+ [ 'xyy' , [ 0 , 1 , 4 ] ] ,
260
+ [ 'x2yy' , [ 2 , 3 , 5 ] ] ,
261
+ [ 'xyx' , [ 6 , 8 ] ] ,
262
+ [ 'solo__x' , [ 7 ] ]
263
+ ] ) ;
264
+ } ) ;
265
+ } ) ;
266
+
267
+ it ( 'should group traces on matching axes and w/ same orientation' , function ( ) {
268
+ var barModes = [ 'group' , 'stack' ] ;
269
+
270
+ barModes . forEach ( function ( mode ) {
271
+ gd = {
272
+ data : [
273
+ { type : 'histogram' , y : [ 1 ] } ,
274
+ { type : 'histogram' , y : [ 2 ] , xaxis : 'x2' } ,
275
+ { type : 'histogram' , x : [ 1 ] , yaxis : 'y2' } ,
276
+ { type : 'histogram' , x : [ 2 ] , yaxis : 'y2' } ,
277
+ ] ,
278
+ layout : {
279
+ barmode : mode ,
280
+ xaxis2 : { matches : 'x' } ,
281
+ yaxis2 : { matches : 'x' }
282
+ }
283
+ } ;
284
+ supplyAllDefaults ( gd ) ;
285
+ _assert ( 'under barmode:' + mode , [
286
+ [ 'g0yy' , [ 0 , 1 ] ] ,
287
+ [ 'g0g0x' , [ 2 , 3 ] ]
288
+ ] ) ;
289
+ } ) ;
290
+ } ) ;
291
+
292
+ it ( 'should not group traces by default under barmode:overlay ' , function ( ) {
293
+ gd = {
294
+ data : [
295
+ { uid : 'a' , type : 'histogram' , y : [ 1 ] } ,
296
+ { uid : 'b' , type : 'histogram' , y : [ 2 ] } ,
297
+
298
+ { uid : 'c' , type : 'histogram' , y : [ 1 ] , xaxis : 'x2' } ,
299
+ { uid : 'd' , type : 'histogram' , y : [ 3 ] , xaxis : 'x2' } ,
300
+
301
+ { uid : 'e' , type : 'histogram' , y : [ 3 ] } ,
302
+ { uid : 'f' , type : 'histogram' , y : [ 2 ] , xaxis : 'x2' } ,
303
+
304
+ { uid : 'g' , type : 'histogram' , x : [ 1 ] } ,
305
+ { uid : 'h' , type : 'histogram' , x : [ 2 ] , yaxis : 'y2' } ,
306
+ { uid : 'i' , type : 'histogram' , x : [ 2 ] }
307
+ ] ,
308
+ layout : { barmode : 'overlay' }
309
+ } ;
310
+ supplyAllDefaults ( gd ) ;
311
+ _assert ( '' , [
312
+ [ 'a__y' , [ 0 ] ] , [ 'b__y' , [ 1 ] ] , [ 'c__y' , [ 2 ] ] ,
313
+ [ 'd__y' , [ 3 ] ] , [ 'e__y' , [ 4 ] ] , [ 'f__y' , [ 5 ] ] ,
314
+ [ 'g__x' , [ 6 ] ] , [ 'h__x' , [ 7 ] ] , [ 'i__x' , [ 8 ] ]
315
+ ] ) ;
316
+ } ) ;
317
+
318
+ it ( 'should not group histogram2d* traces by default' , function ( ) {
319
+ gd = {
320
+ data : [
321
+ { uid : 'a' , type : 'histogram2d' , x : [ 1 ] , y : [ 1 ] } ,
322
+ { uid : 'b' , type : 'histogram2d' , x : [ 2 ] , y : [ 2 ] } ,
323
+ { uid : 'c' , type : 'histogram2dcontour' , x : [ 1 ] , y : [ 1 ] , xaxis : 'x2' , yaxis : 'y2' } ,
324
+ { uid : 'd' , type : 'histogram2dcontour' , x : [ 2 ] , y : [ 2 ] , xaxis : 'x2' , yaxis : 'y2' } ,
325
+ ] ,
326
+ layout : { }
327
+ } ;
328
+ supplyAllDefaults ( gd ) ;
329
+ _assert ( 'N.B. one bingroup for x, one bingroup for y for each trace' , [
330
+ [ 'a__x' , [ 0 ] ] , [ 'a__y' , [ 0 ] ] ,
331
+ [ 'b__x' , [ 1 ] ] , [ 'b__y' , [ 1 ] ] ,
332
+ [ 'c__x' , [ 2 ] ] , [ 'c__y' , [ 2 ] ] ,
333
+ [ 'd__x' , [ 3 ] ] , [ 'd__y' , [ 3 ] ]
334
+ ] ) ;
335
+ } ) ;
336
+
337
+ it ( 'should be able to group traces by *bingroup* under barmode:overlay ' , function ( ) {
338
+ gd = {
339
+ data : [
340
+ { bingroup : '1' , type : 'histogram' , y : [ 1 ] } ,
341
+ { uid : 'b' , type : 'histogram' , y : [ 2 ] } ,
342
+ { bingroup : '2' , type : 'histogram' , y : [ 1 ] , xaxis : 'x2' } ,
343
+ { bingroup : '1' , type : 'histogram' , y : [ 3 ] , xaxis : 'x2' } ,
344
+ { bingroup : '2' , type : 'histogram' , y : [ 3 ] } ,
345
+ { uid : 'f' , type : 'histogram' , y : [ 2 ] , xaxis : 'x2' } ,
346
+ { bingroup : '3' , type : 'histogram' , x : [ 1 ] } ,
347
+ { bingroup : '1' , type : 'histogram' , x : [ 2 ] , yaxis : 'y2' } ,
348
+ { bingroup : '3' , type : 'histogram' , x : [ 2 ] }
349
+ ] ,
350
+ layout : { barmode : 'overlay' }
351
+ } ;
352
+ supplyAllDefaults ( gd ) ;
353
+ _assert ( '' , [
354
+ [ '1' , [ 0 , 3 , 7 ] ] ,
355
+ [ '2' , [ 2 , 4 ] ] ,
356
+ [ '3' , [ 6 , 8 ] ] ,
357
+ [ 'b__y' , [ 1 ] ] ,
358
+ [ 'f__y' , [ 5 ] ]
359
+ ] ) ;
360
+ } ) ;
361
+
362
+ it ( 'should be able to group histogram2d traces by *bingroup*' , function ( ) {
363
+ gd = {
364
+ data : [
365
+ { uid : 'a' , type : 'histogram2d' , x : [ 1 ] , y : [ 1 ] } ,
366
+ { uid : 'b' , type : 'histogram2d' , x : [ 1 ] , y : [ 1 ] } ,
367
+ { bingroup : '1' , type : 'histogram2d' , x : [ 1 ] , y : [ 1 ] } ,
368
+ { bingroup : '1' , type : 'histogram2d' , x : [ 1 ] , y : [ 1 ] } ,
369
+ { uid : 'e' , type : 'histogram2d' , x : [ 1 ] , y : [ 1 ] } ,
370
+ ]
371
+ } ;
372
+ supplyAllDefaults ( gd ) ;
373
+ _assert ( '' , [
374
+ [ 'a__x' , [ 0 ] ] , [ 'a__y' , [ 0 ] ] ,
375
+ [ 'b__x' , [ 1 ] ] , [ 'b__y' , [ 1 ] ] ,
376
+ [ '1__x' , [ 2 , 3 ] ] , [ '1__y' , [ 2 , 3 ] ] ,
377
+ [ 'e__x' , [ 4 ] ] , [ 'e__y' , [ 4 ] ]
378
+ ] ) ;
379
+ } ) ;
380
+
381
+ // TODO figure out what to do in this case!
382
+ it ( 'should be able to group histogram and histogram2d* traces together' , function ( ) {
383
+ gd = {
384
+ data : [
385
+ { bingroup : '1' , type : 'histogram' , y : [ 1 ] } ,
386
+ { bingroup : '1' , type : 'histogram' , y : [ 3 ] , xaxis : 'x2' } ,
387
+ { bingroup : '1' , type : 'histogram2d' , x : [ 1 ] , y : [ 3 ] } ,
388
+ { bingroup : '1' , type : 'histogram2dcontour' , x : [ 1 ] , y : [ 3 ] }
389
+ ] ,
390
+ layout : { barmode : 'overlay' }
391
+ } ;
392
+ supplyAllDefaults ( gd ) ;
393
+ _assert ( 'N.B. histogram2d* indices show up twice, once for x-bins, once for y-bins' , [
394
+ [ '1' , [ 0 , 1 ] ] ,
395
+ [ '1__x' , [ 2 , 3 ] ] ,
396
+ [ '1__y' , [ 2 , 3 ] ]
397
+ ] ) ;
398
+ } ) ;
399
+
400
+ it ( 'should not group traces across axes of different types' , function ( ) {
401
+ gd = {
402
+ data : [
403
+ { uid : 'a' , bingroup : '1' , type : 'histogram' , y : [ 1 ] } ,
404
+ { uid : 'b' , bingroup : '1' , type : 'histogram' , y : [ 'cats' ] , yaxis : 'y2' } ,
405
+ ] ,
406
+ layout : { barmode : 'overlay' }
407
+ } ;
408
+ supplyAllDefaults ( gd ) ;
409
+
410
+ _assert ( '' , [
411
+ [ '1' , [ 0 ] ] ,
412
+ [ 'b__y' , [ 1 ] ]
413
+ ] ,
414
+ 'Attempted to group the bins of trace 1 set on a type:category axis ' +
415
+ 'with bins on type:linear axis.'
416
+ ) ;
417
+ } ) ;
418
+
419
+ it ( 'should force traces that "have to match" to have same bingroup (stack case)' , function ( ) {
420
+ gd = {
421
+ data : [
422
+ // these 3 traces "have to match"
423
+ { bingroup : '1' , type : 'histogram' , y : [ 1 ] } ,
424
+ { type : 'histogram' , y : [ 1 ] } ,
425
+ { bingroup : '2' , type : 'histogram' , y : [ 2 ] }
426
+ ] ,
427
+ layout : { barmode : 'stack' }
428
+ } ;
429
+ supplyAllDefaults ( gd ) ;
430
+
431
+ _assert ( 'used first valid bingroup to identify bin opts' , [
432
+ [ '1' , [ 0 , 1 , 2 ] ]
433
+ ] ,
434
+ 'Trace 2 must match within bingroup 1.' +
435
+ ' Ignoring its bingroup: 2 setting.'
436
+ ) ;
437
+ } ) ;
438
+
439
+ it ( 'traces that "have to match" can be grouped with traces that do not have to match using *bingroup*' , function ( ) {
440
+ gd = {
441
+ data : [
442
+ // these 2 traces "have to match"
443
+ { bingroup : '1' , type : 'histogram' , y : [ 1 ] } ,
444
+ { type : 'histogram' , y : [ 1 ] } ,
445
+ // this one does not have to match with the above two,
446
+ // (it's on another subplot), but it can be grouped
447
+ { bingroup : '1' , type : 'histogram' , y : [ 2 ] , xaxis : 'x2' , yaxis : 'y2' } ,
448
+ // this one does not have to match either
449
+ // (it's a histogram2d* traces), but it can be grouped
450
+ // TODO should this be just "bingroup"???
451
+ { xbingroup : '1' , ybingroup : '1' , type : 'histogram2d' , x : [ 3 ] , y : [ 3 ] }
452
+ ] ,
453
+ layout : { }
454
+ } ;
455
+ supplyAllDefaults ( gd ) ;
456
+
457
+ _assert ( '' , [
458
+ // N.B ordering in *binOpts.traces* does not matter
459
+ [ '1' , [ 0 , 1 , 3 , 3 , 2 ] ]
460
+ ] ) ;
461
+ } ) ;
462
+ } ) ;
189
463
190
464
describe ( 'calc' , function ( ) {
191
465
function _calc ( opts , extraTraces , layout , prependExtras ) {
0 commit comments