r - 是否可以在 Shiny 的应用程序(renderGrViz)中选择一个graphviz节点,然后链接到其他信息?

标签 r shiny graphviz htmlwidgets diagrammer

我想向我 Shiny 的应用程序中的中央 graphviz 节点添加一个功能(弹出窗口或其他功能?),当通过鼠标单击选择时,它们会显示信息(例如 center_nodes 文件中的信息列) 。鉴于这些节点有一个工具提示属性,我认为/希望计算机必须“看到”它们,但我还没有找到连接这两个节点并建立这种行为的方法......

我探索了各种方法(例如reactR,html标签,hover.css,shinyBS,d3,pipeR,XML,htmltools),但认为它一定可以使用css或htmlwidgets,但我对这段代码的了解能力有限,目前还没有找到解决办法。我觉得对于熟悉这种类型编码的人来说它很简单......

这是一个使用 DiagrammeRgrViz 的示例 Shiny 应用程序:

library(DiagrammeR)
library(shiny)

ui = shinyUI(fluidPage(grVizOutput('graphV'))) 

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

shinyApp(ui = ui, server = server)

希望的结果是我可以通过单击选择一个节点,然后将显示与该节点相关的信息。通过工具提示功能,我可以滚动节点并显示信息,但对单击的响应在美观上会更具吸引力。甚至能够更改工具提示的外观也将是对当前工具提示的改进。

非常感谢任何帮助!

最佳答案

这里是关于如何根据被单击的元素添加 html 元素的草案。也许你可以在你想要放置它们的地方详细说明一下,或者如果你也可以添加其他 Shiny 的元素(会更容易)。

下面代码的想法是添加一个 onclick 监听器。捷径是用shinyjs来实现它。元素的标识符似乎是 node1node2 等。

然后有多个选项。将该信息返回给“R/Shiny”,并通过 Shiny.OnInputChanged(...) 添加 Shiny 元素或通过 javascript 附加 html 元素。 使用 Shiny.OnInputChanged(...) 更容易,所以我尝试让第二个也能工作。下面给出一个例子。

在图表中添加新的 html 元素并将它们放在图表前面并不简单。人们可以通过校准 css 以将其显示在前面进行实验 (style="z-index: -1"),但也许进一步指定最佳解决方案是一个好点。

(为了完整起见,添加的元素当然也可以删除,这样一次只显示一个“工具提示”,...)

可重现的示例:

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(),
    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)

尝试让工具提示覆盖图表失败:

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

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

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

ui = shinyUI(
  fluidPage(
    useShinyjs(),
    tags$style("
       .mystyle {
          z-index: 100 !important;
          background-color: coral;
          font-size: 25px;
       }

       #node1 {
         width: 50px; 
         z-index: unset !important;
         background-color: blue;
       }
    "),
    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)

编辑评论中的问题:

例如,如果您有一个 40 个节点的图表,是否有办法自动将节点 ID 链接到节点描述(在上面的情况下为“A 的 Great div”)?或者我只需要按照 graphviz 代码中列出的节点顺序对文本文件进行排序?

正确。在diagrammeR代码中,它似乎只是向上计数id:“node1,node2,node3,...)。

所以我只是在 Shiny 中做同样的事情:

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

    }

如您所见,对于节点号 paste0("node", nodeNr),将为点击事件分配 javascript 代码 jsCode[nodeNr]。 并且 jsCode[nodeNr] 将包含 texts[nodeNr]。 (请注意,jsCode 将是根据 texts 长度的字符串向量。

关于r - 是否可以在 Shiny 的应用程序(renderGrViz)中选择一个graphviz节点,然后链接到其他信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57601875/

相关文章:

r - 两个结构体的猫 : not the same fields

r - 过滤任何包含 Inf 的行

r - 在 Shiny 的应用程序中存储 RHandsontable 的编辑

javascript - 自动打开 Google map 和街景

r - 编译后的 R 代码实际上比启用 JIT 的纯 R 慢

r - 在 R 中将 excel 输出从字符转换为数字

r - global.R 不启动

graphviz - 仅使用 graphviz 工具生成传递闭包

python - 如何使用 PyGraphviz 在无向图的边上添加和显示权重?

graphviz - 从 Graphviz 中记录元素的中心开始绘制传出边