Problem in centering table header in shiny - html

Problem in centering table header in shiny, when centering my table the first column remains aligned to the left. How do I fix this? Just below I made available my CSS code. I'm in doubt as to how to align the first column of my table. I am also in doubt, if I called the CSS correctly in my code.
library(shiny)
library(dplyr)
bd= read.csv("bd.csv", sep = ";")
ui = fluidPage(
fixedRow(
column(12,
titlePanel("Tabelas"),
sidebarLayout(
sidebarPanel(selectInput("TABELA", "Selecione a Tabela:", choices = bd$TABELA),
downloadButton("downloadData", "Download")),
mainPanel(tags$link(
rel='stylesheet',
type='text/css',
href='custom.css'),
(tableOutput("bd")))
)
)
)
)
server = function(input, output) {
output$bd <- renderTable({
bd %>%
dplyr::filter(TABELA == input$TABELA)%>%
dplyr::select(LOCAL, ENTREVISTAS.PRE, ENTREVISTAS.POS, CITACOES.PRE, CITACOES.POS, PERCENT.PRE, PERCENT.POS)
}
)
output$downloadData <- downloadHandler(
filename = function() {
paste("bd-", Sys.Date(), ".csv", sep="")
},
content = function(file) {
write.csv(bd, file)
}
)
}
shinyApp(ui = ui, server = server)
.table.shiny-table>thead>tr>th,
.table.shiny-table>thead>tr>td,
.table.shiny-table>tbody>tr>th,
.table.shiny-table>tbody>tr>td,
.table.shiny-table>tfoot>tr>th,
.table.shiny-table>tfoot>tr>td {
padding-right: 12px;
padding-left: 12px;
font-size:80%;
text-align: center;
}
.table>caption+thead>tr:first-child>td,
.table>caption+thead>tr:first-child>th,
.table>colgroup+thead>tr:first-child>td,
.table>colgroup+thead>tr:first-child>th,
.table>thead:first-child>tr:first-child>td,
.table>thead:first-child>tr:first-child>th {
border-top: 0;
font-size:80%;
text-align: center;
}

