From 6407c51058a1f3fd1a340de4d815df0f6fd3fa56 Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Mon, 23 Jan 2017 13:09:27 -0600 Subject: [PATCH 1/4] first attempt at #768 --- NAMESPACE | 1 + R/print.R | 33 +++++++++++++++++---------------- man/embed_notebook.Rd | 6 +----- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index dabb91abac..3e34c1bb93 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,6 +3,7 @@ S3method(arrange_,plotly) S3method(distinct_,plotly) S3method(do_,plotly) +S3method(embed_notebook,plotly) S3method(filter_,plotly) S3method(fortify,SharedData) S3method(geom2trace,GeomBar) diff --git a/R/print.R b/R/print.R index a54c490548..3403f9900d 100644 --- a/R/print.R +++ b/R/print.R @@ -31,31 +31,32 @@ knit_print.plotly_figure <- function(x, options, ...) { #' \code{plot_ly} is used. If that is also \code{NULL}, '100\%' is the default. #' @param height attribute of the iframe. If \code{NULL}, the height in #' \code{plot_ly} is used. If that is also \code{NULL}, '400px' is the default. -#' @param file a filename for saving the standalone HTML -#' (only used if x is a non-figure object) #' @export -embed_notebook <- function(x, width = NULL, height = NULL, - file = paste0("plotlyJupyterHTML/", digest::digest(Sys.time()), ".html")) { +embed_notebook <- function(x, width = NULL, height = NULL) { if (system.file(package = "IRdisplay") == "") { warning("You need the IRdisplay package to use this function: \n", "devtools::install_github(c('IRkernel/repr', 'IRKernel/IRdisplay'))") return(x) } - l <- plotly_build(x) - src <- if (is.null(l$url)) { - dir <- dirname(file) - if (!dir.exists(dir)) dir.create(dir, recursive = TRUE) - owd <- setwd(dir) - on.exit(setwd(owd), add = TRUE) - htmlwidgets::saveWidget(l, file = basename(file)) - file - } else { - l$url + UseMethod("embed_notebook") +} + +#' @export +embed_notebook.plotly <- function(x, width = NULL, height = NULL) { + p <- plotly_build(x) + p$width <- width %||% p$width + p$height <- height %||% p$height + html <- getFromNamespace("toHTML", asNamespace("htmlwidgets"))(p) + # if we've already printed a plotly object, remove it's dependencies + if (!is.null(last_plot())) { + htmltools::htmlDependencies(html) <- NULL } - iframe <- plotly_iframe(src, width %||% l$width, height %||% l$height, url_ext = "") - get("display_html", envir = asNamespace("IRdisplay"))(iframe) + get("display_html", envir = asNamespace("IRdisplay"))(as.character(html)) } +# TODO: provide method for api_figure objects + + plotly_iframe <- function(url = "", width = NULL, height = NULL, url_ext = ".embed") { url <- paste0(url, url_ext) sprintf( diff --git a/man/embed_notebook.Rd b/man/embed_notebook.Rd index af21800738..637df75e15 100644 --- a/man/embed_notebook.Rd +++ b/man/embed_notebook.Rd @@ -4,8 +4,7 @@ \alias{embed_notebook} \title{Embed a plotly figure as an iframe into a Jupyter Notebook} \usage{ -embed_notebook(x, width = NULL, height = NULL, - file = paste0("plotlyJupyterHTML/", digest::digest(Sys.time()), ".html")) +embed_notebook(x, width = NULL, height = NULL) } \arguments{ \item{x}{a plotly object} @@ -15,9 +14,6 @@ embed_notebook(x, width = NULL, height = NULL, \item{height}{attribute of the iframe. If \code{NULL}, the height in \code{plot_ly} is used. If that is also \code{NULL}, '400px' is the default.} - -\item{file}{a filename for saving the standalone HTML -(only used if x is a non-figure object)} } \description{ Embed a plotly figure as an iframe into a Jupyter Notebook From fe1916302e1dc28bbbbf9d137b3572f0853f23da Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Mon, 20 Mar 2017 12:59:16 -0500 Subject: [PATCH 2/4] wrap html in an iframe --- R/print.R | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/R/print.R b/R/print.R index 3403f9900d..b7f02c9efc 100644 --- a/R/print.R +++ b/R/print.R @@ -44,14 +44,17 @@ embed_notebook <- function(x, width = NULL, height = NULL) { #' @export embed_notebook.plotly <- function(x, width = NULL, height = NULL) { p <- plotly_build(x) - p$width <- width %||% p$width - p$height <- height %||% p$height - html <- getFromNamespace("toHTML", asNamespace("htmlwidgets"))(p) - # if we've already printed a plotly object, remove it's dependencies - if (!is.null(last_plot())) { - htmltools::htmlDependencies(html) <- NULL - } - get("display_html", envir = asNamespace("IRdisplay"))(as.character(html)) + tmp <- tempfile(fileext = ".html") + on.exit(unlink(tmp), add = TRUE) + res <- htmlwidgets::saveWidget(p, tmp) + # wrap in an iframe as *nteract* won't do this automatically + html <- sprintf( + '', + base64enc::dataURI(mime = "text/html;charset=utf-8", file = tmp), + width %||% p$width %||% "100%", + height %||% p$height %||% 400 + ) + IRdisplay::display_html(html) } # TODO: provide method for api_figure objects From df69d2f688097692d1e90281bf58042707aefdfd Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Mon, 20 Mar 2017 14:21:57 -0500 Subject: [PATCH 3/4] soft deprecation of file argument --- R/print.R | 8 ++++++-- man/embed_notebook.Rd | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/R/print.R b/R/print.R index b7f02c9efc..c65d05b502 100644 --- a/R/print.R +++ b/R/print.R @@ -31,18 +31,22 @@ knit_print.plotly_figure <- function(x, options, ...) { #' \code{plot_ly} is used. If that is also \code{NULL}, '100\%' is the default. #' @param height attribute of the iframe. If \code{NULL}, the height in #' \code{plot_ly} is used. If that is also \code{NULL}, '400px' is the default. +#' @param file deprecated. #' @export -embed_notebook <- function(x, width = NULL, height = NULL) { +embed_notebook <- function(x, width = NULL, height = NULL, file = NULL) { if (system.file(package = "IRdisplay") == "") { warning("You need the IRdisplay package to use this function: \n", "devtools::install_github(c('IRkernel/repr', 'IRKernel/IRdisplay'))") return(x) } + if (!is.null(file)) { + warning("The file argument is no longer used", call. = FALSE) + } UseMethod("embed_notebook") } #' @export -embed_notebook.plotly <- function(x, width = NULL, height = NULL) { +embed_notebook.plotly <- function(x, width = NULL, height = NULL, file = NULL) { p <- plotly_build(x) tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) diff --git a/man/embed_notebook.Rd b/man/embed_notebook.Rd index 93a7455a07..15e52a9b48 100644 --- a/man/embed_notebook.Rd +++ b/man/embed_notebook.Rd @@ -4,7 +4,7 @@ \alias{embed_notebook} \title{Embed a plotly figure as an iframe into a Jupyter Notebook} \usage{ -embed_notebook(x, width = NULL, height = NULL) +embed_notebook(x, width = NULL, height = NULL, file = NULL) } \arguments{ \item{x}{a plotly object} @@ -14,6 +14,8 @@ embed_notebook(x, width = NULL, height = NULL) \item{height}{attribute of the iframe. If \code{NULL}, the height in \code{plot_ly} is used. If that is also \code{NULL}, '400px' is the default.} + +\item{file}{deprecated.} } \description{ Embed a plotly figure as an iframe into a Jupyter Notebook From fa86863961db6226e1c1d8be124f2d7467db6623 Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Mon, 20 Mar 2017 14:41:25 -0500 Subject: [PATCH 4/4] support figure objects; update news --- NEWS.md | 1 + R/print.R | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0ab95efeec..c93ee9746b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -23,6 +23,7 @@ ## BUG FIXES +* `embed_notebook()` now works in *nteract* notebooks (see #768). * Fix for hoverinfo displaying the heights of bars in the translation `geom_bar()` via `ggplotly()`. Fixes #557 and #662. * Font faces for axis titles are now translated in `ggplotly()`. Fixes #861. diff --git a/R/print.R b/R/print.R index c65d05b502..7ce9893349 100644 --- a/R/print.R +++ b/R/print.R @@ -47,22 +47,29 @@ embed_notebook <- function(x, width = NULL, height = NULL, file = NULL) { #' @export embed_notebook.plotly <- function(x, width = NULL, height = NULL, file = NULL) { + # TODO: get rid of this and provide method for api_figure objects + if (!is.null(x$x$url)) { + html <- plotly_iframe( + x$x$url, + width %||% x$width %||% "100%", + height %||% x$height %||% 400 + ) + return(IRdisplay::display_html(html)) + } p <- plotly_build(x) tmp <- tempfile(fileext = ".html") on.exit(unlink(tmp), add = TRUE) res <- htmlwidgets::saveWidget(p, tmp) # wrap in an iframe as *nteract* won't do this automatically - html <- sprintf( - '', - base64enc::dataURI(mime = "text/html;charset=utf-8", file = tmp), + html <- plotly_iframe( + base64enc::dataURI(mime = "text/html;charset=utf-8", file = tmp), width %||% p$width %||% "100%", - height %||% p$height %||% 400 + height %||% p$height %||% 400, + "" ) IRdisplay::display_html(html) } -# TODO: provide method for api_figure objects - plotly_iframe <- function(url = "", width = NULL, height = NULL, url_ext = ".embed") { url <- paste0(url, url_ext)