单击相同的绘图标记两次不会触发事件两次

Posted

技术标签:

【中文标题】单击相同的绘图标记两次不会触发事件两次【英文标题】:clicking same plotly marker twice does not trigger events twice 【发布时间】:2017-11-08 18:59:16 【问题描述】:

在用户单击散点图中的标记后,我正在使用 Plotly 的 event_data("plotly_click") 做一些事情(打开模式)。之后(例如关闭模式),event_data("plotly_click") 当然不会改变并且点击相同的标记因此不会再次触发相同的动作。

小例子:

library(plotly)
ui <- fluidPage(  
  plotlyOutput("plot")
)
server <- function(input, output, session) 
  output$plot <- renderPlotly(
    mtcars %>% plot_ly(x=~disp, y=~cyl)
  ) 

  # Do stuff after clicking on a marker in the plot
  observeEvent(event_data("plotly_click"), 
    print("do some stuff now") # this is not executed after second click on same marker
  )  

shinyApp(ui, server)

我尝试过使用 shinyjs 的onclick 解决方法,但无济于事(它在绘图的空白区域效果很好,但在单击标记时却不行):

shinyjs::onclick(id="plot", print("clicked"))

我还尝试使用存储最后一次点击并在之后立即重置的反应值(例如,event_data("plotly_hover")),但所有尝试都失败了,因为event_data("plotly_click") 仍保持其旧值。

谁能帮忙?

【问题讨论】:

我认为这是一个已知问题community.plot.ly/t/reseting-click-events/2718 谢谢,但这只是他们论坛中一个单独问题的链接,没有跟踪问题或类似问题的痕迹:) 【参考方案1】:

[编辑:该问题已在 Plotly 4.9.0 中修复。见答案below。这个答案适用于 Plotly 4.8.0。从plotly 4.9.0.,从源代码中删除字符串.clientValue-或使用below answer。]

我终于解决了这个问题。我知道这会困扰一些人,所以我将在这里发布我的解决方案:

基本上,我使用shinyjs 包来重置有关特定事件(在我的情况下为按钮)的最后一次点击(event_data("plotly_click") 获取其信息的来源)的数据。

函数的定义是(注意如果使用“A”需要用plotly-source字符串替换):

extendShinyjs(text = "shinyjs.resetClick = function()  Shiny.onInputChange('.clientValue-plotly_click-A', 'null'); ")

然后这会在js$resetClick() 的按钮点击时调用。

小例子:

library(shiny)
library(plotly)
library(shinyjs)

ui <- shinyUI(
  fluidPage(
    useShinyjs(),
    # code to reset plotlys event_data("plotly_click", source="A") to NULL -> executed upon action button click
    # note that "A" needs to be replaced with plotly source string if used
    extendShinyjs(text = "shinyjs.resetClick = function()  Shiny.onInputChange('.clientValue-plotly_click-A', 'null'); "),
    actionButton("reset", "Reset plotly click value"),
    plotlyOutput("plot"),
    verbatimTextOutput("clickevent")
  )
)


server <- shinyServer(function(input, output) 

  output$plot <- renderPlotly(
    plot_ly(mtcars, x=~cyl, y=~mpg)
  )

  output$clickevent <- renderPrint(
    event_data("plotly_click")
  )

  observeEvent(input$reset, 
    js$resetClick()
  )
)

shinyApp(ui, server)

【讨论】:

嗨@shosaco 我复制了这个确切的例子,点击没有被重置。我在 R 3.6.0 上,我的 sessionInfo() 如下所示:[1] shinyjs_1.0 plotly_4.9.0 ggplot2_3.1.1 shiny_1.3.2 。新的 plotly 库有问题吗?我还使用了priority = "event" 更改,如下所示,但 javascript 仍未被重置。 亲爱的@Agrosel,感谢您的来信!在 4.9.0 中,他们更改了输入名称。对于 4.8.0,上面的示例是有效的,对于 Plotly 4.9.0,您必须使用行 extendShinyjs(text = "shinyjs.resetClick = function() Shiny.onInputChange('plotly_click-A', 'null'); "),【参考方案2】:

这个问题终于在 Plotly 方面得到了解决:https://github.com/ropensci/plotly/issues/1043

event_data("plotly_click", priority = "event") 每次点击都会更新,而不仅仅是闪亮的输入变化(和以前一样)。从 Plotly 4.9.0 开始工作。

使用 Plotly 4.9.0 的最小示例:

library(shiny)
library(plotly)

ui <- shinyUI(
  fluidPage(
    plotlyOutput("plot", height = 200),
    verbatimTextOutput("time_last_click")
  )
)


server <- shinyServer(function(input, output) 

  output$plot <- renderPlotly(
    plot_ly(mtcars[1,], x=~cyl, y=~mpg, size = 1)
  )


  output$time_last_click <- renderPrint(
    tmp <- event_data("plotly_click", priority = "event")
    Sys.time()
  )

)

shinyApp(ui, server)

【讨论】:

【参考方案3】:

我遇到了同样的问题,并想出了一个解决方案,我将 plotly 对象的 source 参数指定为 reactive value,如下所示:

plot_ly(data,x,y,...,source = x)event_data(...,source = x) 中,让x 成为reactiveValues 对象的一个​​元素。当您的事件触发时,更改 x 的值(增量或散列),这将实例化一个新的 event_data() 对象。

工作就像一个魅力。

【讨论】:

考虑更新您的答案以使用 ` 来格式化您的答案的代码部分。这将有助于提高可读性。在编辑屏幕的右侧,您将看到格式提示。

以上是关于单击相同的绘图标记两次不会触发事件两次的主要内容,如果未能解决你的问题,请参考以下文章

解决input file两次选择相同文件不触发change事件的问题

jquery双击事件(dblclick)时,不触发单击事件(click)

Ext.js 2 复选框和事件通过更改侦听器触发两次

为啥单击功能会在 Angular 2 中为自定义组件触发两次

由于文本框失去焦点,按钮需要单击两次

wpf点击checkbox触发了两次