单击 ggplot/plotly 图表打开超链接
Open hyperlink on click on an ggplot/plotly chart
这是针对 提供的答案的后续问题。考虑以下示例:
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)))
绘图对象不同,似乎 pointNumber
不再保存所有点的绝对索引,而是(颜色)分组中的索引。
关于如何调整示例以使其适用于一般用例以及 color/fill 分组的任何想法?
plotly_click
事件提供数据跟踪的名称。
data
为点击事件信息
data.points[0].data.name
是 trace/category 名字
我们可以通过 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-th 点)。
完整代码
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)))
这是针对
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)))
绘图对象不同,似乎 pointNumber
不再保存所有点的绝对索引,而是(颜色)分组中的索引。
关于如何调整示例以使其适用于一般用例以及 color/fill 分组的任何想法?
plotly_click
事件提供数据跟踪的名称。data
为点击事件信息data.points[0].data.name
是 trace/category 名字
我们可以通过 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"}]
}
然后
检索 URLwindow.open(urls[data.points[0].data.name][data.points[0].pointNumber]['urls'],'_blank');
即从提供的 JSON 中:我们从第一个(也是唯一一个)点击的点 (data.points[0]
) 中获取轨迹的名称 (data.name
) 及其 pointNumber
(即跟踪中的 n-th 点)。
完整代码
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)))