在带有 Shiny 的 rgl 中使用 toggleWidget

Using a toggleWidget in rgl with Shiny

我尝试使用以下代码创建可切换的绘图显示,但没有成功:

library(shiny)
library(rgl)

ui <- (fluidPage(
  checkboxInput("chk", label = "Display", value = TRUE),
  playwidgetOutput("control"),
  rglwidgetOutput("wdg")
))

server <- function(input, output, session) {
  options(rgl.useNULL = TRUE)
  save <- options(rgl.inShiny = TRUE)
  on.exit(options(save))

  open3d()
  plot3d(rnorm(100), rnorm(100), rnorm(100))
  scene <- scene3d()
  rgl.close()

  plot3d(scene)

  output$wdg <- renderRglwidget({
    rglwidget(controllers = c("control"))
  })

  output$control <- renderPlaywidget({
    toggleWidget("wdg", respondTo = "chk",
                 ids = as.integer(names(scene$objects[1])))
  })
}

shinyApp(ui = ui, server = server)

使用当前代码设置,出现以下错误:

Error: length(buttonLabels) == length(components) is not TRUE

据我所知 toggleWidget 包裹 playwidget 的方式,不过,似乎 buttonLabelscomponents 都是长度为 1 的字符向量.

我还尝试了 toggleWidgetids 变量的多种不同变体,并取得了相似的成功水平。 Shiny 中 rgl 的示例似乎很少。

rgl 中使用 Shiny 的 toggleWidget 的正确方法是什么?

您看到的特定错误消息是由于 rgl 中的一个错误:当链接到 Shiny 控件时,您需要将 toggleWidget 标签显式设置为 character()。还有另一个错误相关 到 Shiny 使用的复选框。两个错误都已修复。

但是,这还不足以让您的示例正常工作。我还没有完全调试它,但我可以看到以下内容:

  • 您正在两次绘制场景。您可能只想绘制一次。
  • 由于您已将场景保存在变量 scene 中,您应该将其传递给 rglwidget()
  • 让 ID 切换的最安全方法是保存 plot3d 调用的结果,然后在 toggleWidget 调用中使用这些值。

我不确定是哪一个导致您的脚本失败,但新的 demo(shinyToggle)(如下所示)工作正常。

library(shiny)
library(rgl)

open3d(useNULL = TRUE)
ids <- plot3d(rnorm(100), rnorm(100), rnorm(100))[1]
scene <- scene3d()
rgl.close()

ui <- (fluidPage(
    checkboxInput("chk", label = "Display", value = FALSE),
    playwidgetOutput("control"),
    rglwidgetOutput("wdg")
))

server <- function(input, output, session) {
    options(rgl.useNULL = TRUE)
    save <- options(rgl.inShiny = TRUE)
    on.exit(options(save))

    output$wdg <- renderRglwidget({
        rglwidget(scene, controllers = c("control"))
    })

    output$control <- renderPlaywidget({
        toggleWidget("wdg", respondTo = "chk",
                 ids = ids)
    })
}

if (interactive())
  shinyApp(ui = ui, server = server)