Как убедиться, что Shiny App Checkboxes обновлены правильно? - PullRequest
0 голосов
/ 19 декабря 2018

в настоящее время происходит следующая ситуация:

Например - Запустить приложение - Нажмите кнопку Сбросить все флажки - Теперь посмотрите следующее поведение -

На вкладке «Съедобные» «Проверка»поле с названием «бекон», теперь переключайте вкладки и переходите на вкладку «Жареные» и «проверяйте» кнопку «Выбрать все»

, при этом снимается флажок «проверено» бекона, который мы изначально проверяли, и используется «Жареная»"tab, по сути, первый случай нажатия чего-либо -

, что вы можете проверить все, что захотите потом, включая повторное нажатие select all или другие флажки и снятие некоторых, но это поведение вызывает ошибки из-за того, что первый оператор Dplyrиспользует его как тип ситуации «в первом случае», хотя в наблюдаемом коде

код указан ниже

library(shiny)
library(shinydashboard) 
library(tidyverse)
library(magrittr)

header <- dashboardHeader(
  title = "My Dashboard",
  titleWidth = 500
)

siderbar <- dashboardSidebar(

  sidebarMenu(

    # Add buttons to choose the way you want to select your data
    radioButtons("select_by", "Select by:",
                 c("Food Type" = "Food",
                   "Gym Type" = "Gym",
                   "TV show" = "TV"))

  )   

)

body <- dashboardBody(

  fluidRow(
    uiOutput("Output_panel"),
    tabBox(title = "RESULTS", width = 12, 
           tabPanel("Visualisation",
                    br(),
                    width = 12, 
                    height = 800
           )
    ),
    column(12, actionButton(inputId ="resetBtn", label = "Reset Selection", icon = icon("times-circle")))
  )
) 

ui <- dashboardPage(header, siderbar, body, skin = "purple")


server <- function(input, output, session){

  nodes_data_1 <- data.frame(id = 1:15, 
                             Food = as.character(c("Edibles", "Fried", "Home Cooked", "packaged", "vending machine")), 
                             Product_name = as.character(c("Bacon", "Cheese", "eggs", "chips", "beans", "oast", "oats and beans", "fried beans", "chickpeas", "broad beans", "garbanzo", "oat bars", "dog meat", "cat food", "horse meat")),
                             Gym_type = as.character(paste("Gym", 1:15)), TV = 
                               sample(LETTERS[1:3], 15, replace = TRUE))

  # build a edges dataframe

  edges_data_1 <- data.frame(from = trunc(runif(15)*(15-1))+1,
                             to = trunc(runif(15)*(15-1))+1)


  # create reactive of nodes 

  nodes_data_reactive <- reactive({
    nodes_data_1


  }) # end of reactive
  # create reacive of edges 

  edges_data_reactive <- reactive({

    edges_data_1

  }) # end of reactive



  # The output panel differs depending on the how the data is selected 
  # so it needs to be in the server section, not the UI section and created
  # with renderUI as it is reactive
  output$Output_panel <- renderUI({

    # When selecting by workstream and issues:
    if(input$select_by == "Food") {

      box(title = "Output PANEL", 
          collapsible = TRUE, 
          width = 12,

          do.call(tabsetPanel, c(id='t',lapply(1:length(unique(nodes_data_reactive()$Food)), function(i) {
            food <- unique(sort(as.character(nodes_data_reactive()$Food)))

            tabPanel(food[i], 
                     checkboxGroupInput(paste0("chkgrp_checkboxfood_", i), 
                                        label = NULL, 
                                        choices = nodes_data_reactive() %>% 
                                          filter(Food == food[i]) %>%
                                          select(Product_name) %>%
                                          unlist(use.names = FALSE)),
                     checkboxInput(paste0("chksingle_all_", i), "Select all", value = TRUE)
            )
          })))

      ) # end of Tab box



      # When selecting by the strength of links connected to the issues:  
    } else if(input$select_by == "Gym") {
      box(title = "Output PANEL", collapsible = TRUE, width = 12,
          checkboxGroupInput("chkgrp_select_gyms", "Select gyms you want to display", choices = unique(nodes_data_reactive()$Gym_type)
                             ,
                             selected = NULL,
                             inline = FALSE
          )# end of checkboxGroupInput
      ) # end of box  

    } else if(input$select_by == "TV") {
      box(title = "Output PANEL", collapsible = TRUE, width = 12,
          checkboxGroupInput("chkgrp_select_tvs", 
                             "Select the tv shows you want to see",choices = sort(unique(nodes_data_reactive()$TV)),
                             selected = NULL,
                             inline = FALSE
          )# end of checkboxGroupInput
      ) # end of box  

    }  # end of else if

  }) # end of renderUI

  observe({
    lapply(1:length(unique(nodes_data_reactive()$Food)), function(i) {
      food <- unique(sort(as.character(nodes_data_reactive()$Food)))
      product_choices <- nodes_data_reactive() %>% 
        filter(Food == food[i]) %>%
        select(Product_name) %>%
        unlist(use.names = FALSE)

      if(!is.null(input[[paste0("chksingle_all_", i)]])){
        if(input[[paste0("chksingle_all_", i)]] == TRUE) {
          updateCheckboxGroupInput(session,
                                   paste0("chkgrp_checkboxfood_", i), 
                                   label = NULL, 
                                   choices = product_choices,
                                   selected = product_choices)
        } else {
          updateCheckboxGroupInput(session,
                                   paste0("chkgrp_checkboxfood_", i), 
                                   label = NULL, 
                                   choices =product_choices)
        }
      }
    })
  })

  observeEvent(input$resetBtn, ignoreNULL = TRUE, ignoreInit = TRUE, {
    resetChksingleInputs <- names(input)[grepl("^chksingle*", names(input))]
    cat("Resetting single checkboxes:", resetChksingleInputs, sep = "\n")
    lapply(resetChksingleInputs, updateCheckboxInput, session=session, value = FALSE)

    resetChkgrpInputs <- names(input)[grepl("^chkgrp*", names(input))]
    cat("Resetting checkbox groups:", resetChkgrpInputs, sep = "\n")
    lapply(resetChkgrpInputs, updateCheckboxGroupInput , session=session, selected = character(0))

  })

} # end of server


