2016-02-24 23 views
6

Mam wstępne ładowanie danych z DB w server.R, co trwa kilka sekund. Do tego czasu wyświetlana strona jest zniekształcona (niewłaściwe dane w polu wyboru i dziwne umieszczanie pól, patrz poniżej). Distorted displayShiny Dashboard - wyświetla dedykowaną stronę "loading .." do momentu pierwszego załadowania danych

Chcę wyświetlić inną stronę (lub co najmniej inną treść na mojej pierwszej wyświetlanej karcie), dopóki dane nie zostaną całkowicie załadowane.

Pomyślałem o zrobieniu pewnego rodzaju conditionalPanel przy użyciu warunku opartego na dedykowanej zmiennej globalnej (initial_loading_done), ale gdziekolwiek próbowałem umieścić conditionalPanel, to nie działało.

Jest to struktura mojego UI.R:

shinyUI(

    dashboardPage(
    dashboardHeader(title = "Title"), 
    dashboardSidebar(
     sidebarMenu(
      menuItem("Tab1", tabName = "Tab1",icon = icon("dashboard")), 
      menuItem("Tab2", tabName = "Tab2", icon = icon("bar-chart-o")) 
     ) 
    ), 
    dashboardBody(
     includeCSS("custom_css.css"), 
     tabItems(
      tabItem(tabName = "Tab1", 
        fluidRow(<content>), 
        mainPanel(
         fluidRow(<content>) 
        ) 
      ), 
      tabItem(tabName = "Tab2", 
        fluidRow(<content>), 
        mainPanel(
         dataTableOutput('my_data_table') 
       ) 
      ) 
     ) 
    ) 
) 
) 
+0

patrz [1] (http://stackoverflow.com/questions/17325521/r-shiny-display-loading-message-while-function-is-running) – Batanichek

Odpowiedz

1

W server Lubię używać reactiveValues() przechowywać stan setupComplete. Następnie po załadowaniu danych mój setupComplete jest ustawiony na TRUE.

W ui możemy następnie ocenić tę setupComplete stan w conditionalPanel i tylko wyświetlać zawartość (w moim przykładzie trzech box() widgetów).

Oto przykład pracuje

## app.R ## 
library(shiny) 
library(shinydashboard) 
library(shinyjs) 

ui <- dashboardPage(
    dashboardHeader(), 
    dashboardSidebar(), 
    dashboardBody(
     actionButton(inputId = "btn_data", label = "Download"), 
     conditionalPanel(condition = "output.setupComplete", 
      box(title = "box1"), 
      box(title = "box2"), 
      box(title = "boc3") 
     ), 
     conditionalPanel(condition = "!output.setupComplete", 
         box(title = "loading")) 
    ) 
) 

server <- function(input, output) { 

    rv <- reactiveValues() 
    rv$setupComplete <- FALSE 

    ## simulate data load 
    observe({ 

     if(input$btn_data){ 

      df <- data.frame(id = seq(1,200), 
          val = rnorm(200, 0, 1)) 

      ## Simulate the data load 
      Sys.sleep(5) 
      ## set my condition to TRUE 
      rv$setupComplete <- TRUE 
     } 

     ## the conditional panel reads this output 
     output$setupComplete <- reactive({ 
      return(rv$setupComplete) 
     }) 
     outputOptions(output, 'setupComplete', suspendWhenHidden=FALSE) 

    }) 
} 

shinyApp(ui, server) 
+0

Dzięki, że bardzo pomocne! Chcę wyświetlić stronę "Ładowanie", dopóki ładowanie się nie zakończy, więc utworzyłem kolejny warunkowy panel z warunkiem "! Output.setupComplete". Ale nie może ocenić parametru setupComplete. Co należy zmienić w serwerze.r, aby działał? – KeshetE

+0

Zaktualizowałem swoją odpowiedź za pomocą drugiego panelu warunkowego wyświetlającego okno "ładowanie" przed załadowaniem danych. Jeśli chcesz zacząć wykonywać bardziej złożone operacje, polecam użyć doskonałego pakietu 'shinyjs' @daattali (jak podano w jego odpowiedzi) – SymbolixAU

+0

Teraz twój przykład nie działa dla mnie - pozostaje z" Ładowanie "i nie zmienia się na rzeczywistą stronę treści. Podczas próby w mojej aplikacji widzę pudełko do momentu załadowania danych - ale nie widzę jego zawartości (tylko puste pole). Jestem pewien, że ma to coś wspólnego z położeniem warunkowego panelu w moim kodzie - znajduje się wewnątrz elementu tabItem. – KeshetE

18

Oto bardzo prosty przykład za pomocą shinyjs pakiet

Chodzi o to, aby stworzyć „stronę” Ładowanie i „stronę” treści pod różnymi identyfikatorami, mają zawartość strona początkowo ukryty i użyć show() i hide() po aplikacja jest gotowa

library(shiny) 
library(shinyjs) 

load_data <- function() { 
    Sys.sleep(2) 
    hide("loading_page") 
    show("main_content") 
} 

ui <- fluidPage(
    useShinyjs(), 
    div(
    id = "loading_page", 
    h1("Loading...") 
), 
    hidden(
    div(
     id = "main_content", 
     "Data loaded, content goes here" 
    ) 
) 
) 

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

shinyApp(ui = ui, server = server) 
+0

Po pierwsze - dziękuję! Main_content jest rzeczywiście ukryty i wyświetlany po załadowaniu danych, co jest świetne. Ale 9 na 10 razy uruchamiam aplikację, "loading_page" nie jest wyświetlana w ogóle ... Co robię źle? – KeshetE

+0

Wygląda na to, gdziekolwiek umieściłem pierwszy div (wraz z loading_page), nie jest on obliczany, dopóki dane aplikacji nie zostaną załadowane - próbowałem usunąć część show/hide i jest wyświetlana tylko po całkowitym załadowaniu danych. Czy to ma coś wspólnego z faktem, że używam shinydashboard? – KeshetE

+0

Nie, nie ma znaczenia, gdzie umieścisz elementy. Strona ładująca powinna pojawić się natychmiast, a drugi element div nie powinien się wyświetlać (ponieważ znajduje się wewnątrz funkcji 'hidden()') i powinien się pojawić dopiero po zakończeniu działania polecenia 'Sys.sleep (2)'. Jeśli uruchomisz przykładowy kod, który pokazuję, powinien działać 107 razy. Będzie działać również z błyszczącym panelem –

0

Kod

hidden(
    div(
     id = "main_content", 
     "Data loaded, content goes here" 
    ) 

nie działa z tabsetPanel. Ale jeśli przeniesiesz identyfikator na poziom div, działa on pięknie. Podziękowania dla autora shinyjs Dean Attali za tę wskazówkę. https://stackoverflow.com/users/4432127/keshete

hidden(
     div(id = "mainTabsetPanel", 
      tabsetPanel(
.... 
Powiązane problemy