Skip to content

Commit 671ef30

Browse files
committed
merge conflicts
2 parents e63b5b6 + c6b8a5d commit 671ef30

31 files changed

+222
-162
lines changed

DESCRIPTION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"),
1212
person("Karthik", "Ram", role = "aut",
1313
email = "karthik.ram@gmail.com"),
1414
person("Marianne", "Corvellec", role = "aut",
15-
email = "marianne@plot.ly"),
15+
email = "marianne.corvellec@igdore.org", comment = c(ORCID = "0000-0002-1994-3581")),
1616
person("Pedro", "Despouy", role = "aut",
1717
email = "pedro@plot.ly"),
1818
person("Plotly Technologies Inc.", role = "cph"))
@@ -32,7 +32,7 @@ Imports:
3232
digest,
3333
viridisLite,
3434
base64enc,
35-
htmltools,
35+
htmltools (>= 0.3.6),
3636
htmlwidgets (>= 1.3),
3737
tidyr,
3838
hexbin,
@@ -71,6 +71,6 @@ Suggests:
7171
plotlyGeoAssets,
7272
forcats
7373
LazyData: true
74-
RoxygenNote: 6.1.0
74+
RoxygenNote: 6.1.1
7575
Encoding: UTF-8
7676
Roxygen: list(markdown = TRUE)

