Skip to content

Commit 361868d

Browse files
committed
Export widgets that can be embedded in R Notebooks
cc @hadley
1 parent fa93be3 commit 361868d

File tree

6 files changed

+105
-15
lines changed

6 files changed

+105
-15
lines changed

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ export(toggleOutput)
1818
export(validate_cases)
1919
export(vdiffrAddin)
2020
export(widget_diff)
21+
export(widget_diff_)
2122
export(widget_slide)
23+
export(widget_slide_)
2224
export(widget_toggle)
25+
export(widget_toggle_)
2326
importFrom(R6,R6Class)
2427
importFrom(purrr,"%||%")
2528
importFrom(purrr,every)

NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
* Depends on gdtools 0.1.2 or later as this version fixes a crash on
55
Linux platforms.
66

7+
* `widget_toggle()`, `widget_slide()` and `widget_diff()` now take
8+
plots as arguments. This makes it easy to embed a vdiffr widget in
9+
R Markdown documents. The underscored versions take HTML sources as
10+
argument (paths to SVG files or inline SVGs).
11+
12+
713
# vdiffr 0.1.0
814

915
* Generated SVGs are now reproducible across platforms thanks to

R/shiny-server.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ vdiffrServer <- function(cases) {
1010
output$type_controls <- renderTypeInput(input, cases)
1111
output$case_controls <- renderCaseInput(input, cases$active)
1212

13-
output$toggle <- renderDiffer(input, cases$active, widget_toggle)
14-
output$slide <- renderDiffer(input, cases$active, widget_slide)
15-
output$diff <- renderDiffer(input, cases$active, widget_diff)
13+
output$toggle <- renderDiffer(input, cases$active, widget_toggle_)
14+
output$slide <- renderDiffer(input, cases$active, widget_slide_)
15+
output$diff <- renderDiffer(input, cases$active, widget_diff_)
1616

1717
validateGroupCases(input, cases)
1818
validateSingleCase(input, cases)

R/svg.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ get_aliases <- function() {
1414
aliases
1515
}
1616

17-
write_svg <- function(p, file, title, user_fonts) {
17+
write_svg <- function(p, file, title, user_fonts = NULL) {
1818
user_fonts <- user_fonts %||% get_aliases()
1919
svglite::svglite(file, user_fonts = user_fonts)
2020
on.exit(grDevices::dev.off())
@@ -31,7 +31,7 @@ print_plot.default <- function(p, title) {
3131

3232
print_plot.ggplot <- function(p, title) {
3333
add_dependency("ggplot2")
34-
if (!"title" %in% names(p$labels)) {
34+
if (title != "" && !"title" %in% names(p$labels)) {
3535
p <- p + ggplot2::ggtitle(title)
3636
}
3737
if (!length(p$theme)) {

R/widgets.R

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,33 @@
11
#' HTML Widgets for graphical comparison
22
#'
3+
#' These widgets can be used at the console and embedded in a R
4+
#' Markdown document or Shiny application.
5+
#'
6+
#' The regular versions take plots or functions as \code{before} and
7+
#' \code{after} arguments (see \code{\link{expect_doppelganger}()}
8+
#' for details). The versions suffixed with underscores take HTML image
9+
#' sources. These can be paths to SVG files or inlined SVG
10+
#' images. Currently, \code{widget_diff_()} is compatible only with
11+
#' inlined images.
12+
#'
313
#' @inheritParams htmlwidgets::createWidget
4-
#' @param before Path to the picture that is taken as reference.
5-
#' @param after Path to the picture against which the reference is
6-
#' compared.
14+
#' @param before The picture that is taken as reference.
15+
#' @param after The picture against which the reference is compared.
716
#' @name htmlwidgets
17+
#' @examples
18+
#' p1 <- function() hist(mtcars$disp)
19+
#' p2 <- function() hist(mtcars$drat)
20+
#'
21+
#' # You can also call these functions in a R Markdown document or
22+
#' # in a Shiny application:
23+
#' widget_toggle(p1, p2)
24+
#' widget_slide(p1, p2)
25+
#' widget_diff(p1, p2)
826
NULL
927

1028
#' @rdname htmlwidgets
1129
#' @export
12-
widget_toggle <- function(before, after, width = NULL, height = NULL) {
30+
widget_toggle_ <- function(before, after, width = NULL, height = NULL) {
1331
sources <- list(files = list(before = before, after = after))
1432

1533
htmlwidgets::createWidget("vdiffr-toggle",
@@ -22,7 +40,7 @@ widget_toggle <- function(before, after, width = NULL, height = NULL) {
2240

2341
#' @rdname htmlwidgets
2442
#' @export
25-
widget_slide <- function(before, after, width = NULL, height = NULL) {
43+
widget_slide_ <- function(before, after, width = NULL, height = NULL) {
2644
# Drawing a SVG into a canvas requires that the svg node has 'width'
2745
# and 'height' attributes set. Otherwise the result is oddly cropped.
2846
sources <- list(before = before, after = after)
@@ -38,7 +56,7 @@ widget_slide <- function(before, after, width = NULL, height = NULL) {
3856

3957
#' @rdname htmlwidgets
4058
#' @export
41-
widget_diff <- function(before, after, width = NULL, height = NULL) {
59+
widget_diff_ <- function(before, after, width = NULL, height = NULL) {
4260
sources <- list(before = before, after = after)
4361
sources <- list(sources = map(sources, svg_add_dims))
4462

@@ -49,3 +67,39 @@ widget_diff <- function(before, after, width = NULL, height = NULL) {
4967
package = "vdiffr"
5068
)
5169
}
70+
71+
#' @rdname htmlwidgets
72+
#' @export
73+
widget_toggle <- function(before, after, width = NULL, height = NULL) {
74+
files <- widget_svgs(before, after)
75+
widget_toggle_(files$before, files$after, width, height)
76+
}
77+
78+
#' @rdname htmlwidgets
79+
#' @export
80+
widget_slide <- function(before, after, width = NULL, height = NULL) {
81+
files <- widget_svgs(before, after)
82+
widget_slide_(files$before, files$after, width, height)
83+
}
84+
85+
#' @rdname htmlwidgets
86+
#' @export
87+
widget_diff <- function(before, after, width = NULL, height = NULL) {
88+
files <- widget_svgs(before, after)
89+
widget_diff_(files$before, files$after, width, height)
90+
}
91+
92+
widget_svgs <- function(before, after) {
93+
out <- suppressMessages(list(
94+
before = svglite::stringSVG(print_plot(before, "")),
95+
after = svglite::stringSVG(print_plot(after, ""))
96+
))
97+
98+
# widget_diff() does not work if SVG doesn't finish with newline
99+
out <- map(out, paste0, "\n")
100+
101+
# Inline SVGs so the widget can be easily embedded anywhere
102+
out <- map(out, as_inline_svg)
103+
104+
out
105+
}

man/htmlwidgets.Rd

Lines changed: 31 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)