Skip to content

Commit 800c5b4

Browse files
authored
fix "inward" and "outward" hjust and vjust in geom_text() with angle > 45 (#4447)
1 parent 70986e6 commit 800c5b4

File tree

3 files changed

+91
-7
lines changed

3 files changed

+91
-7
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
* Fix a bug in `guide_bins()` where keys would disappear if the guide was
1717
reversed (@thomasp85, #4210)
1818

19+
* Fix bug in `geom_text()` where `"outward"` and `"inward"` justification for
20+
some `angle` values was reversed (@aphalo, #4169, #4447)
21+
1922
* Fix a bug in legend justification where justification was lost of the legend
2023
dimensions exceeded the available size (@thomasp85, #3635)
2124

R/geom-text.r

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,12 @@ GeomText <- ggproto("GeomText", Geom,
208208
}
209209

210210
data <- coord$transform(data, panel_params)
211+
211212
if (is.character(data$vjust)) {
212-
data$vjust <- compute_just(data$vjust, data$y)
213+
data$vjust <- compute_just(data$vjust, data$y, data$x, data$angle)
213214
}
214215
if (is.character(data$hjust)) {
215-
data$hjust <- compute_just(data$hjust, data$x)
216+
data$hjust <- compute_just(data$hjust, data$x, data$y, data$angle)
216217
}
217218

218219
textGrob(
@@ -234,11 +235,31 @@ GeomText <- ggproto("GeomText", Geom,
234235
draw_key = draw_key_text
235236
)
236237

237-
compute_just <- function(just, x) {
238-
inward <- just == "inward"
239-
just[inward] <- c("left", "middle", "right")[just_dir(x[inward])]
240-
outward <- just == "outward"
241-
just[outward] <- c("right", "middle", "left")[just_dir(x[outward])]
238+
compute_just <- function(just, a, b = a, angle = 0) {
239+
# As justification direction is relative to the text, not the plotting area
240+
# we need to swap x and y if text direction is rotated so that hjust is
241+
# applied along y and vjust along x.
242+
if (any(grepl("outward|inward", just))) {
243+
# ensure all angles are in -360...+360
244+
angle <- angle %% 360
245+
# ensure correct behaviour for angles in -360...+360
246+
angle <- ifelse(angle > 180, angle - 360, angle)
247+
angle <- ifelse(angle < -180, angle + 360, angle)
248+
rotated_forward <-
249+
grepl("outward|inward", just) & (angle > 45 & angle < 135)
250+
rotated_backwards <-
251+
grepl("outward|inward", just) & (angle < -45 & angle > -135)
252+
253+
ab <- ifelse(rotated_forward | rotated_backwards, b, a)
254+
just_swap <- rotated_backwards | abs(angle) > 135
255+
inward <-
256+
(just == "inward" & !just_swap | just == "outward" & just_swap)
257+
just[inward] <- c("left", "middle", "right")[just_dir(ab[inward])]
258+
outward <-
259+
(just == "outward" & !just_swap) | (just == "inward" & just_swap)
260+
just[outward] <- c("right", "middle", "left")[just_dir(ab[outward])]
261+
262+
}
242263

243264
unname(c(left = 0, center = 0.5, right = 1,
244265
bottom = 0, middle = 0.5, top = 1)[just])

tests/testthat/test-geom-text.R

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,63 @@ test_that("inward points close to center are centered", {
2929
c(0.5, 0.5, 0.5)
3030
)
3131
})
32+
33+
test_that("inward moves text towards center at 90 degrees", {
34+
expect_equal(
35+
compute_just(c("inward", "inward", "inward"),
36+
c(0, 0.5, 1),
37+
c(0, 0.5, 1),
38+
c(90, 90, 90)),
39+
c(0, 0.5, 1.0)
40+
)
41+
})
42+
43+
test_that("outward moves text away from center at 90 degrees", {
44+
expect_equal(
45+
compute_just(c("outward", "outward", "outward"),
46+
c(0, 0, 0),
47+
c(0, 0.5, 1),
48+
c(90, 90, 90)),
49+
c(1.0, 0.5, 0)
50+
)
51+
})
52+
53+
test_that("only inward and outward respond to angle", {
54+
expect_equal(
55+
compute_just(c("inward", "left", "outward"),
56+
c(0, 0, 0),
57+
c(0, 0.5, 1),
58+
c(90, 90, 90)),
59+
c(0.0, 0.0, 0.0)
60+
)
61+
})
62+
63+
test_that("inward moves text towards center at 150 degrees", {
64+
expect_equal(
65+
compute_just(c("inward", "inward", "inward"),
66+
c(0, 0.5, 1),
67+
c(0, 0.5, 1),
68+
c(150, 150, 150)),
69+
c(1.0, 0.5, 0.0)
70+
)
71+
})
72+
73+
test_that("inward moves text towards center at -90 degrees", {
74+
expect_equal(
75+
compute_just(c("inward", "inward", "inward"),
76+
c(0, 0.5, 1),
77+
c(0, 0.5, 1),
78+
c(-90, -90, -90)),
79+
c(1.0, 0.5, 0.0)
80+
)
81+
})
82+
83+
test_that("outward moves text away from center at 450 degrees", {
84+
expect_equal(
85+
compute_just(c("inward", "inward", "inward"),
86+
c(0, 0, 0),
87+
c(0, 0.5, 1),
88+
c(450, 450, 450)),
89+
c(0.0, 0.5, 1.0)
90+
)
91+
})

0 commit comments

Comments
 (0)