2016-08-09 6 views
2

私は、ユーザーがデータのテーブルから始めて、前のテーブルの選択されたフィルタ/サマリーに基づいて新しいテーブルを作成することができます。 R内のリストのリストを使用しRシャイニーのactionButtonsを使用してツリーにノードを追加する

Table1 ---- (filter) > Table2 
     ---- (filter) > Table3 ---- (filter) > Table4 
           ---- (filter) > Table5 
     ---- (filter) > Table6 

、Iは各テーブル/ノードを追跡するために(私のコード例にsliceBox.tree呼ばれる)ツリーデータ構造を作りました。 各テーブルには、入力のセットもあります。いくつかのフィルタ設定とactionButtonは、その親テーブルの下に新しい子テーブルを作成するために使用できます。

私はobserveEvent()関数を使用して各ボタンプレスに反応しますが、observeEventハンドラ内のツリーにノードを追加しようとすると、その変更は関数内のコピーツリーにのみ行われ、元のツリーは影響を受けません。 observeEventハンドラの内部から元のツリーを編集する方法はありますか?これを行うには別の方法がありますか?

ここでは、問題を説明するために私のコードのトリムダウンバージョンがあります。現在のコードでは、既存のボタンをクリックしてページ上に子のactionButtonを作成します。日本に貼付されて -

server <- function(input, output) { 

    newNode <- function(id, parentId) { 
    node <- list(
     parent = parentId, 
     children = list(), 
     uiObject = createButton(id, parentId) 
    ) 
    return(node) 
    } 


    createButton <- function(id, parentId) { 
    print(paste0("Creating button ", id)) 
    buttonID <- paste0("sliceBoxButton", id) 
    return(actionButton(buttonID, paste0("I am ", buttonID, ", child of ", parentId), icon("plus-circle fa-2x"))) 
    } 


    rootNode <- newNode(1, 0) 
    sliceBox.tree <- list(rootNode) # We'll store our nodes as a 1D list, so parent and child ID's are recorded as their indices in the list 
    output$debug <- renderPrint({ 
    print(paste0("Button presses: ", v$counter)) 
    print("FULL TREE") 
    print(sliceBox.tree) 
    }) 


    # Keep a total count of all the button presses (also used loosely as the number of tables created) 
    v <- reactiveValues(counter = 1L) 

    # Event handlers: specific function for particular button will run when that button is pressed 
    observeEvent(v$counter, { 
    for (id in 1:v$counter) { 
     buttonID <- paste0("sliceBoxButton", id) 
     observeEvent(input[[buttonID]], { 
     v$counter <- v$counter + 1L 
     print(paste0("Pressed ", buttonID)) 


     # Append new child to list of children 
     numChildren <- length(sliceBox.tree[[id]]$children) 
     sliceBox.tree[[id]]$children[numChildren + 1] <- v$counter 


     sliceBox.tree[[v$counter]] <- newNode(v$counter, id) 
     print(paste0("Appending node to tree at index ", v$counter)) 
     print(sliceBox.tree) 
     }) 
    } 
    }) 


    # renderUI needs a list of uiObjects, so we just extract the uiObjects from every node of the tree 
    output$allSliceBoxes <- renderUI({ 
    table_output_list <- lapply(1:v$counter, function(i) { 
     return(getElement(sliceBox.tree[[i]], 'uiObject')) 
    }) 
    do.call(tagList, table_output_list) # Convert the list to a tagList 
    }) 


} 


ui <- fluidPage(
    uiOutput("allSliceBoxes"), 
    verbatimTextOutput('debug') 
) 


shinyApp(ui = ui, server = server) 

は本当に私は広範囲にグーグルしてきたが、同様の何かを任意の例を発見していない、誰かが助けることを願って!

答えて

1

これを解決する方法の1つは、ツリーをreactiveValues構造体に保存することです。その時点から

# sliceBox.tree <- list(rootNode) 
# Use this instead: 
sliceBox.tree <- reactiveValues(tree=list(rootNode)) 

sliceBox.tree$treeにすべてのsliceBox.treeを変更します。 それは私のために働く。

関連する問題