Solution 1: stick with R
Thanks @MLavoie. In the following example, use pure R to create two plots, "mainplot" and "hover," which respond to the hover event of the first.
library(shiny) library(plotly) ui <- fluidPage( plotlyOutput("mainplot"), plotlyOutput("hover") ) server <- function(input, output) { output$mainplot <- renderPlotly({
In this example, use shiny binds for plotly . For each hover event, a POST request is sent to the server, after which the server updates the pop-up window. This is very inefficient, and therefore may not work well on slow connections.
The above code is for demonstration purposes only and has not yet been verified. See a working and more complex example here (with source ).
Solution 2: Javascript
Yes, you can do this using the graphical Javascript API .
Short answer
- Create your schedule using
R or Python or any other supported language. - Paste the graph into a new HTML page and add a callback function, as shown in the example below. If you have good knowledge of the DOM , you can also add JS to the original HTML instead of creating a new one.
- Draw a popup graph inside the callback function that takes parameters containing datatype data on hover.
More details
As mentioned in @MLavoie, a good example is shown in plotly.hover-events
Let me paste the code. The JS file has a callback function attached to Plot :
Plot.onHover = function(message) { var artist = message.points[0].x.toLowerCase().replace(/ /g, '-'); var imgSrc = blankImg; if(artistToUrl[artist] !== undefined) imgSrc = artistToUrl[artist]; Plot.hoverImg.src = imgSrc; };
Above, artistToUrl is a huge object filled with a base64 string that I will not insert here to flood the message. But you can see it under the JS tab on the example page. It has the following structure:
var artistToUrl = { 'bob-dylan': 'data:image/jpeg;base64,/...',...}
Working example:
For a demonstration, I will prepare a simple example here (click to try):
<!DOCTYPE html> <html> <head> <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> </head> <body> <iframe id="plot" style="width: 900px; height: 600px;" src="https://plot.ly/~jackp/10816.embed" seamless></iframe> <div id="myDiv"></div> <script> (function main() { var Plot = { id: 'plot', domain: 'https://plot.ly' }; Plot.onHover = function(message) { var y = message.points[0].y; var line1 = { x: [0.25,0.5,1], y: [1/y, 2, y], mode: 'lines+markers' }; var layout = { title:'Popup graph on hover', height: 400, width: 480 }; Plotly.newPlot('myDiv', [ line1 ], layout); </script> </body> </html>
This is modified from poltly.hover-events for python. Instead of onhover up the image, I modify the onhover to build a curve based on the y value for each row.
The main diagram is generated by python and inserted here as an iframe . You can make your own in any language, including R On this page, we will add <div id="myDiv"></div> and use plotly.js to draw a pop-up chart.
Export R data frame to JS enviornment
Shiny uses jsonlite to convert R objects to json and send them to the client. We can use the same mechanism to pack and send our data frame so that the JS callback can use the data to display a pop-up chart.
server.r
output$json <- reactive({ paste('<script>data =', RJSONIO::toJSON(your_data_frame, byrow=T, colNames=T),'</script>')
ui.r
fluidPage(..., htmlOutput("json"), ...)
In the JS callback function, you can use data like any other JS objects.
More details here and here .