# Run the application 
shinyApp(ui = ui, server = server)

1 Ответ

0 голосов
/ 19 декабря 2018

Проблема заключается в логике вашего наблюдателя для обновления checkboxGroupInputs.Каждый раз, когда один из ячеек 'выбрать все' отмечен каждый другой 'выбрать все', поле будет переоценено. Если они отменены, флажок checkboxGroupInputs будет отменен.

Вы можете видеть, что выбор не сбрасывается, когда вы игнорируете свое утверждение else внутри наблюдателя:

library(shiny)
library(shinydashboard) 
library(tidyverse)
library(magrittr)

header <- dashboardHeader(
  title = "My Dashboard",
  titleWidth = 500
)

siderbar <- dashboardSidebar(

  sidebarMenu(

    # Add buttons to choose the way you want to select your data
    radioButtons("select_by", "Select by:",
                 c("Food Type" = "Food",
                   "Gym Type" = "Gym",
                   "TV show" = "TV"))

  )   

)

body <- dashboardBody(

  fluidRow(
    uiOutput("Output_panel"),
    tabBox(title = "RESULTS", width = 12, 
           tabPanel("Visualisation",
                    br(),
                    width = 12, 
                    height = 800
           )
    ),
    column(12, actionButton(inputId ="resetBtn", label = "Reset Selection", icon = icon("times-circle")))
  )
) 

ui <- dashboardPage(header, siderbar, body, skin = "purple")