NEWS.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,22 @@
1010
* Upgraded to plotly.js v1.42.5.
1111
* The `orca()` function now supports conversion of much larger figures (#1322) and works without a mapbox api token (#1314).
1212
* The `style()` function now supports "partial updates" (i.e. modification of a particular property of an object, rather than the entire object). For example, notice how the first plot retains the original marker shape (a square): `p <- plot_ly(x = 1:10, y = 1:10, symbol = I(15)); subplot(style(p, marker.color = "red"), style(p, marker = list(color = "red")))` (#1342).
13+
* **plotly** objects can now be serialized and unserialized in different environments (i.e., you can now use `saveRDS()` to save an object as an rds file and restore it on another machine with `readRDS()`). Note this object is *dynamically* linked to JavaScript libraries, so one should take care to use consistent versions of **plotly** when serializing and unserializing (#1376).
14+
* The `plotly_example()` will now attempt to open the source file(s) used to run the example. Set `edit = FALSE` to prevent the source file(s) from opening.
1315

1416
## BUG FIXES
1517

1618
* `subplot()` now bumps annotation `xref`/`yref` anchors correctly (#1181).
1719
* `subplot()` now accumulates images, repositions paper coordinates, and reanchors axis references (#1332).
20+
* `event_data("plotly_selected")` is no longer too eager to clear. That is, it is no longer set to `NULL` when clicking on a plot *after* triggering the "plotly_selected" event (#1121) (#1122).
21+
* The colorscale generated via the `color` argument in `plot_ly()` now uses an evenly spaced grid of values instead of quantiles (#1308).
22+
* When using **shinytest** to test a **shiny** that contains **plotly** graph, false positive differences are no longer reported (rstudio/shinytest#174).
23+
* The `color` and `stroke` arguments now work as expected for trace types with `fillcolor` but no `fill` attribute (e.g. `box` traces) (#1292).
1824
* Information emitted by in `event_data()` for heatmaps with atomic vectors for `x`/`y`/`z` is now correct (#1141).
1925
* Fixed issue where **dplyr** groups caused a problem in the ordering of data arrays passed to `marker` objects (#1351).
20-
* In some cases, a `ggplotly()` colorbar would cause issues with hover behavior, which is now fixed (#1381).
26+
* In some cases, a `ggplotly()` colorbar would cause issues with hover behavior, which is now fixed (#1381).
27+
* An articial marker no longer appears when clearing a crosstalk selection of a plot with a colorbar (#1406).
28+
* Clearing a highlight event via crosstalk no longer deletes all the traces added since initial draw (#1436).
2129
* Recursive attribute validation is now only performed on recursive objects (#1315).
2230

2331
# 4.8.0

R/highlight.R

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,20 +206,26 @@ highlight_defaults <- function() {
206206

207207
selectizeLib <- function(bootstrap = TRUE) {
208208
htmltools::htmlDependency(
209-
"selectize", "0.12.0", depPath("selectize"),
209+
name = "selectize",
210+
version = "0.12.0",
211+
package = "plotly",
212+
src = dependency_dir("selectize"),
210213
stylesheet = if (bootstrap) "selectize.bootstrap3.css",
211214
script = "selectize.min.js"
212215
)
213216
}
214217

215218
colourPickerLib <- function() {
216219
htmltools::htmlDependency(
217-
"colourpicker", "1.1", depPath("colourpicker"),
220+
name = "colourpicker",
221+
version = "1.1",
222+
package = "plotly",
223+
src = dependency_dir("colourpicker"),
218224
stylesheet = "colourpicker.min.css",
219225
script = "colourpicker.min.js"
220226
)
221227
}
222228

223-
depPath <- function(...) {
224-
system.file('htmlwidgets', 'lib', ..., package = 'plotly')
229+
dependency_dir <- function(...) {
230+
file.path('htmlwidgets', 'lib', ...)
225231
}

R/mathjax.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ mathjax_cdn <- function() {
2929
htmltools::htmlDependency(
3030
name = "mathjax",
3131
version = "2.7.4",
32-
src = c(file = depPath("mathjax")),
32+
package = "plotly",
33+
src = dependency_dir("mathjax"),
3334
script = "cdn.js"
3435
)
3536
}

R/orca.R

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ orca <- function(p, file = "plot.png", format = tools::file_ext(file),
7373

7474
# find the relevant plotly.js bundle
7575
plotlyjs <- plotlyjsBundle(b)
76-
plotlyjs_file <- file.path(plotlyjs$src$file, plotlyjs$script)
76+
plotlyjs_path <- file.path(plotlyjs$src$file, plotlyjs$script)
77+
# package field means src file path should be relative to pkg dir
78+
if (!is.null(plotlyjs$package)) {
79+
plotlyjs_path <- system.file(plotlyjs_path, package = plotlyjs$package)
80+
}
7781

7882
tmp <- tempfile(fileext = ".json")
7983
cat(to_JSON(b$x[c("data", "layout")]), file = tmp)
@@ -82,7 +86,7 @@ orca <- function(p, file = "plot.png", format = tools::file_ext(file),
8286
"graph", tmp,
8387
"-o", file,
8488
"--format", format,
85-
"--plotlyjs", plotlyjs_file,
89+
"--plotlyjs", plotlyjs_path,
8690
if (debug) "--debug",
8791
if (verbose) "--verbose",
8892
if (safe) "--safe-mode",
@@ -143,12 +147,16 @@ orca_serve <- function(port = 5151, mathjax = FALSE, safe = FALSE, request_limit
143147

144148
# use main bundle since any plot can be thrown at the server
145149
plotlyjs <- plotlyMainBundle()
146-
plotlyjs_file <- file.path(plotlyjs$src$file, plotlyjs$script)
150+
plotlyjs_path <- file.path(plotlyjs$src$file, plotlyjs$script)
151+
# package field means src file path should be relative to pkg dir
152+
if (!is.null(plotlyjs$package)) {
153+
plotlyjs_path <- system.file(plotlyjs_path, package = plotlyjs$package)
154+
}
147155

148156
args <- c(
149157
"serve",
150158
"-p", port,
151-
"--plotly", plotlyjs_file,
159+
"--plotly", plotlyjs_path,
152160
if (safe) "--safe-mode",
153161
if (orca_version() >= "1.1.1") "--graph-only",
154162
if (keep_alive) "--keep-alive",
@@ -196,9 +204,14 @@ orca_serve <- function(port = 5151, mathjax = FALSE, safe = FALSE, request_limit
196204
)
197205
}
198206

207+
correct_orca <- function() {
208+
orca_help <- processx::run("orca", "-h")
209+
grepl("plotly", orca_help[["stdout"]], ignore.case = TRUE)
210+
}
211+
199212

200213
orca_available <- function() {
201-
if (Sys.which("orca") == "") {
214+
if (Sys.which("orca") == "" || !correct_orca()) {
202215
stop(
203216
"The orca command-line utility is required for this functionality.\n\n",
204217
"Please follow the installation instructions here -- https://github.com/plotly/orca#installation",

R/partial_bundles.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ verify_partial_bundle <- function(p) {
139139
if (!file.exists(tmpfile)) {
140140
curl::curl_download(paste0("https://cdn.plot.ly/", bundle_script), tmpfile)
141141
}
142+
# file src is no longer in plotly's path (it's a temp file)
143+
p$dependencies[[idx]]$package <- NULL
142144
}
143145

144146
p

R/plotly.R

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -387,14 +387,12 @@ plot_dendro <- function(d, set = "A", xmin = -50, height = 500, width = 500, ...
387387
}
388388

389389
get_xy <- function(node) {
390-
setNames(
391-
tibble::as_tibble(dendextend::get_nodes_xy(node)),
392-
c("x", "y")
393-
)
390+
m <- dendextend::get_nodes_xy(node)
391+
colnames(m) <- c("x", "y")
392+
tibble::as_tibble(m)
394393
}
395394

396395

397-
398396
#' Convert a list to a plotly htmlwidget object
399397
#'
400398
#' @param x a plotly object.
@@ -434,8 +432,10 @@ as_widget <- function(x, ...) {
434432

435433
typedArrayPolyfill <- function() {
436434
htmltools::htmlDependency(
437-
"typedarray", "0.1",
438-
src = depPath("typedarray"),
435+
name = "typedarray",
436+
version = "0.1",
437+
package = "plotly",
438+
src = dependency_dir("typedarray"),
439439
script = "typedarray.min.js",
440440
all_files = FALSE
441441
)
@@ -445,19 +445,21 @@ typedArrayPolyfill <- function() {
445445
# and bundle size at print time.
446446
plotlyMainBundle <- function() {
447447
htmltools::htmlDependency(
448-
"plotly-main",
448+
name = "plotly-main",
449449
version = "1.42.5",
450-
src = depPath("plotlyjs"),
450+
package = "plotly",
451+
src = dependency_dir("plotlyjs"),
451452
script = "plotly-latest.min.js",
452453
all_files = FALSE
453454
)
454455
}
455456

456457
plotlyHtmlwidgetsCSS <- function() {
457458
htmltools::htmlDependency(
458-
"plotly-htmlwidgets-css",
459+
name = "plotly-htmlwidgets-css",
459460
version = plotlyMainBundle()$version,
460-
src = depPath("plotlyjs"),
461+
package = "plotly",
462+
src = dependency_dir("plotlyjs"),
461463
stylesheet = "plotly-htmlwidgets.css",
462464
all_files = FALSE
463465
)
@@ -468,8 +470,8 @@ locale_dependency <- function(locale) {
468470
stop("locale must be a character string (vector of length 1)", call. = FALSE)
469471
}
470472

471-
locale_dir <- depPath("plotlyjs", "locales")
472-
locales_all <- sub("\\.js$", "", list.files(locale_dir))
473+
locale_dir <- dependency_dir("plotlyjs", "locales")
474+
locales_all <- sub("\\.js$", "", list.files(system.file(locale_dir, package = "plotly")))
473475
if (!tolower(locale) %in% locales_all) {
474476
stop(
475477
"Invalid locale: '", locale, "'.\n\n",
@@ -491,6 +493,7 @@ locale_dependency <- function(locale) {
491493
htmltools::htmlDependency(
492494
name = paste0("plotly-locale-", locale),
493495
version = plotlyMainBundle()$version,
496+
package = "plotly",
494497
src = list(file = locale_dir),
495498
script = tolower(scripts),
496499
all_files = FALSE

R/plotly_build.R

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,12 @@ plotly_build.plotly <- function(p, registerFrames = TRUE) {
348348
p <- verify_hovermode(p)
349349
# try to convert to webgl if toWebGl was used
350350
p <- verify_webgl(p)
351+
# throw warning if webgl is being used in shinytest
352+
# currently, shinytest won't rely this warning, but it should
353+
# https://github.com/rstudio/shinytest/issues/146
354+
if (isTRUE(getOption("shiny.testmode"))) {
355+
if (is.webgl(p)) warning("shinytest can't currently render WebGL-based graphics.")
356+
}
351357
# crosstalk dynamically adds traces, meaning that a legend could be dynamically
352358
# added, which is confusing. So here we populate a sensible default.
353359
p <- verify_showlegend(p)
@@ -771,7 +777,7 @@ map_color <- function(traces, stroke = FALSE, title = "", colorway, na.color = "
771777
colScale <- scales::col_numeric(pal, rng, na.color = na.color)
772778
# generate the colorscale to be shared across traces
773779
vals <- if (diff(rng) > 0) {
774-
as.numeric(stats::quantile(allColor, probs = seq(0, 1, length.out = 25), na.rm = TRUE))
780+
seq(rng[1], rng[2], length.out = 25)
775781
} else {
776782
c(0, 1)
777783
}
@@ -1001,4 +1007,13 @@ supplyUserPalette <- function(default, user) {
10011007

10021008
# helper functions
10031009
array_ok <- function(attr) isTRUE(tryNULL(attr$arrayOk))
1004-
has_fill <- function(trace) isTRUE(trace$fill %in% c('tozeroy', 'tozerox', 'tonexty', 'tonextx', 'toself', 'tonext'))
1010+
has_fill <- function(trace) {
1011+
trace_type <- trace[["type"]] %||% "scatter"
1012+
# if trace type has fillcolor, but no fill attribute, then fill is always relevant
1013+
has_fillcolor <- has_attr(trace_type, "fillcolor")
1014+
has_fill <- has_attr(trace_type, "fill")
1015+
if (has_fillcolor && !has_fill) return(TRUE)
1016+
fill <- trace[["fill"]] %||% "none"
1017+
if (has_fillcolor && isTRUE(fill != "none")) return(TRUE)
1018+
FALSE
1019+
}

R/plotly_example.R

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,21 @@
55
#'
66
#' @param type the type of example
77
#' @param name the name of the example (valid names depend on `type`).
8+
#' @param edit whether to open the relevant source files using [file.edit]. Only relevant if `type` is `"shiny"` or `"rmd"`.
89
#' @param ... arguments passed onto the suitable method.
910
#' @export
1011
#' @author Carson Sievert
1112

12-
plotly_example <- function(type = c("demo", "shiny", "rmd"), name, ...) {
13+
plotly_example <- function(type = c("demo", "shiny", "rmd"), name, edit = TRUE, ...) {
1314

1415
type <- match.arg(type)
1516

1617
# demos don't necessarily need a name
1718
if (type == "demo") {
1819
if (missing(name)) {
19-
return(utils::demo(package = "plotly"))
20+
return(utils::demo(package = "plotly", ...))
2021
} else {
21-
return(utils::demo(topic = name, package = "plotly"))
22+
return(utils::demo(topic = name, package = "plotly", ...))
2223
}
2324
}
2425

@@ -36,10 +37,15 @@ plotly_example <- function(type = c("demo", "shiny", "rmd"), name, ...) {
3637
}
3738

3839
finalDir <- system.file("examples", type, name, package = "plotly")
40+
if (edit) {
41+
files <- list.files(finalDir, full.names = TRUE)
42+
scripts <- files[tools::file_ext(files) %in% c("R", "Rmd")]
43+
file.edit(scripts)
44+
}
3945

4046
if (type == "shiny") {
4147
try_library("shiny", "plotly_example")
42-
getFromNamespace("runApp", asNamespace("shiny"))(finalDir, display.mode = "showcase", ...)
48+
getFromNamespace("runApp", asNamespace("shiny"))(finalDir, ...)
4349
}
4450

4551
if (type == "rmd") {

R/proxy.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ plotlyProxyInvoke <- function(p, method, ...) {
100100
plotlyjs_methods <- function() {
101101
c(
102102
"restyle", "relayout", "update", "addTraces", "deleteTraces", "moveTraces",
103-
"extendTraces", "prependTraces", "purge", "toImage", "downloadImage", "animate"
103+
"extendTraces", "prependTraces", "purge", "toImage", "downloadImage", "animate",
104+
"newPlot", "react", "validate", "makeTemplate", "validateTemplate", "addFrames"
104105
)
105106
}
106107

R/shiny.R

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,18 @@ renderPlotly <- function(expr, env = parent.frame(), quoted = FALSE) {
3939
# this makes it possible to pass a ggplot2 object to renderPlotly()
4040
# https://github.com/ramnathv/htmlwidgets/issues/166#issuecomment-153000306
4141
expr <- as.call(list(call(":::", quote("plotly"), quote("prepareWidget")), expr))
42-
shinyRenderWidget(expr, plotlyOutput, env, quoted = TRUE)
42+
renderFunc <- shinyRenderWidget(expr, plotlyOutput, env, quoted = TRUE)
43+
# remove 'internal' plotly attributes that are known to cause false
44+
# positive test results in shinytest (snapshotPreprocessOutput was added
45+
# in shiny 1.0.3.9002, but we require >= 1.1)
46+
shiny::snapshotPreprocessOutput(
47+
renderFunc,
48+
function(value) {
49+
json <- from_JSON_safe(value)
50+
json$x <- json$x[setdiff(names(json$x), c("visdat", "cur_data", "attrs"))]
51+
to_JSON(json)
52+
}
53+
)
4354
}
4455

4556
# Converts a plot, OR a promise of a plot, to plotly

R/utils.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,13 @@ from_JSON <- function(x, ...) {
962962
jsonlite::fromJSON(x, simplifyDataFrame = FALSE, simplifyMatrix = FALSE, ...)
963963
}
964964

965+
from_JSON_safe <- function(txt, ...) {
966+
if (!jsonlite::validate(txt)) {
967+
stop("Expected a valid JSON string.")
968+
}
969+
from_JSON(txt, ...)
970+
}
971+
965972
i <- function(x) {
966973
if (is.null(x)) {
967974
return(NULL)

inst/docker/Dockerfile.vtest

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ RUN R -e "update.packages(ask = F)"
5656
RUN R -e "install.packages('devtools')"
5757
RUN R -e "install.packages('roxygen2')"
5858
RUN R -e "install.packages('testthat')"
59+
RUN R -e "install.packages('vdiffr')"
5960

6061
# sf system dependencies
6162
RUN add-apt-repository ppa:ubuntugis/ubuntugis-unstable --yes
@@ -86,17 +87,12 @@ RUN printf '#!/bin/bash \nxvfb-run --auto-servernum --server-args "-screen 0 640
8687
RUN chmod 777 /usr/bin/orca
8788

8889
# install visual testing packages
89-
RUN R -e "devtools::install_github('lionel-/vdiffr')"
9090
RUN R -e "devtools::install_github('brodieG/diffobj@development')"
9191

9292
# switch on visual testing
9393
ENV VDIFFR=true
9494
EXPOSE 3838
9595

96-
# installing rgeos from CRAN is currently broken
97-
# http://r-sig-geo.2731867.n2.nabble.com/Re-Unexpected-configure-error-following-recent-rgeos-release-td7592423.html
98-
RUN R -e "install.packages('rgeos', repos='http://R-Forge.R-project.org', type='source')"
99-
10096
RUN R -e "update.packages(ask=FALSE)"
10197

10298
# install any new dependencies, then either manage cases (the default) or run tests

inst/examples/shiny/Diamonds/server.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ shinyServer(function(input, output, session) {
2121
facets <- paste(input$facet_row, '~', input$facet_col)
2222
if (facets != '. ~ .') p <- p + facet_grid(facets)
2323
# return the ggplot object and renderPlotly() will know how to handle it
24-
p
24+
toWebGL(p)
2525
})
2626

2727
})

0 commit comments

Comments
 (0)