@@ -57,26 +57,6 @@ export class Legend extends Element {
57
57
*/
58
58
this . _hoveredItem = null ;
59
59
60
- this . navigation = {
61
- active : false ,
62
- page : 0 ,
63
- totalPages : 0 ,
64
- itemWidth : 0 ,
65
- itemHeight : 0 ,
66
- navWidth : 0 ,
67
- navHeight : 0 ,
68
- maxBlocks : 0 ,
69
- blocks : undefined ,
70
- text : undefined ,
71
- prev : undefined ,
72
- next : undefined ,
73
- legendItems : undefined ,
74
- _width : 0 ,
75
- _height : 0 ,
76
- _maxWidth : 0 ,
77
- _maxHeight : 0 ,
78
- } ;
79
-
80
60
// Are we in doughnut mode which has a different data type
81
61
this . doughnutMode = false ;
82
62
@@ -98,6 +78,7 @@ export class Legend extends Element {
98
78
this . position = undefined ;
99
79
this . weight = undefined ;
100
80
this . fullSize = undefined ;
81
+ this . navigation = undefined ;
101
82
}
102
83
103
84
update ( maxWidth , maxHeight , margins ) {
@@ -139,17 +120,16 @@ export class Legend extends Element {
139
120
legendItems . reverse ( ) ;
140
121
}
141
122
142
- this . navigation . legendItems = this . legendItems = legendItems ;
123
+ this . legendItems = legendItems ;
143
124
this . _computeNavigation ( ) ;
144
125
}
145
126
146
127
/**
147
128
* @private
148
129
*/
149
- _resetNavigation ( ) {
150
- if ( this . navigation . active ) {
151
- Object . assign ( this . navigation , {
152
- active : false ,
130
+ _initNavigation ( override ) {
131
+ if ( ! this . navigation ) {
132
+ this . navigation = {
153
133
page : 0 ,
154
134
totalPages : 0 ,
155
135
itemWidth : 0 ,
@@ -166,7 +146,11 @@ export class Legend extends Element {
166
146
_height : 0 ,
167
147
_maxWidth : 0 ,
168
148
_maxHeight : 0 ,
169
- } ) ;
149
+ } ;
150
+ }
151
+
152
+ if ( override ) {
153
+ Object . assign ( this . navigation , override ) ;
170
154
}
171
155
}
172
156
@@ -178,25 +162,28 @@ export class Legend extends Element {
178
162
const { navigation : navOpts , labels : labelOpts } = options ;
179
163
180
164
if ( ! ( navOpts && navOpts . display ) ) {
181
- this . _resetNavigation ( ) ;
165
+ this . navigation = undefined ;
182
166
return ;
183
167
}
184
168
const isHorizontal = this . isHorizontal ( ) ;
185
169
186
- this . navigation . active = true ;
187
- this . navigation . totalPages = 0 ;
188
- this . navigation . _width = this . navigation . _height = 0 ;
189
- this . navigation . _maxWidth = this . navigation . _maxHeight = 0 ;
190
- this . navigation . itemWidth = this . navigation . itemHeight = 0 ;
191
- this . navigation . maxBlocks = 0 ;
170
+ this . _initNavigation ( {
171
+ totalPages : 0 ,
172
+ _width : 0 ,
173
+ _height : 0 ,
174
+ _maxWidth : 0 ,
175
+ _maxHeight : 0 ,
176
+ itemWidth : 0 ,
177
+ itemHeight : 0 ,
178
+ maxBlocks : 0 ,
179
+ } ) ;
192
180
193
- const { arrowSize} = navOpts ;
194
181
const labelFont = toFont ( labelOpts . font ) ;
195
182
const { boxWidth, itemHeight : _itemHeight } = getBoxSize ( labelOpts , labelFont . size ) ;
196
183
const font = toFont ( navOpts . font ) ;
197
184
198
185
const padding = toPadding ( navOpts . padding ) ;
199
- this . navigation . navHeight = Math . max ( font . size , arrowSize ) + padding . height ;
186
+ this . navigation . navHeight = Math . max ( font . size , navOpts . arrowSize ) + padding . height ;
200
187
201
188
const grid = getGridAxis ( navOpts . grid ) ;
202
189
@@ -325,17 +312,16 @@ export class Legend extends Element {
325
312
}
326
313
327
314
buildNavigation ( ) {
328
- const { ctx, options : { align, navigation : navOpts , labels : labelOpts } } = this ;
329
- const { active, totalPages, navHeight} = this . navigation ;
330
-
331
- if ( ! active ) {
315
+ if ( ! this . navigation ) {
332
316
return ;
333
317
}
318
+ const { ctx, options : { align, navigation : navOpts , labels : labelOpts } } = this ;
319
+ const { totalPages, navHeight} = this . navigation ;
334
320
335
321
const font = toFont ( navOpts . font ) ;
336
322
337
323
if ( totalPages < 1 || ( totalPages === 1 && navOpts . display === 'auto' ) ) {
338
- this . _resetNavigation ( ) ;
324
+ this . navigation = undefined ;
339
325
return ;
340
326
}
341
327
@@ -394,7 +380,12 @@ export class Legend extends Element {
394
380
*/
395
381
_getLegendItemWidth ( legendItem , boxWidth , labelFont ) {
396
382
const hitboxWidth = calculateItemWidth ( legendItem , boxWidth , labelFont , this . ctx ) ;
397
- const itemWidth = this . navigation . itemWidth || hitboxWidth ;
383
+ let itemWidth = hitboxWidth ;
384
+
385
+ if ( this . navigation && this . navigation . itemWidth ) {
386
+ itemWidth = this . navigation . itemWidth ;
387
+ }
388
+
398
389
return { itemWidth, hitboxWidth} ;
399
390
}
400
391
@@ -403,10 +394,25 @@ export class Legend extends Element {
403
394
*/
404
395
_getLegendItemHeight ( legendItem , _itemHeight , labelFont ) {
405
396
const hitboxHeight = calculateItemHeight ( _itemHeight , legendItem , labelFont . lineHeight ) ;
406
- const itemHeight = this . navigation . itemHeight || hitboxHeight ;
397
+ let itemHeight = hitboxHeight ;
398
+
399
+ if ( this . navigation && this . navigation . itemHeight ) {
400
+ itemHeight = this . navigation . itemHeight ;
401
+ }
402
+
407
403
return { itemHeight, hitboxHeight} ;
408
404
}
409
405
406
+ /**
407
+ * @private
408
+ */
409
+ _getVisibleLegendItems ( ) {
410
+ if ( this . navigation ) {
411
+ return this . navigation . legendItems ;
412
+ }
413
+ return this . legendItems ;
414
+ }
415
+
410
416
fit ( ) {
411
417
const { options, ctx} = this ;
412
418
@@ -433,15 +439,23 @@ export class Legend extends Element {
433
439
if ( isHorizontal ) {
434
440
width = this . maxWidth ; // fill all the width
435
441
height = this . _fitRows ( titleHeight , labelFont , boxWidth , itemHeight ) + 10 ;
442
+
443
+ if ( this . navigation ) {
444
+ height = this . navigation . _height ;
445
+ }
436
446
} else {
437
447
height = this . maxHeight ; // fill all the height
438
448
width = this . _fitCols ( titleHeight , labelFont , boxWidth , itemHeight ) + 10 ;
449
+
450
+ if ( this . navigation ) {
451
+ width = this . navigation . _width ;
452
+ }
439
453
}
440
454
441
455
const maxWidth = isHorizontal ? this . maxWidth : ( options . maxWidth || this . maxWidth ) ;
442
456
const maxHeight = isHorizontal ? ( options . maxHeight || this . maxHeight ) : this . maxHeight ;
443
- this . width = Math . min ( this . navigation . _width || width , maxWidth ) ;
444
- this . height = Math . min ( this . navigation . _height || height , maxHeight ) ;
457
+ this . width = Math . min ( width , maxWidth ) ;
458
+ this . height = Math . min ( height , maxHeight ) ;
445
459
}
446
460
447
461
/**
@@ -460,7 +474,8 @@ export class Legend extends Element {
460
474
let row = 0 ;
461
475
let top = 0 ;
462
476
let currentLineHeight = 0 ;
463
- this . navigation . legendItems . forEach ( ( legendItem , i ) => {
477
+
478
+ this . _getVisibleLegendItems ( ) . forEach ( ( legendItem , i ) => {
464
479
const { itemWidth, itemHeight, hitboxWidth, hitboxHeight} = this . _getLegendItemSize ( legendItem , boxWidth , _itemHeight , labelFont ) ;
465
480
466
481
if ( i > 0 && lineWidths [ lineWidths . length - 1 ] + itemWidth + 2 * padding > maxWidth ) {
@@ -487,7 +502,11 @@ export class Legend extends Element {
487
502
const { maxHeight, options : { labels : { padding} } } = this ;
488
503
const hitboxes = this . legendHitBoxes = [ ] ;
489
504
const columnSizes = this . columnSizes = [ ] ;
490
- const heightLimit = maxHeight - titleHeight - this . navigation . navHeight ;
505
+ let heightLimit = maxHeight - titleHeight ;
506
+
507
+ if ( this . navigation ) {
508
+ heightLimit -= this . navigation . navHeight ;
509
+ }
491
510
492
511
let totalWidth = padding ;
493
512
let currentColWidth = 0 ;
@@ -496,7 +515,7 @@ export class Legend extends Element {
496
515
let left = 0 ;
497
516
let col = 0 ;
498
517
499
- this . navigation . legendItems . forEach ( ( legendItem , i ) => {
518
+ this . _getVisibleLegendItems ( ) . forEach ( ( legendItem , i ) => {
500
519
const { itemWidth, itemHeight, hitboxWidth, hitboxHeight} = this . _getLegendItemSize ( legendItem , boxWidth , _itemHeight , labelFont ) ;
501
520
502
521
// If too tall, go to new column
@@ -545,7 +564,11 @@ export class Legend extends Element {
545
564
left += hitbox . offsetWidth + padding ;
546
565
}
547
566
} else {
548
- const bottom = this . bottom - this . navigation . navHeight ;
567
+ let bottom = this . bottom ;
568
+
569
+ if ( this . navigation ) {
570
+ bottom -= this . navigation . navHeight ;
571
+ }
549
572
550
573
let col = 0 ;
551
574
let top = _alignStartEnd ( align , this . top + titleHeight + padding , bottom - this . columnSizes [ col ] . height ) ;
@@ -674,7 +697,11 @@ export class Legend extends Element {
674
697
// Horizontal
675
698
const isHorizontal = this . isHorizontal ( ) ;
676
699
const titleHeight = this . _computeTitleHeight ( ) ;
677
- const bottom = this . bottom - this . navigation . navHeight ;
700
+ let bottom = this . bottom ;
701
+
702
+ if ( this . navigation ) {
703
+ bottom -= this . navigation . navHeight ;
704
+ }
678
705
679
706
if ( isHorizontal ) {
680
707
cursor = {
@@ -693,7 +720,7 @@ export class Legend extends Element {
693
720
overrideTextDirection ( this . ctx , opts . textDirection ) ;
694
721
695
722
let currentLineHeight = 0 ;
696
- this . navigation . legendItems . forEach ( ( legendItem , i ) => {
723
+ this . _getVisibleLegendItems ( ) . forEach ( ( legendItem , i ) => {
697
724
ctx . strokeStyle = legendItem . fontColor ; // for strikethrough effect
698
725
ctx . fillStyle = legendItem . fontColor ; // render in correct colour
699
726
@@ -745,10 +772,13 @@ export class Legend extends Element {
745
772
* @private
746
773
*/
747
774
_drawNavigation ( ) {
775
+ if ( ! this . navigation ) {
776
+ return ;
777
+ }
748
778
const { ctx, options : { navigation : navOpts } } = this ;
749
- const { active , page, totalPages, maxBlocks, prev, next, text} = this . navigation ;
779
+ const { page, totalPages, maxBlocks, prev, next, text} = this . navigation ;
750
780
751
- if ( ! active || ( totalPages <= 1 && navOpts . display === 'auto' ) ) {
781
+ if ( totalPages <= 1 && navOpts . display === 'auto' ) {
752
782
return ;
753
783
}
754
784
@@ -813,13 +843,20 @@ export class Legend extends Element {
813
843
814
844
if ( this . isHorizontal ( ) ) {
815
845
// Move left / right so that the title is above the legend lines
816
- maxWidth = ( this . navigation . _maxWidth || Math . max ( ...this . lineWidths ) ) + labelOpts . padding ;
846
+ maxWidth = ( this . navigation ? this . navigation . _maxWidth : Math . max ( ...this . lineWidths ) ) + labelOpts . padding ;
817
847
y = this . top + topPaddingPlusHalfFontSize ;
818
848
left = _alignStartEnd ( options . align , left , this . right - maxWidth ) ;
819
849
} else {
820
850
// Move down so that the title is above the legend stack in every alignment
821
- const maxHeight = ( this . navigation . _maxHeight || this . columnSizes . reduce ( ( acc , size ) => Math . max ( acc , size . height ) , 0 ) )
822
- + labelOpts . padding + this . _computeTitleHeight ( ) + this . navigation . navHeight ;
851
+ let maxHeight ;
852
+
853
+ if ( this . navigation ) {
854
+ maxHeight = this . navigation . _maxHeight + this . navigation . navHeight ;
855
+ } else {
856
+ maxHeight = this . columnSizes . reduce ( ( acc , size ) => Math . max ( acc , size . height ) , 0 ) ;
857
+ }
858
+
859
+ maxHeight += labelOpts . padding + this . _computeTitleHeight ( ) ;
823
860
y = topPaddingPlusHalfFontSize + _alignStartEnd ( options . align , this . top , this . bottom - maxHeight ) ;
824
861
}
825
862
@@ -889,11 +926,10 @@ export class Legend extends Element {
889
926
* @private
890
927
*/
891
928
_getNavigationDirAt ( x , y ) {
892
- const { prev, next} = this . navigation ;
893
-
894
- if ( ! ( prev && next ) ) {
929
+ if ( ! ( this . navigation && this . navigation . prev && this . navigation . next ) ) {
895
930
return 0 ;
896
931
}
932
+ const { prev, next} = this . navigation ;
897
933
898
934
const { arrowSize} = this . options . navigation ;
899
935
// Add a padding to the clickable area (30% of the arrow size)
@@ -915,19 +951,20 @@ export class Legend extends Element {
915
951
* @private
916
952
*/
917
953
_getLegendItemAt ( x , y ) {
918
- let i , hitBox , lh ;
919
-
920
954
if ( _isBetween ( x , this . left , this . right )
921
955
&& _isBetween ( y , this . top , this . bottom ) ) {
922
956
// See if we are touching one of the dataset boxes
923
- lh = this . legendHitBoxes ;
924
- for ( i = 0 ; i < lh . length ; ++ i ) {
957
+ const lh = this . legendHitBoxes ;
958
+ const legendItems = this . _getVisibleLegendItems ( ) ;
959
+ let hitBox ;
960
+
961
+ for ( let i = 0 ; i < lh . length ; ++ i ) {
925
962
hitBox = lh [ i ] ;
926
963
927
964
if ( _isBetween ( x , hitBox . left , hitBox . left + hitBox . width )
928
965
&& _isBetween ( y , hitBox . top , hitBox . top + hitBox . height ) ) {
929
966
// Touching an element
930
- return this . navigation . legendItems [ i ] ;
967
+ return legendItems [ i ] ;
931
968
}
932
969
}
933
970
}
@@ -939,20 +976,25 @@ export class Legend extends Element {
939
976
* @private
940
977
*/
941
978
_handleNavigationEvent ( e ) {
942
- if ( e . type === 'click' ) {
943
- const dir = this . _getNavigationDirAt ( e . x , e . y ) ;
944
- if ( dir ) {
945
- const { page, totalPages} = this . navigation ;
946
- const lastPage = totalPages - 1 ;
947
- const newPage = this . navigation . page = Math . max ( 0 , Math . min ( lastPage , this . navigation . page + dir ) ) ;
948
-
949
- if ( newPage !== page ) {
950
- this . buildNavigation ( ) ;
951
- this . fit ( ) ;
952
- this . adjustHitBoxes ( ) ;
953
- this . chart . render ( ) ;
954
- }
955
- }
979
+ if ( ! this . navigation || this . navigation . totalPages < 2 || e . type !== 'click' ) {
980
+ return ;
981
+ }
982
+
983
+ const dir = this . _getNavigationDirAt ( e . x , e . y ) ;
984
+
985
+ if ( ! dir ) {
986
+ return ;
987
+ }
988
+
989
+ const { page, totalPages} = this . navigation ;
990
+ const lastPage = totalPages - 1 ;
991
+ const newPage = this . navigation . page = Math . max ( 0 , Math . min ( lastPage , this . navigation . page + dir ) ) ;
992
+
993
+ if ( newPage !== page ) {
994
+ this . buildNavigation ( ) ;
995
+ this . fit ( ) ;
996
+ this . adjustHitBoxes ( ) ;
997
+ this . chart . render ( ) ;
956
998
}
957
999
}
958
1000
@@ -961,9 +1003,7 @@ export class Legend extends Element {
961
1003
* @param {ChartEvent } e - The event to handle
962
1004
*/
963
1005
handleEvent ( e ) {
964
- if ( this . navigation . totalPages > 1 ) {
965
- this . _handleNavigationEvent ( e ) ;
966
- }
1006
+ this . _handleNavigationEvent ( e ) ;
967
1007
968
1008
const opts = this . options ;
969
1009
if ( ! isListened ( e . type , opts ) ) {
0 commit comments