|
1 | 1 | #' Create a ggplot inset |
2 | 2 | #' |
3 | | -#' @inheritParams ggwrap |
4 | | -#' @return A `patch_inset` object, which can be added in ggplot. |
| 3 | +#' @param plot Any graphic that can be converted into a [`grob`][grid::grob] |
| 4 | +#' using [`patch()`]. |
| 5 | +#' @param ... Additional arguments passed to the [`patch()`] method. |
| 6 | +#' @param align A string specifying the area to place the plot: `"full"` for the |
| 7 | +#' full area, `"plot"` for the full plotting area (including the axis label), or |
| 8 | +#' `"panel"` for only the actual area where data is drawn. |
| 9 | +#' @param clip A single boolean value indicating whether the grob should be |
| 10 | +#' clipped if they expand outside their designated area. |
| 11 | +#' @param on_top A single boolean value indicates whether the graphic plot |
| 12 | +#' should be put frontmost. Note: the graphic plot will always put above the |
| 13 | +#' background. |
| 14 | +#' @param vp A [`viewport`][grid::viewport] object, you can use this to define |
| 15 | +#' the plot area. |
| 16 | +#' @return An `inset` object, which can be added to ggplot. |
5 | 17 | #' @inherit patch seealso |
6 | 18 | #' @examples |
7 | 19 | #' library(grid) |
|
12 | 24 | #' p1 + inset(p2, vp = viewport(0.6, 0.6, |
13 | 25 | #' just = c(0, 0), width = 0.4, height = 0.4 |
14 | 26 | #' )) |
15 | | -#' @export |
16 | | -inset <- function( |
17 | | - plot, |
18 | | - ..., |
19 | | - align = "panel", |
20 | | - on_top = TRUE, |
21 | | - clip = TRUE, |
22 | | - vp = NULL) { |
23 | | - make_inset( |
24 | | - plot = plot, |
25 | | - ..., |
26 | | - align = align, |
27 | | - on_top = on_top, |
28 | | - clip = clip, |
29 | | - vp = vp |
30 | | - ) |
31 | | -} |
32 | | - |
33 | | -#' @importFrom grid editGrob |
34 | 27 | #' @importFrom rlang arg_match0 |
35 | | -make_inset <- function( |
36 | | - plot, |
37 | | - ..., |
38 | | - align, |
39 | | - on_top, |
40 | | - clip, |
41 | | - vp, |
42 | | - call = caller_call()) { |
43 | | - assert_bool(on_top, call = call) |
44 | | - align <- arg_match0(align, c("panel", "plot", "full"), error_call = call) |
45 | | - assert_bool(clip, call = call) |
46 | | - assert_s3_class(vp, "viewport", allow_null = TRUE, call = call) |
47 | | - if (!is.grob(grob <- patch(x = plot, ...))) { |
48 | | - cli_abort("{.fn patch} must return a {.cls grob}", call = call) |
49 | | - } |
50 | | - if (!is.null(vp)) grob <- editGrob(grob, vp = vp) |
51 | | - structure( |
52 | | - list( |
| 28 | +#' @importFrom grid is.grob |
| 29 | +#' @importFrom S7 prop |
| 30 | +#' @export |
| 31 | +inset <- S7::new_class( |
| 32 | + "inset", |
| 33 | + properties = list( |
| 34 | + grob = S7::new_S3_class("grob"), |
| 35 | + vp = S7::new_union(NULL, S7::new_S3_class("viewport")), |
| 36 | + align = S7::new_property( |
| 37 | + S7::class_character, |
| 38 | + setter = function(self, value) { |
| 39 | + value <- arg_match0( |
| 40 | + value, c("panel", "plot", "full"), |
| 41 | + arg_nm = "@align" |
| 42 | + ) |
| 43 | + prop(self, "align", check = FALSE) <- value |
| 44 | + self |
| 45 | + } |
| 46 | + ), |
| 47 | + clip = S7::new_property( |
| 48 | + S7::class_character, |
| 49 | + setter = function(self, value) { |
| 50 | + assert_bool(value, arg = "@clip") |
| 51 | + prop(self, "clip", check = FALSE) <- if (value) "on" else "off" |
| 52 | + self |
| 53 | + } |
| 54 | + ), |
| 55 | + on_top = S7::new_property( |
| 56 | + S7::class_logical, |
| 57 | + setter = function(self, value) { |
| 58 | + assert_bool(value, arg = "@on_top") |
| 59 | + prop(self, "on_top", check = FALSE) <- value |
| 60 | + self |
| 61 | + } |
| 62 | + ) |
| 63 | + ), |
| 64 | + constructor = function(plot, ..., align = "panel", on_top = TRUE, |
| 65 | + clip = TRUE, vp = NULL) { |
| 66 | + if (!is.grob(grob <- patch(x = plot, ...))) { |
| 67 | + cli_abort("{.fn patch} must return a {.cls grob} for {.obj_type_friendly {plot}}") |
| 68 | + } |
| 69 | + new_object( |
| 70 | + S7_object(), |
53 | 71 | grob = grob, |
| 72 | + vp = vp, |
54 | 73 | align = align, |
55 | | - clip = if (clip) "on" else "off", |
| 74 | + clip = clip, |
56 | 75 | on_top = on_top |
57 | | - ), |
58 | | - class = "patch_inset" |
59 | | - ) |
60 | | -} |
| 76 | + ) |
| 77 | + } |
| 78 | +) |
61 | 79 |
|
62 | 80 | #' @importFrom grid grid.draw |
63 | | -#' @export |
64 | | -grid.draw.patch_inset <- function(x, recording = TRUE) { |
65 | | - grid.draw(.subset2(x, "grob")) |
66 | | -} |
| 81 | +local(S7::method(grid.draw, inset) <- function(x, recording = TRUE) { |
| 82 | + grid.draw(prop(x, "grob")) |
| 83 | +}) |
67 | 84 |
|
68 | 85 | #' @importFrom ggplot2 update_ggplot |
69 | | -S7::method( |
70 | | - update_ggplot, |
71 | | - list(S7::new_S3_class("patch_inset"), ggplot2::class_ggplot) |
72 | | -) <- function(object, plot, object_name, ...) { |
73 | | - make_wrap(plot, object) |
74 | | -} |
| 86 | +S7::method(update_ggplot, list(inset, ggplot2::class_ggplot)) <- |
| 87 | + function(object, plot, objectname, ...) { |
| 88 | + make_wrap(plot, object) |
| 89 | + } |
0 commit comments