Skip to content

feat: create plotly.js bundle map programmatically #2336

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
## Improvements

* `ggplotly()` now works better with the development version of ggplot2 (> v3.4.4). (#2315, #2368)
* Create the proper `bundleTraceMap` list as internal package data object directly from the upstream JS file when plotly.js is updated. As a consequence, it's now possible to use the [`strict` bundle](https://github.com/plotly/plotly.js/blob/master/dist/README.md#plotlyjs-strict) via `plotly::partial_bundle(type = "strict")`.

## Bug fixes

Expand Down
62 changes: 3 additions & 59 deletions R/partial_bundles.R
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ verify_partial_bundle <- function(p) {

if (identical(bundleType, "auto")) {

# resolve an auto bundle by using the 1st bundle that supports all the types
# (ordering of bundleTraceMap is important!)
for (i in seq_along(bundleTraceMap)) {
# resolve an auto bundle by using the 1st bundle that supports all the types,
# except for the 'strict' bundle (ordering of bundleTraceMap is important!)
for (i in seq_along(bundleTraceMap[names(bundleTraceMap) != "strict"])) {
if (all(types %in% bundleTraceMap[[i]])) {
bundleType <- names(bundleTraceMap)[[i]]
break
Expand Down Expand Up @@ -158,59 +158,3 @@ plotlyjsBundleIDX <- function(p) {
plotlyjsBundle <- function(p) {
p$dependencies[[plotlyjsBundleIDX(p)]]
}

# TODO: create this object in inst/plotlyjs.R from the dist/README.md
bundleTraceMap <- list(
basic = c(
"scatter",
"bar",
"pie"
),
cartesian = c(
"scatter",
"bar",
"pie",
"box",
"heatmap",
"histogram",
"histogram2d",
"histogram2dcontour",
"contour",
"scatterternary",
"violin"
),
geo = c(
"scatter",
"scattergeo",
"choropleth"
),
gl3d = c(
"scatter",
"scatter3d",
"surface",
"mesh3d",
"cone"
),
gl2d = c(
"scatter",
"scattergl",
"splom",
"pointcloud",
"heatmapgl",
"contourgl",
"parcoords"
),
mapbox = c(
"scatter",
"scattermapbox"
),
finance = c(
"scatter",
"bar",
"pie",
"histogram",
"ohlc",
"candlestick",
"waterfall"
)
)
Binary file modified R/sysdata.rda
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/testthat/test-plotly-partial-bundles.R
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ test_that("Throws an informative error if wrong bundle is specified", {

expect_error(
partial_bundle(p1, type = "basic"),
"The 'basic' bundle supports the following trace types: 'scatter', 'bar', 'pie'"
"The 'basic' bundle supports the following trace types: 'bar', 'pie', 'scatter'"
)
})

Expand Down
45 changes: 30 additions & 15 deletions tools/update_plotlyjs.R
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
library(httr)
library(rprojroot)

# get zip URL to latest plotly.js release
x <- RETRY(
x <- httr::RETRY(
verb = "GET",
url = 'https://api.github.com/repos/plotly/plotly.js/releases/latest',
times = 5,
terminate_on = c(400, 401, 403, 404),
terminate_on_success = TRUE
)
zip <- content(x)$zipball_url
zip <- httr::content(x)$zipball_url

# remember where to copy over assets
pkg_dir <- find_package_root_file()
lib_dir <- find_package_root_file("inst/htmlwidgets/lib/plotlyjs")
pkg_dir <- rprojroot::find_package_root_file()
lib_dir <- rprojroot::find_package_root_file("inst/htmlwidgets/lib/plotlyjs")
patches <- list.files(
find_package_root_file("tools/patches"),
rprojroot::find_package_root_file("tools/patches"),
full.names = TRUE
)

Expand All @@ -25,8 +22,8 @@ dir.create(tmpdir)

withr::with_dir(tmpdir, {
# download source
download.file(zip, "plotly-js.zip")
unzip("plotly-js.zip", exdir = "plotly-js")
utils::download.file(zip, "plotly-js.zip")
utils::unzip("plotly-js.zip", exdir = "plotly-js")

withr::with_dir(
dir("plotly-js", full.names = TRUE), {
Expand Down Expand Up @@ -65,10 +62,27 @@ withr::with_dir(tmpdir, {
file.path(lib_dir, "locales", sub("^plotly-locale-", "", basename(locales))),
overwrite = TRUE
)
# update plot schema
Schema <- jsonlite::fromJSON(Sys.glob("dist/plot-schema.json"))
# update plot schema and (partial) bundles
Schema <- jsonlite::fromJSON("dist/plot-schema.json")
bundleTraceMap <-
paste0(readLines("tasks/util/constants.js"), collapse = "\n") |>
stringr::str_extract(pattern = "(?<=\\b(const|var) partialBundleTraces = )\\{[^}]+\\}")

if (is.na(bundleTraceMap)) {
stop("No `partialBundleTraces` variable definition found in Plotly source file `tasks/util/constants.js`. Does the regex pattern need an update?")
}
bundleTraceMap <- yaml::read_yaml(text = bundleTraceMap)

withr::with_dir(
pkg_dir, usethis::use_data(Schema, overwrite = TRUE, internal = TRUE)
pkg_dir, usethis::use_data(
Schema,
bundleTraceMap,
internal = TRUE,
overwrite = TRUE,
compress = "xz",
# TODO: use `version = 3L` once we depend on R (>= 3.5.0)
version = 2L
)
)

# plotly.js used to bundle a typedarray polyfill to support older browsers,
Expand All @@ -81,7 +95,8 @@ withr::with_dir(tmpdir, {
#)

message("Update plotlyMainBundle()'s version with ", basename(zip))

})

})

# clean up
unlink(tmpdir, recursive = TRUE)
Loading