This chapter briefly covers two main possibilities of adding interactivity to the graphics in a Shiny application: by including interaction possibilities for native R graphics provided by the Shiny package, or by integrating JavaScript-generated visualizations, which can be interactive. Although some of the libraries seen in this book such as googleVis
are interactive, their interaction is already specified. For example, on hovering it is not possible on googleVis
to do something else different from displaying a tooltip. The two solutions presented here are much more flexible in this sense because the developer can receive the information from the interaction and produce any kind of reaction to it.
From Shiny 0.12, it has been possible to develop applications with graphics or images that are responsive to interactions. Its implementation is very simple, as the interaction events are tracked as any other input objects and behave in the exact same way. Until the 0.12 version, there have been four basic interaction events. In order to listen to them, the corresponding argument must be specified to the plotting function where the value of this argument is the corresponding listener. The following are the events:
hover
and the function is hoverOpts()
.click
and the function is clickOpts()
.dblclick
and the function is dblClickOpts()
.brush
and the function is brushOpts()
.A single string can be passed instead of the complete function to each of the arguments previously mentioned. In this case, a listener with that ID will be created. In any case, the listener will be accessible on the server side with the input$(listener_id)
form. This object will be of list
type and will have a series of values according to its nature. A good example of what each of them returns can be found at http://shiny.rstudio.com/gallery/plot-interaction-basic.html.
Take into account that this feature works optimally with the latest version of Shiny and htmlwidgets
, a package that will be introduced in the next section. Updating a package in R is done in the exact same way as installing them.
The following example illustrates the use of this functionality of brush on the iris
dataset. Basically, a plot is displayed and the brushed points appear in the table below. For this particular case, the high level brushedPoints()
function is used. This function takes a brush listener and a data frame object and automatically generates a subset of the selected points in a data frame:
This is for global.R
:
data(iris)
The following snippet is for UI.R
:
library(shiny) # Starting line shinyUI(fluidPage( # Application title titlePanel("Example 1"), sidebarLayout( # Sidebar with a numeric input sidebarPanel( selectInput("var1", "Select variable 1", names(iris)), selectInput("var2", "Select variable 2", names(iris)) ), #The plot created in server.R is displayed mainPanel( plotOutput("plot",brush = brushOpts( id = "plot_brush")), tableOutput("selectedpoints") ) ) ))
The only change with respect to UI files seen so far is that the brush
argument is added to plotOutput()
. In this case, the full brushOpts()
function was used. The following is for server.R
:
library(shiny) #initialization of server.R shinyServer(function(input, output) { #Plot generation output$plot <- renderPlot({ selected.vars <- c(input$var1, input$var2) plot(iris[,c(selected.vars)]) }) output$selectedpoints <- renderTable({ return(brushedPoints(iris,input$plot_brush, xvar = input$var1, yvar = input$var2)) }) })
Inside renderTable()
, the mentioned high-level function was used specifying the dataset, event listener, and corresponding horizontal and vertical variable names. This section can also be rewritten as:
iris.sset <- iris[,iris[[input$var1]] >= input$plot_brush$xmin & iris[[input$var1]] <= input$plot_brush$xmax & iris[[input$var2]] >= input$plot_brush$ymin & iris[[input$var2]] <= input$plot_brush$ymax] return(iris.sset)
This is how the application should look:
In the next section, we will cover how to generate custom functions that render JavaScript-based elements. From all the possibilities, only D3 will be covered.