I would like to filter nodes in a shinyTree based on input values supplied by the user. I have an initial attempt, but the issue is the tree does not maintain state after input, such as open/closed nodes, or selected nodes. For example, in my sample code below, say I have 1-3a and 4-6 expanded, and have value 3 and 5 selected.
If I move the slider to 2, this should remove the 1 entry from 1-3a and 1-3b, I want to keep 1-3a and 4-6 expanded, and values 3-6 checked. However, I'm creating the tree from scratch each time so all state is lost.
Is there a way to show/hide nodes in shiny tree so that the state is maintained?
library(shiny)
library(shinyTree)
library(dplyr)
dat <- tibble(
grp=rep(c("1-3a","1-3b","4-6"),each=3),
leaf=c(1:3,1:3,4:6),
val=c(1:3,1:3,4:6),
)
#' Recursively walks down the columns of a dataframe making nested groups
listTree <- function(dat) {
if(ncol(dat) > 2) {
x <- dat %>% nest(data=-1)
lst <- as.list(x[[2]])
names(lst) <- x[[1]]
lst %>% map(listTree)
} else if(ncol(dat)==2) {
lst<-as.list(dat[[2]])
names(lst)<-dat[[1]]
return(lst)
} else if(ncol<2) {
stop('ERROR')
}
}
ui <- fluidPage(
p('Filter nodes < selected value'),
sliderInput("num", "Value",
min = 1, max = 6, value = 1),
shinyTree("tree",checkbox=TRUE)
)
server <- function(input, output, session) {
datr <- reactive({
dat %>% filter(val >= input$num)
})
output$tree <- renderTree({listTree(datr())})
}
shinyApp(ui, server)
The 'jsTreeR' package is similar to the 'shinyTree' package but it allows more possibilities. Here is how one can do to achieve what you want: