Я создаю панель мониторинга, в которой мне нужно создать несколько блоков (на основе набора данных), а затем дать возможность каждому блоку щелкать и показывать поля подмножеств.
Я могу сделать это, если я знал данные заранее, но у меня возникли проблемы с созданием link id's
и showing and hiding
контента при создании вещей динамически .
Ниже приведен код того, как он должен функция (но с использованием stati c content)
library(shiny)
library(shinydashboard)
library(shinyjs)
#####/UI/####
header <- dashboardHeader()
sidebar <- dashboardSidebar()
body <- dashboardBody(
useShinyjs(),
fluidRow(
uiOutput("box1"),
uiOutput("box2"),
uiOutput("box3")
),
fluidRow(
div(id = "ILRow",
uiOutput("box1a"),
uiOutput("box1b"),
uiOutput("box1c")
),
div(id = "NCRow",
uiOutput("box2a"),
uiOutput("box2b")
),
div(id = "INRow",
uiOutput("box3a")
)
)
)
ui <- dashboardPage(header, sidebar, body)
#####/SERVER/####
server <- function(input, output) {
CSRbox <- function(description = NULL, linkName = NULL) {
# the box tags
withTags(
# col
div(
class = "col-md-2",
# Widget: user widget style 1
div(
class = "box",
## Box Header ##
div(
actionLink(linkName, NULL, icon = icon("plus-square-o", "fa-2x")),
h2(description)
)
)
)
)
}
dat <- data.frame(State = c("Illinois","Illinois","Illinois","North Carolina","North Carolina","Indiana"), City = c("Chicago","Niles","Evanston","Charlotte","Raleigh","West Lafayette"))
output$box1 <- renderUI({
CSRbox("Illinois", "Ill_Link")
})
output$box2 <- renderUI({
CSRbox("North Carolina", "NC_Link")
})
output$box3 <- renderUI({
CSRbox("Indiana", "IN_Link")
})
output$box1a <- renderUI({
CSRbox("Chicago", "CH_Link")
})
output$box1b <- renderUI({
CSRbox("Niles", "NI_Link")
})
output$box1c <- renderUI({
CSRbox("Evanston", "EV_Link")
})
output$box2a <- renderUI({
CSRbox("Charlotte", "CA_Link")
})
output$box2b <- renderUI({
CSRbox("Raleigh", "RL_Link")
})
output$box3a <- renderUI({
CSRbox("West Lafayette", "WL_Link")
})
shinyjs::hide("ILRow")
shinyjs::hide("NCRow")
shinyjs::hide("INRow")
observeEvent(input$Ill_Link, {
shinyjs::toggle("ILRow")
shinyjs::hide("NCRow")
shinyjs::hide("INRow")
})
observeEvent(input$NC_Link, {
shinyjs::toggle("NCRow")
shinyjs::hide("ILRow")
shinyjs::hide("INRow")
})
observeEvent(input$IN_Link, {
shinyjs::toggle("INRow")
shinyjs::hide("ILRow")
shinyjs::hide("NCRow")
})
}
shinyApp(ui, server)
Ниже приведен код динамического создания блоков, но функциональность не работает (вот где мне нужна помощь!):
library(shiny)
library(shinydashboard)
library(shinyjs)
#####/UI/####
header <- dashboardHeader()
sidebar <- dashboardSidebar()
body <- dashboardBody(
useShinyjs(),
fluidRow(
uiOutput("boxLevel1")
),
fluidRow(
div(id = "LevelDetail",
uiOutput("boxLevel2")
)
)
)
ui <- dashboardPage(header, sidebar, body)
#####/SERVER/####
server <- function(input, output) {
CSRbox <- function(description = NULL, linkName = NULL) {
# the box tags
withTags(
# col
div(
class = "col-md-2",
# Widget: user widget style 1
div(
class = "box",
## Box Header ##
div(
actionLink(linkName, NULL, icon = icon("plus-square-o", "fa-2x")),
h2(description)
)
)
)
)
}
dat <- data.frame(State = c("Illinois","Illinois","Illinois","North Carolina","North Carolina","Indiana"), City = c("Chicago","Niles","Evanston","Charlotte","Raleigh","West Lafayette"))
output$boxLevel1 <- renderUI({
lapply(sort(unique(dat$State)), function(name) {
CSRbox(name, paste0(name,"Link"))
})
})
output$boxLevel2 <- renderUI({
temp <- dat[dat$State == "Illinois",] #Should be based of off the input$Click of the Input Link. Ex: input$Illinois
lapply(sort(unique(temp$City)), function(name) {
CSRbox(name, paste0(name,"Link2"))
})
})
shinyjs::hide("LevelDetail")
observeEvent(input$IllinoisLink, { #Would need to loop through and make an observeEvent for each possible input$click
shinyjs::toggle("LevelDetail")
})
}
shinyApp(ui, server)
ОБНОВЛЕНИЕ
Я выяснил, как отслеживать идентификаторы ввода, что позволяет мне динамически создавать правильное подмножество блоков (ух!). У меня все еще проблемы с show
и hide
. Я понял, как show
подмножество ящиков, но я не могу понять, как hide
, так как я использую input ID
, который не меняется при двойном нажатии на link
, поэтому observeEvent
не работает Я попытался получить только ввод ссылки, которая сообщала бы мне count
об этом, так что я знаю, изменилась ли она, НО я получаю ошибки, когда использую input[[input$last_btn]]
(которая должна быть такой же, как ex: input$Illinois
). Любая помощь приветствуется! Я мог бы добавить другую кнопку отдельно, которая бы скрывала, но это не идеально.
library(shiny)
library(shinydashboard)
library(shinyjs)
#####/UI/####
header <- dashboardHeader()
sidebar <- dashboardSidebar()
body <- dashboardBody(
useShinyjs(),
tags$head(tags$script(HTML("$(document).on('click', '.needed', function () {
Shiny.onInputChange('last_btn',this.id);
});"))),
fluidRow(
uiOutput("boxLevel1"),
textOutput("lastButtonCliked")
),
fluidRow(
div(id = "LevelDetail",
uiOutput("boxLevel2")
)
)
)
ui <- dashboardPage(header, sidebar, body)
#####/SERVER/####
server <- function(input, output) {
CSRbox <- function(description = NULL, linkName = NULL) {
# the box tags
withTags(
# col
div(
class = "col-md-2",
# Widget: user widget style 1
div(
class = "box",
## Box Header ##
div(
actionLink(linkName, NULL, icon = icon("plus-square-o", "fa-2x"), class="needed"),
h2(description)
)
)
)
)
}
dat <- data.frame(State = c("Illinois","Illinois","Illinois","North Carolina","North Carolina","Indiana"), City = c("Chicago","Niles","Evanston","Charlotte","Raleigh","West Lafayette"))
output$boxLevel1 <- renderUI({
lapply(sort(unique(dat$State)), function(name) {
CSRbox(name, paste0(name))
})
})
output$boxLevel2 <- renderUI({
temp <- dat[dat$State == input$last_btn,] #Should be based of off the input$Click of the Input Link. Ex: input$Illinois
lapply(sort(unique(temp$City)), function(name) {
CSRbox(name, paste0(name,"Link2"))
})
})
avs <- reactiveValues(
clickN = NA, #new click
clickO = NA, #original click
dataSame = TRUE #data sets are the same
)
observe({
avs$clickN <- input$last_btn
})
shinyjs::hide("LevelDetail")
observeEvent(input$last_btn, {
avs$dataSame <- identical(avs$clickN, avs$clickO)
if(!avs$dataSame) {
shinyjs::show("LevelDetail")
avs$clickO <- avs$clickN
} else {
shinyjs::hide("LevelDetail")
avs$clickO <- NULL
}
})
}
shinyApp(ui, server)