The shinyjs https://deanattali.com/2015/04/23/shinyjs-r-package/包确实可以简化这类事情。我们可以使用onevent
使用“mouseenter”作为参数来捕获这些事件的函数。为了让它工作,我们必须给元素一个 id,或者将它们包装在一个带有我们可以引用的 id 的 div 中。然后我们可以使用它们来更新reactiveVal
保存当前悬停的元素,该元素又用于reactive
这改变了我们的data.frame
被绘制。我们可以重置reactiveVal
还可以监听“mouseleave”事件。
我希望这有帮助!
library(shiny)
library(shinyjs)
library(dplyr)
library(ggplot2)
set.seed(1)
words <- sort(sapply(1:50, USE.NAMES = F, FUN = function (x) paste(sample(letters, 15), collapse = "")), decreasing = T)
dat <- data.frame(words, f = sort(rgamma(50, shape = 5, scale = 1)),stringsAsFactors = F)
ui <- pageWithSidebar(
headerPanel("Playground"),
sidebarPanel(),
mainPanel(
uiOutput("links"),
plotOutput("out.plot"),
useShinyjs()
))
server <- function(input, output, session) {
urls <- lapply(dat$words, FUN = function (x) {
div(id=x, a(paste0(" ", x, " "),
href = paste0("https://", x, ".de"),
target = "_blank"))
})
output$links <- renderUI({
tagList(urls)
})
# Add a reactieVal that we can update once an object is hovered.
hovered_element <- reactiveVal('')
# Add onevent for each element in dat$words, to update reactiveVal.
lapply(dat$words,function(x){
onevent(event='mouseleave',id=x,hovered_element(''))
onevent(event='mouseenter',id=x,hovered_element(x))
})
# Add a reactive for the dataset, which we debounce so it does not invalidate too often.
my_data <- reactive({
dat$color <- ifelse(dat$words==hovered_element(),'hovered','')
dat
})
my_data <- my_data %>% debounce(50) # tune for responsiveness
# Plot
output$out.plot <- renderPlot({
ggplot(my_data(), aes(x = words, y = f,fill=color)) +
geom_bar(stat = "identity") +
theme(axis.text.x = element_text(angle = 90)) + theme(legend.position="none")
})
}
shinyApp(ui, server)