I have a shiny app that updates a scatter plot based on user input for the x and y variable. I want to be able to have the data for the x and y in the tooltip and have this update when the user updates what they want on the x and y axis. Below is some sample code with 2 of my attempt at this issue (2nd attempt commented out). Note that I have added to the Iris data set to give each data point a unique ID based on its row number in the data set.
#Check packages to use in library
{
library('shiny') #allows for the shiny app to be used
library('stringr') #string opperator
library('ggvis') #allows for interactive ploting
library('dplyr')
library('RSQLite')
}
alldata <- iris
#adds a column of a unique ID for each row
alldata$ID <- 1:nrow(alldata)
# UI
ui<-fluidPage(
titlePanel("Iris"),
fluidRow(
column(12,
ggvisOutput("plot1")
),
column(4,
wellPanel(
h4("Data Variables"),
selectInput(inputId = "x", label="Select x-axis Variable:", choices=as.character(names(alldata[,1:4])),selected='Petal.Length', multiple = FALSE),
selectInput(inputId = "y", label="Select y-axis Variable:", choices=as.character(names(alldata[,1:4])),selected='Petal.Width', multiple = FALSE)
))
))
#SERVER
server<-function(input,output,session)
{
# Function for generating tooltip text
my_tooltip <- function(tt) {
if (is.null(tt)) return(NULL)
if (is.null(tt$ID)) return(NULL)
# Pick out the shot with this ID
alldata <- isolate(alldata)
Datapoint <- alldata[alldata$ID == tt$ID, ]
paste0("<b>", "Species: ", Datapoint$`Species`,
"</b><br>", "ID: ", Datapoint$`ID`,
"<br>", "X Variable: ", Datapoint$`input$x`,
"<br>", "Y Variable: ", Datapoint$`input$y`
# "<br>", "X Variable: ", Datapoint %>% `input$x`,
# "<br>", "Y Variable: ", Datapoint %>% `input$y`
)
}
vis <- reactive({
xvar <- prop("x", as.symbol(input$x))
yvar <- prop("y", as.symbol(input$y))
p1 = alldata %>%
ggvis(x = xvar, y = yvar) %>%
layer_points(size.hover := 200,
fillOpacity:= 0.5, fillOpacity.hover := 1,
fill = ~Species,
key := ~ID
) %>%
# Adds the previously defined tool_tip my_tooltip
add_tooltip(my_tooltip, "hover")
# Specifies the size of the plot
# set_options(width = 800, height = 450, duration = 0)
})
#Actually plots the data
vis %>% bind_shiny("plot1")
}
#Run the Shiny App to Display Webpage
shinyApp(ui=ui, server=server)
One option is to subset to only the columns of interest within your tooltip function, and then display all values from this dataset.
my_tooltip <- function(tt) {
if (is.null(tt)) return(NULL)
if (is.null(tt$ID)) return(NULL)
Datapoint <- alldata[alldata$ID == tt$ID, c("Species", "ID", input$x, input$y)]
paste0(names(Datapoint), ": ", format(Datapoint), collapse = "<br />")
}
Or just use, e.g., input$x
directly as these are characters so are easy to pull out of datasets and use as tooltip names.
my_tooltip <- function(tt) {
if (is.null(tt)) return(NULL)
if (is.null(tt$ID)) return(NULL)
Datapoint = alldata[alldata$ID == tt$ID, ]
paste0("<b>", "Species: ", Datapoint$`Species`,
"</b><br>", "ID: ", Datapoint$`ID`,
"<br>", input$x, ": ", Datapoint[[input$x]],
"<br>", input$y, ": ", Datapoint[[input$y]])
}