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.
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)
Ciao,
I have some trouble in changing font color in my flextable.
The R version is 3.5.2
I am working on this object since I have to add the table on a pptx presentation and to do this I will of course use officer package. Let me show you a dummy code and the output:
library(officer)
library(flextable)
ppt <- read_pptx()
ppt <- add_slide( ppt, layout = "Title and Content", master = "Office Theme")
ppt <- ph_with_text(ppt, "Title whatever", type = "title")
df = head(mtcars)
ft = flextable(df)
ft <- bg(ft, i = 1, bg = "#FF0000", part = "body")
ft <- bg(ft, i = 1, bg = "#FF0000", part = "header")
ft <- fontsize(ft, i = 1, size = 15, part = "body")
ft <- fontsize(ft, i = 1, size = 20, part = "header")
ft <- color(ft, i = 1, color = "#FFFFFF", part = "body")
ft <- color(ft, i = 1, color = "white", part = "header")
ft <- font(ft, i = 1, fontname = "Consolas", part = "header")
ft <- autofit(ft)
ppt <- ph_with_flextable(ppt, ft)
if(file.exists("prova.pptx"))
file.remove("prova.pptx")
print(x = ppt, target = "prova.pptx")
As you can see I apply to the table a lot of formatting functions but I've noticed that the only one that fails is the "color" function.
The header and the first line of the table should be white. Notice that I've tried to assign to the "color" parameter both values "white" and "#FFFFFF" but in both case it does not work.
It is even more wierd considering that all other settings have been successfully applied.
What I am missing about color function from flextable package? Have you noticed the same issue (bug) ?
Thanks,
Ciao
AM
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 have a list of documents to process, and for each record I want to attach some metadata to the document "member" inside the "corpus" data structure that tm, the R package, generates (from reading in text files).
This for-loop works but it is very slow,
Performance seems to degrade as a function f ~ 1/n_docs.
for (i in seq(from= 1, to=length(corpus), by=1)){
if(opts$options$verbose == TRUE || i %% 50 == 0){
print(paste(i, " ", substr(corpus[[i]], 1, 140), sep = " "))
}
DublinCore(corpus[[i]], "title") = csv[[i,10]]
DublinCore(corpus[[i]], "Publisher" ) = csv[[i,16]] #institutions
}
This may do something to the corpus variable but I don't know what.
But when I put it inside a tm_map() (similar to lapply() function), it runs much faster, but the changes are not made persistent:
i = 0
corpus = tm_map(corpus, function(x){
i <<- i + 1
if(opts$options$verbose == TRUE){
print(paste(i, " ", substr(x, 1, 140), sep = " "))
}
meta(x, tag = "Heading") = csv[[i,10]]
meta(x, tag = "publisher" ) = csv[[i,16]]
})
Variable corpus has empty metadata fields after exiting the tm_map function. It should be filled. I have a few other things to do with the collection.
The R documentation for the meta() function says this:
Examples:
data("crude")
meta(crude[[1]])
DublinCore(crude[[1]])
meta(crude[[1]], tag = "Topics")
meta(crude[[1]], tag = "Comment") <- "A short comment."
meta(crude[[1]], tag = "Topics") <- NULL
DublinCore(crude[[1]], tag = "creator") <- "Ano Nymous"
DublinCore(crude[[1]], tag = "Format") <- "XML"
DublinCore(crude[[1]])
meta(crude[[1]])
meta(crude)
meta(crude, type = "corpus")
meta(crude, "labels") <- 21:40
meta(crude)
I tried many of these calls (with var "corpus" instead of "crude"), but they do not seem to work.
Someone else once seemed to have had the same problem with a similar data set (forum post from 2009, no response)
Here's a bit of benchmarking...
With the for loop :
expr.for <- function() {
for (i in seq(from= 1, to=length(corpus), by=1)){
DublinCore(corpus[[i]], "title") = LETTERS[round(runif(26))]
DublinCore(corpus[[i]], "Publisher" ) = LETTERS[round(runif(26))]
}
}
microbenchmark(expr.for())
# Unit: milliseconds
# expr min lq median uq max
# 1 expr.for() 21.50504 22.40111 23.56246 23.90446 70.12398
With tm_map :
corpus <- crude
expr.map <- function() {
tm_map(corpus, function(x) {
meta(x, "title") = LETTERS[round(runif(26))]
meta(x, "Publisher" ) = LETTERS[round(runif(26))]
x
})
}
microbenchmark(expr.map())
# Unit: milliseconds
# expr min lq median uq max
# 1 expr.map() 5.575842 5.700616 5.796284 5.886589 8.753482
So the tm_map version, as you noticed, seems to be about 4 times faster.
In your question you say that the changes in the tm_map version are not persistent, it is because you don't return x at the end of your anonymous function. In the end it should be :
meta(x, tag = "Heading") = csv[[i,10]]
meta(x, tag = "publisher" ) = csv[[i,16]]
x
I have created a progress bar to keep tabs on the execution of some R scripts. And I want to insert a custom icon in the bar instead of the default 'Tk' one. I am able to do this on Windows using a .ico file and the following command
tcl('wm', 'iconbitmap', .win, 'Icon.ico')
But I am a loss about how to do the same in Mac OSX and Linux. Obviously, the .ico format doesn't work but neither does .png, .jpg, .bmp, .xbm or .xpm. Any suggestion on how I could proceed? Sample image and progress bar code attached below:-
Sample image http://tinypic.com/r/jt8efn/6 - http://tinypic.com/r/jt8efn/6
tkProgressBar2 <- function (title = 'Test progress bar', label = '', min = 0, max = 100, initial = 0, width = 300, userfn='helvetica', backg='white') {
useText <- FALSE
have_ttk <- as.character(tcl('info', 'tclversion')) >= '8.5'
if (!have_ttk && as.character(tclRequire('PBar')) == 'FALSE') useText <- TRUE
.win <<- tktoplevel(background=backg)
tkfocus()
tcl('wm', 'geometry', .win, '500x100+450+350')
tcl('wm', 'iconbitmap', .win, '#Icon.xbm')
.val <- initial
.killed <- FALSE
tkwm.geometry(.win, sprintf('%dx80', width + 40))
tkwm.title(.win, title)
fn <- tkfont.create(family = userfn, size = 12)
if (useText) {
.lab <- tklabel(.win, text = label, font = fn, padx = 0, background=backg)
tkpack(.lab, side = 'left')
fn2 <- tkfont.create(family = userfn, size = 16)
.vlab <- tklabel(.win, text = '0%', font = fn2, padx = 20, background=backg)
tkpack(.vlab, side = 'right')
up <- function(value) {
if (!is.finite(value) || value < min || value > max) return()
.val <<- value
tkconfigure(.vlab, text = sprintf('%d%%', round(100 * (value - min)/(max - min))))
}
} else {
.lab <- tklabel(.win, text = label, font = fn, pady = 0, background=backg)
.tkval <- tclVar(0)
tkpack(.lab, side = 'top')
tkpack(tklabel(.win, text = '', font = fn, background=backg), side = 'bottom')
pBar <- if (have_ttk)
ttkprogressbar(.win, length = width, variable = .tkval) else
tkwidget(.win, 'ProgressBar', width = width, variable = .tkval)
tkpack(pBar, side = 'bottom')
up <- function(value) {
if (!is.finite(value) || value < min || value > max) return()
.val <<- value
tclvalue(.tkval) <<- 100 * (value - min)/(max - min)
}
}
getVal <- function() .val
kill <- function() if (!.killed) {
tkdestroy(.win)
.killed <<- TRUE
}
title <- function(title) tkwm.title(.win, title)
lab <- function(label) tkconfigure(.lab, text = label)
tkbind(.win, '<Destroy>', function() stop())
up(initial)
structure(list(getVal = getVal, up = up, title = title, label = lab, kill = kill), class = 'tkProgressBar')
}
pb <- tkProgressBar2(title='Performing k-Means clustering', label='Some information in %', min=0, max=100, initial=0, width=400, userfn='verdana', backg='white')
On Linux you set the icon with wm iconphoto; wm iconbitmap does something else entirely. To do that, you'll need to create a photo image with the image data in it.
I'm guessing that you write this in R as:
tcl('wm', 'iconphoto', .win, tcl('image', 'create', 'photo', '-file', 'Icon.gif'))
I'm not quite sure which image formats are supported by the version of Tk you're using, including any image format support packages it has available. The minimal set is GIF and PPM unless you're (bravely) using 8.6, when PNG is also available by default.
(You can also create the content of a photo image programatically, but that's slow for various reasons.)
OSX doesn't have window icons in the same sense; it's normal for each minimized window to just show a snapshot of itself when it is minimized to the dock.