Week14 - Exporting Widgets
April 09, 2015
htmlwidgets News This Week
Just do this Github search, and you’ll likely see all the newest and latest. As a follow-up to last week’s widget stmBrowser
, I thought this research on applications of stm
to MOOCs is especially interesting.
This Week’s Widget - exportwidget
It seems exporting widgets is a popular request. This week’s widget exportwidget
offers an easy way to add an export to PNG
button to other htmlwidgets
or SVG
. It works, but it is more an experiment and conversation starter for the broader discussion at htmlwidgets issue #95. There are lots of questions looking for answers.
- Why would you want to export an
htmlwidget
? - How would you like to export an
htmlwidget
- clientside or headless? - In what format would you like your exported `htmlwidget?
Thanks so much to the authors of canvg
, svg-crowbar
, and Download-File-JS
on which exportwidget
relies.
Quick Installation
As with almost all widgets posted here, exportwidget
is not on CRAN, so for now please install with devtools::install_github
. Given enough interest, I’m happy to put in the effort to make this or any others CRAN-worthy. Just let me know.
devtools::install_github("timelyportfolio/exportwidget")
Examples
Example With SVG + Custom Font
I’ll start with what I think is the least likely use case of this widget but a demanding case that eliminates many of the SVG
exporting JavaScript libraries. To conduct the test and as an extra benefit and proof of functionality, I’ll add a custom font from Google Fonts with htmlDependency
from htmltools
. External fonts cause trouble in some of the other libraries I evaluated.
library(exportwidget)
library(htmltools)
library(pipeR)
tagList(
'<svg id = "svg_to_export" width="400" height="200">
<text x="50" y="100" text-anchor="start" dy="14" style="font-family:\'Indie Flower\';font-size:36pt;">
Custom Fonts
</text>
</svg>' %>>%
HTML
,export_widget( "svg" )
) %>>%
attachDependencies(list(
htmlDependency(
name = "IndieFlower"
,version = "0.1"
,src = c(href='http://fonts.googleapis.com/css?family=Indie+Flower')
,stylesheet = ""
)
))
Example with another widget streamgraph
Alex Bresler assures me that streamgraphs are art, and thanks to Bob Rudis @hrbrmstr, there is an htmlwidget
streamgraph
for that. Let’s see how we can use exportwidget
to show somebody our “art”. The ChickWeight
dataset is definitely not the best for streamgraphs
but it is small and built-in, so we’ll go with it despite these issues.
library(dplyr)
library(streamgraph)
library(htmltools)
library(exportwidget)
# use the built in ChickWeight data set; not ideal but built-in
ChickWeight %>%
group_by( Diet, Time ) %>%
summarise( MeanWeight = mean(weight) ) %>%
streamgraph( "Diet", "MeanWeight", "Time", scale = "continuous" ) %>%
sg_legend( show = TRUE ) %>%
tagList(
export_widget( )
)
Example with multiple widgets
Let’s assume that we love our htmlwidgets
and like to use lots of them on a page. export_widget
without arguments will try to apply its button to all the htmlwidgets
it finds. This could be bad. For instance, I doubt we would want to export a navr
. If there are htmlwidgets
in your page that you don’t want to export, you’ll probably want to be more specific in your export_widget( )
and explicitly export just those htmlwidgets
. As an example, with grViz
from DiagrammeR
, you could export_widget(".grViz")
or with the streamgraph
from the previous example, export_widget(".streamgraph")
. Any css
selector should work as an argument to export_widget( )
.
Let’s try it with DiagrammeR
, rcdimple
, and networkD3
.
library(htmltools)
library(DiagrammeR)
library(rcdimple)
library(networkD3)
library(exportwidget)
tagList(
# A slightly more involved example
# using example from http://www.graphviz.org/pdf/dotguide.pdf
# "Drawing graphs with dot"
# Emden R. Gansner and Eleftherios Koutsofios and Stephen North
# January 5, 2015
grViz('
digraph G {
size = "4,4";
main [shape = box]; /* this is a comment */
main -> parse [weight = 8];
parse -> execute;
main -> init [style = dotted];
main -> cleanup;
execute -> { make_string; printf}
init -> make_string;
edge [color = red]; // so is this
main -> printf;
node [shape = box, style = filled, color = ".7 .3 1.0"];
execute -> compare;
}
')
,dimple(
mtcars
, mpg ~ cyl
, groups = "cyl"
, type = "bubble"
) %>>%
default_colors( streamgraph:::tableau_colors( "tableau10medium" ) ) %>>%
set_bounds( x = "10%", y = "15%", width = "80%", height = "70%" )
,simpleNetwork(
data.frame(
Source = c("A", "A", "A", "A", "B", "B", "C", "C", "D")
,Target = c("B", "C", "D", "J", "E", "F", "G", "H", "I")
)
,height = 400
,width = 400
)
,export_widget()
)
Example | Headless with webshot
Often, you might not want exportwidget
at all. We very well might like a headless way to make a static copy of an htmlwidget
. For this, we can use the excellent package webshot
by Winston Chang from RStudio. webshot
uses the very widely used and tested phantomjs
. We can push an htmlwidget
through the pipe and get a PNG
out the other end. Note, webshot
and Windows aren’t best friends yet. If you suffer through Windows like I do, then you can install my forked webshot
.
library(networkD3)
library(webshot)
html_print(
simpleNetwork(
data.frame(
Source = c("A", "A", "A", "A", "B", "B", "C", "C", "D")
,Target = c("B", "C", "D", "J", "E", "F", "G", "H", "I")
)
,height = 400
,width = 400
)) %>>%
normalizePath(.,winslash="/") %>%
gsub(x=.,pattern = ":/",replacement="://") %>%
paste0("file:///",.) %>%
webshot( file = "headless_widget.png", delay = 2 )
Thanks
Thanks so much for all the work by
canvg
from Gabe Lernersvg-crowbar
from the NY TimesDownload-File-JS
from Denis Radin- Ramnath Vaidyanathan and RStudio for
htmlwidgets
- all the contributors to
R