点击 ggplot/plotly 图表上的超链接打开链接

6

这是对于在R中创建HTML插件后添加点击打开超链接事件答案的跟进问题。请考虑以下示例:

library(ggplot2)
library(plotly)
library(htmlwidgets)
library(htmltools)
myData <- data.frame(
  x=c(1,2,3), 
  y=c(3,2,1),
  label=c("Google", "Bing", "R"),
  category=c("search", "search", "other"),
  urls=c("http://google.de", "http://bing.com", "http://r-project.org")
)

f <- function(p) {
  ply <- ggplotly(p)
  javascript <- HTML(paste("
   var myPlot = document.getElementById('", ply$elementId, "');
   myPlot.on('plotly_click', function(data){
   var urls = ['", paste(myData$urls, collapse = "', '"), "'];
   window.open(urls[data.points[0].pointNumber],'_blank');
   });", sep=''))  
  prependContent(ply, onStaticRenderComplete(javascript))
}

这个功能能够正常工作 - 点击任何点都会打开相应的URL:

f(ggplot(myData, aes(x=x, y=y)) + geom_point(aes(text=label)))

这个并没有按预期工作 - 索引不再匹配:

f(ggplot(myData, aes(x=x, y=y)) + geom_point(aes(text=label, color=category)))

在此输入图片描述

Plotly对象不同,似乎pointNumber不再保存所有点的绝对索引,而是在(颜色)分组内的索引。

有什么想法可以调整示例,使其适用于一般情况,包括颜色/填充分组吗?


您可以在此处找到相应的文档:https://plotly-r.com/supplying-custom-data.html - ismirsehregal
1个回答

5
  • plotly_click 事件提供了数据跟踪的名称。
  • data 是点击事件的信息。
  • data.points[0].data.name 是跟踪/类别名称。

我们可以按照 category(就像 aes 一样)将数据框拆分并传递到我们的 JavaScript 函数中,而不是传递扁平化的数据框。

var urls = ", toJSON(split(myData, myData$category)), ";
                       

以下是对应的JSON格式:
{"other": [{"x":3,"y":1,"label":"R","category":"other","urls":"http://r-project.org"}],
 "search":[{"x":1,"y":3,"label":"Google","category":"search","urls":"http://google.de"},
           {"x":2,"y":2,"label":"Bing","category":"search","urls":"http://bing.com"}]
} 

URL然后是通过检索获得的

window.open(urls[data.points[0].data.name][data.points[0].pointNumber]['urls'],'_blank');
                       

即从提供的JSON中,我们从被点击的第一个(也是唯一的)点(data.points [0])中获取迹线的名称(data.name )和其pointNumber(即迹线中的第n个点)。

完整代码

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

myData <- data.frame(
  x=c(1,2,3), 
  y=c(3,2,1),
  label=c("Google", "Bing", "R"),
  category=c("search", "search", "other"),
  urls=c("http://google.de", "http://bing.com", "http://r-project.org")
)

f <- function(p) {
  ply <- ggplotly(p)
  
  javascript <- HTML(paste("
                           var myPlot = document.getElementsByClassName('js-plotly-plot')[0];
                           myPlot.on('plotly_click', function(data){
                           var urls = ", toJSON(split(myData, myData$category)), ";
                           window.open(urls[data.points[0].data.name][data.points[0].pointNumber]['urls'],'_blank');
                           });", sep=''))  
  prependContent(ply, onStaticRenderComplete(javascript))
}

f(ggplot(myData, aes(x=x, y=y)) + geom_point(aes(text=label, color=category)))

1
非常好用 - 感谢您的帮助和解释! - lukeA
1
对我来说,点击没有任何反应。您确定这个解决方案仍然有效吗? - geotheory
1
@geotheory:Plotly从ggplotly中删除了elementID,请参见https://cran.r-project.org/web/packages/plotly/news/news.html。示例已更新,希望最新版本也适用于您。 - Maximilian Peters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接