Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
- name: Install kaleido
if: matrix.config.visual_tests == true
run: |
Rscript -e 'library(reticulate); use_python(Sys.which("python")); py_install(c("kaleido", "plotly"))'
Rscript -e 'library(reticulate); use_python(Sys.which("python")); py_install(c("kaleido==0.2.1", "plotly"))'

# Run test() before R CMD check since, for some reason, rcmdcheck::rcmdcheck() skips vdiffr tests
- name: Run Tests
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Rapp.history
*.RData
*.Rproj.user
*.DS_Store
.venv
node_modules/
build_site.R
revdep_email.R
Expand Down
64 changes: 62 additions & 2 deletions R/kaleido.R
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ kaleido <- function(...) {

call_env <- rlang::caller_env()

if (!reticulate::py_available()) {
if (!reticulate::py_available(TRUE)) {
rlang::abort(c("`{reticulate}` wasn't able to find a Python environment.",
i = "If you have an existing Python installation, use `reticulate::use_python()` to inform `{reticulate}` of it.",
i = "To have `{reticulate}` install Python for you, `reticulate::install_python()`."
Expand All @@ -97,6 +97,67 @@ kaleido <- function(...) {
}
)

res <- if (is.null(tryNULL(kaleido$scopes))) {
newKaleidoScope(kaleido)
} else {
legacyKaleidoScope(kaleido)
}

class(res) <- "kaleidoScope"
res
}

newKaleidoScope <- function(kaleido) {
list(
scopes = NULL,
transform = function(p, file, ..., width = NULL, height = NULL, scale = NULL) {
# Perform JSON conversion exactly how the R package would do it
fig <- to_JSON(
plotly_build(p)$x[c("data", "layout", "config")]
)

# Write to JSON file
tmp_json <- tempfile(fileext = ".json")
on.exit(unlink(tmp_json))
writeLines(fig, tmp_json)

# Import it as a fig (dict)
load_json <- sprintf(
"import json; fig = json.load(open('%s'))",
tmp_json
)
reticulate::py_run_string(load_json)

# TODO: Pass plotlyMainBundlePath() (and mathjax?)
# to page level options
#reticulate::py_run_string(
# "import kaleido; kaleido.PageGenerator()"
#)

# Gather figure-level options
opts <- list(
format = tools::file_ext(file),
width = reticulate::r_to_py(width),
height = reticulate::r_to_py(height),
scale = reticulate::r_to_py(scale)
)

# TODO: how to bring in Mapbox token?
# https://github.com/plotly/Kaleido/issues/348
#mapbox <- Sys.getenv("MAPBOX_TOKEN", NA)
#if (!is.na(mapbox)) {
# opts$mapboxAccessToken <- mapbox
#}

# Write the figure to a file using kaleido
kaleido$write_fig_sync(reticulate::py$fig, file, opts = opts)
},
shutdown = function() {}
)
}


legacyKaleidoScope <- function(kaleido) {
py <- reticulate::py
scope_name <- paste0("scope_", new_id())
py[[scope_name]] <- kaleido$scopes$plotly$PlotlyScope(
Expand Down Expand Up @@ -151,7 +212,6 @@ kaleido <- function(...) {
reticulate::py_run_string(paste("del", scope_name))
})

class(res) <- "kaleidoScope"
res
}

Expand Down