I am new to r-plotly and trying to figure out how to handle clicks which are not on the data. It seems that using event_data("plotly_click")
I get events that are on points from the data, but so far have not figured out how to do this for clicks which are not close to the data, but just on the white part of the plot.
Shiny click events from plots can do this and I just get the x and y of the click. I want similar, but for plotly plots.
Can I specify click events to be from anywhere on the plotly plot, not just on the data?
EDIT: Surprisingly this does not exist yet in plotly. See this feature request
https://github.com/plotly/plotly.js/issues/2696
https://github.com/ropensci/plotly/issues/1194
So until this feature is added, I guess my question is what options are there to do this? Seems like such a basic feature, that I hope someone with more knowledge of JavaScript/Shiny/Plotly has hacked into.
Edit: The Plotly.plot()
function has been deprecated - now using Plotly.update()
instead:
Please check the following workaround based on this codepen I found via this question.
The following is using plotlyProxy
instead of re-rendering the plot, which is faster:
library(plotly)
library(shiny)
library(htmlwidgets)
initDF <- data.frame(x = 1:10, y = 1:10)
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.update(id).then(attach);
function attach() {
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(initDF)
observeEvent(input$clickposition, {
clickposition_history(rbind(clickposition_history(), input$clickposition))
})
output$myPlot <- renderPlotly({
plot_ly(initDF, 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)
Related GitHub issue and PR.
Thanks @unumileappassionato for providing the solution regarding the small horizontal offset in my initial answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With