I’m working on a Quarto dashboard using Shiny and I’m having trouble updating a plot based on the selected tab. I have two datasets, mtcars and trees, and I want the plot to change dynamically depending on which tab is selected. Below is a snippet of my code:
---
title: "panel-tabset"
format: dashboard
server: shiny
---
```{r}
#|context: setup
data(trees)
data(mtcars)
Input {.sidebar}
::: panel-tabset
mtcars
selectInput("axis_x_mtcars",
"axis x",
choices = names(mtcars),
selected = names(mtcars)[1]
)
selectInput("axis_y_mtcars",
"axis y",
choices = names(mtcars),
selected = names(mtcars)[4]
)
trees
selectInput("axis_x_trees",
"axis x",
choices = names(trees),
selected = names(trees)[1]
)
selectInput("axis_y_trees",
"axis y",
choices = names(trees),
selected = names(trees)[2]
)
:::
Plot
plotOutput("plot_data")
#| context: server
library(ggplot2)
library(tidyverse)
dataset <- reactive({
# if (input$active_tab == "mtcars") {
mtcars %>%
select(x = input$axis_x_mtcars,
y = input$axis_y_mtcars)
# } else {
# trees %>%
# select(x = input$axis_x_trees,
# y = input$axis_y_trees)
# }
})
output$plot_data <- renderPlot({
ggplot(dataset(), aes(x, y)) +
geom_point()
})
I’ve commented out the conditionals for selecting the dataset based on the active tab because I’m not sure how to correctly implement the tab-switching functionality. I’m also aware that JavaScript might be needed to track the active tab and communicate it back to Shiny, but I’m not sure how to integrate it in a Quarto dashboard.
You can provide an id
to the Tabset Panel and attach an event handler inside a Javascript chunk which in case of a tab change applies Shiny.setInputValue()
for setting the active tab's name to an input value.
---
title: "panel-tabset"
format: dashboard
server: shiny
---
```{r}
#| context: setup
data(trees)
data(mtcars)
```
# Input {.sidebar}
::: {.panel-tabset #tabs}
## mtcars
```{r}
selectInput("axis_x_mtcars",
"axis x",
choices = names(mtcars),
selected = names(mtcars)[1]
)
selectInput("axis_y_mtcars",
"axis y",
choices = names(mtcars),
selected = names(mtcars)[4]
)
```
## trees
```{r}
selectInput("axis_x_trees",
"axis x",
choices = names(trees),
selected = names(trees)[1]
)
selectInput("axis_y_trees",
"axis y",
choices = names(trees),
selected = names(trees)[2]
)
```
:::
# Plot
```{r}
plotOutput("plot_data")
```
```{r}
#| context: server
library(ggplot2)
library(dplyr)
dataset <- reactive({
req(input$active_tab)
if (input$active_tab == "mtcars") {
mtcars %>%
select(x = input$axis_x_mtcars,
y = input$axis_y_mtcars)
} else {
trees %>%
select(x = input$axis_x_trees,
y = input$axis_y_trees)
}
})
output$plot_data <- renderPlot({
ggplot(dataset(), aes(x, y)) +
geom_point()
})
```
```{js}
$(document).on("shiny:connected", function() {
// initially, the first tab is chosen, set this
var target = $('#tabs').find("a").first().text();
Shiny.setInputValue("active_tab", target);
// add an event handler which updates this value when a change occurs
$('#tabs').on('shown.bs.tab', function (e) {
var target = $(e.target).text();
Shiny.setInputValue("active_tab", target);
});
});
```