2

I would like to be able to do something like the answer of this but without using shiny. I also want to bind onclick events which open a hyperlink associated with the data point.

I am using the saveWidget function from htmlwidgets and know that I can insert javascript code with the appendContent function from the htmltools package.

Here is a small sample code:

library(ggplot2)
library(plotly)
library(htmlwidgets)
library(htmltools)

path.test.results <- "C:\\Users\\img\\"

myData <- data.frame(x=c(1,2,3), y=c(3,2,1))
myLinks <- c("https://www.google.com/", "https://stackoverflow.com/", "https://www.r-project.org/")

ggp <- ggplot(data=myData, aes(x=x, y=y)) + geom_point()
ply <- plotly_build(ggp)

ply$elementId <- "PlotlyGraph"

#javascript <- HTML('<script>document.getElementById("htmlwidget_container").innerHTML = "test";</script>')
javascript <- HTML(paste(
        paste('<button type="button" onclick="document.getElementById(',"'", 'PlotlyGraph', "'", ').style.display=',
                "'", 'none', "'", '">Hide Plot</button>', sep=''),
        paste('<button type="button" onclick="document.getElementById(',"'", 'PlotlyGraph', "'", ').style.display=',
                "'", 'block', "'", '">Show Plot</button>', sep='')
        ,sep=''))

ply <- appendContent(ply, javascript)

saveWidget(widget=ply, file=paste(path.test.results, "test.html", sep=""), selfcontained = FALSE)
dev.off()

Now obviously I am asking for help for the correct java script code to save in the 'javascript' variable which I then could integrate with appendContent into the html widget.

Community
  • 1
  • 1
N. Maks
  • 539
  • 3
  • 15

2 Answers2

5

One way would be to

  • add the Javascript code via onStaticRenderComplete in order to execute it once the plot is rendered
  • the Javascript event is a simple modification of the example found here
  • the URL is opened via window.open

For a general solution with different traces, see: Open hyperlink on click on an ggplot/plotly chart

The complete code

library(ggplot2)
library(plotly)
library(htmlwidgets)
library(htmltools)

path.test.results <- "C:\\Users\\img\\"

myData <- data.frame(x=c(1,2,3), y=c(3,2,1), urls=c("https://www.google.com/", "http://stackoverflow.com/", "https://www.r-project.org/"))
myLinks <- c("https://www.google.com/", "http://stackoverflow.com/", "https://www.r-project.org/")

ggp <- ggplot(data=myData, aes(x=x, y=y)) + geom_point()
ply <- plotly_build(ggp)

ply$elementId <- "PlotlyGraph"

html <- HTML(paste(
  paste('<button type="button" onclick="document.getElementById(',"'", 'PlotlyGraph', "'", ').style.display=',
        "'", 'none', "'", '">Hide Plot</button>', sep=''),
  paste('<button type="button" onclick="document.getElementById(',"'", 'PlotlyGraph', "'", ').style.display=',
        "'", 'block', "'", '">Show Plot</button>', sep='')
  ,sep=''))

javascript <- HTML(paste("var myPlot = document.getElementById('PlotlyGraph');
myPlot.on('plotly_click', function(data){
var urls = ['", paste(myLinks, collapse = "', '"), "'];
window.open(urls[data.points[0].pointNumber],'_blank');
});", sep=''))

ply <- prependContent(ply, html)
ply <- prependContent(ply, onStaticRenderComplete(javascript))

saveWidget(widget=ply, file=paste(path.test.results, "test.html", sep=""), selfcontained = FALSE)
Maximilian Peters
  • 30,348
  • 12
  • 86
  • 99
  • Great! Does exactly what I had in mind. Thank you very much, you helped me out a lot! – N. Maks Feb 13 '17 at 06:54
  • I have now tried to apply the same technique onto a stacked barchart. Everything works if I leave everything out of `aes()` apart from `x=x, y=y` in the `ggplot` call. But when I try to add e.g. `, fill=urls` inside `aes()` it seems to mess up the JavaScript functionality. Then always the same link will open (in my case, the first one which is google), no matter on which bar I click. Do you maybe know whats going on? – N. Maks Sep 11 '17 at 13:12
  • Sorry, but I didn't encounter this problem before. Please ask a separate question and I am sure somebody has a solution for it. – Maximilian Peters Sep 11 '17 at 13:14
2

A slight correction to Maximilian Peters code which did not quite work for me for a factor(x). I am not a Javascript programmer so cannot really explain it (maybe somebody can ?), and just used the plotly example.

(I added the 2 lines with the comments)

javascript <- HTML(paste("var myPlot = 
document.getElementById('PlotlyGraph');
                     myPlot.on('plotly_click', function(data){
                     var urls = ['", paste(myLinks, collapse = "', '"),'];//added
                     for(var i=0; i < data.points.length; i++){
                     window.open(urls[data.points[i].x],'_blank'); //changed
                     }//added
                     });", sep=''))
GM1313
  • 49
  • 8