@@ -513,7 +513,8 @@ GuideLegend <- ggproto(
513513 keys <- lapply(decor , function (g ) {
514514 data <- vec_slice(g $ data , i )
515515 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 )
517518 } else {
518519 zeroGrob()
519520 }
@@ -550,7 +551,7 @@ GuideLegend <- ggproto(
550551 # A guide may have already specified the size of the decoration, only
551552 # measure when it hasn't already.
552553 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 ,
554555 default_width = elements $ key.width ,
555556 default_height = elements $ key.height
556557 )
@@ -776,41 +777,55 @@ GuideLegend <- ggproto(
776777label_hjust_defaults <- c(top = 0.5 , bottom = 0.5 , left = 1 , right = 0 )
777778label_vjust_defaults <- c(top = 0 , bottom = 1 , left = 0.5 , right = 0.5 )
778779
779- measure_legend_keys <- function (decor , n , dim , byrow = FALSE ,
780+ measure_legend_keys <- function (keys , n , dim , byrow = FALSE ,
780781 default_width = 1 , default_height = 1 ) {
781- if (is.null(decor )) {
782+ if (is.null(keys )) {
782783 ans <- list (widths = NULL , heights = NULL )
783784 return (ans )
784785 }
785786
786787 # Vector padding in case rows * cols > keys
787- zeroes <- rep(0 , prod(dim ) - n )
788+ padding_zeroes <- rep(0 , prod(dim ) - n )
788789
789790 # 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 )
804793
805794 # 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 )
807797
808798 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 ))
811801 )
812802}
813803
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+
814829# For legend keys, check if the guide key's `.value` also occurs in the layer
815830# data when `show.legend = NA` and data is discrete. Note that `show.legend`
816831# besides TRUE (always show), FALSE (never show) and NA (show in relevant legend),
0 commit comments