2 Interface do usuário
O layout do seu aplicativo será determinado pelo ui
, onde é configurado toda a parte estética do aplicativo, e onde é definido os objetos que serão controlados pelo servidor e que serão importantes para reatividade no código.
2.1 Iniciando
No exemplo do capítulo anterior foi mostrado a função fluidPage()
, esta função é responsável por gerar a página onde o Layout será configurado. Portanto, sempre comece por esta função e na sequência utilize outras funções conforme a necessidade. As configurações de layout são abordadas a seguir.
2.2 Opções de layout
Funções para criar layouts são necessárias, layouts de paginas inclui linhas e colunas, ou seja, elementos espalhados horizontalmente e verticalmente, para isso existe diferentes funções.
2.2.1 Camadas com tabpanels
Uma função para configurar o layout e facilitar a organização das subdivisões do aplicativo é navbarPage()
que cria uma página que contém uma barra de navegação de nível superior que pode ser usada para alternar um conjunto de elementos usando tabPanel()
.
<- fluidPage(
ui navbarPage(title = 'Primeiro aplicativo Shiny')
)
<- function(input, output){
server
}
shinyApp(ui = ui, server = server)

Figure 2.1: Escrevendo o ‘Primeiro aplicativo Shiny.’
Fonte: Elaborado pela Autora.
A função navbarPage()
cria uma barra superior, e um dos seus argumentos é o título title
. Caso deseje escolher um tema para seu aplicativo utilize o pacote shinythemes
.
install.packages("shinythemes")
library(shinythemes)
Utilizando o tabPanel()
temos a seguinte estrutura e resultado.
<- fluidPage(
ui navbarPage(title = 'Primeiro aplicativo Shiny',
tabPanel("tabPanel1"),
tabPanel("tabPanel2"),
tabPanel("tabPanel3")
))
<- function(input, output){
server
}shinyApp(ui = ui, server = server)

Figure 2.2: Funcionamento da função tabPanel().
Fonte: Elaborado pela Autora.
Desse modo, é possível incluir quantas barras de navegação precisar.
Outras opções similares ao navbarPage()
são tabsetPanel()
e navlistPanel()
. O tabsetPanel()
é semelhante ao navbarPage()
com a diferença que não permite incluir um título, de maneira similiar o navlistPanel()
também não permite incluir um título, os tabPanel()
ficam posicionados na barra lateral, conforme é mostrado a seguir. Para adicionar o título, será necessário incluir dentro da função fluidPage()
a função title()
.
<- fluidPage(
ui navlistPanel(
tabPanel("tabPanel1"),
tabPanel("tabPanel2"),
tabPanel("tabPanel3")
))
<- function(input, output){
server
}shinyApp(ui = ui, server = server)

Figure 2.3: Função navlistPanel() e seu funcionamento.
Fonte: Elaborado pela Autora.
2.2.2 Elementos do layout
Ao organizar o layout do seu aplicativo, use fluidRow()
para organizar as linhas e column()
para organizar as colunas dentro das linhas, os argumentos width
e offset
controlam a largura e o espaçamento entre uma coluna e outra, respectivamente. A largura total de cada linha deve somar 12 que é baseado no sistema de grade de 12 larguras do Bootstrap.
<- fluidPage(
ui fluidRow(
column(width = 4, wellPanel("Coluna 1")),
column(width = 5, wellPanel("Coluna 2"), offset = 3),
fluidRow(column(width = 12, wellPanel("Coluna 3")))
)
)
<- function(input, output){
server
}
shinyApp(ui = ui, server = server)

Figure 2.4: Organização de linhas e colunas com fluidRow().
Fonte: Elaborado pela Autora.
A função wellPanel()
cria um painel com uma borda levemente inserida e fundo cinza, e foi utilizado para facilitar a visualização dos argumentos utilizados em fluidRow()
.
A função flowLayout()
apresenta elementos em um arranjo da esquerda para a direita, de cima para baixo. Os elementos em uma determinada linha serão alinhados no topo uns dos outros. Esse layout não funcionará bem com elementos que tenham uma largura baseada em porcentagem (por exemplo, plotOutput()
em sua configuração padrão de largura = “100%”). A seguir um exemplo, para facilitar o entendimento dessa função.
<- fluidPage(
ui flowLayout(
wellPanel(numericInput("texto", "Número de linhas", 22)),
wellPanel(selectInput("questoes", "Número de acertos", 130)),
wellPanel(dateInput("data", "Selecione uma data ")),
wellPanel(sliderInput("nota", "Pontuação", 0, 1000, 700))
)
)
<- function(input, output){
server
}
shinyApp(ui = ui, server = server)

