如何使用 shinyjs link graphviz 节点数据到 Shiny UI htmlOutput?

How to use shinyjs to link graphviz node data to the Shiny UI htmlOutput?

我希望能够在我的 graphviz 图表中 select 一个节点(带有工具提示),并将与该节点关联的文本信息输出到闪亮的 UI 中(例如htmlOutput/renderUI).

这个问题紧接着另一个问题 (Is it possible to select a graphviz node in a shiny app (renderGrViz) and then link to other information?)。尽管上一个问题部分成功(例如,我现在可以 select 一个节点,然后在 graphviz 图的底部生成相关信息),但它没有起到任何作用,因为输出没有出现闪亮应用程序的一部分。作为该问题的一部分,函数 Shiny.OnInputChanged(...)(或 Shiny.setInputValue)被认为是产生类似结果的更方便的方法(通过 javascript 附加 html 元素)和我想知道这是否会导致与闪亮框架更兼容的结果,因此可以作为闪亮小部件输出的输入? 不幸的是,我无法找到任何描述类似问题的网站(例如,必须首先从 graphviz 节点提取数据,然后将此输入连接到闪亮的输出)。因此,我整理了一个成功的基于 javascript 的代码示例,我希望用 shinyjs 重新创建它,并添加了一个 htmlOutput ('info') 'texts' 数据将出现相应的节点是 selected.

library(DiagrammeR)
library(shiny)
library(shinyjs)

texts <- c("Great div for A", "Even better div for B")

jsCode <- paste0("
    elem = document.getElementById('graphV');
        var node = document.createElement('div');
        var textnode = document.createTextNode('", texts,"');
        node.appendChild(textnode);
        elem.appendChild(node);
")

ui = shinyUI(
  fluidPage(
    useShinyjs(),
    sidebarLayout(
      sidebarPanel(htmlOutput('info')),
      mainPanel(grVizOutput('graphV'))
  ))
) 

server = function(input, output, session) {

  observe({
    for(nodeNr in 1:length(jsCode)){
      local({
        jsToAdd <- jsCode[nodeNr]
        shinyjs::onclick(paste0("node", nodeNr), runjs(jsToAdd)) 
      })

    }
  })

  output$graphV <- renderGrViz({ 
    grViz( "digraph test{
           A[tooltip='A word']; 
           B[tooltip='Another word'];
           A -> B;}" )
  })}

shinyApp(ui = ui, server = server)

您可以将 shinyjsonclickOninputchangedrenderUI 一起使用。

添加一个点击事件:

 shinyjs::onclick(paste0("node", nodeNr), runjs(jsToAdd)) 

使用 javascript:

在点击事件中产生闪亮的输入
jsCode <- paste0("Shiny.onInputChange('clickedElemNr',", 1:2,")")

(详情见此处:https://shiny.rstudio.com/articles/js-send-message.html),..

并渲染一个 ui 元素:

observeEvent(eventExpr = input$clickedElemNr,{
        output$tooltip <- renderUI({
          textInput(inputId = "x", label = "x", value = texts[input$clickedElemNr])
        })
      })

可重现的例子:

library(DiagrammeR)
library(shiny)
library(shinyjs)

texts <- c("Great div for A", "Even better div for B")

jsCode <- paste0("Shiny.onInputChange('clickedElemNr',", 1:2,")")

ui = shinyUI(
  fluidPage(
    useShinyjs(),
    sidebarLayout(
      sidebarPanel(htmlOutput('info'), uiOutput("tooltip")),
      mainPanel(grVizOutput('graphV'))
    ))
) 

server = function(input, output, session) {

  observeEvent(eventExpr = input$clickedElemNr,{
    output$tooltip <- renderUI({
      textInput(inputId = "x", label = "x", value = texts[input$clickedElemNr])
    })
  })

  observe({
    for(nodeNr in 1:length(jsCode)){
      local({
        jsToAdd <- jsCode[nodeNr]
        shinyjs::onclick(paste0("node", nodeNr), runjs(jsToAdd)) 
      })

    }
  })

  output$graphV <- renderGrViz({ 
    grViz( "digraph test{
           A[tooltip='A word']; 
           B[tooltip='Another word'];
           A -> B;}" )
})}

shinyApp(ui = ui, server = server)