Skip to content

Commit

Permalink
Addresses issue #13. Adds cut_path to override vjust.
Browse files Browse the repository at this point in the history
  • Loading branch information
AllanCameron committed Nov 20, 2021
1 parent d5acee6 commit a29e6c9
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 8 deletions.
10 changes: 8 additions & 2 deletions R/geom_textpath.R
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@
#' line should be plotted along with the text. If FALSE, any parameters or
#' aesthetics relating to the drawing of the line in the layer will be
#' ignored.
#' @param cut_path A single logical TRUE or FALSE which if TRUE breaks the path
#' into two sections, one on either side of the string and if FALSE leaves the
#' path unbroken. The default value is NA, which will break the line if the
#' string has a vjust of between 0 and 1.
#'
#' @details The \code{spacing} aesthetic allows fine control of spacing of text,
#' which is called 'tracking' in typography. The default is 0 and units are
Expand Down Expand Up @@ -168,7 +172,7 @@ geom_textpath <- function(
position = "identity", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE, ...,
lineend = "butt", linejoin = "round", linemitre = 10,
include_line = TRUE
include_line = TRUE, cut_path = NA
)
{
layer(geom = GeomTextpath, mapping = mapping, data = data, stat = stat,
Expand All @@ -180,6 +184,7 @@ geom_textpath <- function(
linejoin = linejoin,
linemitre = linemitre,
include_line = include_line,
cut_path = cut_path,
...
))
}
Expand Down Expand Up @@ -222,7 +227,7 @@ GeomTextpath <- ggproto("GeomTextpath", Geom,
# into a tree of grobs for plotting.
draw_panel = function(
data, panel_params, coord,
lineend = "butt", linejoin = "round", linemitre = 10
lineend = "butt", linejoin = "round", linemitre = 10, cut_path = NA
) {

#---- type conversion, checks & warnings ---------------------------#
Expand Down Expand Up @@ -301,6 +306,7 @@ GeomTextpath <- ggproto("GeomTextpath", Geom,
id = data$group,
hjust = data$hjust[first],
vjust = data$vjust,
cut_path = cut_path,
gp_text = text_gp,
gp_path = path_gp,
default.units = "npc"
Expand Down
16 changes: 13 additions & 3 deletions R/geometry_helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@
#' @param letters A `data.frame` with at least a numeric `length` column and
#' integer `id` column. The `id` column must match that in the `path`
#' argument.
#' @param cut_path A single logical TRUE or FALSE which if TRUE breaks the path
#' into two sections, one on either side of the string and if FALSE leaves the
#' path unbroken. The default value is NA, which will break the line if the
#' string has a vjust of between 0 and 1
#'
#' @details We probably want the option to draw the path itself, since this will
#' be less work for the end-user. If the `vjust` is between 0 and 1 then the
Expand All @@ -247,18 +251,24 @@
#' xy <- .add_path_data(xy)
#' glyphs <- .get_path_points(xy)
#' .get_surrounding_lines(xy, glyphs)
.get_surrounding_lines <- function(path, letters) {
.get_surrounding_lines <- function(path, letters, cut_path = NA) {


if(is.na(cut_path))
{
cut_path <- !(all(path$vjust <= 0) || all(path$vjust >= 1))
}

# Simplify if text isn't exactly on path
if (all(path$vjust < 0) || all(path$vjust > 1)) {
if (!cut_path) {
path$section <- "all"
} else {
# Lengths of group runs (assumed to be sorted)
# The `rle()` function handles NAs inelegantly,
# but I'm assuming `group` cannot be NA.
letter_lens <- rle(letters$id)$lengths
curve_lens <- rle(path$id)$lengths
trim <- rep_len(!(path$vjust < 0 | path$vjust > 1), length(letter_lens))
trim <- rep_len(TRUE, length(letter_lens))
trim <- rep(trim, curve_lens)

# Get locations where strings start and end
Expand Down
10 changes: 9 additions & 1 deletion R/grob_textpath.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
#' @param gp_text,gp_path An object of class `"gpar"`, typically the output from
#' a call from the [`gpar()`][grid::gpar] function. These are basically lists
#' of graphical parameters for the text and path respectively.
#' @param cut_path A single logical TRUE or FALSE which if TRUE breaks the path
#' into two sections, one on either side of the string and if FALSE leaves the
#' path unbroken. The default value is NA, which will break the line if the
#' string has a vjust of between 0 and 1
#' @inheritParams grid::textGrob
#'
#' @return An object of class `gTree`, containing grobs.
Expand Down Expand Up @@ -44,6 +48,7 @@ textpathGrob <- function(
vjust = NULL,
gp_text = gpar(),
gp_path = gpar(),
cut_path = NA,
default.units = "npc",
name = NULL,
vp = NULL
Expand Down Expand Up @@ -85,6 +90,7 @@ textpathGrob <- function(
x = x, y = y,
id = rep(seq_along(id_lens), id_lens),
vjust = vjust, hjust = hjust,
cut_path = cut_path,
gp_text = gp_text,
gp_path = gp_path
),
Expand Down Expand Up @@ -123,7 +129,7 @@ makeContent.textpath <- function(x) {
path <- do.call(rbind.data.frame, c(path, make.row.names = FALSE))

# Get bookends by trimming paths when it intersects text
path <- .get_surrounding_lines(path, text)
path <- .get_surrounding_lines(path, text, v$cut_path)

# Recycle graphical parameters to match lengths of path
gp_path <- recycle_gp(v$gp_path, `[`, i = path$id[path$start])
Expand Down Expand Up @@ -190,3 +196,5 @@ gp_fill_defaults <- function(gp, ..., defaults = get.gpar()) {
`%||%` <- function(x, y) {
if (is.null(x)) y else x
}


8 changes: 7 additions & 1 deletion man/geom_textpath.Rd

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

3 changes: 2 additions & 1 deletion man/geomtextpath-package.Rd

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

6 changes: 6 additions & 0 deletions man/textpathGrob.Rd

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

0 comments on commit a29e6c9

Please sign in to comment.