Figure 2.5: Arranjo dos painéis usando flowLayout().
Fonte: Elaborado pela Autora.
Usando o layout sidebarLayout()
é criado uma barra lateral e com mainPanel()
uma área principal. A barra lateral é exibida com uma cor de fundo distinta e normalmente contém controles de entrada. A área principal ocupa 2/3 da largura horizontal e normalmente contém saídas. Veja um exemplo simples usando essas funções.
<- fluidPage(
ui titlePanel("Aplicativo Shiny"),
sidebarLayout(
sidebarPanel(sliderInput("nota", "Pontuação", 0, 1000, 700)),
mainPanel = mainPanel("Deslize o botão ao lado para interagir com aplicativo")
)
)
<- function(input, output){
server
}
shinyApp(ui = ui, server = server)

Figure 2.6: Exemplo utilizando uma barra lateral e painel principal.
Fonte: Elaborado pela Autora.
O pacote Shiny utiliza recursos adicionais em HTML e JavaScript, como é o caso da função conditionalPanel()
que é uma expressão baseada em JavaScript, na subseção que trata da reatividade em um aplicativo Shiny será abordado melhor o funcionamento dessa função.
Em splitLayout()
pode-se dividir o espaço horizontal disponível em partes iguais (por padrão).
Os argumentos são: cellWidths()
que indica as larguras das células individuais, e cellArgs()
para atributos adicionais que devem ser usados para cada célula do layout.
Com verticalLayout()
disponha os elementos da interface do usuário verticalmente. O mesmo permite criar paneis que incluem uma ou mais linhas de conteúdo em ordem vertital. O argumento fluid()
define TRUE para usar layout fluid; FALSE para usar layout fixed.
2.3 Opções auxiliares
Segue a mesma lógica de construção de layout vista anteriormente, com a diferença que a estrutura da pagina se adapta a janela do navegador.
2.3.1 Layout adaptativo
A função fillPage()
cria uma página cuja altura e largura sempre preenchem a área disponível da janela do navegador. Eles podem ser alinhados para criar layouts de grade proporcional arbitrária.
O argumento fillRow()
terá layouts de linha e fillCol()
layouts de coluna com células de tamanho proporcional a janela do navegador.
2.3.2 Layout fixo
A função FixedPage()
cria uma página com um layout fixo, um layout de página fixo consiste em linhas que, por sua vez, incluem colunas. As linhas existem com o objetivo de garantir que seus elementos apareçam na mesma linha (se o navegador tiver largura adequada).
A função fixedRow()
é usada para controlar as larguras das colunas e espaçamento entre as colunas.
2.4 Controles de entradas
Os inputs (ou entradas) coleta valores de um objeto de entrada com input$
As funções numericInput()
, selectInput()
, sliderInput()
e dateInput()
foram utilizadas anteriormente em um layout criado usando flowLayout
.
2.4.1 Valores númericos
O numericInput()
cria um controle de entrada para entrada de valores numéricos, os argumento obrigatórios são, inputId
, label
e value
, onde:
inputId
funciona como um conector de entrada que será usado para acessar o valor e que servirá de gatilho para interação entreui
eserver
, todas as funções inputs terão obrigatóriamente uminputId
.label
onde é adicionado o rótulo (ou nome ) para o controle, esse é o nome que aparecerá para o usuário, pode se utilizar NULL para nenhum rótulo ser adicionado.value
é onde é definido o valor inicial.
Outros argumentos podem ser usados como min
e max
para determinar o valor minímo e máximo, respectivamente e step
para o intervalo entre min
e max
.
2.4.2 Seleção de valores
Crie uma lista de seleção que pode ser usada para escolher um ou vários itens de uma lista de valores usando selectInput()
. Os argumentos obrigatórios são inputId
, label
e choices
, onde:
choices
lista os valores para serem selecionados.
Exemplo:
selectInput("inputId", "label:",
c("Quilômetro" = "km",
"Metro" = "m",
"Centímetro" = "cm"))
Adicionando o argumento list
é possivel adicionar mais de um item para cada elemento nomeado. Os valores adicionados à esquerda são os rótulos que aparecerá na interface do usuário enquanto os valores à direita são os valores chave que serão usados como gatilho entre o ui
e o server
.
2.4.3 Elementos de interação
A função sliderInput()
constrói um elemento de interação (widget) de controle deslizante para selecionar um número, data ou data-hora de um intervalo. Os argumentos obrigatórios são, inputId
, label
, value
, min
e max
, que seguem a mesma lógica do numericInput()
.
2.4.4 Entradas de datas
Utilizando dateInput()
cria-se uma entrada de texto que, quando clicada, abre um calendário no qual o usuário pode clicar para selecionar as datas. Os argumentos necessários são, inputId
e label
.
Outra função interessante é dateRangeInput()
que funciona com os mesmos argumentos de dateInput()
, com a diferença que cria um par de entradas de texto, útil quando se deseja preencher, por exemplo, uma data inicial e uma data final.
2.4.5 Entradas de textos e senhas
Para criar um controle de entrada para entrada de valores de texto não estruturados utilize textInput()
com os argumentos inputId
e label
obrigatórios.
Para criar um controle para entrada de senhas, utilize passwordInput()
com os argumentos inputId
e label
obrigatórios.
2.4.6 Entrada de arquivo
Para realizar o upload de arquivos, use fileInput()
que pode ser usado para fazer upload de um ou mais arquivos. A imagem abaixo exemplifica o uso desse recurso.

