From dfa2c6adf78e5bb48fb5e5c020c3bdd205cb4b1e Mon Sep 17 00:00:00 2001 From: Stefan Moog Date: Sun, 7 Jun 2020 20:27:32 +0200 Subject: [PATCH 1/5] Fix bug in verify_attr. Closes issue #1720. --- R/utils.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/utils.R b/R/utils.R index 6fc2472f13..93dd1461b5 100644 --- a/R/utils.R +++ b/R/utils.R @@ -521,7 +521,7 @@ verify_attr <- function(proposed, schema, layoutAttr = FALSE) { # do the same for "sub-attributes" if (identical(role, "object") && is.recursive(proposed[[attr]])) { - proposed[[attr]] <- verify_attr(proposed[[attr]], schema[[attr]], layoutAttr = layoutAttr) + proposed[[attr]] <- verify_attr(proposed[[attr]], attrSchema, layoutAttr = layoutAttr) } } From 6ca747d544a3bc1509fd16da72a5b19078c741c1 Mon Sep 17 00:00:00 2001 From: Stefan Moog Date: Sun, 7 Jun 2020 20:29:16 +0200 Subject: [PATCH 2/5] Add test to check that ggplotly does not break discrete x-axis in facet panels with only one category. --- tests/testthat/test-facet-axis.R | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/testthat/test-facet-axis.R diff --git a/tests/testthat/test-facet-axis.R b/tests/testthat/test-facet-axis.R new file mode 100644 index 0000000000..d8e5c8ea87 --- /dev/null +++ b/tests/testthat/test-facet-axis.R @@ -0,0 +1,11 @@ +test_that("ggplotly does not break discrete x-axis with facet_yyyy in panels > 1 with only one category", { + d <- data.frame(cat = c("A", "A", "A"), pan = paste("Panel", c(1, 2, 2))) + gp <- ggplot(d, aes(cat)) + + geom_bar() + + facet_wrap(~pan) + L <- plotly_build(ggplotly(gp)) + # tickvals, ticktext and categoryarray have class 'AsIs' + expect_equal(class(L$x$layout$xaxis2$tickvals), "AsIs") + expect_equal(class(L$x$layout$xaxis2$ticktext), "AsIs") + expect_equal(class(L$x$layout$xaxis2$categoryarray), "AsIs") +}) From 7096402a9cfbc84c57bcfb7b611ef14b63150fb0 Mon Sep 17 00:00:00 2001 From: Stefan Moog Date: Wed, 17 Jun 2020 11:05:17 +0200 Subject: [PATCH 3/5] Update tests/testthat/test-facet-axis.R Co-authored-by: Carson Sievert --- tests/testthat/test-facet-axis.R | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/testthat/test-facet-axis.R b/tests/testthat/test-facet-axis.R index d8e5c8ea87..62562c9319 100644 --- a/tests/testthat/test-facet-axis.R +++ b/tests/testthat/test-facet-axis.R @@ -5,7 +5,11 @@ test_that("ggplotly does not break discrete x-axis with facet_yyyy in panels > 1 facet_wrap(~pan) L <- plotly_build(ggplotly(gp)) # tickvals, ticktext and categoryarray have class 'AsIs' - expect_equal(class(L$x$layout$xaxis2$tickvals), "AsIs") - expect_equal(class(L$x$layout$xaxis2$ticktext), "AsIs") - expect_equal(class(L$x$layout$xaxis2$categoryarray), "AsIs") + lapply(L$x$layout[c("xaxis", "xaxis2")], function(axis) { + expect_s3_class(axis$tickvals, "AsIs") + expect_s3_class(axis$ticktext, "AsIs") + expect_true(axis$ticktext == "A") + expect_s3_class(axis$categoryarray, "AsIs") + expect_true(axis$categoryarray == "A") + }) }) From 642069d4021963c80048ea1f2712253cea4e40f2 Mon Sep 17 00:00:00 2001 From: Stefan Moog Date: Wed, 17 Jun 2020 11:16:48 +0200 Subject: [PATCH 4/5] Add news item. --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 762df24359..9f4fe92385 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,8 @@ ## BUG FIXES +* `ggplotly()` now handles discrete axes of a `facet_wrap` and `facet_grid` correctly when there is only one category in panels > 1 (#1577 and #1720). + * `ggplotly()` now handles `element_blank()` and `factor()` labels in positional scales correctly (#1731 and #1772). # 4.9.2.1 From 9a856aea305e8ba7a74f6a544f92bb264458d62c Mon Sep 17 00:00:00 2001 From: Salim B Date: Mon, 22 Jun 2020 16:12:55 +0200 Subject: [PATCH 5/5] Translate `\n` to `
` in fct labels, too (#1700) * Translate `\n` to `
` in fct labels, too Before, this only worked for colums of type character. * add @salim-b as ctb * Add test for `translate_linebreaks()` * remove superfluous char conversion * change order of authors * replace forcats code with base R * add news item --- DESCRIPTION | 2 ++ NEWS.md | 2 ++ R/utils.R | 4 +++- tests/testthat/test-plotly.R | 31 +++++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index e9551518f0..8c5c69eef9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -15,6 +15,8 @@ Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"), email = "marianne.corvellec@igdore.org", comment = c(ORCID = "0000-0002-1994-3581")), person("Pedro", "Despouy", role = "aut", email = "pedro@plot.ly"), + person("Salim", "Brüggemann", role = "ctb", + email = "salim-b@pm.me", comment = c(ORCID = "0000-0002-5329-5987")), person("Plotly Technologies Inc.", role = "cph")) License: MIT + file LICENSE Description: Create interactive web graphics from 'ggplot2' graphs and/or a custom interface to the (MIT-licensed) JavaScript library 'plotly.js' inspired by the grammar of graphics. diff --git a/NEWS.md b/NEWS.md index 9f4fe92385..998d7a4c91 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,8 @@ * All HTTP requests are now retried upon failure (#1656) +* R linebreaks (`\n`) in _factor labels_ are now translated to HTML linebreaks (`
`), too. Before, this conversion was only done for colums of type character. ([#1700](https://github.com/ropensci/plotly/pull/1700), @salim-b) + ## BUG FIXES * `ggplotly()` now handles discrete axes of a `facet_wrap` and `facet_grid` correctly when there is only one category in panels > 1 (#1577 and #1720). diff --git a/R/utils.R b/R/utils.R index 93dd1461b5..5161d93491 100644 --- a/R/utils.R +++ b/R/utils.R @@ -609,12 +609,14 @@ translate_linebreaks <- function(p) { typ <- typeof(a) if (typ == "list") { # retain the class of list elements - # which important for many things, such as colorbars + # which is important for many things, such as colorbars a[] <- lapply(a, recurse) } else if (typ == "character" && !inherits(a, "JS_EVAL")) { attrs <- attributes(a) a <- gsub("\n", br(), a, fixed = TRUE) attributes(a) <- attrs + } else if (is.factor(a)) { + levels(a) <- gsub("\n", br(), levels(a), fixed = TRUE) } a } diff --git a/tests/testthat/test-plotly.R b/tests/testthat/test-plotly.R index 8dd43a405a..9f42656291 100644 --- a/tests/testthat/test-plotly.R +++ b/tests/testthat/test-plotly.R @@ -317,3 +317,34 @@ test_that("toWebGL() shouldn't complain if it's already webgl", { toWebGL() expect_silent(plotly_build(p)) }) + +test_that("Line breaks are properly translated (R -> HTML)", { + # create target labels + suffix <- "\n\n(third line)\n(fourth line)" + + target_labels <- iris$Species %>% + unique() %>% + paste0(suffix) %>% + gsub(pattern = "\n", + replacement = br(), + x = ., + fixed = TRUE) + + # test factor column + d <- iris + levels(d$Species) <- paste0(levels(d$Species), suffix) + p1 <- d %>% plot_ly(x = ~Sepal.Length, + y = ~Species) + + expect_equivalent(plotly_build(p1)[["x"]][["layout"]][["yaxis"]][["categoryarray"]], + target_labels) + + # test character column + p2 <- d %>% + dplyr::mutate(Species = as.character(Species)) %>% + plot_ly(x = ~Sepal.Length, + y = ~Species) + + expect_equivalent(plotly_build(p2)[["x"]][["layout"]][["yaxis"]][["categoryarray"]], + target_labels) +})