@@ -4,6 +4,9 @@ var Registry = require('../../registry');
44var helpers = require ( './helpers' ) ;
55
66module . exports = function getLegendData ( calcdata , opts ) {
7+ var grouped = helpers . isGrouped ( opts ) ;
8+ var reversed = helpers . isReversed ( opts ) ;
9+
710 var lgroupToTraces = { } ;
811 var lgroups = [ ] ;
912 var hasOneNonBlankGroup = false ;
@@ -18,14 +21,14 @@ module.exports = function getLegendData(calcdata, opts) {
1821 // TODO: check this against fullData legendgroups?
1922 var uniqueGroup = '~~i' + lgroupi ;
2023 lgroups . push ( uniqueGroup ) ;
21- lgroupToTraces [ uniqueGroup ] = [ [ legendItem ] ] ;
24+ lgroupToTraces [ uniqueGroup ] = [ legendItem ] ;
2225 lgroupi ++ ;
2326 } else if ( lgroups . indexOf ( legendGroup ) === - 1 ) {
2427 lgroups . push ( legendGroup ) ;
2528 hasOneNonBlankGroup = true ;
26- lgroupToTraces [ legendGroup ] = [ [ legendItem ] ] ;
29+ lgroupToTraces [ legendGroup ] = [ legendItem ] ;
2730 } else {
28- lgroupToTraces [ legendGroup ] . push ( [ legendItem ] ) ;
31+ lgroupToTraces [ legendGroup ] . push ( legendItem ) ;
2932 }
3033 }
3134
@@ -66,31 +69,66 @@ module.exports = function getLegendData(calcdata, opts) {
6669 // won't draw a legend in this case
6770 if ( ! lgroups . length ) return [ ] ;
6871
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 ;
7674
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 ) ;
8082 }
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+ }
8498
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+ ] ;
88127 }
89- lgroupsLength = 1 ;
90128 }
91129
92130 // number of legend groups - needed in legend/draw.js
93- opts . _lgroupsLength = lgroupsLength ;
131+ opts . _lgroupsLength = legendData . length ;
94132 // maximum name/label length - needed in legend/draw.js
95133 opts . _maxNameLength = maxNameLength ;
96134
0 commit comments