2016-02-24 7 views
6

У меня есть начальная загрузка данных из БД в server.R, которая занимает несколько секунд. Пока это не будет сделано, отображаемая страница будет искажена (неверные данные в поле выбора и странное размещение ящиков, см. Ниже). Distorted displayShiny Dashboard - отображает специальную страницу «loading ..» до тех пор, пока не будет начата первоначальная загрузка данных.

Я хочу отобразить другую страницу (или хотя бы разное содержимое на первой вкладке) до тех пор, пока данные не будут полностью загружены.

Я думал о том, чтобы сделать какой-то conditionalPanel, используя условие, основанное на выделенной глобальной переменной (initial_loading_done), но везде, где я пытался разместить conditionalPanel, это не сработало.

Это структура моего 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

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

ответ

1

В server Мне нравится использовать reactiveValues() для хранения setupComplete состояния. Затем, когда данные загружаются, мой setupComplete установлен в TRUE.

В ui мы можем оценить это состояние setupComplete в conditionalPanel, и отображать только содержание (в моем примере три box() виджетов).

Вот рабочий пример

## 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

Спасибо, что действительно полезно! Я хочу отобразить страницу «Загрузка» до тех пор, пока загрузка не будет выполнена, поэтому создана другая условная панель с условием «! Output.setupComplete». Но он не может оценить параметр setupComplete. Что я должен изменить на сервере.r, чтобы он работал? – KeshetE

+0

Я обновил свой ответ со второй условной панелью, которая показывает поле «загрузка» перед загрузкой данных. Если вы хотите начать более сложные операции, я рекомендую использовать превосходный пакет 'shinyjs' @daattali (как указано в его ответе) – SymbolixAU

+0

Теперь ваш пример не работает для меня - остается с« Загрузка »и не изменяется на фактическая страница содержания. Когда я пытаюсь в своем приложении, я вижу окно до загрузки данных, но не вижу его содержимого (просто пустую ячейку). Довольно уверен, что это имеет какое-то отношение к расположению условной панели в моем коде - она ​​находится внутри tabItem. – KeshetE

18

Вот очень простой пример использования shinyjs пакета

Идея заключается в том, чтобы создать загрузочную «страницу» и «страницу» содержания под различными идентификаторами, имеет содержание страница изначально скрыты, а также использовать show() и hide() после того, как приложение готово

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

Прежде всего - спасибо! Основной_контент действительно скрыт и отображается после загрузки данных, что отлично. Но 9 из 10 раз запускаю приложение, «load_page» вообще не отображается ... Что я делаю неправильно? – KeshetE

+0

Похоже, где бы я ни размещал первый div (с загружаемой_страницей), он не вычисляется до тех пор, пока данные приложения не будут завершены. Я попытался удалить часть show/hide, и она отображается только после полной загрузки данных. Это связано с тем, что я использую shinydashboard? – KeshetE

+0

нет, неважно, где вы размещаете элементы. Загружаемая страница должна отображаться немедленно, а другой div не должен отображаться (потому что он находится внутри функции 'hidden()'), и он должен появляться только после завершения 'Sys.sleep (2)'. Если вы запустите этот примерный код, который я покажу, он должен работать 10/10 раз. Он также будет работать с shinydashboard –

0

код

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

не работает с tabsetPanel. Но если вы переместили id на уровень div, он прекрасно работает. Спасибо shinyjs автор Дин Аттали за этот совет. https://stackoverflow.com/users/4432127/keshete

hidden(
     div(id = "mainTabsetPanel", 
      tabsetPanel(
....