使用 shiny 和 ggvis 突出显示点击点

Highlight points on click with shiny and ggvis

我试图通过单击在我的散点图上突出显示(例如笔划)点。因此,例如我有一个工具提示,如果工具提示给我一些重要信息,我想标记这一点。有没有已经可用的东西?

我已经玩过两个工具提示,一个打印一些信息,另一个将点的 ID 附加到列表中,我尝试将此信息添加到数据中并创建一个突出显示 ID 的新图形.不太好用。

这是一个最小的例子:

library(dplyr)
library(ggvis)
library(shiny)
library(ggplot2)
df <- data.frame(x=rnorm(10), y=rnorm(10), id=letters[1:10])
server <- function(input, output) {
  movie_tooltip <- function(x) {
    x$id
  }
  vis <- reactive({
    df %>%
      ggvis(~x, ~y) %>% 
      layer_points(key := ~id)  %>%
      add_tooltip(movie_tooltip, "hover")
  })
  vis %>% bind_shiny("plot1") 
  observe({
    if(input$myBtn > 0){
      stopApp()
    }
  })
}
ui <- fluidPage(
  ggvisOutput("plot1"),
  actionButton("myBtn", "Press ME!")
)
shinyApp(ui = ui, server = server) 

如何突出显示或标记一些点?

更新:

到目前为止,我得到了部分我想展示的结果。我可以突出显示一个点,但我还想在点击时再次 "unhighlight" 它们。

我添加了第二个 add_tooltip 函数和一些 reactiveValues,但我无法切换回未标记状态。它进入一种循环,永不停止...

这是我更新的示例:

library(dplyr)
library(ggvis)
library(shiny)
library(ggplot2)
df <- data.frame(x=rnorm(10), y=rnorm(10), id=letters[1:10])

server <- function(input, output) {
  movie_tooltip <- function(x) {
    x$id
  }
  movie_tooltip2 <- function(x) {
    i <- which(df$id == x$id)
#     ifelse(values$stroke[i] == 'Yes',
#            values$stroke[i] <- 'No',
#            values$stroke[i] <- 'Yes')
    values$stroke[i] <- "Yes"
    return(NULL)
  }
  values <- reactiveValues(stroke=rep('No',nrow(df)))
  vis <- reactive({
    df %>%
      ggvis(~x, ~y, stroke = ~values$stroke) %>% 
      layer_points(key := ~id)  %>%
      add_tooltip(movie_tooltip, "hover")  %>%
      add_tooltip(movie_tooltip2, "click")
  })
  vis %>% bind_shiny("plot1") 
}
ui <- fluidPage(
  ggvisOutput("plot1")
)
shinyApp(ui = ui, server = server) 

如果我取消三个#comments的注释,把这一行注释掉# values$stroke[i] <- "Yes",我卡在一个循环里,看不懂

我相信正在发生的事情是,通过对 tooltip() 内的反应对象进行更改,您会使工具提示本身无效,因此您陷入了无限循环。

要解决此问题,请使用 isolate() 更改值。

library(dplyr)
library(ggvis)
library(shiny)
library(ggplot2)
df <- data.frame(x=rnorm(10), y=rnorm(10), id=letters[1:10])

server <- function(input, output) {
  movie_tooltip <- function(x) {
    x$id
  }
  movie_tooltip2 <- function(x) {
    i <- which(df$id == x$id)
    isolate(values$stroke[i] <- ifelse(values$stroke[i] == 'Yes',
                values$stroke[i] <- 'No',
                values$stroke[i] <- 'Yes'))
    return(NULL)
  }
  values <- reactiveValues(stroke=rep('No',nrow(df)))
  vis <- reactive({
    df %>%
      ggvis(~x, ~y, stroke = ~values$stroke) %>% 
      layer_points(key := ~id)  %>%
      add_tooltip(movie_tooltip, "hover")  %>%
      add_tooltip(movie_tooltip2, "click")
  })
  vis %>% bind_shiny("plot1") 
}
ui <- fluidPage(
  ggvisOutput("plot1")
)
shinyApp(ui = ui, server = server)