rbokeh
rbokeh copied to clipboard
tool_tap doesn't work for bar plots
For an RBokeh bar plot embedded in a Shiny app, tool_tap()
doesn't respond to taps in RStudio or in Chrome, even though tool_hover()
does respond to hover events.
library(shiny)
library(rbokeh)
ui <- shinyUI(fluidPage(
fluidRow(
rbokehOutput("plot"),
verbatimTextOutput("tap_blurb"),
verbatimTextOutput("hover_blurb")
)
))
server <- shinyServer(function(input, output) {
output$plot <- renderRbokeh({
figure() %>%
ly_bar(x=cut, data=diamonds) %>%
tool_tap(shiny_callback(id="tap"), "g1l1") %>%
tool_hover(shiny_callback(id="hover"), "g1l1")
})
output$tap_blurb <- renderPrint({
evt <- input$tap
if (! is.null(evt)) {
str(evt)
} else {
"Tap me"
}
})
output$hover_blurb <- renderPrint({
evt <- input$hover
if (! is.null(evt)) {
str(evt)
} else {
"Hover me"
}
})
})
shinyApp(ui = ui, server = server)
I'll look into this. I'm actually surprised hover works for bar plots :). The reason I'm surprised is that callbacks is something I've only added experimentally and really only targeted points / glyphs. It's time to really get into callbacks and making them more robust and stable, so I'll use this as a use case for that. One question when going beyond points is what information the callback should provide (with points, it's the index of the row of the data that the point came from).
With a bar plot, I would want a callback to provide the x-axis index of the bar and the y-axis height of the tap. I'd also want to check that the solution works if a plot is rotated, with bars extending from the vertical axis rather than from the horizontal axis.
Another thing that's a little weird here is that the layer for callbacks is called "g1l1" rather than "bar".
I thought the callback provided the index of the row of the data as well, so I wrote a script to use that index as a reference to the dataset so I could get various attributes and summary statistics as output for the points selected. But the index the callback provides and the rownumber of the data doesn't seem to be matching up for me.
output$myChart <- renderRbokeh({
print(paste0("now rendering!"," ",date()))
input$myText
figure() %>%
ly_points(x = mtcars$cyl, y = mtcars$hp, data = mtcars,
hover = c(mtcars$cyl, mtcars$hp), lname = "points") %>%
tool_hover(callback = shiny_callback(id = "hover_info"), "points") %>%
tool_tap(callback = shiny_callback(id = "tap_info"), "points") %>%
tool_box_select(callback = shiny_callback(id = "selection_info"), "points")
})
output$selection_table <- renderTable({
index <- input$selection_info
index <- as.data.frame(index)
data$index<-seq.int(nrow(data))
data <- semi_join(data, index, by="index")
data
})
output$summary_stats_selected <- renderPrint({
index <- input$selection_info
index <- as.data.frame(index)
data$index<-seq.int(nrow(data))
data <- semi_join(data, index, by="index")
summary(data)
})
There are some issues with the index currently. One is that it is a zero-based index. So simply adding one to the index might fix your issue. Another is that sometimes rbokeh has to break a single layer into multiple Bokeh layers, and the actual index gets lost in the process. The callbacks are something I'm going to be giving much more attention to soon, once I get the most recent updates released. For now, callbacks should be treated as experimental and subject to change. There is some discusson of this in #163 as well.
Ok, that sounds great. I'll definitely play around with it. Thanks a lot for the heads up!
Again, I really love the package and excited to see it grow.
BTW, adding one to the index solved my problem!