diff --git a/NEWS.md b/NEWS.md index cadba2e78e..272f551ca3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # ggplot2 (development version) +* (internal) New `Facet$draw_panel_content()` method for delegating panel + assembly (@Yunuuuu, #6406). * Facet gains a new method `setup_panel_params` to interact with the panel_params setted by Coord object (@Yunuuuu, #6397, #6380) * `position_fill()` avoids stacking observations of zero (@teunbrand, #6338) diff --git a/R/facet-.R b/R/facet-.R index 6e8c96f277..94b75148ee 100644 --- a/R/facet-.R +++ b/R/facet-.R @@ -68,6 +68,10 @@ NULL #' between the layer stack and the foreground defined by the Coord object #' (usually empty). The default is, as above, to return an empty grob. #' +#' - `draw_panel_content`: Draws each panel for the facet. Should return a list +#' of grobs, one for each panel. The output is used by the `draw_panels` +#' method. +#' #' - `draw_labels`: Given the gtable returned by `draw_panels`, #' add axis titles to the gtable. The default is to add one title at each side #' depending on the position and existence of axes. @@ -138,6 +142,34 @@ Facet <- ggproto("Facet", NULL, draw_front = function(data, layout, x_scales, y_scales, theme, params) { rep(list(zeroGrob()), vec_unique_count(layout$PANEL)) }, + draw_panel_content = function(self, panels, layout, x_scales, y_scales, + ranges, coord, data, theme, params, ...) { + facet_bg <- self$draw_back( + data, + layout, + x_scales, + y_scales, + theme, + params + ) + facet_fg <- self$draw_front( + data, + layout, + x_scales, + y_scales, + theme, + params + ) + + # Draw individual panels, then call `$draw_panels()` method to + # assemble into gtable + lapply(seq_along(panels[[1]]), function(i) { + panel <- lapply(panels, `[[`, i) + panel <- c(facet_bg[i], panel, facet_fg[i]) + panel <- coord$draw_panel(panel, ranges[[i]], theme) + ggname(paste("panel", i, sep = "-"), panel) + }) + }, draw_panels = function(self, panels, layout, x_scales = NULL, y_scales = NULL, ranges, coord, data = NULL, theme, params) { diff --git a/R/layout.R b/R/layout.R index 23048609dc..e2a27339e5 100644 --- a/R/layout.R +++ b/R/layout.R @@ -60,29 +60,17 @@ Layout <- ggproto("Layout", NULL, # Assemble the facet fg & bg, the coord fg & bg, and the layers # Returns a gtable render = function(self, panels, data, theme, labels) { - facet_bg <- self$facet$draw_back(data, + panels <- self$facet$draw_panel_content( + panels, self$layout, self$panel_scales_x, self$panel_scales_y, - theme, - self$facet_params - ) - facet_fg <- self$facet$draw_front( + self$panel_params, + self$coord, data, - self$layout, - self$panel_scales_x, - self$panel_scales_y, theme, self$facet_params ) - - # Draw individual panels, then assemble into gtable - panels <- lapply(seq_along(panels[[1]]), function(i) { - panel <- lapply(panels, `[[`, i) - panel <- c(facet_bg[i], panel, facet_fg[i]) - panel <- self$coord$draw_panel(panel, self$panel_params[[i]], theme) - ggname(paste("panel", i, sep = "-"), panel) - }) plot_table <- self$facet$draw_panels( panels, self$layout, diff --git a/man/ggplot2-ggproto.Rd b/man/ggplot2-ggproto.Rd index 9ba1fdfdce..dcd57c12a1 100644 --- a/man/ggplot2-ggproto.Rd +++ b/man/ggplot2-ggproto.Rd @@ -324,6 +324,9 @@ return an empty grob for each panel. \item \code{draw_front}: As above except the returned grob is placed between the layer stack and the foreground defined by the Coord object (usually empty). The default is, as above, to return an empty grob. +\item \code{draw_facet_panels}: Draws each panel for the facet. Should return a list +of grobs, one for each panel. The output is used by the \code{draw_panels} +method. \item \code{draw_labels}: Given the gtable returned by \code{draw_panels}, add axis titles to the gtable. The default is to add one title at each side depending on the position and existence of axes.