@@ -504,86 +504,70 @@ Guides <- ggproto(
504504 }
505505
506506 # prepare the position of inside legends
507- default_inside_just <- valid.just(
508- calc_element(" legend.justification.inside" , theme )
509- )
510- default_inside_position <- calc_element(
511- " legend.position.inside" , theme
507+ default_inside_just <- calc_element(" legend.justification.inside" , theme )
508+ default_inside_position <- calc_element(" legend.position.inside" , theme )
509+
510+ groups <- data_frame0(
511+ positions = positions ,
512+ justs = list (NULL ),
513+ coords = list (NULL )
512514 )
513- inside_justs <- inside_positions <- vector(" list" , length(positions ))
514515
515516 # we grouped the legends by the positions, for inside legends, they'll be
516517 # splitted by the actual inside coordinate
517518 for (i in which(positions == " inside" )) {
518- # the actual inside position and justification can be set in each guide
519- # by `theme` argument, here, we won't use `calc_element()` which will
520- # use inherits from `legend.justification` or `legend.position`, we only
521- # follow the inside elements from the guide theme
522- inside_just <- params [[i ]]$ theme [[" legend.justification.inside" ]]
523- inside_justs [i ] <- list (
524- valid.just(inside_just %|| % default_inside_just )
525- )
526- inside_positions [i ] <- list (
527- params [[i ]]$ theme [[
528- " legend.position.inside"
529- ]] %|| % default_inside_position %|| % inside_justs [[i ]]
530- )
531- }
532-
519+ # the actual inside position and justification can be set in each guide
520+ # by `theme` argument, here, we won't use `calc_element()` which will
521+ # use inherits from `legend.justification` or `legend.position`, we only
522+ # follow the inside elements from the guide theme
523+ just <- params [[i ]]$ theme [[" legend.justification.inside" ]]
524+ just <- valid.just(just %|| % default_inside_just )
525+ coord <- params [[i ]]$ theme [[" legend.position.inside" ]]
526+ coord <- coord %|| % default_inside_position %|| % just
533527
534- positions <- positions [ keep ]
535- inside_positions <- inside_positions [ keep ]
536- inside_justs <- inside_justs [ keep ]
528+ groups $ justs [[ i ]] <- just
529+ groups $ coord [[ i ]] <- coord
530+ }
537531
538- # we group the guide legends
539- locs <- vec_group_loc(new_data_frame(
540- set_names(
541- list (positions , inside_positions , inside_justs ),
542- c(" position" , " coords" , " justs" )
543- )
544- ))
545- grobs <- vec_chop(grobs , indices = locs $ loc )
546- keys <- locs $ key
532+ groups <- vec_group_loc(vec_slice(groups , keep ))
533+ grobs <- vec_chop(grobs , indices = groups $ loc )
534+ names(grobs ) <- groups $ key $ positions
547535
548536 # Set spacing
549537 theme $ legend.spacing <- theme $ legend.spacing %|| % unit(0.5 , " lines" )
550538 theme $ legend.spacing.y <- calc_element(" legend.spacing.y" , theme )
551539 theme $ legend.spacing.x <- calc_element(" legend.spacing.x" , theme )
552540
553541 # prepare output
554- ans <- vector(" list" , 5L )
555- names(ans ) <- c(.trbl , " inside" )
556- for (i in vec_seq_along(locs )) {
557- if (identical(position <- keys $ position [i ], " inside" )) {
558- ans [[position ]] <- c(
559- ans [[position ]],
560- list (self $ package_box(
561- grobs = grobs [[i ]],
562- position = position ,
563- theme = theme + theme(
564- legend.position.inside = keys $ coords [[i ]],
565- legend.justification.inside = keys $ justs [[i ]]
566- )
567- ))
542+ for (i in vec_seq_along(groups )) {
543+ adjust <- NULL
544+ position <- groups $ key $ position [i ]
545+ if (position == " inside" ) {
546+ adjust <- theme(
547+ legend.position.inside = groups $ key $ coord [[i ]],
548+ legend.justification.inside = groups $ key $ justs [[i ]]
568549 )
569- } else {
570- ans [[position ]] <- self $ package_box(
571- grobs = grobs [[i ]],
572- position = position , theme = theme
573- )
574- }
550+ }
551+ grobs [[i ]] <- self $ package_box(grobs [[i ]], position , theme + adjust )
575552 }
553+
576554 # merge inside grobs into single gtable
577- if ( ! is.null( ans $ inside )) {
578- ans $ inside <- gtable_add_grob(
579- gtable(unit(1 , " null " ), unit(1 , " null " )),
580- grobs = ans $ inside ,
581- clip = " off " ,
582- t = 1L , l = 1L ,
583- name = paste (" guide-box-inside" , seq_along( ans $ inside ), sep = " - " )
555+ is_inside <- names( grobs ) == " inside "
556+ if (sum( is_inside ) > 1 ) {
557+ inside <- gtable(unit(1 , " npc " ), unit(1 , " npc " ))
558+ inside <- gtable_add_grob(
559+ inside , grobs [ is_inside ] ,
560+ t = 1 , l = 1 , clip = " off " ,
561+ name = paste0 (" guide-box-inside- " , seq_len(sum( is_inside )) )
584562 )
563+ grobs <- grobs [! is_inside ]
564+ grobs $ inside <- inside
585565 }
586- ans
566+
567+ # fill in missing guides
568+ grobs [setdiff(c(.trbl , " inside" ), names(grobs ))] <- list (zeroGrob())
569+
570+ grobs
587571 },
588572
589573 # Render the guides into grobs
0 commit comments