@@ -4,6 +4,9 @@ var Registry = require('../../registry');
4
4
var helpers = require ( './helpers' ) ;
5
5
6
6
module . exports = function getLegendData ( calcdata , opts ) {
7
+ var grouped = helpers . isGrouped ( opts ) ;
8
+ var reversed = helpers . isReversed ( opts ) ;
9
+
7
10
var lgroupToTraces = { } ;
8
11
var lgroups = [ ] ;
9
12
var hasOneNonBlankGroup = false ;
@@ -18,14 +21,14 @@ module.exports = function getLegendData(calcdata, opts) {
18
21
// TODO: check this against fullData legendgroups?
19
22
var uniqueGroup = '~~i' + lgroupi ;
20
23
lgroups . push ( uniqueGroup ) ;
21
- lgroupToTraces [ uniqueGroup ] = [ [ legendItem ] ] ;
24
+ lgroupToTraces [ uniqueGroup ] = [ legendItem ] ;
22
25
lgroupi ++ ;
23
26
} else if ( lgroups . indexOf ( legendGroup ) === - 1 ) {
24
27
lgroups . push ( legendGroup ) ;
25
28
hasOneNonBlankGroup = true ;
26
- lgroupToTraces [ legendGroup ] = [ [ legendItem ] ] ;
29
+ lgroupToTraces [ legendGroup ] = [ legendItem ] ;
27
30
} else {
28
- lgroupToTraces [ legendGroup ] . push ( [ legendItem ] ) ;
31
+ lgroupToTraces [ legendGroup ] . push ( legendItem ) ;
29
32
}
30
33
}
31
34
@@ -66,31 +69,66 @@ module.exports = function getLegendData(calcdata, opts) {
66
69
// won't draw a legend in this case
67
70
if ( ! lgroups . length ) return [ ] ;
68
71
69
- // rearrange lgroupToTraces into a d3-friendly array of arrays
70
- var lgroupsLength = lgroups . length ;
71
- var ltraces ;
72
- var legendData ;
73
-
74
- if ( hasOneNonBlankGroup && helpers . isGrouped ( opts ) ) {
75
- legendData = new Array ( lgroupsLength ) ;
72
+ // collapse all groups into one if all groups are blank
73
+ var shouldCollapse = ! hasOneNonBlankGroup || ! grouped ;
76
74
77
- for ( i = 0 ; i < lgroupsLength ; i ++ ) {
78
- ltraces = lgroupToTraces [ lgroups [ i ] ] ;
79
- legendData [ i ] = helpers . isReversed ( opts ) ? ltraces . reverse ( ) : ltraces ;
75
+ var legendData = [ ] ;
76
+ for ( i = 0 ; i < lgroups . length ; i ++ ) {
77
+ var t = lgroupToTraces [ lgroups [ i ] ] ;
78
+ if ( shouldCollapse ) {
79
+ legendData . push ( t [ 0 ] ) ;
80
+ } else {
81
+ legendData . push ( t ) ;
80
82
}
81
- } else {
82
- // collapse all groups into one if all groups are blank
83
- legendData = [ new Array ( lgroupsLength ) ] ;
83
+ }
84
+ if ( shouldCollapse ) legendData = [ legendData ] ;
85
+
86
+ for ( i = 0 ; i < legendData . length ; i ++ ) {
87
+ // find minimum rank within group
88
+ var groupMinRank = Infinity ;
89
+ for ( j = 0 ; j < legendData [ i ] . length ; j ++ ) {
90
+ var rank = legendData [ i ] [ j ] . trace . legendrank ;
91
+ if ( groupMinRank > rank ) groupMinRank = rank ;
92
+ }
93
+
94
+ // record on first group element
95
+ legendData [ i ] [ 0 ] . _groupMinRank = groupMinRank ;
96
+ legendData [ i ] [ 0 ] . _preGroupSort = i ;
97
+ }
84
98
85
- for ( i = 0 ; i < lgroupsLength ; i ++ ) {
86
- ltraces = lgroupToTraces [ lgroups [ i ] ] [ 0 ] ;
87
- legendData [ 0 ] [ helpers . isReversed ( opts ) ? lgroupsLength - i - 1 : i ] = ltraces ;
99
+ var orderFn1 = function ( a , b ) {
100
+ return (
101
+ ( a [ 0 ] . _groupMinRank - b [ 0 ] . _groupMinRank ) ||
102
+ ( a [ 0 ] . _preGroupSort - b [ 0 ] . _preGroupSort ) // fallback for old Chrome < 70 https://bugs.chromium.org/p/v8/issues/detail?id=90
103
+ ) ;
104
+ } ;
105
+
106
+ var orderFn2 = function ( a , b ) {
107
+ return (
108
+ ( a . trace . legendrank - b . trace . legendrank ) ||
109
+ ( a . _preSort - b . _preSort ) // fallback for old Chrome < 70 https://bugs.chromium.org/p/v8/issues/detail?id=90
110
+ ) ;
111
+ } ;
112
+
113
+ // sort considering minimum group legendrank
114
+ legendData . forEach ( function ( a , k ) { a [ 0 ] . _preGroupSort = k ; } ) ;
115
+ legendData . sort ( orderFn1 ) ;
116
+ for ( i = 0 ; i < legendData . length ; i ++ ) {
117
+ // sort considering trace.legendrank and legend.traceorder
118
+ legendData [ i ] . forEach ( function ( a , k ) { a . _preSort = k ; } ) ;
119
+ legendData [ i ] . sort ( orderFn2 ) ;
120
+ if ( reversed ) legendData [ i ] . reverse ( ) ;
121
+
122
+ // rearrange lgroupToTraces into a d3-friendly array of arrays
123
+ for ( j = 0 ; j < legendData [ i ] . length ; j ++ ) {
124
+ legendData [ i ] [ j ] = [
125
+ legendData [ i ] [ j ]
126
+ ] ;
88
127
}
89
- lgroupsLength = 1 ;
90
128
}
91
129
92
130
// number of legend groups - needed in legend/draw.js
93
- opts . _lgroupsLength = lgroupsLength ;
131
+ opts . _lgroupsLength = legendData . length ;
94
132
// maximum name/label length - needed in legend/draw.js
95
133
opts . _maxNameLength = maxNameLength ;
96
134
0 commit comments