onclick function is not functioning properly - shiny

Apparently my code looks fine to me, i have already run one such example, but these onclick() functions are not performing their job no matter what. Can anybody please help me out with that?
Its just a simple code with 6 buttons. 3 buttons for plotting scatter plot, histogram and bar plot whereas one button to hide the output div one button to show output div and one button to change the background of output div.. these onclick functions are not working :/
library(shiny)
library(shinyjs)
library(shinyWidgets)
moduleTestUI <- function(id){
ns=NS(id)
# Application title
titlePanel("My First Shiny Program")
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
tags$style(type='text/css'
, ".btn {padding: 8px; font-size: 120%;background-color: rgb(0, 102, 204);color: white;}"
,"div.main{width: 750px;height: 550px;border-style: double;border-width: 10px;border-color:grey; }"
),
tags$div(id=ns("div1"),
hr(),
actionButton("btn",id=ns("button1"),label = "Scatter Plot"),
actionButton("btn",id=ns("button2"),label = "Histogram"),
actionButton("btn",id=ns("button3"),label = "Bar Plot"),
hr(),
br(),
actionButton("btn",id=ns("button4"),label = "Hide Output"),
actionButton("btn",id=ns("button5"),label = "Show Output"),
actionButton("btn",id=ns("button6"),label = "Change Color"))),
# Show a plot of the generated distribution
mainPanel(
br(),br(),br(),
tags$p(strong(" ***** MY OUTPUT PANEL ***** ")),
tags$div(id=ns('div2'),class="main")
)
)
}
moduleTest <- function(input, output, session){
#scatter plot
onclick('button1',
plot(mtcars$disp, mtcars$mpg,xlab="Engine displacement",
ylab="mpg", main="MPG vs engine displacement",
las=1))
#or onclick('button1',qplot(disp, mpg, data=mtcars,main="MPG vs engine displacement"))
#histogram
onclick('button2',hist(mtcars$disp,xlab="Engine displacement", breaks = 5))
#bar plot
onclick('button3',barplot(mtcars$disp, main="Graph of displacement", names.arg = mtcars$mpg))
onclick('button4',hide('div2'))
onclick('button5',show('div2'))
onclick('button6',setBackgroundColor("blue"))
#---------- other method
#scatter plot
# observeEvent(input$button1,plot(mtcars$disp, mtcars$mpg,xlab="Engine displacement",
# ylab="mpg", main="MPG vs engine displacement", las=1))
#or onclick('button1',qplot(disp, mpg, data=mtcars,main="MPG vs engine displacement"))
#histogram
#observeEvent(input$button2,hist(mtcars$disp,xlab="Engine displacement", breaks = 5))
#bar plot
#observeEvent(input$button3,barplot(mtcars$disp, main="Graph of displacement", names.arg = mtcars$mpg))
#observeEvent(input$button4,hide("div2"))
#observeEvent(input$button5,show("div2"))
#observeEvent(input$button6,setBackgroundColor("blue"))
}
ui <- fluidPage(
useShinyjs(),
moduleTestUI('test')
)
# Define server logic required to draw a histogram
server <- function(input, output) {
}
# Run the application
shinyApp(ui = ui, server = server)

Related

Scaling plotOutput height to fill the row in a sidebarLayout

