-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cross layout #33
Merged
Merged
Cross layout #33
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I have tried to use three methods to implement cross_layout
#' @include layout-.R
methods::setClass(
"CrossLayout",
contains = "Layout",
list(
left = "ANY",
right = "ANY",
direction = "character",
plot = "ANY",
size = "ANY",
sizes = "ANY"
),
prototype = list(left = NULL, right = NULL)
)
new_cross_layout <- function(left, right, direction, mapping = aes(),
size = NA, theme = NULL, sizes = NA) {
call <- caller_call()
arg1 <- caller_arg(left) # nolint
arg2 <- caller_arg(right) # nolint
if (!is.null(theme)) assert_s3_class(theme, "theme", call = call)
# if the left layout is a `cross_layout()`, we get the right coords
left_coords <- get_layout_coords(left,
direction = direction, hand = "right"
)
if (is.null(left_coords)) {
cli_abort(c(
sprintf("{.arg {arg1}} cannot be a %s", object_name(left)),
i = "{.arg {arg1}} must align observations in {.field {direction}}."
), call = call)
} else if (is.null(left_nobs <- .subset2(left_coords, "nobs"))) {
cli_abort("layout coordinates for {.arg {arg1}} must be initialized",
call = call
)
}
# if the right layout is a `cross_layout()`, we get the left coords
right_coords <- get_layout_coords(right,
direction = direction, hand = "left"
)
if (is.null(right_coords)) {
cli_abort(c(
sprintf("{.arg {arg2}} cannot be a %s", object_name(right)),
i = "{.arg {arg2}} must align observations in {.field {direction}}."
), call = call)
} else if (is.null(right_nobs <- .subset2(right_coords, "nobs"))) {
cli_abort("layout coordinates for {.arg {arg2}} must be initialized",
call = call
)
}
# both layout must have same `nobs`
if (!identical(left_nobs, right_nobs)) {
cli_abort(
"{.arg {arg1}} (nobs: {left_nobs}) and {.arg {arg2}} (nobs: {right_nobs}) are incompatible",
call = call
)
}
# both layout must have compatible `panel`
left_panel <- .subset2(left_coords, "panel")
right_panel <- .subset2(right_coords, "panel")
if (is.null(left_panel) && is.null(right_panel)) {
} else if (!is.null(left_panel) && !is.null(right_panel)) {
# they can have different labels, but the underlying value must be the
# same
if (!identical(as.integer(left_panel), as.integer(right_panel))) {
cli_abort(
"{.arg {arg1}} and {.arg {arg2}} have incompatible panel groups",
call = call
)
}
} else if (is.null(left_panel)) {
left_coords$panel <- right_panel
# we always make the index following the panel
if (!is.null(old_index <- .subset2(left_coords, "index"))) {
# we always prevent from reordering twice.
if (!all(old_index == reorder_index(right_panel, old_index))) {
cli_abort(sprintf(
"%s disrupt the previously established ordering index of %s",
"{.arg {arg2}}", "{.arg {arg1}}"
), call = call)
}
}
left <- update_layout_coords(left,
direction = direction, coords = left_coords
)
} else {
right_coords$panel <- left_panel
# we always make the index following the panel
if (!is.null(old_index <- .subset2(right_coords, "index"))) {
# we always prevent from reordering twice.
if (!all(old_index == reorder_index(left_panel, old_index))) {
cli_abort(sprintf(
"%s disrupt the previously established ordering index of %s",
"{.arg {arg1}}", "{.arg {arg2}}"
), call = call)
}
}
right <- update_layout_coords(right,
direction = direction, coords = right_coords
)
}
size <- check_size(size, call = call)
sizes <- check_stack_sizes(sizes, call = call)
methods::new(
"CrossLayout",
left = left, right = right,
direction = direction,
plot = ggplot(mapping = mapping),
size = size,
sizes = sizes,
theme = theme
)
}
#' Connect two layouts crosswise
#'
#' @param e1,e2 A `r rd_layout()`.
#' @param ... Not used currently.
#' @inheritParams stack_align
#' @param size A single numeric value or a [`unit`][grid::unit] object
#' specifying the relative width (when `direction = "horizontal"`) or height
#' (when `direction = "vertical"`) of the main plot.
#' @inheritParams quad_free
#' @rdname cross_link
#' @export
methods::setGeneric("cross_link",
function(e1, e2, direction = NULL, ..., mapping = aes(),
size = NA, theme = NULL, sizes = NA) {
standardGeneric("cross_link")
},
signature = c("e1", "e2")
)
cross_link <- function() structure(list(), class = "ggalign_cross_link")
#' @include layout-stack-.R
#' @rdname cross_link
methods::setMethod(
"cross_link", c("StackLayout", "StackLayout"),
function(e1, e2, direction = NULL, ...) {
direction1 <- e1@direction
direction2 <- e2@direction
if (is.null(direction)) {
if (!identical(direction1, direction2)) {
cli_abort(
"{.arg e1} and {.arg e2} must have the same direction"
)
}
direction <- direction1
} else {
direction <- match.arg(direction, c("horizontal", "vertical"))
if (!identical(direction, direction1)) {
cli_abort(c(
"{.arg e1} is not compatible with the layout",
i = "Only {.field {direction}} stack is allowed"
))
} else if (!identical(direction, direction2)) {
cli_abort(c(
"{.arg e2} is not compatible with the layout",
i = "Only {.field {direction}} stack is allowed"
))
}
}
new_cross_layout(left = e1, right = e2, direction = direction, ...)
}
)
#' @include layout-quad-.R
#' @include layout-stack-.R
#' @rdname cross_link
methods::setMethod(
"cross_link", c("QuadLayout", "StackLayout"),
function(e1, e2, direction = NULL, ...) {
direction2 <- e2@direction
if (is.null(direction)) {
direction <- direction2
} else {
direction <- match.arg(direction, c("horizontal", "vertical"))
if (!identical(direction, direction2)) {
cli_abort(c(
"{.arg e2} is not compatible with the layout",
i = "Only {.field {direction}} stack is allowed"
))
}
}
new_cross_layout(left = e1, right = e2, direction = direction, ...)
}
)
#' @include layout-quad-.R
#' @include layout-stack-.R
#' @rdname cross_link
methods::setMethod(
"cross_link", c("StackLayout", "QuadLayout"),
function(e1, e2, direction = NULL, ...) {
direction1 <- e1@direction
if (is.null(direction)) {
direction <- direction1
} else {
direction <- match.arg(direction, c("horizontal", "vertical"))
if (!identical(direction, direction1)) {
cli_abort(c(
"{.arg e1} is not compatible with the layout",
i = "Only {.field {direction}} stack is allowed"
))
}
}
new_cross_layout(left = e1, right = e2, direction = direction, ...)
}
)
|
|
try to fix #14 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.