2015-06-11 3 views
0

У меня есть прецедент, где я визуализую операционные данные для приборной панели. Я бы хотел, чтобы это было так, что визуализация обновляется периодически, когда данные добавляются в базу данных. Логика, на мой взгляд, заключается в том, чтобы сначала проверить, равно ли количество строк в таблице реальной базы данных количеству строк в соответствующем фрейме данных в пределах R. Если да, тогда нет необходимости извлекать данные, если нет, то извлекать данные из база данных. То, что я хочу избежать, - это просто вытащить данные (фактическая таблица базы данных имеет более 5 миллионов строк) периодически, независимо от того, есть ли новые данные или нет.Странное поведение R Shiny reactiveValues ​​() и invalidateLater()

Я создал подмножество данных here. Код ниже я написал как доказательство концепции, чтобы сначала обернуть мою голову тем, как invalidateLater() и reactiveValues() работают в R и как я могу их использовать. Он просто считывает количество строк в таблице базы данных и отображает их пользователю. Если количество строк изменяется, пользовательский интерфейс обновляется с новым количеством строк. Обратите внимание, что для воспроизведения вы можете поместить данные в базу данных, чтобы вы могли имитировать добавление и удаление строк, чтобы увидеть реакцию «приложения». Я использовал postgres и соединение ODBC. Если вы запустите код как есть, вы заметите, что когда строки добавляются в db, когда приложение выполняет проверку, пользовательский интерфейс (textOutput() widget) выделяется на несколько секунд и, кажется, находится в состоянии медитации, прежде чем в итоге правильно отобразить новое количество строк. Это использует код, который первым проверяет, имеются различия в числах строк между базой данных и значения, сохраняемого в R.

Однако, если я закомментировать ту часть кода, проверьте различия (закомментируйте ниже блок)

sharedValues$data <- if(!is.null(sharedValues$data)){ 
     if(nrow(sqlFetch(conn2,"test2")) == sharedValues$data){ 
     return(sharedValues$data) 
     } 
    } 
    else{ 
     sharedValues$data <- nrow(sqlFetch(conn2,"test2")) 
     return(sharedValues$data) 
    } 

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

#sharedValues$data <- nrow(sqlFetch(conn2,"test2")) 

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

Мой вопрос заключается в том, что приводит к поведению «лаг-как» при запуске первой альтернативы (которая является желательной альтернативой) первой проверки изменений базы данных, прежде чем делать запрос на выборку с большой стоимостью), но когда код изменен на вытащить данные независимо от изменений базы данных (что кажется мне неэффективным), это отставание от поведения приводит к его уродливой голове? Весь код ниже:

library(shiny) 
library(shinydashboard) 
library(rCharts) 
library(curl) 
library(RODBC) 

conn2 <- odbcConnect("postgres") # database connection object 

ui <- dashboardPage(
    dashboardHeader(), 
    dashboardSidebar(), 
    dashboardBody(
    fluidRow(
     box(textOutput("text1"),width = 6) 
    ) 
) 
) 

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

    sharedValues <<- reactiveValues() 
    observe({ 
    invalidateLater(30000,session) 
    cat("updating data...\n") 
    sharedValues$data <- if(!is.null(sharedValues$data)){ 
     if(nrow(sqlFetch(conn2,"test2")) == sharedValues$data){ 
     return(sharedValues$data) 
     } 
    } 
    else{ 
     sharedValues$data <- nrow(sqlFetch(conn2,"test2")) 
     return(sharedValues$data) 
    } 

    #sharedValues$data <- nrow(sqlFetch(conn2,"test2")) 
    }) 

    output$text1 <- renderText({ 

    y <- sharedValues$data 
    return(y) 

    }) 

} 

shinyApp(ui, server) 

Любая помощь очень ценится.

ответ

0

Согласно this ответ, это может быть исправлено путем манипулирования CSS в ui.R

tags$style(type="text/css", 
    ".recalculating { opacity: 1.0; }" 
) 
Смежные вопросы