Показывать «частичные» результаты (например, графики) после их доступности вместо всех сразу (полная загрузка страницы)?

#r #shiny #shiny-reactivity

#r #блестящий #блестящая реактивность

Вопрос:

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

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

Поскольку все графики имеют одинаковую зависимость ввода (количество ячеек), изменение ввода делает недействительными все элементы на странице (они становятся серыми). Для извлечения данных (вызовов БД) и отображения графиков на каждый из графиков может потребоваться n секунд для вычисления (пример: 3 секунды). На данный момент пользователю нужно будет подождать, пока не будут вычислены все графики (3 3 = 6 секунд), чтобы увидеть оба графика одновременно. Мое ожидание «ленивой» загрузки будет заключаться в том, что результаты будут отображаться асинхронно, если нет зависимости друг от друга.

Мои вопросы, основанные на приведенном ниже примере:

  1. Есть ли способ показать график 1 через 3 секунды и показать график 2 еще через 3 секунды?
  2. Я хотел бы использовать функцию Shiny withProgress(), чтобы показывать обновления о состоянии каждого графика. Это все еще будет работать?
  3. Что, если график 2 зависит от вычисления графика 1 (выходные данные / переменная)?

Пример (я изменил блестящий шаблонный код для этого примера):

 library(shiny)

ui <- fluidPage(
    sliderInput("bins",
                "Number of bins:",
                min = 1,
                max = 50,
                value = 30),
    plotOutput("distPlot1"),
    plotOutput("distPlot2")
)

server <- function(input, output) {
    output$distPlot1 <- renderPlot({
        Sys.sleep(3) # Simulating a slow database call
        x    <- faithful[, 2] # Actual data for the sake of this example
        bins <- seq(min(x), max(x), length.out = input$bins   1)
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
    })
    output$distPlot2 <- renderPlot({
        Sys.sleep(3) # Simulating a slow database call
        x    <- iris[, 2] # Actual data for the sake of this example
        bins <- seq(min(x), max(x), length.out = input$bins   1)
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
   })
}

shinyApp(ui=ui,server=server)
  

Комментарии:

1. Shiny является однопоточным. У вас есть возможность использовать обещания , чтобы избежать блокировки других сеансов (межсессионная асинхронность). Однако в настоящее время нет официального способа избежать блокировки внутри сеанса. Неофициальный способ следует использовать с осторожностью. Кроме того, вы можете проверить библиотеку ( ipc ).

2. Я знал, что R является однопоточным, но не был уверен, усложнит ли это эту задачу, поскольку я был бы в порядке с приложением, работающим с отдельными элементами последовательно. До тех пор, пока это приведет к удалению некоторых результатов, прежде чем сначала просмотреть все — учитывая, что между результатами не было зависимости.