Figure 2.7: Exemplo utilizando a função fileInput().
Fonte: Elaborado pela Autora.
2.4.7 Caixas de seleção
Para criar uma caixa de seleção que possa ser usada para especificar valores lógicos, use checkboxInput()
, na imagem utilizada para exemplificar os uso do recurso de upload de arquivo, foi usado o recurso de checkboxInput()
onde a opção Header poder ser marcada, ao marcar essa opção você está dizendo que a primeira linha do arquivo deve ser interpretada como os nomes das colunas.
Uma outra função que segue a mesma lógica de checkboxInput()
é checkboxGroupInput()
que cria um grupo de caixas de seleção que podem ser usadas para alternar várias opções de forma independente. O servidor receberá a entrada como vetor de caracteres dos valores selecionados. Ambas as funções possuem inputId
e label
como argumentos obrigatórios.
2.4.8 Botões de ação
As funções actionButton()
e actionLink()
são usadas para criar um botão de ação ou link cujo valor é inicialmente zero e incrementa em um cada vez que é pressionado. Veja um exemplo a seguir.
O funcionamento do submitButton()
é similar actionButton()
sendo esse último mais utilizado.

Figure 2.8: Exemplo de painel deslizante e uso da função actionButton().
Fonte: Elaborado pela Autora.
Na imagem, ao mudar o número de observações, será preciso pressionar o botão Visualizar para poder observar as alterações no histograma, pois é onde está implementado a função actionButton()
.
2.4.9 Botões de opção
Crie um conjunto de botões de opção para selecionar um item de uma lista com a função radioButtons()
, essa função é útil quando você precisa listar uma quantidade de opções, mas deseja-se que apenas uma seja selecionada, por exemplo, listas de de múltiplas escolha, onde apenas um item deve ser marcado.
2.5 Controles de saídas
As funções de saídas *Output()
trabalham em conjunto com as funções de renderização render*()
, sendo está última definida da estrutura server
do aplicativo Shiny e a primeira na estrutura ui
. A função output()
serve de gatilho para conectar ambas as estruturas, o capítulo 3 abordará melhor esse funcionamento.
As funções *Output()
da estrutura ui
e suas respectivas renderizações são mostradas a seguir:
dataTableOutput()
: Faz uma versão reativa da função data que retorna um data frame (ou matriz), que será renderizado com a funçãorenderDataTable()
. É utilizado em saídas de tabela com a biblioteca JavaScript DataTables.tableOutput()
: Cria uma tabela reativa que é adequada para exibir pequenas matrizes e quadros de dados, que será renderizado com a funçãorenderTable()
.textOutput()
: Cria um elemento de saída de texto em uma página do aplicativo, geralmente é renderizado comrenderText()
.imageOutput()
: Cria elemento de saída de imagem, renderizada porrenderImage()
.plotOutput()
: Cria elemento de saída de plotagem, renderizada porrenderPlot()
.verbatimTextOutput()
: Fornece uma saída de texto de largura fixa, similar a um print da saída em R, geralmente renderizada comrenderPrint()
.uiOutput()
ehtmlOutput()
são utilizadas para criar um elemento de saída HTML e são renderizadas comrenderUI()
.
O funcionamento prático das estruturas de entradas e saídas são explicadas nos próximos capítulos. Abaixo um resumo das funções de saídas *Output()
e renderização render*()
.
dataTableOutput() \(\Longleftrightarrow\) renderDataTable()
tableOutput() \(\Longleftrightarrow\) renderTable()
textOutput() \(\Longleftrightarrow\) renderText()
imageOutput() \(\Longleftrightarrow\) renderImage()
plotOutput() \(\Longleftrightarrow\) renderPlot()
verbatimTextOutput() \(\Longleftrightarrow\) renderPrint()
uiOutput() e htmlOutput() \(\Longleftrightarrow\) renderUI()