@@ -452,43 +452,127 @@ function computeLegendDimensions(gd, groups, traces) {
452
452
opts = fullLayout . legend ,
453
453
borderwidth = opts . borderwidth ;
454
454
455
- if ( helpers . isGrouped ( opts ) ) {
456
- groups . attr ( 'transform' , function ( d , i ) {
457
- return 'translate(0,' + i * opts . tracegroupgap + ')' ;
455
+ if ( helpers . isVertical ( opts ) ) {
456
+ if ( helpers . isGrouped ( opts ) ) {
457
+ groups . attr ( 'transform' , function ( d , i ) {
458
+ return 'translate(0,' + i * opts . tracegroupgap + ')' ;
459
+ } ) ;
460
+ }
461
+
462
+ opts . width = 0 ;
463
+ opts . height = 0 ;
464
+
465
+ traces . each ( function ( d ) {
466
+ var legendItem = d [ 0 ] ,
467
+ textHeight = legendItem . height ,
468
+ textWidth = legendItem . width ;
469
+
470
+ d3 . select ( this ) . attr ( 'transform' ,
471
+ 'translate(' + borderwidth + ',' +
472
+ ( 5 + borderwidth + opts . height + textHeight / 2 ) +
473
+ ')'
474
+ ) ;
475
+
476
+ opts . height += textHeight ;
477
+ opts . width = Math . max ( opts . width , textWidth ) ;
458
478
} ) ;
479
+
480
+ opts . width += 45 + borderwidth * 2 ;
481
+ opts . height += 10 + borderwidth * 2 ;
482
+
483
+ if ( helpers . isGrouped ( opts ) ) {
484
+ opts . height += ( opts . _lgroupsLength - 1 ) * opts . tracegroupgap ;
485
+ }
486
+
487
+ traces . selectAll ( '.legendtoggle' )
488
+ . attr ( 'width' , ( gd . _context . editable ? 0 : opts . width ) + 40 ) ;
489
+
490
+ // make sure we're only getting full pixels
491
+ opts . width = Math . ceil ( opts . width ) ;
492
+ opts . height = Math . ceil ( opts . height ) ;
459
493
}
494
+ else if ( helpers . isGrouped ( opts ) ) {
495
+ opts . width = 0 ;
496
+ opts . height = 0 ;
497
+
498
+ var groupXOffsets = [ opts . width ] ;
499
+ groups . each ( function ( d ) {
500
+ var textWidths = d . map ( function ( legendItemArray ) {
501
+ return legendItemArray [ 0 ] . width ;
502
+ } ) ;
460
503
461
- opts . width = 0 ;
462
- opts . height = 0 ;
504
+ var groupWidth = 40 + Math . max . apply ( null , textWidths ) ;
505
+ opts . width += opts . tracegroupgap + groupWidth ;
463
506
464
- traces . each ( function ( d ) {
465
- var legendItem = d [ 0 ] ,
466
- textHeight = legendItem . height ,
467
- textWidth = legendItem . width ;
507
+ groupXOffsets . push ( opts . width ) ;
508
+ } ) ;
468
509
469
- d3 . select ( this ) . attr ( 'transform' ,
470
- 'translate(' + borderwidth + ',' +
471
- ( 5 + borderwidth + opts . height + textHeight / 2 ) +
472
- ')'
473
- ) ;
510
+ groups . attr ( 'transform' , function ( d , i ) {
511
+ return 'translate(' + groupXOffsets [ i ] + ',0)' ;
512
+ } ) ;
474
513
475
- opts . height += textHeight ;
476
- opts . width = Math . max ( opts . width , textWidth ) ;
477
- } ) ;
514
+ groups . each ( function ( ) {
515
+ var group = d3 . select ( this ) ,
516
+ groupTraces = group . selectAll ( 'g.traces' ) ,
517
+ groupHeight = 0 ;
518
+
519
+ groupTraces . each ( function ( d ) {
520
+ var legendItem = d [ 0 ] ,
521
+ textHeight = legendItem . height ;
522
+
523
+ d3 . select ( this ) . attr ( 'transform' ,
524
+ 'translate(0,' +
525
+ ( 5 + borderwidth + groupHeight + textHeight / 2 ) +
526
+ ')'
527
+ ) ;
528
+
529
+ groupHeight += textHeight ;
530
+ } ) ;
478
531
479
- opts . width += 45 + borderwidth * 2 ;
480
- opts . height += 10 + borderwidth * 2 ;
532
+ opts . height = Math . max ( opts . height , groupHeight ) ;
533
+ } ) ;
534
+
535
+ opts . height += 10 + borderwidth * 2 ;
536
+ opts . width += borderwidth * 2 ;
481
537
482
- if ( helpers . isGrouped ( opts ) ) {
483
- opts . height += ( opts . _lgroupsLength - 1 ) * opts . tracegroupgap ;
538
+ // make sure we're only getting full pixels
539
+ opts . width = Math . ceil ( opts . width ) ;
540
+ opts . height = Math . ceil ( opts . height ) ;
541
+
542
+ traces . selectAll ( '.legendtoggle' )
543
+ . attr ( 'width' , ( gd . _context . editable ? 0 : opts . width ) ) ;
484
544
}
545
+ else {
546
+ opts . width = 0 ;
547
+ opts . height = 0 ;
548
+
549
+ traces . each ( function ( d ) {
550
+ var legendItem = d [ 0 ] ,
551
+ traceWidth = 40 + legendItem . width ,
552
+ traceGap = opts . tracegroupgap || 5 ;
553
+
554
+ d3 . select ( this ) . attr ( 'transform' ,
555
+ 'translate(' +
556
+ ( borderwidth + opts . width ) +
557
+ ',' +
558
+ ( 5 + borderwidth + legendItem . height / 2 ) +
559
+ ')'
560
+ ) ;
561
+
562
+ opts . width += traceGap + traceWidth ;
563
+ opts . height = Math . max ( opts . height , legendItem . height ) ;
564
+ } ) ;
565
+
566
+ opts . width += borderwidth * 2 ;
567
+ opts . height += 10 + borderwidth * 2 ;
485
568
486
- traces . selectAll ( '.legendtoggle' )
487
- . attr ( 'width' , ( gd . _context . editable ? 0 : opts . width ) + 40 ) ;
569
+ // make sure we're only getting full pixels
570
+ opts . width = Math . ceil ( opts . width ) ;
571
+ opts . height = Math . ceil ( opts . height ) ;
488
572
489
- // make sure we're only getting full pixels
490
- opts . width = Math . ceil ( opts . width ) ;
491
- opts . height = Math . ceil ( opts . height ) ;
573
+ traces . selectAll ( '.legendtoggle' )
574
+ . attr ( 'width' , ( gd . _context . editable ? 0 : opts . width ) ) ;
575
+ }
492
576
}
493
577
494
578
function expandMargin ( gd ) {
0 commit comments