Margo
Margo

Reputation: 93

Scatter point click to weblink disabled when ggplot/ggplotly includes annotations or shapes

I am working on a shiny app using shiny dashboard and trying to make the plot points clickable. When clicked, an associated webpage should appear from the associated url column in the dataset.

I am using plotly, converting a ggplot to a ggplotly.

Unfortunately, my ggplot has annotations and shapes and this seems to disable the htmlwidgets::onRender() function. However, onRender() seems to work when I don't have added aesthetics such as shape and annotations.

Anyone have any insight as to how I can make the code below work with annotations and shapes? Help would be much appreciated!

Version that I am trying to code:

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

iris$url <- paste0(
  "http://google.com/#q=", 
  iris$Species
)

p <- ggplot(data = iris, aes(x = Petal.Width, y = Sepal.Length, shape = Species))+
  geom_point()+
  annotate('rect', xmin = 2, xmax = 6, ymin = 2, ymax = 6,fill="firebrick",alpha = .2)
p
p1 <- ggplotly(p)
p1

p1$x$data[[1]]$customdata <- iris$url

#pp  <- add_markers(pp, customdata = ~url)

p2 <- onRender(p1, "
                function(el, x) {
                el.on('plotly_click', function(d) {
                var url = d.points[0].customdata;
                //url
                window.open(url);
                });
                }
                ")
p2

Simpler version that works and used as the foundational code for above:

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

iris$url <- paste0(
  "http://google.com/#q=", 
  iris$Species
)

p <- ggplot(data = iris, aes(x = Petal.Width, y = Sepal.Length))+
  geom_point()
p
p1 <- ggplotly(p)
p1

p1$x$data[[1]]$customdata <- iris$url

#pp  <- add_markers(pp, customdata = ~url)

p2 <- onRender(p1, "
                function(el, x) {
                el.on('plotly_click', function(d) {
                var url = d.points[0].customdata;
                //url
                window.open(url);
                });
                }
                ")
p2

Upvotes: 1

Views: 204

Answers (1)

Max Teflon
Max Teflon

Reputation: 1800

You have to add the link-information to every layer you want to have linked. This should work:

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



p <- ggplot(data = iris, aes(x = Petal.Width, y = Sepal.Length, shape = Species))+
  geom_point()+
  annotate('rect', xmin = 2, xmax = 6, ymin = 2, ymax = 6,fill="firebrick",alpha = .2)
p
p1 <- ggplotly(p)
p1

for(i in 1:length(p1$x$data)){
  if(p1$x$data[[i]]$name %in% levels(iris$Species)){
    p1$x$data[[i]]$customdata = rep(paste0("http://google.com/#q=",
    p1$x$data[[i]]$name),length(p1$x$data[[i]]$x))
  }
}


p2 <- onRender(p1, "
                function(el, x) {
                el.on('plotly_click', function(d) {
                var url = d.points[0].customdata;
                //url
                window.open(url);
                });
                }
                ")
p2

It just loops through all the layers on the plotly-instance and adds links to the respective google-query if the name matches one of the species-names.

Upvotes: 2

Related Questions