@@ -25,13 +25,22 @@ var helpers = require('./helpers');
25
25
var MAIN_TITLE = 1 ;
26
26
27
27
module . exports = function draw ( gd , opts ) {
28
- drawOne ( gd , opts || gd . _fullLayout . legend ) ;
28
+ if ( opts ) {
29
+ drawOne ( gd , opts ) ;
30
+ } else {
31
+ var legendGroups = gd . _fullLayout . _legends ;
32
+ for ( var i = 0 ; i < legendGroups . length ; i ++ ) {
33
+ drawOne ( gd , gd . _fullLayout [ 'legend' + legendGroups [ i ] ] ) ;
34
+ }
35
+ }
29
36
} ;
30
37
31
38
function drawOne ( gd , opts ) {
32
39
var legendObj = opts || { } ;
33
40
34
41
var fullLayout = gd . _fullLayout ;
42
+ var id = getId ( legendObj ) ;
43
+
35
44
var clipId , layer ;
36
45
37
46
var inHover = legendObj . _inHover ;
@@ -40,7 +49,7 @@ function drawOne(gd, opts) {
40
49
clipId = 'hover' ;
41
50
} else {
42
51
layer = fullLayout . _infolayer ;
43
- clipId = 'legend' ;
52
+ clipId = 'legend' + id ;
44
53
}
45
54
if ( ! layer ) return ;
46
55
clipId += fullLayout . _uid ;
@@ -50,7 +59,7 @@ function drawOne(gd, opts) {
50
59
var legendData ;
51
60
if ( ! inHover ) {
52
61
if ( ! gd . calcdata ) return ;
53
- legendData = fullLayout . showlegend && getLegendData ( gd . calcdata , legendObj ) ;
62
+ legendData = fullLayout . showlegend && getLegendData ( gd . calcdata , legendObj , fullLayout . _legends . length > 1 ) ;
54
63
} else {
55
64
if ( ! legendObj . entries ) return ;
56
65
legendData = getLegendData ( legendObj . entries , legendObj ) ;
@@ -59,12 +68,12 @@ function drawOne(gd, opts) {
59
68
var hiddenSlices = fullLayout . hiddenlabels || [ ] ;
60
69
61
70
if ( ! inHover && ( ! fullLayout . showlegend || ! legendData . length ) ) {
62
- layer . selectAll ( '.legend' ) . remove ( ) ;
71
+ layer . selectAll ( '.legend' + id ) . remove ( ) ;
63
72
fullLayout . _topdefs . select ( '#' + clipId ) . remove ( ) ;
64
- return Plots . autoMargin ( gd , 'legend' ) ;
73
+ return Plots . autoMargin ( gd , 'legend' + id ) ;
65
74
}
66
75
67
- var legend = Lib . ensureSingle ( layer , 'g' , 'legend' , function ( s ) {
76
+ var legend = Lib . ensureSingle ( layer , 'g' , 'legend' + id , function ( s ) {
68
77
if ( ! inHover ) s . attr ( 'pointer-events' , 'all' ) ;
69
78
} ) ;
70
79
@@ -85,14 +94,14 @@ function drawOne(gd, opts) {
85
94
legendObj . _titleWidth = 0 ;
86
95
legendObj . _titleHeight = 0 ;
87
96
if ( title . text ) {
88
- var titleEl = Lib . ensureSingle ( scrollBox , 'text' , 'legendtitletext ' ) ;
97
+ var titleEl = Lib . ensureSingle ( scrollBox , 'text' , 'legend' + id + 'titletext ') ;
89
98
titleEl . attr ( 'text-anchor' , 'start' )
90
99
. call ( Drawing . font , title . font )
91
100
. text ( title . text ) ;
92
101
93
102
textLayout ( titleEl , scrollBox , gd , legendObj , MAIN_TITLE ) ; // handle mathjax or multi-line text and compute title height
94
103
} else {
95
- scrollBox . selectAll ( '.legendtitletext ' ) . remove ( ) ;
104
+ scrollBox . selectAll ( '.legend' + id + 'titletext ') . remove ( ) ;
96
105
}
97
106
98
107
var scrollBar = Lib . ensureSingle ( legend , 'rect' , 'scrollbar' , function ( s ) {
@@ -118,7 +127,7 @@ function drawOne(gd, opts) {
118
127
} )
119
128
. each ( function ( ) { d3 . select ( this ) . call ( drawTexts , gd , legendObj ) ; } )
120
129
. call ( style , gd , legendObj )
121
- . each ( function ( ) { if ( ! inHover ) d3 . select ( this ) . call ( setupTraceToggle , gd ) ; } ) ;
130
+ . each ( function ( ) { if ( ! inHover ) d3 . select ( this ) . call ( setupTraceToggle , gd , id ) ; } ) ;
122
131
123
132
Lib . syncOrAsync ( [
124
133
Plots . previousPromises ,
@@ -128,7 +137,7 @@ function drawOne(gd, opts) {
128
137
var bw = legendObj . borderwidth ;
129
138
130
139
if ( ! inHover ) {
131
- var expMargin = expandMargin ( gd ) ;
140
+ var expMargin = expandMargin ( gd , id ) ;
132
141
133
142
// IF expandMargin return a Promise (which is truthy),
134
143
// we're under a doAutoMargin redraw, so we don't have to
@@ -146,10 +155,10 @@ function drawOne(gd, opts) {
146
155
ly = Lib . constrain ( ly , 0 , fullLayout . height - legendObj . _effHeight ) ;
147
156
148
157
if ( lx !== lx0 ) {
149
- Lib . log ( 'Constrain legend.x to make legend fit inside graph' ) ;
158
+ Lib . log ( 'Constrain legend' + id + ' .x to make legend fit inside graph') ;
150
159
}
151
160
if ( ly !== ly0 ) {
152
- Lib . log ( 'Constrain legend.y to make legend fit inside graph' ) ;
161
+ Lib . log ( 'Constrain legend' + id + ' .y to make legend fit inside graph') ;
153
162
}
154
163
}
155
164
@@ -295,7 +304,7 @@ function drawOne(gd, opts) {
295
304
}
296
305
297
306
function scrollHandler ( scrollBoxY , scrollBarHeight , scrollRatio ) {
298
- legendObj . _scrollY = gd . _fullLayout . legend . _scrollY = scrollBoxY ;
307
+ legendObj . _scrollY = gd . _fullLayout [ ' legend' + id ] . _scrollY = scrollBoxY ;
299
308
Drawing . setTranslate ( scrollBox , 0 , - scrollBoxY ) ;
300
309
301
310
Drawing . setRect (
@@ -331,11 +340,14 @@ function drawOne(gd, opts) {
331
340
} ,
332
341
doneFn : function ( ) {
333
342
if ( xf !== undefined && yf !== undefined ) {
334
- Registry . call ( '_guiRelayout' , gd , { 'legend.x' : xf , 'legend.y' : yf } ) ;
343
+ var obj = { } ;
344
+ obj [ 'legend' + id + '.x' ] = xf ;
345
+ obj [ 'legend' + id + '.y' ] = yf ;
346
+ Registry . call ( '_guiRelayout' , gd , obj ) ;
335
347
}
336
348
} ,
337
349
clickFn : function ( numClicks , e ) {
338
- var clickedTrace = layer . selectAll ( 'g.traces' ) . filter ( function ( ) {
350
+ var clickedTrace = groups . selectAll ( 'g.traces' ) . filter ( function ( ) {
339
351
var bbox = this . getBoundingClientRect ( ) ;
340
352
return (
341
353
e . clientX >= bbox . left && e . clientX <= bbox . right &&
@@ -403,6 +415,7 @@ function clickOrDoubleClick(gd, legend, legendItem, numClicks, evt) {
403
415
}
404
416
405
417
function drawTexts ( g , gd , legendObj ) {
418
+ var id = getId ( legendObj ) ;
406
419
var legendItem = g . data ( ) [ 0 ] [ 0 ] ;
407
420
var trace = legendItem . trace ;
408
421
var isPieLike = Registry . traceIs ( trace , 'pie-like' ) ;
@@ -425,7 +438,7 @@ function drawTexts(g, gd, legendObj) {
425
438
}
426
439
}
427
440
428
- var textEl = Lib . ensureSingle ( g , 'text' , 'legendtext ' ) ;
441
+ var textEl = Lib . ensureSingle ( g , 'text' , 'legend' + id + 'text ') ;
429
442
430
443
textEl . attr ( 'text-anchor' , 'start' )
431
444
. call ( Drawing . font , font )
@@ -479,12 +492,12 @@ function ensureLength(str, maxLength) {
479
492
return str ;
480
493
}
481
494
482
- function setupTraceToggle ( g , gd ) {
495
+ function setupTraceToggle ( g , gd , id ) {
483
496
var doubleClickDelay = gd . _context . doubleClickDelay ;
484
497
var newMouseDownTime ;
485
498
var numClicks = 1 ;
486
499
487
- var traceToggle = Lib . ensureSingle ( g , 'rect' , 'legendtoggle ' , function ( s ) {
500
+ var traceToggle = Lib . ensureSingle ( g , 'rect' , 'legend' + id + 'toggle ', function ( s ) {
488
501
if ( ! gd . _context . staticPlot ) {
489
502
s . style ( 'cursor' , 'pointer' ) . attr ( 'pointer-events' , 'all' ) ;
490
503
}
@@ -506,7 +519,7 @@ function setupTraceToggle(g, gd) {
506
519
} ) ;
507
520
traceToggle . on ( 'mouseup' , function ( ) {
508
521
if ( gd . _dragged || gd . _editing ) return ;
509
- var legend = gd . _fullLayout . legend ;
522
+ var legend = gd . _fullLayout [ ' legend' + id ] ;
510
523
511
524
if ( ( new Date ( ) ) . getTime ( ) - gd . _legendMouseDownTime > doubleClickDelay ) {
512
525
numClicks = Math . max ( numClicks - 1 , 1 ) ;
@@ -532,7 +545,11 @@ function computeTextDimensions(g, gd, legendObj, aTitle) {
532
545
533
546
var mathjaxGroup = g . select ( 'g[class*=math-group]' ) ;
534
547
var mathjaxNode = mathjaxGroup . node ( ) ;
535
- if ( ! legendObj ) legendObj = gd . _fullLayout . legend ;
548
+
549
+ var id = getId ( legendObj ) ;
550
+ if ( ! legendObj ) {
551
+ legendObj = gd . _fullLayout [ 'legend' + id ] ;
552
+ }
536
553
var bw = legendObj . borderwidth ;
537
554
var font ;
538
555
if ( aTitle === MAIN_TITLE ) {
@@ -557,9 +574,12 @@ function computeTextDimensions(g, gd, legendObj, aTitle) {
557
574
Drawing . setTranslate ( mathjaxGroup , 0 , height * 0.25 ) ;
558
575
}
559
576
} else {
560
- var textEl = g . select ( aTitle === MAIN_TITLE ?
561
- '.legendtitletext' : '.legendtext'
562
- ) ;
577
+ var cls = '.legend' + id + (
578
+ aTitle === MAIN_TITLE ? 'title' : ''
579
+ ) + 'text' ;
580
+
581
+ var textEl = g . select ( cls ) ;
582
+
563
583
var textLines = svgTextUtils . lineCount ( textEl ) ;
564
584
var textNode = textEl . node ( ) ;
565
585
@@ -620,7 +640,7 @@ function getTitleSize(legendObj) {
620
640
}
621
641
622
642
/*
623
- * Computes in fullLayout. legend:
643
+ * Computes in fullLayout[' legend' + id] :
624
644
*
625
645
* - _height: legend height including items past scrollbox height
626
646
* - _maxHeight: maximum legend height before scrollbox is required
@@ -631,7 +651,10 @@ function getTitleSize(legendObj) {
631
651
*/
632
652
function computeLegendDimensions ( gd , groups , traces , legendObj ) {
633
653
var fullLayout = gd . _fullLayout ;
634
- if ( ! legendObj ) legendObj = fullLayout . legend ;
654
+ var id = getId ( legendObj ) ;
655
+ if ( ! legendObj ) {
656
+ legendObj = fullLayout [ 'legend' + id ] ;
657
+ }
635
658
var gs = fullLayout . _size ;
636
659
637
660
var isVertical = helpers . isVertical ( legendObj ) ;
@@ -819,7 +842,7 @@ function computeLegendDimensions(gd, groups, traces, legendObj) {
819
842
var edits = gd . _context . edits ;
820
843
var isEditable = edits . legendText || edits . legendPosition ;
821
844
traces . each ( function ( d ) {
822
- var traceToggle = d3 . select ( this ) . select ( '.legendtoggle ' ) ;
845
+ var traceToggle = d3 . select ( this ) . select ( '.legend' + id + 'toggle ') ;
823
846
var h = d [ 0 ] . height ;
824
847
var legendgroup = d [ 0 ] . trace . legendgroup ;
825
848
var traceWidth = getTraceWidth ( d , legendObj , textGap ) ;
@@ -834,13 +857,13 @@ function computeLegendDimensions(gd, groups, traces, legendObj) {
834
857
} ) ;
835
858
}
836
859
837
- function expandMargin ( gd ) {
860
+ function expandMargin ( gd , id ) {
838
861
var fullLayout = gd . _fullLayout ;
839
- var legendObj = fullLayout . legend ;
862
+ var legendObj = fullLayout [ ' legend' + id ] ;
840
863
var xanchor = getXanchor ( legendObj ) ;
841
864
var yanchor = getYanchor ( legendObj ) ;
842
865
843
- return Plots . autoMargin ( gd , 'legend' , {
866
+ return Plots . autoMargin ( gd , 'legend' + id , {
844
867
x : legendObj . x ,
845
868
y : legendObj . y ,
846
869
l : legendObj . _width * ( FROM_TL [ xanchor ] ) ,
@@ -861,3 +884,7 @@ function getYanchor(legendObj) {
861
884
Lib . isMiddleAnchor ( legendObj ) ? 'middle' :
862
885
'top' ;
863
886
}
887
+
888
+ function getId ( legendObj ) {
889
+ return legendObj . _id || '' ;
890
+ }
0 commit comments