Skip to content

Commit 15aca2b

Browse files
committed
ggplotly() failed when labels or title were a factor, because nchar() doesn't like factors.
1 parent c5beddf commit 15aca2b

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

R/ggplotly.R

+16-12
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ ggplotly.plotly <- function(p = ggplot2::last_plot(), width = NULL, height = NUL
8282
p
8383
}
8484

85+
# nchar() needs a character vector; sometimes x will be a
86+
# factor
87+
nchar0 <- function(x, ...) nchar(as.character(x), ...)
88+
8589
#' @export
8690
ggplotly.ggmatrix <- function(p = ggplot2::last_plot(), width = NULL,
8791
height = NULL, tooltip = "all", dynamicTicks = FALSE,
@@ -127,7 +131,7 @@ ggplotly.ggmatrix <- function(p = ggplot2::last_plot(), width = NULL,
127131
titleY = TRUE, titleX = TRUE) %>%
128132
hide_legend() %>%
129133
layout(dragmode = "select")
130-
if (nchar(p$title %||% "") > 0) {
134+
if (nchar0(p$title %||% "") > 0) {
131135
s <- layout(s, title = p$title)
132136
}
133137
for (i in seq_along(p$xAxisLabels)) {
@@ -436,7 +440,7 @@ gg2list <- function(p, width = NULL, height = NULL,
436440
font = text2font(theme$text)
437441
)
438442
# main plot title
439-
if (nchar(plot$labels$title %||% "") > 0) {
443+
if (nchar0(plot$labels$title %||% "") > 0) {
440444
gglayout$title <- list(
441445
text = faced(plot$labels$title, theme$plot.title$face),
442446
font = text2font(theme$plot.title),
@@ -567,7 +571,7 @@ gg2list <- function(p, width = NULL, height = NULL,
567571
# allocate enough space for the _longest_ text label
568572
axisTextX <- theme[["axis.text.x"]] %||% theme[["axis.text"]]
569573
labz <- unlist(lapply(layout$panel_params, function(pp) { pp[["x"]]$get_labels %()% pp$x.labels }))
570-
lab <- labz[which.max(nchar(labz))]
574+
lab <- labz[which.max(nchar0(labz))]
571575
panelMarginY <- panelMarginY + axisTicksX +
572576
bbox(lab, axisTextX$angle, unitConvert(axisTextX, "npc", "height"))[["height"]]
573577
}
@@ -579,7 +583,7 @@ gg2list <- function(p, width = NULL, height = NULL,
579583
# allocate enough space for the _longest_ text label
580584
axisTextY <- theme[["axis.text.y"]] %||% theme[["axis.text"]]
581585
labz <- unlist(lapply(layout$panel_params, function(pp) { pp[["y"]]$get_labels %()% pp$y.labels }))
582-
lab <- labz[which.max(nchar(labz))]
586+
lab <- labz[which.max(nchar0(labz))]
583587
panelMarginX <- panelMarginX + axisTicksY +
584588
bbox(lab, axisTextY$angle, unitConvert(axisTextY, "npc", "width"))[["width"]]
585589
}
@@ -806,15 +810,15 @@ gg2list <- function(p, width = NULL, height = NULL,
806810

807811
# do some stuff that should be done once for the entire plot
808812
if (i == 1) {
809-
axisTickText <- axisObj$ticktext[which.max(nchar(axisObj$ticktext))]
813+
axisTickText <- axisObj$ticktext[which.max(nchar0(axisObj$ticktext))]
810814
side <- if (xy == "x") "b" else "l"
811815
# account for axis ticks, ticks text, and titles in plot margins
812816
# (apparently ggplot2 doesn't support axis.title/axis.text margins)
813817
gglayout$margin[[side]] <- gglayout$margin[[side]] + axisObj$ticklen +
814818
bbox(axisTickText, axisObj$tickangle, axisObj$tickfont$size)[[type]] +
815819
bbox(axisTitleText, axisTitle$angle, unitConvert(axisTitle, "pixels", type))[[type]]
816820

817-
if (nchar(axisTitleText) > 0) {
821+
if (nchar0(axisTitleText) > 0) {
818822
axisTextSize <- unitConvert(axisText, "npc", type)
819823
axisTitleSize <- unitConvert(axisTitle, "npc", type)
820824
offset <-
@@ -836,7 +840,7 @@ gg2list <- function(p, width = NULL, height = NULL,
836840
}
837841
# facets have multiple axis objects, but only one title for the plot,
838842
# so we empty the titles and try to draw the title as an annotation
839-
if (nchar(axisTitleText) > 0) {
843+
if (nchar0(axisTitleText) > 0) {
840844
# npc is on a 0-1 scale of the _entire_ device,
841845
# but these units _should_ be wrt to the plotting region
842846
# multiplying the offset by 2 seems to work, but this is a terrible hack
@@ -873,7 +877,7 @@ gg2list <- function(p, width = NULL, height = NULL,
873877
)
874878
if (is_blank(theme[["strip.text.x"]])) col_txt <- ""
875879
if (inherits(plot$facet, "FacetGrid") && lay$ROW != 1) col_txt <- ""
876-
if (nchar(col_txt) > 0) {
880+
if (nchar0(col_txt) > 0) {
877881
col_lab <- make_label(
878882
col_txt, x = mean(xdom), y = max(ydom),
879883
el = theme[["strip.text.x"]] %||% theme[["strip.text"]],
@@ -890,7 +894,7 @@ gg2list <- function(p, width = NULL, height = NULL,
890894
)
891895
if (is_blank(theme[["strip.text.y"]])) row_txt <- ""
892896
if (inherits(plot$facet, "FacetGrid") && lay$COL != nCols) row_txt <- ""
893-
if (nchar(row_txt) > 0) {
897+
if (nchar0(row_txt) > 0) {
894898
row_lab <- make_label(
895899
row_txt, x = max(xdom), y = mean(ydom),
896900
el = theme[["strip.text.y"]] %||% theme[["strip.text"]],
@@ -1180,7 +1184,7 @@ is_blank <- function(x) {
11801184
# given text, and x/y coordinates on 0-1 scale,
11811185
# convert ggplot2::element_text() to plotly annotation
11821186
make_label <- function(txt = "", x, y, el = ggplot2::element_text(), ...) {
1183-
if (is_blank(el) || is.null(txt) || nchar(txt) == 0 || length(txt) == 0) {
1187+
if (is_blank(el) || is.null(txt) || nchar0(txt) == 0 || length(txt) == 0) {
11841188
return(NULL)
11851189
}
11861190
angle <- el$angle %||% 0
@@ -1215,9 +1219,9 @@ has_facet <- function(x) {
12151219

12161220
bbox <- function(txt = "foo", angle = 0, size = 12) {
12171221
# assuming the horizontal size of a character is roughly half of the vertical
1218-
n <- nchar(txt)
1222+
n <- nchar0(txt)
12191223
if (sum(n) == 0) return(list(height = 0, width = 0))
1220-
w <- size * (nchar(txt) / 2)
1224+
w <- size * (nchar0(txt) / 2)
12211225
angle <- abs(angle %||% 0)
12221226
# do the sensible thing in the majority of cases
12231227
if (angle == 0) return(list(height = size, width = w))

0 commit comments

Comments
 (0)