Rome Was Not Built In A Day But widgetcard Was!

I saw a second post on turning htmlwidgets into interactive Twitter Player cards and felt somewhat compelled to make creating said entities a bit easier so posited the following:

I figured 40+ 💙 could not be wrong, so thus begat widgetcard:

To make this post as short as possible, the TLDR is that you just pass in an htmlwidget and some required parameters and you get back a deployable interactive Twitter Player card as an archive file and local directory. The example code is almost as short since we’re cheating and using the immensely helpful plotly package to turn a ggplot2 vis into something interactive.

First, make the vis:

library(ssh)
library(plotly)
library(ggplot2)
library(widgetcard)

ggplot(mtcars, aes(wt, mpg)) +
  geom_point() -> gg

Now, we create a local preview image for the plot we just made since we need one for the card:

preview <- gg_preview(gg)

NOTE that you can use any image you want. This function streamlines the process for plotly plots created from ggplot2 plots. There are links to image sizing guidelines in the package help files.

Now, we convert our ggplot2 object to a plotly object and create the Twitter Player card. Note that Twitter really doesn’t like standalone widgets being used as Twitter Player card links due to their heavyweight size. Therefore, card_widget() creates a non-standalone widget but bundles everything up into a single directory and deployable archive.

ggplotly(gg) %>% 
  card_widget(
    output_dir = "~/widgets/tc",
    name_prefix = "tc",
    preview_img = preview,
    html_title = "A way better title",
    card_twitter_handle = "@hrbrmstr",
    card_title = "Basic ggplot2 example",
    card_description = "This is a sample caRd demonstrating card_widget()",
    card_image_url_prefix = "https://rud.is/vis/tc/",
    card_player_url_prefix = "https://rud.is/vis/tc/",
    card_player_width = 480,
    card_player_height = 480
  ) -> arch_fil

Here’s what the resulting directory structure looks like:

tc
├── tc.html
├── tc.png
└── tc_files
    ├── crosstalk-1.0.0
    │   ├── css
    │   │   └── crosstalk.css
    │   └── js
    │       ├── crosstalk.js
    │       ├── crosstalk.js.map
    │       ├── crosstalk.min.js
    │       └── crosstalk.min.js.map
    ├── htmlwidgets-1.3
    │   └── htmlwidgets.js
    ├── jquery-1.11.3
    │   ├── jquery-AUTHORS.txt
    │   ├── jquery.js
    │   ├── jquery.min.js
    │   └── jquery.min.map
    ├── plotly-binding-4.8.0
    │   └── plotly.js
    ├── plotly-htmlwidgets-css-1.39.2
    │   └── plotly-htmlwidgets.css
    ├── plotly-main-1.39.2
    │   └── plotly-latest.min.js
    ├── pymjs-1.3.2
    │   ├── pym.v1.js
    │   └── pym.v1.min.js
    └── typedarray-0.1
        └── typedarray.min.js

(There’s also a tc.tgz at the same level as the tc directory.)

The widget is iframe’d using widgetframe and then saved out using htmlwidgets::saveWidget().

Now, for deploying this to a web server, one could use a method like this to scp the deployable archive:

sess <- ssh_connect(Sys.getenv("SSH_HOST"))

invisible(scp_upload(
  sess, files = arch_fil, Sys.getenv("REMOTE_VIS_DIR"), verbose = FALSE
))

ssh_exec_wait(
  sess,
  command = c(
    sprintf("cd %s", Sys.getenv("REMOTE_VIS_DIR")),
    sprintf("tar -xzf %s", basename(arch_fil))
  )
)

Alternatively, you can use other workflows to transfer and expand the archive or copy output to your static blog host.

Make sure to test anything you build with Twitter’s validator before tweeting it out.

FIN

This works but is super nascent and could use some serious IRL tyre kicking and brutal feedback. Pick the least offensive social coding site you prefer and file issues & PR’s at-will.

Cover image from Data-Driven Security
Amazon Author Page

1 Comment Rome Was Not Built In A Day But widgetcard Was!

  1. Pingback: Rome Was Not Built In A Day But widgetcard Was! – Data Science Austria

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.