What I like to do to format the table is to use the datatable function from the DT package.
I create a create_dt function with new variables to pass some values, which I use throughout the shiny application. I leave the format that I use in my tables, if you want to use it. There are many options to configure your table here.
create_dt <- function(x,y = NULL,z = NULL,w,v = NULL){
v <- if_else(is.null(v),TRUE,FALSE)
y <- if_else(is.null(y),16,y)
datatable(x,
rownames = FALSE,
class = "compact cell-border",
extensions = 'Buttons',
caption = z,
options = list(dom = 'rtB',
buttons = list(list(extend='excel',
filename = 'Nombre tabla',
text = '<i class="fas fa-download"></i>')),
pageLenght = y,
lengthMenu = list(c(y,25,50,-1),
c(y,25,50,"All")),
scrollX = TRUE,
initComplete = htmlwidgets::JS(
"function(settings, json) {",
"$(this.api().table().header()).css({'background-color': '#000', 'color': '#fff'});","}"),
columnDefs = list(list(className = 'dt-center', targets = '_all'))
),
container = w,
escape = v) %>%
formatStyle(columns = names(x),
color = "black",
fontSize = '8pt')
This is what my table looks like.
example of table
And this is how I apply the function with the data:
And the Ui part:
fluidRow(column(6,withSpinner(dataTableOutput("resume_tbl_entero",height = '100%'))))
The server part:
output$resume_tbl_entero <- renderDataTable(
{create_dt({React_ano_filter_general_entero() %>%
mutate(Resultado = str_to_sentence(Resultado)) %>%
pivot_wider(names_from = Resultado,values_from=Total)},
z = "Enterococcus")}
And the data used looks like this
I hope it serves you greetings!

Related

VisNetwork: Use VisConfigure argument container to move parameters to dropdownBlock (shinydashboardPlus)

I am having a hard time understanding how the container argument from function VisNetwork::VisConfigure works. It seems as though one can move the configuration list in another HTML container but my understanding is too limited (and I found no examples online).
My goal would be to place the configuration list in a shinydashboardPlus::dropdownBlock (i.e., in the dashboardHeader leftUI argument), see reproducible example below:
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(visNetwork)
# Define the function to retrieve the parameters from VisConfigure
# See: https://github.com/datastorm-open/visNetwork/issues/333
visShinyGetOptionsFromConfigurator <- function (graph, input = paste0(graph$id, "_configurator")) {
if (!any(class(graph) %in% "visNetwork_Proxy")) {
stop("Can't use visGetPositions with visNetwork object. Only within shiny & using visNetworkProxy")
}
data <- list(id = graph$id, input = input)
graph$session$sendCustomMessage("visShinyGetOptionsFromConfigurator", data)
graph
}
ui <- dashboardPage(
dashboardHeader(title = "Test visConfigure container argument",
leftUi = tagList(
shinydashboardPlus::dropdownBlock(
id = "graphparams",
title = "Graph parameters",
icon = shiny::icon("gears"),
shinyWidgets::prettyRadioButtons(
inputId = "physics",
label = "Parameters should appear here",
choices = c("Yes","No"))))),
dashboardSidebar(width = 220),
dashboardBody(
fluidRow(box(id = "network",
title = "Network",
status = "primary",
width = 12,
solidHeader = TRUE,
collapsible = TRUE,
visNetworkOutput('network'))),
fluidRow(actionButton("ops", "Options"))))
server <- function(input, output, session) {
getDiagramPlot <- function(nodes, edges){
v <- visNetwork(
nodes,
edges) %>%
visIgraphLayout(layout = "layout_on_sphere", physics = TRUE, randomSeed = 1234) %>%
visPhysics(solver = "hierarchicalRepulsion",
hierarchicalRepulsion = list(springLength = 850, nodeDistance = 90),
stabilization = "onlyDynamicEdges") %>%
visOptions(highlightNearest = list(enabled = T, degree = 1, hover = F), autoResize = TRUE, collapse = FALSE) %>%
visEdges(color = list(highlight = "red")) %>%
visEdges(arrows = edges$arrows) %>%
visConfigure(enabled = TRUE, filter = "physics", container = NULL) %>%
visInteraction(multiselect = F)
return(v)
}
nodes <- data.frame(id = 0:20, label = LETTERS[1:21])
edges <- data.frame(from = 0, to = 1:20, value = seq(0.35, 0.5, length.out = 20))
output$network <- renderVisNetwork(
getDiagramPlot(nodes, edges)
)
# Send to console the settings from VisConfigure
# See: https://github.com/datastorm-open/visNetwork/issues/333
observeEvent(input$ops, { visNetworkProxy("network") %>% visShinyGetOptionsFromConfigurator() })
observe({ if(!is.null(input$network_configurator)) print(input$network_configurator)
})
session$onSessionEnded(stopApp)
}
shinyApp(ui, server)
Any idea?
Best,
C.
I tried to set container = input$graphparams but it didn't work.

Position DT search box to center of table

I am having a hard time figuring out the code to position the search box from a DT table in a Shiny app to the middle. I'm using a DT extension package, called DTedit, to create my table. Here is some example code:
library(shiny)
library(DTedit)
##### Create the shiny UI
ui <- fluidPage(
h3('DTedit Template'),
uiOutput('mycontacts')
)
##### Create the Shiny server
server <- function(input, output) {
mydata <- data.frame(name = character(),
email = character(),
useR = factor(levels = c('Yes', 'No')),
notes = character(),
stringsAsFactors = FALSE)
##### Callback functions.
my.insert.callback <- function(data, row) {
mydata <- rbind(data, mydata)
return(mydata)
}
my.update.callback <- function(data, olddata, row) {
mydata <- olddata
mydata[row, ] <- data[row, ]
return(mydata)
}
my.delete.callback <- function(data, row) {
mydata <- mydata[-row,]
return(mydata)
}
##### Create the DTedit object
DTedit::dtedit(input, output,
name = 'mycontacts',
thedata = mydata,
edit.cols = c('name', 'email', 'useR', 'notes'),
edit.label.cols = c('Name', 'Email Address', 'Are they an R user?', 'Additional notes'),
input.types = c(notes='textAreaInput'),
view.cols = c('name', 'email', 'useR'),
callback.update = my.update.callback,
callback.delete = my.delete.callback,
show.insert = FALSE,
show.copy = FALSE)
}
##### Start the shiny app
shinyApp(ui = ui, server = server)
Based on googling, I found this CSS to align the search box to the center:
div.dataTables_wrapper div.dataTables_filter {
width: 100%;
float: none;
text-align: center;
}
However, I'm not sure how to insert this CSS into the table. dtedit() has datatable.options parameter, so I think I'd have to use this parameter somehow.
Any help would be greatly appreciated!
Yes, the CSS you found works. Here is how to include it:
css <- "
div.dataTables_wrapper div.dataTables_filter {
width: 100%;
float: none;
text-align: center;
}
"
ui <- fluidPage(
tags$head(
tags$style(HTML(css))
),
......
The box is centered but only in the available space, so it is not "globally" centered because of the "Show" item:
If you want to remove the "Show" item, you can use the option dom = "frtip". Or if you want to keep it but globally center the search box, use this CSS instead:
css <- "
div.dataTables_wrapper div.dataTables_filter {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
"

Images for radiobutton r shiny

I am learning how to use images as radiobuttons.
I found this page and have been playing around with it:
Can you have an image as a radioButton choice in shiny?
The answer here has been very useful but the app doesn't load the Rlogo for the radiobutton (when using the second part of the answer using the functions). I have saved the image into a www file. I have tried different variations of writing the line '<img src="Rlogo.png">' = 'logo' like removing the quotations, replacing it with img(src='Rlogo.png') = 'logo' , replace it with the web link, but have been unsuccessful. Please can someone point out where I am going wrong or if the original code works for you!
logo is here: http://i1.wp.com/www.r-bloggers.com/wp-content/uploads/2016/02/Rlogo.png?resize=300%2C263
code is copied over from the page:
library(shiny)
radioButtons_withHTML <- function (inputId, label, choices, selected = NULL, inline = FALSE,
width = NULL)
{
choices <- shiny:::choicesWithNames(choices)
selected <- if (is.null(selected))
choices[[1]]
else {
shiny:::validateSelected(selected, choices, inputId)
}
if (length(selected) > 1)
stop("The 'selected' argument must be of length 1")
options <- generateOptions_withHTML(inputId, choices, selected, inline,
type = "radio")
divClass <- "form-group shiny-input-radiogroup shiny-input-container"
if (inline)
divClass <- paste(divClass, "shiny-input-container-inline")
tags$div(id = inputId, style = if (!is.null(width))
paste0("width: ", validateCssUnit(width), ";"), class = divClass,
shiny:::controlLabel(inputId, label), options)
}
generateOptions_withHTML <- function (inputId, choices, selected, inline, type = "checkbox")
{
options <- mapply(choices, names(choices), FUN = function(value,
name) {
inputTag <- tags$input(type = type, name = inputId, value = value)
if (value %in% selected)
inputTag$attribs$checked <- "checked"
if (inline) {
tags$label(class = paste0(type, "-inline"), inputTag,
tags$span(HTML(name)))
}
else {
tags$div(class = type, tags$label(inputTag, tags$span(HTML(name))))
}
}, SIMPLIFY = FALSE, USE.NAMES = FALSE)
div(class = "shiny-options-group", options)
}
choices <- c('\\( e^{i \\pi} + 1 = 0 \\)' = 'equation',
'<img src="Rlogo.png">' = 'logo')
ui <- shinyUI(fluidPage(
withMathJax(),
img(src='Rlogo.png'),
fluidRow(column(width=12,
radioButtons('test', 'Radio buttons with MathJax choices',
choices = choices, inline = TRUE),
br(),
h3(textOutput('selected'))
))
))
server <- shinyServer(function(input, output) {
output$selected <- renderText({
paste0('You selected the ', input$test)
})
})
shinyApp(ui = ui, server = server)
Here is a way.
library(shiny)
radioImages <- function(inputId, images, values){
radios <- lapply(
seq_along(images),
function(i) {
id <- paste0(inputId, i)
tagList(
tags$input(
type = "radio",
name = inputId,
id = id,
class = "input-hidden",
value = as.character(values[i])
),
tags$label(
`for` = id,
tags$img(
src = images[i]
)
)
)
}
)
do.call(
function(...) div(..., class = "shiny-input-radiogroup", id = inputId),
radios
)
}
css <- HTML(
".input-hidden {",
" position: absolute;",
" left: -9999px;",
"}",
"input[type=radio] + label>img {",
" width: 50px;",
" height: 50px;",
" transition: 500ms all;",
"}",
"input[type=radio]:checked + label>img {",
" border: 1px solid #fff;",
" box-shadow: 0 0 3px 3px #090;",
" transform: rotateZ(-10deg) rotateX(10deg);",
"}"
)
ui <- fluidPage(
tags$head(tags$style(css)),
br(),
wellPanel(
tags$label("Choose a language:"),
radioImages(
"radio",
images = c("java.svg", "javascript.svg", "julia.svg"),
values = c("java", "javascript", "julia")
)
),
verbatimTextOutput("language")
)
server <- function(input, output, session){
output[["language"]] <- renderPrint({
input[["radio"]]
})
}
shinyApp(ui, server)
Credit.
This will also work:
library(shiny)
library(shinyWidgets)
ui <- shinyUI(fluidPage(
withMathJax(),
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "style.css")),
fluidRow(column(width=12,
radioGroupButtons('test', 'Radio buttons with MathJax choices',
choiceNames = c('\\( e^{i \\pi} + 1 = 0 \\)',
'<i class="icon_rlogo"></i>'),
choiceValues = c('equation', 'logo')),
br(),
h3(textOutput('selected'))
))
))
server <- shinyServer(function(input, output) {
output$selected <- renderText({
paste0('You selected the ', input$test)
})
})
shinyApp(ui = ui, server = server)
With in your www folder your Rlogo.png image and a style.css file with:
.icon_rlogo {background: url(Rlogo.png) no-repeat center;
background-size: contain;
display: inline-block;
width: 30px;
height: 20px;}
To be customised as you wish.

R/Shiny : RenderUI in a loop to generate multiple objects

After the success of the dynamic box in shiny here : R/Shiny : Color of boxes depend on select I need you to use these boxes but in a loop.
Example :
I have an input file which give this :
BoxA
BoxB
BoxC
I want in the renderUI loop these values as a variable to generate dynamically a Box A, B and C. (if I have 4 value, i will have 4 boxes etC.)
Here is my actually code:
for (i in 1:nrow(QRSList))
{
get(QRSOutputS[i]) <- renderUI({
column(4,
box(title = h3(QRSList[1], style = "display:inline; font-weight:bold"),
selectInput("s010102i", label = NULL,
choices = list("Non commencé" = "danger", "En cours" = "warning", "Terminé" = "success"),
selected = 1) ,width = 12, background = "blue", status = get(QRSIntputS[i])))
})
column(4,
observeEvent(input$s010102i,{
get(QRSOutputS[i]) <- renderUI({
box(title = h3(QRSList[1], style = "display:inline; font-weight:bold"),
selectInput("s010102i", label = NULL,
choices = list("Not good" = "danger", "average" = "warning", "good" = "success"),
selected = get(QRSIntputS[i])) ,width = 12, background = "blue",status = get(QRSIntputS[i]))
})
The aim is to replace these box names to a variable like input$s010102 for example. But get and assign function does not exist.
Any idea ?
Thanks a lot
Here is an example how to generate boxes dynamically
library(shinydashboard)
library(shiny)
QRSList <- c("Box1","Box2","Box3","Box4","Box5")
ui <- dashboardPage(
dashboardHeader(title = "render Boxes"),
dashboardSidebar(
sidebarMenu(
menuItem("Test", tabName = "Test")
)
),
dashboardBody(
tabItems(
tabItem(tabName = "Test",
fluidRow(
tabPanel("Boxes",uiOutput("myboxes"))
)
)
)
)
)
server <- function(input, output) {
v <- list()
for (i in 1:length(QRSList)){
v[[i]] <- box(width = 3, background = "blue",
title = h3(QRSList[i], style = "display:inline; font-weight:bold"),
selectInput(paste0("slider",i), label = NULL,choices = list("Not good" = "danger", "average" = "warning", "good" = "success"))
)
}
output$myboxes <- renderUI(v)
}
shinyApp(ui = ui, server = server)

Shiny - Control Widgets Inside Leaflet Map

I have a simple shiny-app with just a dropdown listing districts of Afghanistan and a leaflet map of the same.
The shape file can be accessed at this link - using AFG_adm2.shp from http://www.gadm.org/download
here's the app code:
library(shiny)
library(leaflet)
library(rgdal)
library(sp)
afg <- readOGR(dsn = "data", layer ="AFG_adm2", verbose = FALSE, stringsAsFactors = FALSE)
ui <- fluidPage(
titlePanel("Test App"),
selectInput("yours", choices = c("",afg$NAME_2), label = "Select Country:"),
actionButton("zoomer","reset zoom"),
leafletOutput("mymap")
)
server <- function(input, output){
initial_lat = 33.93
initial_lng = 67.71
initial_zoom = 5
output$mymap <- renderLeaflet({
leaflet(afg) %>% #addTiles() %>%
addPolylines(stroke=TRUE, color = "#00000", weight = 1)
})
proxy <- leafletProxy("mymap")
observe({
if(input$yours!=""){
#get the selected polygon and extract the label point
selected_polygon <- subset(afg,afg$NAME_2==input$yours)
polygon_labelPt <- selected_polygon#polygons[[1]]#labpt
#remove any previously highlighted polygon
proxy %>% removeShape("highlighted_polygon")
#center the view on the polygon
proxy %>% setView(lng=polygon_labelPt[1],lat=polygon_labelPt[2],zoom=7)
#add a slightly thicker red polygon on top of the selected one
proxy %>% addPolylines(stroke=TRUE, weight = 2,color="red",data=selected_polygon,layerId="highlighted_polygon")
}
})
observeEvent(input$zoomer, {
leafletProxy("mymap") %>% setView(lat = initial_lat, lng = initial_lng, zoom = initial_zoom) %>% removeShape("highlighted_polygon")
})
}
# Run the application
shinyApp(ui = ui, server = server)
EDIT: I'm actually trying to add an action button which resets zoom to a default value (using leafletproxy and setview) and I want to put this button on the top-right corner of the map instead of it being above the map.
Can I use addLayersControl to do this?
EDIT2:
Code in full-app:
# Create the map
output$mymap <- renderLeaflet({
leaflet(afg) %>% addTiles() %>%
addPolygons(fill = TRUE,
fillColor = ~factpal(acdf$WP_2012), #which color for which attribute
stroke = TRUE,
fillOpacity = 1, #how dark/saturation the fill color should be
color = "black", #color of attribute boundaries
weight = 1, #weight of attribute boundaies
smoothFactor = 1,
layerId = aid
#popup = ac_popup
) %>% addPolylines(stroke=TRUE, color = "#000000", weight = 1) %>%
addLegend("bottomleft", pal = factpal, values = ~WP_2012,
title = "Party",
opacity = 1
) %>% setView(lng = initial_lng, lat = initial_lat, zoom = initial_zoom) %>%
addControl(html = actionButton("zoomer1","Reset", icon = icon("arrows-alt")), position = "topright")
})
I can't see the map tiles from addTiles or the zoom reset button from addControl. Any ideas why this might be happening?
You can use the addControl function directly:
output$mymap <- renderLeaflet({
leaflet(afg) %>% #addTiles() %>%
addPolylines(stroke=TRUE, color = "#00000", weight = 1) %>%
addControl(actionButton("zoomer","Reset"),position="topright")
})
You can achieve this by using the shiny absolutePanel() function in your UI, E.g.
library(shiny)
library(leaflet)
library(rgdal)
library(sp)
afg <- readOGR(dsn = "data", layer ="AFG_adm2", verbose = FALSE, stringsAsFactors = FALSE)
ui <- fluidPage(
tags$head(
tags$style(
HTML(
'
.outer {
position: fixed;
top: 80px;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
padding: 0;
}
#controls-filters {
background-color: white;
border:none;
padding: 10px 10px 10px 10px;
z-index:150;
}
'
)
)
),
titlePanel("Test App"),
absolutePanel(
id = "controls-filters",
class = "panel panel-default",
fixed = TRUE,
draggable = TRUE,
top = 100,
left = "auto",
right = 20,
bottom = "auto",
width = 330,
height = "auto",
selectInput("yours", choices = c("", afg$NAME_2), label = "Select Country:"),
actionButton("zoomer", "reset zoom")
),
div(class = "outer", leafletOutput("mymap"))
)
server <- function(input, output){
initial_lat = 33.93
initial_lng = 67.71
initial_zoom = 5
output$mymap <- renderLeaflet({
leaflet(afg) %>% #addTiles() %>%
addPolylines(stroke=TRUE, color = "#00000", weight = 1)
})
proxy <- leafletProxy("mymap")
observe({
if(input$yours!=""){
#get the selected polygon and extract the label point
selected_polygon <- subset(afg,afg$NAME_2==input$yours)
polygon_labelPt <- selected_polygon#polygons[[1]]#labpt
#remove any previously highlighted polygon
proxy %>% removeShape("highlighted_polygon")
#center the view on the polygon
proxy %>% setView(lng=polygon_labelPt[1],lat=polygon_labelPt[2],zoom=7)
#add a slightly thicker red polygon on top of the selected one
proxy %>% addPolylines(stroke=TRUE, weight = 2,color="red",data=selected_polygon,layerId="highlighted_polygon")
}
})
observeEvent(input$zoomer, {
leafletProxy("mymap") %>% setView(lat = initial_lat, lng = initial_lng, zoom = initial_zoom) %>% removeShape("highlighted_polygon")
})
}
# Run the application
shinyApp(ui = ui, server = server)
This should get you started but I would recommend structuring your app in such a way that it has a stand alone CSS file.