对 htmlWidgets 的 onRender() 函数中的 Javascript 代码进行故障排除
Troubleshoot Javascript code in onRender() function of htmlWidgets
我正在尝试在 RStudio 中的 (https://plot.ly/javascript/click-events/) 重新创建名为 "Create annotation on click event" 的示例。在我的尝试中,我想出了以下用于 RStudio 的定制代码:
library(plotly)
trace_0 <- rnorm(100, mean = 5)
trace_1 <- rnorm(100, mean = 0)
trace_2 <- rnorm(100, mean = -5)
x <- c(1:100)
data <- data.frame(x, trace_0, trace_1, trace_2)
data %>% plot_ly(x = ~x, y = ~trace_0, name = 'trace 0', type = 'scatter', mode = 'lines') %>%
layout(hovermode = "closest", showlegend = FALSE) %>%
onRender("
function(el, x) {
var myGraph = document.getElementById(el.id);
el.on('plotly_click', function(e) {
var pts = '';
for(var i=0; i < e.points.length; i++){
annotate_text = 'x = '+e.points[i].x +
'y = '+e.points[i].y.toPrecision(4);
annotation = {
text: annotate_text,
x: e.points[i].x,
y: parseFloat(e.points[i].y.toPrecision(4))
}
annotations = self.layout.annotations || [];
annotations.push(annotation);
Plotly.relayout('myGraph',{annotations: annotations})
}
}
")
在 RStudio 中 运行 设置我的代码后,我确实在绘图查看器中看到了交互式绘图图像,但我无法创建与它交互时应该出现的任何注释(例如在线教程)。
我的问题分为两部分。
1) 我正在尝试弄清楚如何排除和解决这个特定问题。
2) 我试图从总体上更好地理解如何对 html 小部件的 onRender() 函数中嵌入的 Javascript 代码进行故障排除。是否可以逐行 运行 这段代码并说创建变量 "pts" 并查看它在循环中如何更新以及当我单击某些点时注释变量如何变化?如果无法通过这种方式进行故障排除,我担心很难为我正在开发的交互式绘图定制 onRender()。我相信 Javascript 可以在 Web 浏览器中进行故障排除,但我不清楚如何使用这个特定的 Javascript 代码(嵌入在 R 中)。
感谢您的宝贵意见!
编辑:
考虑到@bethanyP 的一些建议,我尝试了以下方法:
1) 制作了以下格式的 .Rmd 文件:
---
title: "annotePlot"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r makePlot}
########### Ex: Change scatterplot opacity ###########
# Supposed to keep clicked point black, but it turns all gray
set.seed(1)
(Rest of code in here)
````
2) 运行 rmarkdown::render("annotate.Rmd") 生成了 .html 文件
3) 在 Chrome
中打开了 URL (file:///Users/user1835/annotate.html)
4) 注意到网页底部已经创建了交互图。我可以和它互动(如果我点击一个点,所有的点都会从黑色变成灰色)
5) 单击 Chrome 右上角的图标 --> 更多工具 --> 开发者工具
此时,我不确定如何使用可用的工具来解决问题。我的 Chrome 浏览器中有如下内容(见图):
当我单击图表中的某个点时,我看到标记突出显示。但是,我无法看到有关单个对象(例如 e)的更多信息。我不确定我怎么会知道对象 e 有一个名为点的子对象。此外,我不确定当用户单击某个点时如何查看哪些对象更新(以及更新方式)。我有可能看到这样的东西吗?我相信我需要了解这些对象并了解它们在与之交互时如何变化。
非常感谢任何建议!
它可能看起来很复杂,但我必须使用 Javascript 和 R 的最佳工具在 chrome 的检查器中,所以我将图形导出为网页。您实际上可以通过这种方式编辑和重新运行 代码来找出Javascript 问题所在。
此外,我发现 rStudio 查看器并不是 100% 乐于推广 JS 对象。我的 Leaflet 地图在 time-to-time 的查看器控制台中工作时遇到一些问题。有些功能在 rStudio 中失败(不是编译版本,通常是正确的,但控制台版本可能不是)。
我的解决方案是创建一个 rMarkdown 文档并将其输出指定给 html。然后绘制、绘制地图和图表。编写文档并在 R & rStudio 之外对其进行测试。
当您使用 knitR 运行 文件时,它会保存您文档的网络版本。在 Chrome 中打开它,看看里面发生了什么。也就是说,如果您可以让 R 将其无错误地呈现到 HTML 页面中...
为了解决此类代码问题,我通常直接在浏览器中查看绘图。如果您使用的是 RStudio,则可以单击查看器顶部的 "Show in new window" 按钮直接在浏览器中打开它。
否则,您也可以在代码中将 viewer
选项设置为 NULL
,绘图将直接在浏览器中打开。为此,您可以添加:
default_viewer = getOption("viewer")
options("viewer"=NULL)
在您绘制之前保存当前查看器选项并将其设置为空,并且
options("viewer"=default_viewer)
在你的计划之后将其重置为默认值。
在您的 onRender
函数中,当代码为 运行 时,您可以使用 console.log
将自定义消息打印到 javascript 控制台。如果您使用的是 Chrome 开发人员工具,则可以访问此控制台。
您的代码本身有一些问题。首先,括号并没有全部关闭。那么最后一行的 'myGraph'
应该是 div
的 id
,所以在这种情况下 el.id
.
这是一个工作函数:
onRender("
function(el, x) {
var myGraph = document.getElementById(el.id);
el.on('plotly_click', function(e) {
var pts = '';
for(var i=0; i < e.points.length; i++){
var annotate_text = 'x = '+e.points[i].x +
'y = '+e.points[i].y.toPrecision(4);
var annotation = {
text: annotate_text,
x: e.points[i].x,
y: parseFloat(e.points[i].y.toPrecision(4))
}
annotations = el.layout.annotations || [];
annotations.push(annotation);
Plotly.relayout(el.id,{annotations: annotations})
}
})}
")
我正在尝试在 RStudio 中的 (https://plot.ly/javascript/click-events/) 重新创建名为 "Create annotation on click event" 的示例。在我的尝试中,我想出了以下用于 RStudio 的定制代码:
library(plotly)
trace_0 <- rnorm(100, mean = 5)
trace_1 <- rnorm(100, mean = 0)
trace_2 <- rnorm(100, mean = -5)
x <- c(1:100)
data <- data.frame(x, trace_0, trace_1, trace_2)
data %>% plot_ly(x = ~x, y = ~trace_0, name = 'trace 0', type = 'scatter', mode = 'lines') %>%
layout(hovermode = "closest", showlegend = FALSE) %>%
onRender("
function(el, x) {
var myGraph = document.getElementById(el.id);
el.on('plotly_click', function(e) {
var pts = '';
for(var i=0; i < e.points.length; i++){
annotate_text = 'x = '+e.points[i].x +
'y = '+e.points[i].y.toPrecision(4);
annotation = {
text: annotate_text,
x: e.points[i].x,
y: parseFloat(e.points[i].y.toPrecision(4))
}
annotations = self.layout.annotations || [];
annotations.push(annotation);
Plotly.relayout('myGraph',{annotations: annotations})
}
}
")
在 RStudio 中 运行 设置我的代码后,我确实在绘图查看器中看到了交互式绘图图像,但我无法创建与它交互时应该出现的任何注释(例如在线教程)。
我的问题分为两部分。
1) 我正在尝试弄清楚如何排除和解决这个特定问题。
2) 我试图从总体上更好地理解如何对 html 小部件的 onRender() 函数中嵌入的 Javascript 代码进行故障排除。是否可以逐行 运行 这段代码并说创建变量 "pts" 并查看它在循环中如何更新以及当我单击某些点时注释变量如何变化?如果无法通过这种方式进行故障排除,我担心很难为我正在开发的交互式绘图定制 onRender()。我相信 Javascript 可以在 Web 浏览器中进行故障排除,但我不清楚如何使用这个特定的 Javascript 代码(嵌入在 R 中)。
感谢您的宝贵意见!
编辑:
考虑到@bethanyP 的一些建议,我尝试了以下方法:
1) 制作了以下格式的 .Rmd 文件:
---
title: "annotePlot"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r makePlot}
########### Ex: Change scatterplot opacity ###########
# Supposed to keep clicked point black, but it turns all gray
set.seed(1)
(Rest of code in here)
````
2) 运行 rmarkdown::render("annotate.Rmd") 生成了 .html 文件
3) 在 Chrome
中打开了 URL (file:///Users/user1835/annotate.html)4) 注意到网页底部已经创建了交互图。我可以和它互动(如果我点击一个点,所有的点都会从黑色变成灰色)
5) 单击 Chrome 右上角的图标 --> 更多工具 --> 开发者工具
此时,我不确定如何使用可用的工具来解决问题。我的 Chrome 浏览器中有如下内容(见图):
当我单击图表中的某个点时,我看到标记突出显示。但是,我无法看到有关单个对象(例如 e)的更多信息。我不确定我怎么会知道对象 e 有一个名为点的子对象。此外,我不确定当用户单击某个点时如何查看哪些对象更新(以及更新方式)。我有可能看到这样的东西吗?我相信我需要了解这些对象并了解它们在与之交互时如何变化。
非常感谢任何建议!
它可能看起来很复杂,但我必须使用 Javascript 和 R 的最佳工具在 chrome 的检查器中,所以我将图形导出为网页。您实际上可以通过这种方式编辑和重新运行 代码来找出Javascript 问题所在。
此外,我发现 rStudio 查看器并不是 100% 乐于推广 JS 对象。我的 Leaflet 地图在 time-to-time 的查看器控制台中工作时遇到一些问题。有些功能在 rStudio 中失败(不是编译版本,通常是正确的,但控制台版本可能不是)。
我的解决方案是创建一个 rMarkdown 文档并将其输出指定给 html。然后绘制、绘制地图和图表。编写文档并在 R & rStudio 之外对其进行测试。
当您使用 knitR 运行 文件时,它会保存您文档的网络版本。在 Chrome 中打开它,看看里面发生了什么。也就是说,如果您可以让 R 将其无错误地呈现到 HTML 页面中...
为了解决此类代码问题,我通常直接在浏览器中查看绘图。如果您使用的是 RStudio,则可以单击查看器顶部的 "Show in new window" 按钮直接在浏览器中打开它。
否则,您也可以在代码中将 viewer
选项设置为 NULL
,绘图将直接在浏览器中打开。为此,您可以添加:
default_viewer = getOption("viewer")
options("viewer"=NULL)
在您绘制之前保存当前查看器选项并将其设置为空,并且
options("viewer"=default_viewer)
在你的计划之后将其重置为默认值。
在您的 onRender
函数中,当代码为 运行 时,您可以使用 console.log
将自定义消息打印到 javascript 控制台。如果您使用的是 Chrome 开发人员工具,则可以访问此控制台。
您的代码本身有一些问题。首先,括号并没有全部关闭。那么最后一行的 'myGraph'
应该是 div
的 id
,所以在这种情况下 el.id
.
这是一个工作函数:
onRender("
function(el, x) {
var myGraph = document.getElementById(el.id);
el.on('plotly_click', function(e) {
var pts = '';
for(var i=0; i < e.points.length; i++){
var annotate_text = 'x = '+e.points[i].x +
'y = '+e.points[i].y.toPrecision(4);
var annotation = {
text: annotate_text,
x: e.points[i].x,
y: parseFloat(e.points[i].y.toPrecision(4))
}
annotations = el.layout.annotations || [];
annotations.push(annotation);
Plotly.relayout(el.id,{annotations: annotations})
}
})}
")