Sharing Trelliscope displays
Trelliscope displays are best used as a way to explore data with colleagues, particularly domain experts who can provide insight into what is being seen. As such, it is important to be able to share Trelliscope displays with others. There are a few ways to do this.
Trelliscope displays are self-contained serverless web applications that can be easily shared with others. They are designed to be able to be used completely offline (no web dependencies for libraries, fonts, etc.), so you can share them with others without having to worry about hosting them on a server with complex dependencies. The only requirement is that the person you are sharing with has a modern web browser.
Sharing the app directory
One of the easiest ways to share a Trelliscope display is to simply
send a copy of the output directory to a colleague. This could be
through email, a shared file system, or cloud-based file sharing. The
output directory will contain everything needed to run the display. The
only thing the recipient needs to do is open the index.html
file in a web browser.
GitHub Pages
Services like GitHub Pages, Netlify, Amazon S3, and others make it easy to host static web content, often for free. Trelliscope displays are static web content, so they can be hosted on these services. You can read more about these services by visiting their websites. Typically you can set things up so that any new commits of your app directory will automatically be deployed to the web.
R Markdown and Shiny
We will discuss how to embed Trelliscope displays in R Markdown documents in later sections in this document.
Password Protection
If your content is sensitive, you can either use services provided by
your web hosting solution or you can pass your Trelliscope data frame
through the add_charm()
function to add a simple password
protection layer to your display. This will require the user to enter a
password before they can view the display. This function makes use of
the fidelius R
package and currently only encrypts the index.html file, so you will
want to make sure your web hosting platform does not allow direct access
to any of the other files in your app directory.
Embedding Trelliscope in R Markdown
We have worked to make it easy to embed Trelliscope displays in R
Markdown documents. It is as easy as calling
view_trelliscope()
on a Trelliscope data frame. However,
there are a few things to keep in mind.
First, you can only embed Trelliscope outputs in HTML-formatted output types that aren’t self-contained. We have tested the following output formats:
rmarkdown::html_vignette
rmarkdown::html_document
rmarkdown::slidy_presentation
revealjs::revealjs_presentation
Second, your output chunk needs to have a name. This will be used to determine where to write the output of the display.
Third, you need to leave the path
option of
as_trelliscope_df()
blank. Trelliscope will automatically
determine the path to use, which will be a relative path inside your R
Markdown output directory.
Additionally, you might consider setting some chunk options to make
the output look better. For example, it is a good idea to set
out.width="100%"
and hard-code the height
(out.height="___px"
) to control the size of the display. We
have also added support for a scale
chunk option that can
be used to scale the output UI so that it doesn’t appear so large when
rendered in confined spaces.
Below is an example of a chunk that will embed a Trelliscope display in an R Markdown document with these considerations in mind.
---
title: "Trelliscope RMarkdown Embedding"
output:
html_document:
self_contained: false
---
# Mars Rover Images
```{r mars_trelliscope, out.width="100%", out.height="700px", scale=0.5}
library(trelliscope)
d <- as_trelliscope_df(mars_rover, name = "mars rover")
view_trelliscope(d)
```
Another option for embedding Trelliscope displays in R Markdown documents is to pre-render them and host them somewhere on the internet and then stick an iframe tag in your R Markdown document.
Embedding Trelliscope in Quarto
Similar to R Markdown, when embedding in Quarto, you can set necessary output options in your code block to help a display render in the way you would like. For example:
Embedding Trelliscope in Shiny
Trelliscope is a great alternative to Shiny for a wide range of interactive visualization applications. In any situation where you are considering building a Shiny app that provides the user with many controls that produce a visual output, you should consider using Trelliscope instead by producing a data frame of visualizations corresponding to every combination of user input values. Trelliscope displays are easier to build, maintain, and share than shiny apps, and provide the benefit of being able to view many outputs simultaneously, as well as exploring the input parameter space interactively.
It can be the case, however, that you might want to build a Shiny app that allows a user to provide inputs for building a Trelliscope display, or in which you would like a user to be able to view a Trelliscope display. If the latter (no dynamic inputs required for creating the display), we advise to simply build the display up-front and embed it in an iframe somewhere in the Shiny app. For building and displaying dynamically-generated Trelliscope displays, we provide an example below.
In this example, we create a simple app that allows a user to choose
a dataset (either mars_rover
or none), provide a
description for the Trelliscope display, and then view the resulting
display.
library(trelliscope)
library(shiny)
tr_dir <- tempfile()
dir.create(tr_dir)
add_trelliscope_resource_path("trelliscope", tr_dir)
ui <- fluidPage(
titlePanel("Trelliscope Embed in Shiny"),
sidebarLayout(
sidebarPanel(
selectInput(
"dataset",
"Choose a dataset:",
choices = c("mars_rover", "[no data]")),
textInput("description", "Description:", "[display description]")
),
mainPanel(
trelliscopeOutput("trelliscope", style = "height: 800px")
)
)
)
server <- function(input, output) {
output$trelliscope <- renderTrelliscope({
if (input$dataset == "mars_rover") {
d <- as_trelliscope_df(mars_rover,
name = "mars rover",
description = input$description,
path = file.path(tr_dir, "test"),
jsonp = FALSE
)
d
} else {
NULL
}
})
}
shinyApp(ui = ui, server = server)
For those with experience in Shiny, most of the above should be
straightforward. One main function to call out is
add_trelliscope_resource_path()
, which allows you to
specify a path that the app can look in to find your Trelliscope
displays. In the UI, you can use trelliscopeOutput()
to
specify where a Trelliscope display will be rendered. In the server, you
use renderTrelliscope()
to write create the display. You
must place the display in the path you used with
add_trelliscope_resource_path()
. The object returned by
renderTrelliscope()
should be a Trelliscope data frame.
Trelliscope will take care of writing the display to the specified path
and rendering it in the UI.
Note that when we create our Trelliscope data frame in
renderTrelliscope()
, we use jsonp = FALSE
. If
you are using Shiny locally, you can likely stick with the default of
jsonp = TRUE
. However, if you are deploying your Shiny app
to a server, we have noticed that services like shinyapps.io and Posit
Connect do not like the data files written out by Trelliscope to be
stored as jsonp so you will need to set jsonp = FALSE
.