I have a shiny app below that shows a file content from a server-side sqlite file
I want to overwrite the sqlite every week on my shiny server from a csv upload and filter it through the App
When I update the sqlite file from within the shiny ran in RStudio I get new content OK and am able to work with it and upload multiple new content as expected
When I run the same app on the shiny server in my browser, I get disconnected from the server as soon as I click on the 'Upload' button after uploading the new csv with 'Browse' (which succeeds).
Can someone please explain this behaviour
I suspect something off in :
observeEvent(input$Upload, {
if(is.null(input$Browse))
{
return(NULL)
}
else
{
file <- input$Browse
createDB(file$datapath, basename(file$name), dbfile)
shinyalert(paste(basename(file$name), "database uploaded, please refresh the session", sep=" "), type = "success", timer=2000)
}
})
REM: it is not the shinyalert though
my full App code :
# accounts.shinyapp
# R/shiny tool to filter the weekly accounts_filtered.csv
library("shiny")
library("shinyBS")
library("shinyalert")
library("RSQLite")
library("DT")
# you may un-comment the next line to allow 10MB input files
options(shiny.maxRequestSize=10*1024^2)
# the following test checks if we are running on shinnyapps.io to limit file size dynamically
# ref: https://stackoverflow.com/questions/31423144/how-to-know-if-the-app-is-running-at-local-or-on-server-r-shiny/31425801#31425801
#if ( Sys.getenv('SHINY_PORT') == "" ) { options(shiny.maxRequestSize=1000*1024^2) }
# App defaults
app.name <- "accounts"
script.version <- "1.0b"
version <- "NA"
names <- c("Last","First","Email","Phone","Level","DeptNum","Code","Short","Logon","Location")
# database functions
createDB <- function(filepath, filename, dbfile){
data <- read_csv(filepath,
locale = locale(encoding = "ISO-8859-2",
asciify = TRUE))
# give proper english names to columns
colnames(data) <- names
data$Email <- tolower(data$Email)
version <- data.frame(version=filename)
# create sqlite and save
mydb <- dbConnect(RSQLite::SQLite(), dbfile)
dbWriteTable(mydb, "data", data, overwrite=TRUE)
dbWriteTable(mydb, "version", version, overwrite=TRUE)
dbDisconnect(mydb)
}
loadDB <- function(dbfile){
mydb <- dbConnect(RSQLite::SQLite(), dbfile)
data <- dbReadTable(mydb, "data")
version <- dbReadTable(mydb, "version")
dbDisconnect(mydb)
# return resulting data.frame
return(list(data = as.data.frame(data), version = as.data.frame(version)))
}
# initial DB creation
# infile <- "Data/ori_accounts_filtered.csv"
# createDB(infile, basename(infile), dbfile)
#############################
# Define UI for application #
#############################
ui <- fluidPage(
useShinyalert(),
HTML('<style type="text/css">
.row-fluid { width: 25%; }
.well { background-color: #99CCFF; }
.shiny-html-output { font-size: 14px; line-height: 15px; }
</style>'),
# Application header
headerPanel("Filter the weekly accounts list"),
# Application title
titlePanel(
windowTitle = "accounts",
tags$a(href="https://http://someIP:8787/accounts", target="_blank",
img(src='logo.png', align = "right",
width="150", height="58.5", alt="myApp"))
),
sidebarLayout(
# show file import weekly update csv data
sidebarPanel(
tags$h5(paste(app.name, " version: ", script.version, sep="")),
tipify(fileInput("Browse",
"Choose new Weekly update:",
accept = ".csv"),
"a accounts_filtered.csv file"),
tipify(actionButton("Upload", "Upload new table"),
"This will replace the current database content!"),
hr(),
checkboxGroupInput("show_vars",
"Check columns to be shown:",
names,
selected = names[c(1:4,6)]),
hr(),
tipify(actionButton("Refresh", "Refresh Session"),
"This will reload the database content!")
),
mainPanel(
htmlOutput("version_tag"),
hr(),
dataTableOutput('dataTable')
)
)
)
#######################
# Define server logic #
#######################
server <- function(input, output, session) {
# initialize content at startup
dbfile <- "Data/data.sqlite"
# load both data and version
mydat <- loadDB(dbfile)
version <- mydat$version[1,1]
accounts <- mydat$data
names <- colnames(accounts)
output$version_tag <- renderText({
paste("<b>Data file: ", version, "</b>")
})
observeEvent(input$Refresh, {
session$reload()
})
observeEvent(input$Upload, {
if(is.null(input$Browse))
{
return(NULL)
}
else
{
file <- input$Browse
createDB(file$datapath, basename(file$name), dbfile)
shinyalert(paste(basename(file$name), "database uploaded, please refresh the session", sep=" "), type = "success", timer=2000)
}
})
output$dataTable <- renderDT(
accounts[,input$show_vars], # data
class = "display nowrap compact", # style
filter = "top", # location of column filters
options = list(pageLength = 20, autoWidth = TRUE),
rownames= FALSE
)
}
# Run the application
shinyApp(ui = ui, server = server)
This is missing.
library("readr")
Related
enter image description hereI copied the exercise code but it is for cereal, how do I change it to show air quality? I will attach a picture for reference from the book rstudio for dummies. I try inputting the data set but it throws off my app.
library(shinydashboard)
library(MASS)
ui <- dashboardPage(
dashboardHeader(title = "Brushing"),
dashboardSidebar(collapsed = TRUE),
dashboardBody(
fluidRow(
plotOutput("CerealPlot",
click = "single_click",
hover = "hovering",
brush = "brushing")
),
box((verbatimTextOutput("coords")), width = 8)
)
)
head(airquality)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$CerealPlot <- renderPlot({
plot(x=UScereal$protein, y=UScereal$calories,
xlab="Protein(gm)",
ylab="Calories",
pch=as.character(UScereal$mfr))
})
output$coords <- renderPrint({
nearPoints(UScereal, input$single_click,
xvar = "protein", yvar = "calories", threshold=20)
})
}
# Run the application
shinyApp(ui=ui, server = server)
I am converting Markdown to HTML with Pandoc. With --toc, Pandoc generates a table of contents and inserts it under the first H1 heading (of which there is only one).
I would like it to have a separate, additional table of contents for each subheading. More specifically, I would like a small local table of contents under each H3.
Can Pandoc do that, and if yes, how?
I received an answer on the pandoc-discuss mailing list in the form of a Lua filter.
Quoting from the author of the solution:
Warning: Assumes that all chapters are heading level 2 — change the chapter_level and toc_level variables to match!
Warning: Assumes that each section/chapter has a unique identifier!
local chapter_level = 2
local toc_level = 3
local headings = {}
local current_chapter = nil
local function collect_headings (head)
if head.level == chapter_level then
local id = head.identifier
current_chapter = {
chapter = id,
toc = {},
}
headings[id] = current_chapter
elseif head.level == toc_level then
if current_chapter then
local toc = current_chapter.toc
toc[#toc+1] = head
end
end
return nil
end
local function build_toc (heads)
local toc = {}
for _,head in ipairs(heads) do
local entry = {
pandoc.Plain{
pandoc.Link(
head.content:clone(), -- text
'#' .. head.identifier, -- target
"", -- empty title
pandoc.Attr(
"", -- empty identifier
{'local-toc-link'} -- class
)
)
}
}
toc[#toc+1] = entry
end
return pandoc.Div(
{ pandoc.BulletList(toc) },
pandoc.Attr( "", {'local-toc'} )
)
end
local function insert_toc (head)
if head.level == chapter_level then
local id = head.identifier
if headings[id] then
local toc = build_toc(
headings[id].toc
)
return {head,toc}
end
end
return nil
end
return {
{ Header = collect_headings },
{ Header = insert_toc },
}
I have a data table that contains some very wide columns and I want to add a scrolling-bar to make it more presentable. So far I have found examples using a scrolling-bar for the entire table - but ideally I would like to have a scrolling-bar for EACH column in the table if that is possible. Below there is an illustrating example. In this code I want a scrolling-bar for both "This_is_a_very_long_name_1", "This_is_a_very_long_name_2" etc.
library("shinydashboard")
library("shiny")
body <- dashboardBody(
fluidPage(
column(width = 4,
box(
title = "Box title", width = NULL, status = "primary",
div(style = 'overflow-x: scroll', tableOutput('table'))
)
)
)
)
ui <- dashboardPage(
dashboardHeader(title = "Column layout"),
dashboardSidebar(),
body
)
server <- function(input, output) {
test.table <- data.frame(lapply(1:8, function(x) {1:10}))
names(test.table) <- paste0('This_is_a_very_long_name_', 1:8)
output$table <- renderTable({
test.table
})
}
# Preview the UI in the console
shinyApp(ui = ui, server = server)
I thought about splitting the table into 8 tables, making a scrolling table for each of them and then putting them next to each other, but space was added betweeen them and it did not look that nice. I think it would be preferable to keeping it as one table (but suggestions are very welcome!).
Does anyone whether this is possible - and how to solve it?
Thanks in advance!
I would not recommend scrolling column header, i think it would not be very clear to read it or so. Here is the code which You can use to get the header in 2 lines so the columns are not too wide:
library("shinydashboard")
library("shiny")
library(DT)
test.table <- data.frame(lapply(1:8, function(x) {1:10}))
names(test.table) <- paste0('This_is_a_very_long_name_', 1:8)
body <- dashboardBody(
fluidPage(
column(width = 8,
box(
title = "Box title", width = NULL, status = "primary",
div(style = 'overflow-x: scroll', dataTableOutput('table'))
)
)
)
)
ui <- dashboardPage(
dashboardHeader(title = "Column layout"),
dashboardSidebar(),
body
)
server <- function(input, output) {
output$table <- renderDataTable({
names(test.table) <- gsub("_"," ",names(test.table))
datatable(test.table, options = list(columnDefs = list(list(width = '100px', targets = c(1:8)))))
})
}
# Preview the UI in the console
shinyApp(ui = ui, server = server)
[UPDATE] --> Column text rendering
Here is a one solution which can be usefull for You. There is no scrolling, however Your row text displays only first three characters (the number of characters displayed can be changed) and ..., with mouse over the row You get the pop up with whole variable name in this row:
library("shinydashboard")
library("shiny")
library(DT)
x <- c("aaaaaaaaaaaaaa", "bbbbbbbbbbbb", "ccccccccccc")
y <- c("aaaaaaaaaaaaaa", "bbbbbbbbbbbb", "ccccccccccc")
z <- c(1:3)
data <- data.frame(x,y,z)
body <- dashboardBody(
fluidPage(
column(width = 4,
box(
title = "Box title", width = NULL, status = "primary",
div(style = 'overflow-x: scroll', dataTableOutput('table'))
)
)
)
)
ui <- dashboardPage(
dashboardHeader(title = "Column layout"),
dashboardSidebar(),
body
)
server <- function(input, output) {
output$table <- renderDataTable({
datatable(data, options = list(columnDefs = list(list(
targets = c(1:3),
render = JS(
"function(data, type, row, meta) {",
"return type === 'display' && data.length > 3 ?",
"'<span title=\"' + data + '\">' + data.substr(0, 3) + '...</span>' : data;",
"}")),list(width = '100px', targets = c(1:3)))))
})
}
# Preview the UI in the console
shinyApp(ui = ui, server = server)
I am building a shiny application that renders large number of images in the form of tiles. I want to integrate Lightbox jScript into my application, something similar to the four image set example given. How do i do that.
The data file here.
The styles.css here.
The minimal working codes:
UI:
shinyUI(dashboardPage(skin = "green",
dashboardHeader(title = "MYAPP"),
dashboardSidebar(
useShinyjs(),
includeCSS("www/styles.css"),
includeCSS("www/lightbox.css"),
includeCSS("www/lightbox.min.css"),
includeScript("www/lightbox.js"),
includeScript("www/lightbox.min.js"),
sidebarMenu(id = "tabs",
menuItem("PICTURES & IMAGES", tabName = "imag", icon = shiny::icon("angle-double-right"))
)
),
dashboardBody(
tabItems(
tabItem(
tabName = "imag", h3("PICTURES & IMAGES"),
fluidRow(
uiOutput("picss")
)
)
))
))
The server code:
shinyServer(function(input, output) {
output$picss <- renderUI({
fluidRow(
column(12, id="columns",
lapply(df1$recipe.link, function(i) {
box(width=NULL,
title = HTML(paste0("<div class='image-wrap'>
<img src='./images/",
df1$img[df1$recipe.link == i],"'class=fixed-height'",
df1$img[df1$recipe.link == i],
"'></div>"
))
)}
)))
})
})
The global.R
library(shiny)
library(shinydashboard)
library(shinyjs)
library(base64enc)
df1 <- readRDS("df1.RDS")
filepath <- "www/images/"
dir.create(file.path(filepath), showWarnings = FALSE)
for (i in 1:nrow(df1)){
if(df1[i,"image_path"] == "NULL"){
next
}
testObj <- strsplit(df1[i,"image_path"],",")[[1]][2]
inconn <- testObj
outconn <- file(paste0(filepath,"image_id",df1[i,"id"],".jpg"),"wb")
base64decode(what=inconn, output=outconn)
close(outconn)
}
If you are trying to reproduce the Four image set (in your case three images) this is how I was able to do it.
In the ui.R i have use tagList to include all the necessary components. Note the by Lightbox instructions. Point 3 of getting started lightbox.js should be included at the bottom of the body.
Just be sure to put the correct paths back for inlcudeCSS and includeJS since I have changed them.
ui.R
library(shiny)
shinyUI(tagList(
tags$head(
useShinyjs(),
includeCSS("www/css/styles.css"),
includeCSS("www/css/lightbox.css")
),
dashboardPage(skin = "green",
dashboardHeader(title = "MYAPP"),
dashboardSidebar(
sidebarMenu(id = "tabs",
menuItem("PICTURES & IMAGES", tabName = "imag", icon = shiny::icon("angle-double-right"))
)
),
dashboardBody(
tabItems(
tabItem(
tabName = "imag", h3("PICTURES & IMAGES"),
fluidRow(
uiOutput("picss")
)
)
))
),
includeScript("www/js/lightbox.js")
))
server.R
library(shiny)
shinyServer(function(input, output) {
output$picss <- renderUI({
fluidRow(
column(12, id="columns",
lapply(df1$recipe.link, function(i) {
box(width=NULL,
title = HTML(paste0('<div class="image-wrap"><a href="images/',
df1[df1$recipe.link == i, 6],
'" data-lightbox="image-1" data-title="My caption"><img border="0" alt="" class="fixed-height" src="images/'
,df1[df1$recipe.link == i, 6],'"></a></div>'))
)}
)
))
})
})
global.R is unchanged.
Let me know if this helps.
I have created a Shiny app which takes .csv file as input and generates tabs based on the Grade column.
The data looks like this
Name Age Score Grade
Jane 13 89 A
Hanna 14 67 B
Jack 13 80 A
Leena 14 78 B
Amy 12 65 B
Nina 14 90 A
Steven 12 45 C
Omy 13 59 C
The code will generate tables in each tab containing only rows of the dataset that match the Grade.
These tables are editable. I am trying to download the edited table from the active tabPanel, but I am stuck on what should be the content in the downloadHandler. I have attached my code for reference. Sorry for the messy code, I am fairly new to shiny.
library(shiny)
library(xlsx)
library(rhandsontable)
ui <- fluidPage(
titlePanel("Scores"),
sidebarLayout(
sidebarPanel(
fileInput("file", "Upload the file"),
br(),
downloadButton('downloadData', 'Save as excel')
),
mainPanel(uiOutput("op"))
)
)
server <- function(input, output, session) {
data <- reactive({
file1 <- input$file
if (is.null(file1)) {
return()
}
read.csv(file = file1$datapath)
})
fun1 <- function(x) {
mydf <- data()
DF <- mydf[(mydf$Grade == x), c(1:3)]
table <- renderRHandsontable({
newtable<- rhandsontable(DF, rowHeaders = NULL)
})
tabPanel(x, table)
}
output$op <- renderUI({
if (is.null(data()))
helpText("File not uploaded!")
else{
mydf <- data()
Tabs <- lapply((unique(mydf$Grade)), fun1)
do.call(tabsetPanel, c(id = "tabs", Tabs))
}
})
output$downloadData <- downloadHandler(
filename = function() {
'Edited table.xls'
},
# what should go in place of table
content = function(file) {
write.xlsx(table, file)
}
)
}
shinyApp(ui, server)