This can be simplified quite a bit I think. Here I'm using clicking instead of hovering, but that can be changed based on taste of course.
require(shiny)
require(ggplot2)
ui <- shinyUI(fluidPage(
tags$head(
tags$script(
HTML("
// Get mouse coordinates
var mouseX, mouseY;
$(document).mousemove(function(e) {
mouseX = e.pageX;
mouseY = e.pageY;
}).mouseover();
// Function to position draggable, place on current mouse coordinates
Shiny.addCustomMessageHandler ('placeDraggable',function (message) {
var element = $('#click_info').parent();
element.css({'top': mouseY + 'px', 'left' : mouseX + 'px'})
});
")
)
),
absolutePanel(fixed=TRUE, draggable = TRUE, uiOutput("click_info")),
plotOutput("myplot", click = clickOpts(id ="myplot_click"))
))
server <- shinyServer(function(input, output, session) {
output$myplot <- renderPlot({
ggplot(mtcars) + geom_point(aes(mpg,cyl))
})
show_this = reactiveVal(NULL)
print_this = reactiveVal(NULL)
observeEvent(input$myplot_click, {
p <- nearPoints(mtcars, input$myplot_click, maxpoints=1)
if( nrow(p) == 0 ) {
show_this(NULL)
}
else {
session$sendCustomMessage(type = 'placeDraggable', message = list())
show_this(tagList(
{ actionButton("input_button","OK") },
{ br() },
{ verbatimTextOutput("point_info") }
)
)
print_this({p})
}
})
output$click_info <- renderUI (show_this() )
output$point_info <- renderPrint(print_this())
observeEvent(input$input_button,{
if (input$input_button) { show_this(NULL) }
})
})
shinyApp(ui, server)
As you see, the whole hideDraggable is unnecssary, as well as the helper function and the points(). And the output is now outside of the observer, which is recommended.
Probably if you know a little bit of JavaScript (I don't!!!) it would be possible to also remove the placeDraggable function, and just specify that the #click_info element should always be placed according to the mouse coordinates. The shiny code makes sure it's only displayed when you want it to be.
Here I also included a little button with the displayed text just to show that you can use this as an opportunity to get more input from the user if needed. (Obviously then you need something more informative than just an OK button. For example, you could use this as a way to remove the point.)