Skip to content
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

Copy angle heuristic for more guides. #5957

Merged
merged 11 commits into from
Aug 28, 2024
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# ggplot2 (development version)

* `guide_bins()`, `guide_colourbar()` and `guide_coloursteps()` gain an `angle`
argument to overrule theme settings, similar to `guide_axis(angle)`
(@teunbrand, #4594).
* (internal) rearranged the code of `Facet$draw_paensl()` method (@teunbrand).
* ggplot2 no longer imports {glue} (@teunbrand, #5986).
* `geom_rect()` can now derive the required corners positions from `x`/`width`
or `y`/`height` parameterisation (@teunbrand, #5861).
Expand Down
78 changes: 28 additions & 50 deletions R/guide-axis.R
Original file line number Diff line number Diff line change
Expand Up @@ -254,21 +254,8 @@ GuideAxis <- ggproto(
},

override_elements = function(params, elements, theme) {
label <- elements$text
if (!inherits(label, "element_text")) {
return(elements)
}
label_overrides <- axis_label_element_overrides(
params$position, params$angle
)
# label_overrides is an element_text, but label_element may not be;
# to merge the two elements, we just copy angle, hjust, and vjust
# unless their values are NULL
label$angle <- label_overrides$angle %||% label$angle
label$hjust <- label_overrides$hjust %||% label$hjust
label$vjust <- label_overrides$vjust %||% label$vjust

elements$text <- label
elements$text <-
label_angle_heuristic(elements$text, params$position, params$angle)
return(elements)
},

Expand Down Expand Up @@ -568,49 +555,40 @@ axis_label_priority_between <- function(x, y) {
)
}

#' Override axis text angle and alignment
#' Override text angle and alignment
#'
#' @param element An `element_text()`
#' @param axis_position One of bottom, left, top, or right
#' @param angle The text angle, or NULL to override nothing
#'
#' @return An [element_text()] that contains parameters that should be
#' overridden from the user- or theme-supplied element.
#' @noRd
#'
axis_label_element_overrides <- function(axis_position, angle = NULL) {

if (is.null(angle) || is.waive(angle)) {
return(element_text(angle = NULL, hjust = NULL, vjust = NULL))
label_angle_heuristic <- function(element, position, angle) {
if (!inherits(element, "element_text")
|| is.null(position)
|| is.null(angle %|W|% NULL)) {
return(element)
}
arg_match0(position, .trbl)

check_number_decimal(angle)
angle <- angle %% 360
arg_match0(
axis_position,
c("bottom", "left", "top", "right")
)

if (axis_position == "bottom") {

hjust = if (angle %in% c(0, 180)) 0.5 else if (angle < 180) 1 else 0
vjust = if (angle %in% c(90, 270)) 0.5 else if (angle > 90 & angle < 270) 0 else 1

} else if (axis_position == "left") {

hjust = if (angle %in% c(90, 270)) 0.5 else if (angle > 90 & angle < 270) 0 else 1
vjust = if (angle %in% c(0, 180)) 0.5 else if (angle < 180) 0 else 1

} else if (axis_position == "top") {

hjust = if (angle %in% c(0, 180)) 0.5 else if (angle < 180) 0 else 1
vjust = if (angle %in% c(90, 270)) 0.5 else if (angle > 90 & angle < 270) 1 else 0

} else if (axis_position == "right") {

hjust = if (angle %in% c(90, 270)) 0.5 else if (angle > 90 & angle < 270) 1 else 0
vjust = if (angle %in% c(0, 180)) 0.5 else if (angle < 180) 1 else 0

}

element_text(angle = angle, hjust = hjust, vjust = vjust)
radian <- deg2rad(angle)
digits <- 3

# Taking the sign of the (co)sine snaps the value to c(-1, 0, 1)
# Doing `x / 2 + 0.5` rescales it to c(0, 0.5, 1), which are good values for justification
# The rounding step ensures we can get (co)sine to exact 0 so it can become 0.5
# which we need for center-justifications
cosine <- sign(round(cos(radian), digits)) / 2 + 0.5
sine <- sign(round(sin(radian), digits)) / 2 + 0.5

# Depending on position, we might need to swap or flip justification values
hjust <- switch(position, left = cosine, right = 1 - cosine, top = 1 - sine, sine)
vjust <- switch(position, left = 1 - sine, right = sine, top = 1 - cosine, cosine)
Comment on lines +595 to +604
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm very pleased with this bit replacing a whole slew of nested if blocks.
cyclocomp::cyclocomp() says complexity has been reduced from 28 to 8 (>15 is generally considered 'too complex').


element$angle <- angle %||% element$angle
element$hjust <- hjust %||% element$hjust
element$vjust <- vjust %||% element$vjust
element
}
7 changes: 7 additions & 0 deletions R/guide-bins.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ NULL
#' guide if they are mapped in the same way.
#'
#' @inheritParams guide_legend
#' @param angle Overrules the theme settings to automatically apply appropriate
#' `hjust` and `vjust` for angled legend text. Can be a single number
#' representing the text angle in degrees, or `NULL` to not overrule the
#' settings (default).
#' @param show.limits Logical. Should the limits of the scale be shown with
#' labels and ticks. Default is `NULL` meaning it will take the value from the
#' scale. This argument is ignored if `labels` is given as a vector of
Expand Down Expand Up @@ -65,6 +69,7 @@ guide_bins <- function(
theme = NULL,

# general
angle = NULL,
position = NULL,
direction = NULL,
override.aes = list(),
Expand All @@ -85,6 +90,7 @@ guide_bins <- function(
theme = theme,

# general
angle = angle,
position = position,
direction = direction,
override.aes = rename_aes(override.aes),
Expand Down Expand Up @@ -115,6 +121,7 @@ GuideBins <- ggproto(
default_axis = element_line("black", linewidth = (0.5 / .pt)),
default_ticks = element_line(inherit.blank = TRUE),

angle = NULL,
direction = NULL,
override.aes = list(),
reverse = FALSE,
Expand Down
7 changes: 7 additions & 0 deletions R/guide-colorbar.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ NULL
#' @param alpha A numeric between 0 and 1 setting the colour transparency of
#' the bar. Use `NA` to preserve the alpha encoded in the colour itself
#' (default).
#' @param angle Overrules the theme settings to automatically apply appropriate
#' `hjust` and `vjust` for angled legend text. Can be a single number
#' representing the text angle in degrees, or `NULL` to not overrule the
#' settings (default).
#' @param draw.ulim A logical specifying if the upper limit tick marks should
#' be visible.
#' @param draw.llim A logical specifying if the lower limit tick marks should
Expand Down Expand Up @@ -124,6 +128,7 @@ guide_colourbar <- function(
alpha = NA,
draw.ulim = TRUE,
draw.llim = TRUE,
angle = NULL,
position = NULL,
direction = NULL,
reverse = FALSE,
Expand Down Expand Up @@ -151,6 +156,7 @@ guide_colourbar <- function(
nbin = nbin,
display = display,
alpha = alpha,
angle = angle,
draw_lim = c(isTRUE(draw.llim), isTRUE(draw.ulim)),
position = position,
direction = direction,
Expand Down Expand Up @@ -193,6 +199,7 @@ GuideColourbar <- ggproto(
direction = NULL,
reverse = FALSE,
order = 0,
angle = NULL,

# parameter
name = "colourbar",
Expand Down
2 changes: 2 additions & 0 deletions R/guide-colorsteps.R
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ guide_coloursteps <- function(
title = waiver(),
theme = NULL,
alpha = NA,
angle = NULL,
even.steps = TRUE,
show.limits = NULL,
direction = NULL,
Expand All @@ -65,6 +66,7 @@ guide_coloursteps <- function(
title = title,
theme = theme,
alpha = alpha,
angle = angle,
even.steps = even.steps,
show.limits = show.limits,
direction = direction,
Expand Down
3 changes: 3 additions & 0 deletions R/guide-legend.R
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ GuideLegend <- ggproto(
ggname("legend.key", element_grob(elements$key))
}

elements$text <-
label_angle_heuristic(elements$text, elements$text_position, params$angle)

elements
},

Expand Down
6 changes: 6 additions & 0 deletions man/guide_bins.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions man/guide_colourbar.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions man/guide_coloursteps.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 21 additions & 21 deletions tests/testthat/_snaps/coord_sf/coord-sf-with-custom-guides.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading