R 动态生成数据树
我正在尝试创建一个动态闪亮页面来利用data.tree包,但在尝试通过操作按钮动态添加子级和同级时遇到了问题。我已经提供了一个例子,但我不能让它正常工作。如果用户可以定义附加到父对象的子对象和兄弟对象的列表,那就太棒了R 动态生成数据树,r,dynamic,shiny,R,Dynamic,Shiny,我正在尝试创建一个动态闪亮页面来利用data.tree包,但在尝试通过操作按钮动态添加子级和同级时遇到了问题。我已经提供了一个例子,但我不能让它正常工作。如果用户可以定义附加到父对象的子对象和兄弟对象的列表,那就太棒了 library(shiny); library(data.tree) library(DiagrammeR) ui <- fluidPage( sidebarLayout( sidebarPanel = ( textInput("parent","
library(shiny);
library(data.tree)
library(DiagrammeR)
ui <- fluidPage(
sidebarLayout(
sidebarPanel = (
textInput("parent","parent","parent"),
actionButton("add_child", "Add Child"),
actionButton("add_sibling", "Add Sibling")
)
)
mainPanel(grVizOutput("HTATree") ),
)
server <- function(input, output){
output$HTATree=renderGrViz({
org <- Node$new(input$parent)
child1 = org$AddChild("Child_1")
child2 = org$AddChild("Child_2")
child1$AddSibling("Sibling")
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(org)))
})
observeEvent(input$add_child,{
#add a child under the parent
}
)
observeEvent(input$add_sibling,{
#Add sibling
}
}
shinyApp(ui = ui, server = server)
库(闪亮);
库(data.tree)
图书馆(图解机)
ui嗯,这并不漂亮,也不是什么累赘,但它很管用。请注意,为了创建同级节点,您必须首先使用“遍历”选项爬升到该节点,因为您无法在根节点上创建同级节点:
library(shiny)
library(data.tree)
library(DiagrammeR)
ui <- fluidPage(
uiOutput("mainpage")
)
server <- function(input, output){
working <- reactiveValues(org = NULL)
current <- reactiveValues(ch_name = NULL,prefix = NULL,addchild=NULL,addsibling=NULL)
output$mainpage <- renderUI({
sidebarLayout(
sidebarPanel(
fixedRow(
textInput("parent","name of parent")
),
fixedRow(
textInput("initch_name","first child node name")
),
fixedRow(
h5("Must assign parent with initial child node")
),
fixedRow(
actionButton("crt_parent","Create Parent")
),
fixedRow(
if(!is.null(working$org)){
selectInput("ttl","traverse to level",choices=c("root",if(!is.null(current$ch_names)){current$ch_names}))
}
),
fixedRow(
textInput("ch_name","Child node name")
),
fixedRow(
actionButton("add_child", "Add Child")
),
fixedRow(
textInput("sib_name","sibling node name")
),
fixedRow(
actionButton("add_sibling", "Add Sibling")
)
),
mainPanel(grVizOutput("HTATree") )
)
})
output$HTATree=renderGrViz({
working$org
if(!is.null(working$org)){
if(!is.null(current$addchild)){
working$org$AddChild(current$addchild)
current$ch_names <- names(working$org$children)
current$addchild <- NULL}
if(!is.null(current$addsibling)){
working$org$Climb(input$ttl)$AddSibling(current$addsibling)
current$ch_names <- names(working$org$Climb(input$ttl)$children)
current$addsibling <- NULL}
#child2 = org$AddChild("Child_2")
#child1$AddSibling("Sibling")
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(working$org)))
}
})
observeEvent(input$crt_parent,{
working$org <- makeorg()
print(current$prefix$children)
})
makeorg <- reactive({
if(is.null(input$parent)){
return(NULL)
}
if(is.null(working$org)){
org <- Node$new(input$parent)
org$AddChild(input$initch_name)
current$ch_names <- names(org$children)
return(org)}else{
return(working$org)
}
})
observeEvent(input$add_child,{
current$addchild <- input$ch_name
})
observeEvent(input$add_sibling,{
current$addsibling <- input$sib_name
})
}
shinyApp(ui = ui, server = server)
库(闪亮)
库(data.tree)
图书馆(图解机)
ui正如我所说,您可以添加panel来控制您的树
例如,您有基本树:
#create main tree
vv$org <- Node$new(input$root_name)
vv$org$AddChildNode(child = Node$new(input[["1_child"]]))
vv$names=vv$org$Get('name') # get names of main tree
听众:
observeEvent(input$add_child,{
FindNode(node=vv$org,name = input$Parent_name)$AddChildNode(Node$new(input$new_node_name)) # add child
vv$names=vv$org$Get('name')# get names of new tree
#re-generate chart
output$xx=renderGrViz({
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(vv$org)),engine = "dot")
})
})
2) 除去
视图:
Listener1查找所选节点的子节点:
observeEvent({
list(input$Parent_name_remove,
input$add_child ,
input$remove_child)},{
if(!is.null(input[["Parent_name_remove"]])){
node_=FindNode(node=vv$org,name = input$Parent_name_remove)
children_names=node_$Get('name')
updateSelectInput(session,inputId ="Name_to_remove",choices = children_names[children_names!=input$Parent_name_remove] )
}
})
Listener2要删除子项:
observeEvent(input$remove_child,{
if(input$Name_to_remove!=""){
FindNode(node=vv$org,name = input$Parent_name_remove)$RemoveChild(input$Name_to_remove)
#re-generate chart
output$xx=renderGrViz({
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(vv$org)),engine = "dot")
})
}
})
完整代码
library(shiny);
library(data.tree)
library(DiagrammeR)
library(shinyjs)
ui <- fluidPage(
mainPanel(
useShinyjs(),
div(id="start",
textInput("root_name","root_name","1"),
textInput("1_child","1_child","1.1"),
actionButton("go","go")
),
uiOutput("add_child_ui"),
grVizOutput("xx") )
)
server <- function(input, output,session){
#Create reative value to app
vv=reactiveValues(org=NULL,names=NULL)
observeEvent(input$go,{
#create main tree
vv$org <- Node$new(input$root_name)
vv$org$AddChildNode(child = Node$new(input[["1_child"]]))
vv$names=vv$org$Get('name') # get names of main tree
output$xx=renderGrViz({
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(vv$org)),engine = "dot")
})
shinyjs::hide(id ="start" )
output$add_child_ui=renderUI({
fluidRow(
column(4,selectInput("Parent_name","Parent_name",vv$names),
textInput("new_node_name","new_node_name",""),
actionButton("add_child","add_child")),
column(4,selectInput("Parent_name_remove","Parent_name_remove",vv$names),
selectInput("Name_to_remove","Name_to_remove",""),
actionButton("remove_child","remove_child"))
)
})
})
observeEvent({
list(input$Parent_name_remove,
input$add_child ,
input$remove_child)},{
if(!is.null(input[["Parent_name_remove"]])){
node_=FindNode(node=vv$org,name = input$Parent_name_remove)
children_names=node_$Get('name')
updateSelectInput(session,inputId ="Name_to_remove",choices = children_names[children_names!=input$Parent_name_remove] )
}
})
observeEvent(input$remove_child,{
if(input$Name_to_remove!=""){
FindNode(node=vv$org,name = input$Parent_name_remove)$RemoveChild(input$Name_to_remove)
vv$names=vv$org$Get('name')# get names of new tree
#re-generate chart
output$xx=renderGrViz({
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(vv$org)),engine = "dot")
})
}
})
observeEvent(input$add_child,{
FindNode(node=vv$org,name = input$Parent_name)$AddChildNode(Node$new(input$new_node_name)) # add child
vv$names=vv$org$Get('name')# get names of new tree
#re-generate chart
output$xx=renderGrViz({
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(vv$org)),engine = "dot")
})
})
}
shinyApp(ui = ui, server = server)
库(闪亮);
库(data.tree)
图书馆(图解机)
图书馆(shinyjs)
感谢@Phi的回复。当我尝试添加childen或兄弟姐妹时,我只看到它与根直接相关,无法复制多个级别(即,将1.2.1作为子级创建为1.2)。这可能吗?好的,我已经改变了很多事情。我将制作完整的第二组代码作为第二次修订版..感谢您查看此内容。当我试图将一个子对象添加到一个子对象中,从而向层次结构/树请求第三级时,它只是将其添加到初始父对象中。这是可视化软件包的限制还是R中树生成器的限制?由于我编写代码的方式,可能还有更好的方法,您必须遍历到要添加子级或同级的“级别”。我会考虑其他方法来做这件事,回头看看我的例子,这就是你想要的?
observeEvent({
list(input$Parent_name_remove,
input$add_child ,
input$remove_child)},{
if(!is.null(input[["Parent_name_remove"]])){
node_=FindNode(node=vv$org,name = input$Parent_name_remove)
children_names=node_$Get('name')
updateSelectInput(session,inputId ="Name_to_remove",choices = children_names[children_names!=input$Parent_name_remove] )
}
})
observeEvent(input$remove_child,{
if(input$Name_to_remove!=""){
FindNode(node=vv$org,name = input$Parent_name_remove)$RemoveChild(input$Name_to_remove)
#re-generate chart
output$xx=renderGrViz({
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(vv$org)),engine = "dot")
})
}
})
library(shiny);
library(data.tree)
library(DiagrammeR)
library(shinyjs)
ui <- fluidPage(
mainPanel(
useShinyjs(),
div(id="start",
textInput("root_name","root_name","1"),
textInput("1_child","1_child","1.1"),
actionButton("go","go")
),
uiOutput("add_child_ui"),
grVizOutput("xx") )
)
server <- function(input, output,session){
#Create reative value to app
vv=reactiveValues(org=NULL,names=NULL)
observeEvent(input$go,{
#create main tree
vv$org <- Node$new(input$root_name)
vv$org$AddChildNode(child = Node$new(input[["1_child"]]))
vv$names=vv$org$Get('name') # get names of main tree
output$xx=renderGrViz({
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(vv$org)),engine = "dot")
})
shinyjs::hide(id ="start" )
output$add_child_ui=renderUI({
fluidRow(
column(4,selectInput("Parent_name","Parent_name",vv$names),
textInput("new_node_name","new_node_name",""),
actionButton("add_child","add_child")),
column(4,selectInput("Parent_name_remove","Parent_name_remove",vv$names),
selectInput("Name_to_remove","Name_to_remove",""),
actionButton("remove_child","remove_child"))
)
})
})
observeEvent({
list(input$Parent_name_remove,
input$add_child ,
input$remove_child)},{
if(!is.null(input[["Parent_name_remove"]])){
node_=FindNode(node=vv$org,name = input$Parent_name_remove)
children_names=node_$Get('name')
updateSelectInput(session,inputId ="Name_to_remove",choices = children_names[children_names!=input$Parent_name_remove] )
}
})
observeEvent(input$remove_child,{
if(input$Name_to_remove!=""){
FindNode(node=vv$org,name = input$Parent_name_remove)$RemoveChild(input$Name_to_remove)
vv$names=vv$org$Get('name')# get names of new tree
#re-generate chart
output$xx=renderGrViz({
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(vv$org)),engine = "dot")
})
}
})
observeEvent(input$add_child,{
FindNode(node=vv$org,name = input$Parent_name)$AddChildNode(Node$new(input$new_node_name)) # add child
vv$names=vv$org$Get('name')# get names of new tree
#re-generate chart
output$xx=renderGrViz({
grViz(DiagrammeR::generate_dot(ToDiagrammeRGraph(vv$org)),engine = "dot")
})
})
}
shinyApp(ui = ui, server = server)