É muito comum termos visualizações no nosso app que demoram para serem geradas. Quando estamos carregando o app, isso pode fazer com que parte da UI fique em branco, parecendo que a página está quebrada ou fazendo com que alguém passe em branco pelo output que tivemos tanto trabalho para fazer. Quando a visualização está sendo recalculada, o padrão do Shiny é deixar a versão anterior acizentada até que a nova apareça, o que pode gerar estranheza e também passar a ideia de que o aplicativo quebrou.
É uma boa prática sempre avisarmos a quem estiver usando o app que alguma coisa está acontecendo por trás das cortinas. Quando a espera é muito longa, devemos sempre que possível explicar o porquê a pessoa está esperando e dar uma estimativa do tempo. Nesses casos, barras de carregamento são a melhor alternativa. Falaremos delas em um outro post.
Quando a espera não é tão grande (entre 2 e 10 segundos, por exemplo), animações giratórias ou de looping infinito podem ser utilizadas para indicar que algo vai aparecer ali e reduzir um pouco a percepção do tempo de espera.
Neste post, falaremos de dois pacotes que deixam muito simples a tarefa de incluir essas animações em nossos outputs: o shinycssloaders
e o shinyWidgets
.
Se você ainda não tem esses pacotes instalados, ambos estão no CRAN:
install.packages("shinycssloaders")
install.packages("shinyWidgets")
O shinycssloaders
é um pacote mantido pelo Dean Attali que possui uma única função: withSpinner()
. Para colocar a animação de carregamento em uma visualização, basta colocar a função *Output()
dentro da função withSpinner()
! Sempre que ela estiver sendo calculada, um spinner será mostrado no lugar.
Rode o Shiny app abaixo para ver um exemplo:
library(shiny)
ui <- fluidPage(
titlePanel("Exemplo shinyWidgets::addSpinner"),
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "variavel",
label = "Escolha uma variável",
choices = names(mtcars)
)
),
mainPanel(
shinycssloaders::withSpinner(
plotOutput(outputId = "histograma"),
type = 4,
color = "orange",
size = 2
)
)
)
)
server <- function(input, output, session) {
output$histograma <- renderPlot({
Sys.sleep(5)
hist(mtcars[[input$variavel]])
})
}
shinyApp(ui, server)
Além de 8 opções de animações diferentes, que você pode trocar com o argumento type
, também é possível ajustar o tamanho, a cor, a cor de fundo e até usar uma imagem própria como animação1.
Veja aqui um Shiny app que apresenta todas as opções de customização do shinycssloaders
.
O pacote shinyWidgets
é mantido pelo pessoal da dreamRs e possui diversos widgets muito úteis (falaremos bastante desse pacote em próximos posts). Adicionamos animações de carregamento utilizando a função addSpinner()
e, assim como a função shinycssloards::withSpinner()
, basta embrulhar suas funções *Output()
com a função addSpinner()
.
São 9 opções de animação, escolhidas por meio do argumento spin
. Aqui podemos customizar apenas a cor delas. Rode o app a seguir para ver um exemplo.
library(shiny)
ui <- fluidPage(
titlePanel("Exemplo shinyWidgets::addSpinner"),
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "variavel",
label = "Escolha uma variável",
choices = names(mtcars)
)
),
mainPanel(
shinyWidgets::addSpinner(
plotOutput(outputId = "histograma"),
spin = "cube",
color = "purple"
)
)
)
)
server <- function(input, output, session) {
output$histograma <- renderPlot({
Sys.sleep(5)
hist(mtcars[[input$variavel]])
})
}
shinyApp(ui, server)
É isso! Dúvidas, sugestões e críticas, mande aqui nos comentários.
Até a próxima!
Pode ser uma imagem estática ou GIF.↩︎