I have a Shiny app with produces the following output. I would like the height of the graph to scale to fill the row which contains the sidebar, (down to some minimum dimension). This sidebar height changes depending on the data being examined.
The ui code I'm currently using is:
sidebarLayout(
sidebarPanel(
uiOutput("ridgeDates")
),
mainPanel(
plotOutput("ridgesPlot")
)
)
with the plot being rendered by renderPlot(...) This seems to adjust the /width/ automatically as I change the browser window width.
I've spent a while searching but can't find anything that does this. Is this possible?
We can use jQuery to track the height of the sidebar and set the height of the plot in css before creating the plotOutput. To do that, we need to use uiOutput in the UI, then render the plot dynamically.
So in the UI, the mainPanel will now have:
uiOutput("ridgePlot")
Then the plot is rendered in the server like so:
output$ridgePlot <- renderUI({
# plot data
output$ridges <- renderPlot({
# plot()
})
plotOutput("ridges")
})
Now we use shinyjs() to write a simple javascript function that sets the height value of the plot to the height of the sidebar. The sidebar is of class well, so we first get the height of the well, save it to a variable then set the ridges plot to the height of the variable, in javascript like this:
var newHeight = $('.well').outerHeight(); $('#ridges').height(newHeight)
I have used .outerHeight() because the well has extra padding that effectively gives it extra height than the height specified in the css rules for the well.
We can use this function in shiny using runjs() from shinyjs package. Since we need to get the height from the well after it has been rendered, we use observe and use it before the plotOutput inside the renderPlot, which is also inside the renderUI.
observe({
session$onFlushed(function() {
shinyjs::runjs("var newHeight = $('.well').outerHeight(); $('#ridges').height(newHeight)")
}, once=TRUE)
})
Putting it together in one Shiny app:
library(shiny)
library(shinyjs)
library(ggplot2)
ui = fluidPage(
useShinyjs(),
titlePanel("This is just a test!"),
sidebarLayout(
sidebarPanel(
uiOutput("ridgeDates")
),
mainPanel(
uiOutput("ridgePlot")
))
)
server = function(input, output, session) {
output$ridgeDates <- renderUI({
rng <- round(runif(1, 15, 21))
radioButtons("choose", "A changing list", choices = 1:rng)
})
output$ridgePlot <- renderUI({
datax <- matrix(c(1,2,3,4,5,6),6,1)
datay <- matrix(c(1,7,6,4,5,3),6,1)
titleplot<-"title"
summary <- "testing text"
output$ridges <- renderPlot({
# pl <- plot(datax, datay, main = titleplot, xlab = "input$axis1", ylab = "input$axis2", pch=18, col="blue")
ggplot(NULL, aes(datax, datay))+
geom_point(colour = "#1e90ff")
})
observe({
session$onFlushed(function() {
shinyjs::runjs("var newHeight = $('.well').outerHeight(); $('#ridges').height(newHeight)")
}, once=TRUE)
})
plotOutput("ridges")
})
}
# Run the application
shinyApp(ui = ui, server = server)
My example:

Problem using if and Else to render text in R shiny

I am trying to set up a shiny app which allows individuals to select an option and then with that option a specific text appears if they select the other option different text appears.
Currently i am getting an error, i have tried to use the if else, I am new to shiny and fairly new to R so am struggling with the code.
I have tried playing about with using a reactive x but couldn't get it to work either potentially because this is not numeric?
# Sidebar with a select input for number of bins
sidebarLayout(
sidebarPanel(
selectInput(inputId = "Options",
label = "Option",
choices = c("Option 1","Option 2"))
),
# Show a text output
mainPanel(
textOutput(outputId = "ParticpantInformation1"),
textOutput(outputId = "ParticpantInformation2")
)),
# Define server logic required to rendertext
server <- function(input, output) {
if (input$Options=="Option 1") output$ParticpantInformation1 <- renderText("Option 1")
else output$ParticpantInformation2 <-renderText("Option 2")
I am hoping for it to render either one set of text or the other onto the main panel of the app
Currently i get an Error - "cannot coerce type 'closure' to vector of type 'character' "
You don't need that if(). You can directly refer to the user selection like this:
library(shiny)
ui <- fluidPage(
# Sidebar with a select input for number of bins
sidebarLayout(
sidebarPanel(
selectInput(inputId = "Options",
label = "Option",
choices = list("Option 1" = "My option 1 text", "Option 2" = "My option 2 text"))
),
# Show a text output
mainPanel(
textOutput(outputId = "ParticpantInformation")
))
)
server <- function(input, output, session) {
output$ParticpantInformation <- renderText({input$Options})
}
shinyApp(ui = ui, server = server)
For an alternative please see ?conditionalPanel, but for this case it's unnecessary complex.

Hide widgets created in a tagList in shiny

I am recently building a shiny app, somewhere in my app I am expecting an arbitrary number of inputs which the user can specify from a line of selectInput() widgets.
Since the number of selectInput() widgets may be large, I would like it to happen that the next selectInput() widget only shows when the pervious one is filled by the user.
My idea is that I will:
create all possible selectInput() widgets in a tagList,
hide them all by default, and
show the next one when the previous one is filled.
I am fine with the first and third step, but when I tried to hide them all using the shinyjs function hide, it seems it does not work for input objects created in a tagList, it only works for those widgets that is created with a specific name, please see the example below:
library(shiny)
library(shinyjs)
ui <- fluidPage(
# Application title
titlePanel("Hello Shiny!"),
sidebarLayout(
# Sidebar with a slider input
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min = 0,
max = 1000,
value = 500)
),
# Show a plot of the generated distribution
mainPanel(
useShinyjs(),
uiOutput('comparisons')
)
)
server <- shinyServer(function(input, output, session) {
observe(1, shinyjs::hide('compare_1') )
output$comparisons=renderUI({
out=tagList()
out=lapply(1:6, function(x){
selectizeInput(paste0('compare_',x),
label = 'Condition 1',
c('aa','bb', 'cc'))
})
out
})
})
shinyApp(ui, server)
Say I'm creating 6 selectInput widgets, name them compare_1 to compare_6, I also created a sliderInput called obs just to show as an example. In Server if I just say shinyjs::hide('obs'), the sliderInput will be hidden, but when I call shinyjs::hide('compare_1'), the selectInput is still there. Any idea will be appreciated!
Hi you can do that with conditinalPanel quite easy
ui <- fluidPage(
# Application title
titlePanel("Hello Shiny!"),
sidebarLayout(
# Sidebar with a slider input
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min = 0,
max = 1000,
value = 500)
),
# Show a plot of the generated distribution
mainPanel(
useShinyjs(),
uiOutput('comparisons')
)
)
)
server <- shinyServer(function(input, output, session) {
output$comparisons=renderUI({
out=tagList(
selectizeInput(paste0('compare_1'),
label = 'Condition 1',
c("",'aa','bb', 'cc')),
lapply(2:6, function(x){
conditionalPanel(
paste0("input.compare_",x-1," != ''"),
selectizeInput(paste0('compare_',x),
label = paste0('Condition ',x),
c("",'aa','bb', 'cc'))
)
})
)
out
})
})
shinyApp(ui, server)

