In my mod_page_charts
I have two charts as an output TypeA_Chart
TypeB_Chart
,
In my mod_page_ui
have added a filter for charts, where i am attempting to filter charts where the output in tabPanel
for plotlyOutput
should show the chart based on chart type selected.
How do i render UI so that the chart changes based on pickerInput
selection?
mod_page_ui <- function(id) {
ns <- NS(id)
tabItem(
tabName = "chart_page",
fluidPage(
fluidRow(
column(12, ),
fluidRow(column(12, tabsetPanel(
tabPanel("Value Chart " , fluidRow(
column(
2,
align = "center",
h3("Filter Chart"),
pickerInput(
inputId = ns("selectType"),
label = "Select Type to View",
choices = c("TypeA", "TypeB"),
selected = c("TypeA", "TypeB"),
),
uiOutput(ns("attributePicker"))
),
column(12, tabsetPanel(tabPanel(
"chart Panel ",
plotlyOutput(ns("TypeA_Chart"),
plotlyOutput(ns("TypeB_Chart")))
))))))))}
mod_page_charts <- function(input, output, session) {
ns <- session$ns
options(scipen = 100, digits = 4)
output$attributePicker <- renderUI({
if (input$selectType == "TypeA") {
pickerInput(
inputId = ns("selectedTypeA"),
label = "Select Category to View",
choices = c("Daily", "Weekly"),
selected = c("Daily", "Weekly"),
multiple = TRUE,
options = list(size = 5)
)
} else if (input$selectType == "TypeB") {
pickerInput(
inputId = ns("selectedTypeB"),
label = "Select Category to View",
choices = c("Daily", "Weekly"),
selected = c("Daily", "Weekly"),
multiple = TRUE,
options = list(size = 5)
)}})
output$TypeA_Chart <- renderPlotly({
plt <- generate_plot_typeA(
data = datatypeA,
attributeID = input$selectType,
x = `Dates`,
y = `Values`,
title = "Type-A Chart"
)
})
output$TypeB_Chart <- renderPlotly({
plt <- generate_plot_typeB(
data = datatypeB,
attributeID = input$selectType,
x = `Dates`,
y = `Values`,
title = "Type-B Chart"
)})
There's a lot of things going on in your code which I'm not sure is all intentional or not. Since it appears that you only want to show a plot based on a condition, conditionalPanel()
might be all you need.
I've stripped it down to its very basics; I've omitted the use of modules and removed the dependency to shinydashboard
and shinyWidgets
, but it should work the same. Showing a panel does not need anything special from the server component. The app below simply shows the header A is showing
and B is showing
based on the selected values from the selectInput()
.
library(shiny)
shinyApp(
fluidPage(
selectInput(
label = 'Select Type to View',
inputId = 'selectType',
choices = c('TypeA', 'TypeB'),
multiple = TRUE
),
conditionalPanel(
condition = 'input.selectType.includes("TypeA")',
h1('A is showing')
),
conditionalPanel(
condition = 'input.selectType.includes("TypeB")',
h1('B is showing')
)
),
server = function(input, output) {}
)
If it's more convenient, you could also consider the use of checkboxes. Nothing about the condition inside conditionalPanel
should change.
library(shiny)
shinyApp(
fluidPage(
checkboxGroupInput(
inputId = 'selectType',
label = 'Select Type to View',
choices = c('TypeA', 'TypeB')
),
conditionalPanel(
condition = 'input.selectType.includes("TypeA")',
h1('A is showing')
),
conditionalPanel(
condition = 'input.selectType.includes("TypeB")',
h1('B is showing')
)
),
server = function(input, output) {}
)
From here, simply replace the h1()
with your plot and render it without considering any of the conditions.
library(shiny)
library(plotly)
shinyApp(
fluidPage(
checkboxGroupInput(
inputId = 'selectType',
label = 'Select Type to View',
choices = c('TypeA', 'TypeB')
),
conditionalPanel(
condition = 'input.selectType.includes("TypeA")',
plotlyOutput('TypeA_Chart')
),
conditionalPanel(
condition = 'input.selectType.includes("TypeB")',
plotlyOutput('TypeB_Chart')
)
),
server = function(input, output) {
# sample data
data <- data.frame(x = 1:10, y = rnorm(10), group = sample(letters[1:3], 10, replace = TRUE))
output$TypeA_Chart <- renderPlotly(
# no conditions needed
plot_ly(data, x = ~x, y = ~y, type = 'scatter', mode = 'markers', color = ~group)
)
output$TypeB_Chart <- renderPlotly(
plot_ly(data, x = ~group, y = ~y, type = 'bar')
)
}
)
If you insist on using modules, note that Shiny 1.5.0 introduced a moduleServer()
function that should streamline the server function creation part. For conditionalPanel()
, you have to also pass in the ns
function itself.
library(shiny)
library(plotly)
chartModuleUI <- function(id) {
ns <- NS(id)
tagList(
checkboxGroupInput(
inputId = ns('selectType'),
label = 'Select Type to View',
choices = c('TypeA', 'TypeB')
),
conditionalPanel(
condition = 'input.selectType.includes("TypeA")',
plotlyOutput(ns('TypeA_Chart')),
ns = ns
),
conditionalPanel(
condition = 'input.selectType.includes("TypeB")',
plotlyOutput(ns('TypeB_Chart')),
ns = ns
)
)
}
chartModuleServer <- function(id) {
moduleServer(
id,
function(input, output, session) {
data <- data.frame(x = 1:10, y = rnorm(10), group = sample(letters[1:3], 10, replace = TRUE))
output$TypeA_Chart <- renderPlotly(
plot_ly(data, x = ~x, y = ~y, type = 'scatter', mode = 'markers', color = ~group)
)
output$TypeB_Chart <- renderPlotly(
plot_ly(data, x = ~group, y = ~y, type = 'bar')
)
}
)
}
shinyApp(
fluidPage(
chartModuleUI('chartModule')
),
server = function(input, output) {
chartModuleServer('chartModule')
}
)