【问题标题】:plotly click events from anywhere on the plot情节上任何地方的情节点击事件
【发布时间】:2019-10-05 04:22:36
【问题描述】:

我是 r-plotly 的新手,并试图弄清楚如何处理不在数据上的点击。似乎使用event_data("plotly_click") 我从数据中获得了点上的事件,但到目前为止还没有弄清楚如何为不靠近数据的点击执行此操作,而只是在绘图的白色部分。

来自绘图的闪亮点击事件可以做到这一点,我只得到点击的 x 和 y。我想要类似的,但对于情节。

我可以将点击事件指定为来自绘图上的任何位置,而不仅仅是在数据上吗?

编辑:令人惊讶的是,这在情节中还不存在。查看此功能请求

https://github.com/plotly/plotly.js/issues/2696

https://github.com/ropensci/plotly/issues/1194

所以在添加此功能之前,我想我的问题是有哪些选项可以做到这一点?似乎是这样一个基本功能,我希望对 JavaScript/Shiny/Plotly 有更多了解的人已经破解了。

【问题讨论】:

  • 对于非绘图绘图,您如何能够在绘图数据区域之外获得绘图点击?这个我还没想通。

标签: javascript r shiny plotly r-plotly


【解决方案1】:

请根据我通过this 问题找到的this codepen 检查以下解决方法。

但是,到目前为止,我无法消除一个小的水平偏移 - 也许有人知道如何修复它?

library(plotly)
library(shiny)
library(htmlwidgets)

ui <- fluidPage(
  plotlyOutput("graph"),
  verbatimTextOutput("click")
)

server <- function(input, output, session) {
  
  js <- "
    function(el, x, inputName){
      var id = el.getAttribute('id');
      var gd = document.getElementById(id);
      var d3 = Plotly.d3;
      Plotly.plot(id).then(attach);
        function attach() {
          var xaxis = gd._fullLayout.xaxis;
          var yaxis = gd._fullLayout.yaxis;
          var l = gd._fullLayout.margin.l;
          var t = gd._fullLayout.margin.t;
          var coordinates = [null, null]
    
          gd.addEventListener('click', function(evt) {
            var coordinates = [xaxis.p2c(evt.x - l), yaxis.p2c(evt.y - t)];
            Shiny.setInputValue(inputName, coordinates);
          });
        };
  }
  "
  clickposition_history <- reactiveVal(data.frame(x = 1:10, y = 1:10))
  
  observeEvent(input$clickposition, {
    clickposition_history(rbind(clickposition_history(), input$clickposition))
  })
  
  output$graph <- renderPlotly({
      plot_ly(clickposition_history(), x = ~x, y = ~y, type = "scatter", mode = "markers") %>%
      onRender(js, data = "clickposition")
  })
  
  output$click <- renderPrint({
    input$clickposition
  })
}

shinyApp(ui, server)


编辑:

这是使用plotlyProxy 而不是重新渲染的相同方法 - 偏移量更糟:

library(plotly)
library(shiny)
library(htmlwidgets)

ui <- fluidPage(
  plotlyOutput("myPlot"),
  verbatimTextOutput("click")
)

server <- function(input, output, session) {
  
  js <- "
    function(el, x, inputName){
      var id = el.getAttribute('id');
      var gd = document.getElementById(id);
      var d3 = Plotly.d3;
      Plotly.plot(id).then(attach);
        function attach() {
          var xaxis = gd._fullLayout.xaxis;
          var yaxis = gd._fullLayout.yaxis;
          var l = gd._fullLayout.margin.l;
          var t = gd._fullLayout.margin.t;
          var coordinates = [null, null]

          gd.addEventListener('click', function(evt) {
            var coordinates = [xaxis.p2c(evt.x - l), yaxis.p2c(evt.y - t)];
            Shiny.setInputValue(inputName, coordinates);
          });
        };
  }
  "
  clickposition_history <- reactiveVal(data.frame(x = NA, y = NA))
  
  observeEvent(input$clickposition, {
    clickposition_history(rbind(clickposition_history(), input$clickposition))
  })
  
  output$myPlot <- renderPlotly({
    plot_ly(data.frame(x = NA, y = NA), x = ~x, y = ~y, type = "scatter", mode = "markers") %>%
      onRender(js, data = "clickposition")
  })
  
  myPlotProxy <- plotlyProxy("myPlot", session)
  
  observe({
    plotlyProxyInvoke(myPlotProxy, "restyle", list(x = list(clickposition_history()$x), y = list(clickposition_history()$y)))
  })
  
  output$click <- renderPrint({
    clickposition_history()
  })
}

shinyApp(ui, server)

相关的 GitHub issuePR

【讨论】:

    【解决方案2】:

    根据 ismirsehregal 的回答,请注意减去父对象的顶部和左侧尺寸而不是绘图边距似乎有效。请参见以下示例:

    library(plotly)
    library(shiny)
    library(htmlwidgets)
    
    ui <- fluidPage(
      plotlyOutput("graph"),
      verbatimTextOutput("click")
    )
    
    server <- function(input, output, session) {
      
      js <- "
        function(el, x, inputName){
          var id = el.getAttribute('id');
          var gd = document.getElementById(id);
          var d3 = Plotly.d3;
          Plotly.plot(id).then(attach);
            function attach() {
              var coordinates = [null, null]
        
              gd.addEventListener('click', function(evt) {
                var xaxis = gd._fullLayout.xaxis;
                var yaxis = gd._fullLayout.yaxis;
                var bb = evt.target.getBoundingClientRect();
                var x = xaxis.p2d(evt.clientX - bb.left);
                var y = yaxis.p2d(evt.clientY - bb.top);
                var coordinates = [x, y];
                Shiny.setInputValue(inputName, coordinates);
              });
            };
      }
      "
      clickposition_history <- reactiveVal(data.frame(x = 1:10, y = 1:10))
      
      observeEvent(input$clickposition, {
        clickposition_history(rbind(clickposition_history(), input$clickposition))
      })
      
      output$graph <- renderPlotly({
        plot_ly(clickposition_history(), x = ~x, y = ~y, type = "scatter", mode = "markers") %>%
          onRender(js, data = "clickposition")
      })
      
      output$click <- renderPrint({
        input$clickposition
      })
    }
    
    shinyApp(ui, server)
    

    我在这里改编了 sleighsoft 实现的代码:https://github.com/plotly/plotly.js/pull/5443

    【讨论】:

      猜你喜欢
      • 2021-11-07
      • 2017-08-17
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 2012-07-08
      • 2016-06-14
      • 1970-01-01
      • 2018-03-30
      相关资源
      最近更新 更多