Shiny interactive plotting with selected likert scale

I have created several likert scales with R package "likert" and would like to plot each one of them in shiny when the radio button of that one is selected.
The sample scales is:
a <- sample(rep((1:5),5))
b <- sample(rep((1:5),5))
c <- data.frame(sapply(data.frame(a), factor))
d <- data.frame(sapply(data.frame(b), factor))
scaledc <- likert(c)
scaledd <- likert(d)
The shiny codes are:
ui <- fluidPage(
titlePanel("Survey"),
sidebarLayout(
sidebarPanel(
selectInput("type",
"Plot Type",
choices = c("Likert"="bar",
"Density"="density",
"Heatmap"="heat"), selected="Likert"),
radioButtons("qtype",
"Question type:",
c("Agreement"="scaledc", "Helpfulness"="scaledd"),
selected="scaledc")
),
# Show a plot of the generated distribution
mainPanel(
tabsetPanel(
tabPanel("Yearly Data", plotOutput("distPlot1"))
)
)
)
)
#server
server <- function(input, output) {
output$distPlot1 <- renderPlot({plot(input$qtype, type=input$type)+
ggtitle("How agree are you with following statements?")}, height = 1000)
}
The shiny returned error "need finite 'ylim' values." I think it's becaue the input$qtype doesn't pass the correct information to the plot command, but I don't know how to fix it. Thank you for advance!
I've just solved the problem.
The missing codes in server are:
scale <- reactive({
get(input$qtype)
})
output$dat <- renderPrint({
scale()
})
And then do plot with scale() will show selected plot.

Shiny Server Error - could not find function "renderplot"

I am new to Shiny and am trying to add a chord diagram to a shiny server. When I hit the runApp button in RStudio I get the application to run and it generates the UI, but then closes down immediately and I get the following error in the RConsole window: Error in (structure(function (input, output) :
could not find function "renderplot".
Unfortunately, I cannot attach the data as it is proprietary, but I am just creating an adjacency matrix in order to generate the chord plot. The Chord plot works fine outside Shiny. Thanks in advance!
My UI and Server code is below:
library(shiny)
# Starting line
shinyUI(fluidPage(
# Application title
titlePanel("Chord Chart"),
# Sidebar
sidebarLayout(
sidebarPanel(
#Data selection for Chord Chart
selectInput("data","Select a Dataset:",
c("Marine"))),
#The plot created in server.R is displayed
mainPanel(
plotOutput("plot")
)))
)
library(circlize)
library(dplyr)
library(reshape2)
library(manipulate)
library(shiny)
# read marine summaries
marine <- readfile("C:/Personal/R/MarineDataSummary.csv")
# group and summarize by O-D
marine.sum <- marine %>%group_by(Handling_Port, OD_Port_Country) %>%
summarise(tons <-sum(tonnes)) # prepare pivot table
marine.sum1 <- acast(marine.sum, Handling_Port~OD_Port_Country, value.tons="z") # reshape matrix
marine.sum1[is.na(marine.sum1)] <- 0 # set NA to zero
#initialization of server.R
shinyServer(function(input, output) {
output$plot <- renderplot({
c <- chordDiagram(marine.sum1,annotationTrack="grid",preAllocateTracks=list(track.height = 0.3))
##change axis
c <- c + circos.trackPlotRegion(track.index=1, panel.fun=function(x,y) {
xlim = get.cell.meta.data("xlim")
ylim = get.cell.meta.data("ylim")
sector.name=get.cell.meta.data("sector.index")
circos.text(mean(xlim), ylim[1], sector.name,facing="clockwise",
niceFacing=TRUE,adj=c(0,0.4), cex = 0.4)},bg.border=NA)
print(c)
})
})