@@ -513,7 +513,8 @@ GuideLegend <- ggproto(
513
513
keys <- lapply(decor , function (g ) {
514
514
data <- vec_slice(g $ data , i )
515
515
if (data $ .draw %|| % TRUE ) {
516
- g $ draw_key(data , g $ params , key_size )
516
+ key <- g $ draw_key(data , g $ params , key_size )
517
+ set_key_size(key , data $ linewidth , data $ size , key_size / 10 )
517
518
} else {
518
519
zeroGrob()
519
520
}
@@ -550,7 +551,7 @@ GuideLegend <- ggproto(
550
551
# A guide may have already specified the size of the decoration, only
551
552
# measure when it hasn't already.
552
553
sizes <- params $ sizes %|| % measure_legend_keys(
553
- params $ decor , n = n_breaks , dim = dim , byrow = byrow ,
554
+ grobs $ decor , n = n_breaks , dim = dim , byrow = byrow ,
554
555
default_width = elements $ key.width ,
555
556
default_height = elements $ key.height
556
557
)
@@ -776,41 +777,55 @@ GuideLegend <- ggproto(
776
777
label_hjust_defaults <- c(top = 0.5 , bottom = 0.5 , left = 1 , right = 0 )
777
778
label_vjust_defaults <- c(top = 0 , bottom = 1 , left = 0.5 , right = 0.5 )
778
779
779
- measure_legend_keys <- function (decor , n , dim , byrow = FALSE ,
780
+ measure_legend_keys <- function (keys , n , dim , byrow = FALSE ,
780
781
default_width = 1 , default_height = 1 ) {
781
- if (is.null(decor )) {
782
+ if (is.null(keys )) {
782
783
ans <- list (widths = NULL , heights = NULL )
783
784
return (ans )
784
785
}
785
786
786
787
# Vector padding in case rows * cols > keys
787
- zeroes <- rep(0 , prod(dim ) - n )
788
+ padding_zeroes <- rep(0 , prod(dim ) - n )
788
789
789
790
# For every layer, extract the size in cm
790
- size <- lapply(decor , function (g ) {
791
- lwd <- g $ data $ linewidth %|| % 0
792
- lwd [is.na(lwd )] <- 0
793
- size <- g $ data $ size %|| % 0
794
- size [is.na(size )] <- 0
795
- vec_recycle((size + lwd ) / 10 , size = nrow(g $ data ))
796
- })
797
- size <- inject(cbind(!!! size ))
798
-
799
- # Binned legends may have `n + 1` breaks, but we need to display `n` keys.
800
- size <- vec_slice(size , seq_len(n ))
801
-
802
- # For every key, find maximum across all layers
803
- size <- apply(size , 1 , max )
791
+ widths <- c(get_key_size(keys , " width" , n ), padding_zeroes )
792
+ heights <- c(get_key_size(keys , " height" , n ), padding_zeroes )
804
793
805
794
# Apply legend layout
806
- size <- matrix (c(size , zeroes ), nrow = dim [1 ], ncol = dim [2 ], byrow = byrow )
795
+ widths <- matrix (widths , nrow = dim [1 ], ncol = dim [2 ], byrow = byrow )
796
+ heights <- matrix (heights , nrow = dim [1 ], ncol = dim [2 ], byrow = byrow )
807
797
808
798
list (
809
- widths = pmax(default_width , apply(size , 2 , max )),
810
- heights = pmax(default_height , apply(size , 1 , max ))
799
+ widths = pmax(default_width , apply(widths , 2 , max )),
800
+ heights = pmax(default_height , apply(heights , 1 , max ))
811
801
)
812
802
}
813
803
804
+ get_key_size <- function (keys , which = " width" , n ) {
805
+ size <- lapply(keys , attr , which = which )
806
+ size [lengths(size ) != 1 ] <- 0
807
+ size <- matrix (unlist(size ), ncol = n )
808
+ apply(size , 2 , max )
809
+ }
810
+
811
+ set_key_size <- function (key , linewidth = NULL , size = NULL , default = NULL ) {
812
+ if (! is.null(attr(key , " width" )) && ! is.null(attr(key , ' height' ))) {
813
+ return (key )
814
+ }
815
+ if (! is.null(size ) || ! is.null(linewidth )) {
816
+ size <- size %|| % 0
817
+ linewidth <- linewidth %|| % 0
818
+ size <- if (is.na(size )[1 ]) 0 else size [1 ]
819
+ linewidth <- if (is.na(linewidth )[1 ]) 0 else linewidth [1 ]
820
+ size <- (size + linewidth ) / 10 # From mm to cm
821
+ } else {
822
+ size <- NULL
823
+ }
824
+ attr(key , " width" ) <- attr(key , " width" , TRUE ) %|| % size %|| % default [1 ]
825
+ attr(key , " height" ) <- attr(key , " height" , TRUE ) %|| % size %|| % default [2 ]
826
+ key
827
+ }
828
+
814
829
# For legend keys, check if the guide key's `.value` also occurs in the layer
815
830
# data when `show.legend = NA` and data is discrete. Note that `show.legend`
816
831
# besides TRUE (always show), FALSE (never show) and NA (show in relevant legend),
0 commit comments