使 div 出现在 R 中的点击上

Make div appear on click in R plotly

我是 Javascript 与 R 结合的新手,我的 Javascript 知识非常有限。我正在尝试制作一个 plotly 国际象棋开局图,当你点击开局时,它会显示一个棋盘,其中包含开局的初始动作。

library(plotly)
library(htmlwidgets)
library(data.table)
library(rchess)

data("chessopenings")
setDT(chessopenings)
mychess = chessopenings[1:10]
mychess[, Pop := sample(c(1,2,4), nrow(mychess), replace = T)]
mychess[, fens := sapply(pgn, function(x) {chsspgn <- Chess$new(); chsspgn$load_pgn(x); chsspgn$fen()})]

上面的代码只是创建了一个包含 10 个空缺职位的样本数据集。然后我根据我在此处找到的指导使用 plotly 绘制那些 https://plotly-r.com/supplying-custom-data.html#fig:hover-annotate 我尝试创建一个新函数,当您单击这些点时它会显示棋盘。 棋盘功能是此处指定的功能 https://chessboardjs.com/examples#1002 如果我理解正确(如果我错了请纠正我)它 returns 一个 'div' 元素,这是我必须显示的元素。

q = plot_ly(mychess, x = ~eco, y = ~Pop) %>% 
  add_markers(text = ~name,
              customdata = ~fens)  
    
onRender(
  q, "
     function(el) {
      el.on('plotly_click', function(d) {
      var pt = d.points[0]; 
      var fen =  d.points[0].customdata
      var newboard = Chessboard('myBoard', fen);
      newboard.style.visibility = 'visible';
      newboard.style.display = 'block';
      })}")

很遗憾,没有任何显示。我使用了此处提供的信息 Show/hide 'div' using JavaScript,但我似乎遗漏了什么。

更新:我尝试了@Bas 的建议,使用以下代码转换图像:

png(pic1 <- tempfile(fileext = ".png"));chessboardjs(fen = mychess$fens[1]); dev.off() 
text = knitr::image_uri(pic1) 
text = sub(".*?,", "", text) 
html <- sprintf('<html><body><img src="data:image/png;base64,%s"></body></html>', text) 
cat(html, file = tf2 <- tempfile(fileext = ".html")) 
browseURL(tf2)

但这也不行。

如果您像下面那样应用 Plotly.relayout(...) 函数,它就会起作用。请注意,我用一些自定义数据替换了图像,因为我没有 Chessboard(...) 函数。

htmlwidgets::onRender(
  q, "
  function(el) {
      el.on('plotly_click', function(d) {
      var pt = d.points[0]; 
      var fen =  d.points[0].customdata
      var img = {
            // location of image
            source: \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==\",
            // top-left corner
            x: 0,
            y: 1,
            sizex: 0.2,
            sizey: 0.2,
            xref: 'paper',
            yref: 'paper'
          };
      Plotly.relayout(el.id, {
               images: [img] 
      });
      })}
      ")

您必须包含棋盘 JavaScript 和 CSS-Files 才能使用 Chessboard 功能。该函数不会创建 div,而是将 chessboard-visualization 附加到给定的 CSS-selector。所以 div 必须事先创建。


闪亮版:

library(plotly)
library(htmlwidgets)
library(data.table)
library(rchess)
library(shiny)

data("chessopenings")
setDT(chessopenings)
mychess = chessopenings[1:10]
mychess[, Pop := sample(c(1,2,4), nrow(mychess), replace = T)]
mychess[, fens := sapply(pgn, function(x) {chsspgn <- Chess$new();
chsspgn$load_pgn(x); chsspgn$fen()})]

ui <- fluidPage(
  tags$head(tags$link(href = "https://unpkg.com/@chrisoakman/chessboardjs@1.0.0/dist/chessboard-1.0.0.min.css", rel = "stylesheet", type = "text/css")),
  tags$head(tags$script(src = "https://unpkg.com/@chrisoakman/chessboardjs@1.0.0/dist/chessboard-1.0.0.min.js")),
  plotlyOutput("plt"),
  div(id = "myBoard", style="width: 400px")
)

server <- function(input, output, session) {
  output$plt <- renderPlotly({
    q = plot_ly(mychess, x = ~eco, y = ~Pop) %>% 
      add_markers(text = ~name,
                  customdata = ~fens)  
    onRender(
      q, "
     function(el) {
      el.on('plotly_click', function(d) {
      var pt = d.points[0];
      var fen =  d.points[0].customdata;
      var newboard = Chessboard('myBoard', fen);
      })}")
  })
}

shinyApp(ui, server)

要查看 chess pieces 的图像,请将它们包含在 Shiny App 的 www/img/chesspieces/wikipedia/ 文件夹中。否则你会在浏览器控制台看到一些错误。

GET http://127.0.0.1:5247/img/chesspieces/wikipedia/wK.png HTTP/1.1 404 Not Found 11ms


一个 Markdown 版本:

要查看国际象棋位置,您必须下载 png files 并根据 .Rmd 文件所在的位置将它们放入此文件夹结构 /img/chesspieces/wikipedia/

---
  title: "Chess Openings"
  output: html_document
---

<style type="text/css">
@import url("https://unpkg.com/@chrisoakman/chessboardjs@1.0.0/dist/chessboard-1.0.0.min.css");
</style>

  <script src="https://unpkg.com/@chrisoakman/chessboardjs@1.0.0/dist/chessboard-1.0.0.min.js"></script>

```{r setup, include=FALSE}
library(plotly)
library(htmlwidgets)
library(data.table)
library(rchess)
library(shiny)
data("chessopenings")
setDT(chessopenings)
mychess = chessopenings[1:10]
mychess[, Pop := sample(c(1,2,4), nrow(mychess), replace = T)]
mychess[, fens := sapply(pgn, function(x) {chsspgn <- Chess$new();
chsspgn$load_pgn(x); chsspgn$fen()})]
```

```{r out.width='100%', echo=FALSE, warning = FALSE}
q = plot_ly(mychess, x = ~eco, y = ~Pop) %>%
  add_markers(text = ~name,
              customdata = ~fens)
onRender(
  q, "
 function(el) {
  el.on('plotly_click', function(d) {
  var pt = d.points[0];
  var fen =  d.points[0].customdata;
  var newboard = Chessboard('myBoard', fen);
  })}")
```

  <div id="myBoard" style="width: 400px"></div>