server <- function(input, output, session){

  nodes_data_1 <- data.frame(id = 1:15, 
                             Food = as.character(c("Edibles", "Fried", "Home Cooked", "packaged", "vending machine")), 
                             Product_name = as.character(c("Bacon", "Cheese", "eggs", "chips", "beans", "oast", "oats and beans", "fried beans", "chickpeas", "broad beans", "garbanzo", "oat bars", "dog meat", "cat food", "horse meat")),
                             Gym_type = as.character(paste("Gym", 1:15)), TV = 
                               sample(LETTERS[1:3], 15, replace = TRUE))

  # build a edges dataframe

  edges_data_1 <- data.frame(from = trunc(runif(15)*(15-1))+1,
                             to = trunc(runif(15)*(15-1))+1)


  # create reactive of nodes 

  nodes_data_reactive <- reactive({
    nodes_data_1


  }) # end of reactive
  # create reacive of edges 

  edges_data_reactive <- reactive({

    edges_data_1

  }) # end of reactive



  # The output panel differs depending on the how the data is selected 
  # so it needs to be in the server section, not the UI section and created
  # with renderUI as it is reactive
  output$Output_panel <- renderUI({

    # When selecting by workstream and issues:
    if(input$select_by == "Food") {

      box(title = "Output PANEL", 
          collapsible = TRUE, 
          width = 12,

          do.call(tabsetPanel, c(id='t',lapply(1:length(unique(nodes_data_reactive()$Food)), function(i) {
            food <- unique(sort(as.character(nodes_data_reactive()$Food)))

            tabPanel(food[i], 
                     checkboxGroupInput(paste0("chkgrp_checkboxfood_", i), 
                                        label = NULL, 
                                        choices = nodes_data_reactive() %>% 
                                          filter(Food == food[i]) %>%
                                          select(Product_name) %>%
                                          unlist(use.names = FALSE)),
                     checkboxInput(paste0("chksingle_all_", i), "Select all", value = TRUE)
            )
          })))

      ) # end of Tab box



      # When selecting by the strength of links connected to the issues:  
    } else if(input$select_by == "Gym") {
      box(title = "Output PANEL", collapsible = TRUE, width = 12,
          checkboxGroupInput("chkgrp_select_gyms", "Select gyms you want to display", choices = unique(nodes_data_reactive()$Gym_type)
                             ,
                             selected = NULL,
                             inline = FALSE
          )# end of checkboxGroupInput
      ) # end of box  

    } else if(input$select_by == "TV") {
      box(title = "Output PANEL", collapsible = TRUE, width = 12,
          checkboxGroupInput("chkgrp_select_tvs", 
                             "Select the tv shows you want to see", choices = sort(unique(nodes_data_reactive()$TV)),
                             selected = NULL,
                             inline = FALSE
          )# end of checkboxGroupInput
      ) # end of box  

    }  # end of else if

  }) # end of renderUI

  observe({
    lapply(1:length(unique(nodes_data_reactive()$Food)), function(i) {
      food <- unique(sort(as.character(nodes_data_reactive()$Food)))
      product_choices <- nodes_data_reactive() %>% 
        filter(Food == food[i]) %>%
        select(Product_name) %>%
        unlist(use.names = FALSE)

      if(!is.null(input[[paste0("chksingle_all_", i)]])){
        if(input[[paste0("chksingle_all_", i)]] == TRUE) {
          updateCheckboxGroupInput(session,
                                   paste0("chkgrp_checkboxfood_", i), 
                                   label = NULL, 
                                   choices = product_choices,
                                   selected = product_choices)
        }
      }
    })
  })

  observeEvent(input$resetBtn, ignoreNULL = TRUE, ignoreInit = TRUE, {
    resetChksingleInputs <- names(input)[grepl("^chksingle*", names(input))]
    cat("Resetting single checkboxes:", resetChksingleInputs, sep = "\n")
    lapply(resetChksingleInputs, updateCheckboxInput, session=session, value = FALSE)

    resetChkgrpInputs <- names(input)[grepl("^chkgrp*", names(input))]
    cat("Resetting checkbox groups:", resetChkgrpInputs, sep = "\n")
    lapply(resetChkgrpInputs, updateCheckboxGroupInput , session=session, selected = character(0))

  })

} # end of server


# Run the application 
shinyApp(ui = ui, server = server)

Тем не менее, таким образом ваши checkboxGroupInput s не будут следовать, есливаше "все" - checkboxInput отменено.Чтобы также разрешить отмену выбора через «все», не выбрасывая выборки на других вкладках, вам нужно будет определить, какое «все» - checkboxInput было изменено пользователем, и обращаться только к соответствующему checkboxGroupInput.Например, это можно сделать с помощью observeEvent() для каждого «всего» - checkboxInput.

...