[英]Shiny dashboard with conditional plotOut
I am just starting with shiny and dashboard, so any help is greatly appreciated!我刚开始使用闪亮的仪表板,因此非常感谢您的帮助!
I have a shinydashboard app displaying one row with two elements: A tabBox
on the left with two tabPanel
s, and a box
on the right (to display a plot).我有一个 Shinydashboard 应用程序显示一行,其中包含两个元素:左侧的
tabBox
带有两个tabPanel
s,右侧的一个box
(用于显示绘图)。
What I want is to display a particular plot in the box depending on the active tabPanel
.我想要的是根据活动
tabPanel
在框中显示特定图。 The plot should be not clickable when the first tab is active, but clickable when the second tab is active.当第一个选项卡处于活动状态时,该图不应可单击,但在第二个选项卡处于活动状态时可单击。
My problem is that I only know how to set up the clickable property in the ui
through the plotOutput
function using the option click = "plot_click"
.我的问题是我只知道如何使用选项
click = "plot_click"
通过plotOutput
函数在ui
设置 clickable 属性。 But this sets both plots as clickable.但这将两个图都设置为可点击。 Of course, removing the option
click = "plot_click"
sets both plots as not-clickable.当然,删除选项
click = "plot_click"
将两个图都设置为不可点击。 How can I make the clickable property depend on the active tab?如何使可点击属性依赖于活动选项卡?
What I tried: Place an if
statement inside box()
such that, depending on the id of the tabPanel
, it would activate the option click = "plot_click"
for the correct plot.我尝试过的:在
box()
放置一个if
语句,这样,根据tabPanel
的 ID,它会激活选项click = "plot_click"
以获得正确的绘图。 I failed at this.我失败了。
Here's the code.这是代码。 You can play with either plot by (un)commenting the desired plot inside
box()
.您可以通过(取消)注释
box()
内的所需图来玩任一图。
library(shiny)
library(shinydashboard)
library(ggplot2)
ui <- dashboardPage(
dashboardHeader(title = "Conditional plotOutput click", titleWidth = 450),
dashboardSidebar(disable = TRUE),
dashboardBody(
fluidRow(
tabBox(title = "Choose tab", id = "choose.tab", height = 250, selected = "Automatic",
tabPanel(title = "Automatic", id = "auto", sliderInput("slider", "Nobs:", 1, 10, 5)),
tabPanel(title = "Manual", id = "man")
),
box(title = "Plot", solidHeader = TRUE,
# plotOutput("plot1", height = 250) # Try me!
plotOutput("plot2", height = 250, click = "plot_click") # Or me!
)
)
)
)
server <- function(input, output) {
set.seed(123)
react.vals <- reactiveValues(
df = data.frame(x = numeric(), y = numeric()),
plot1 = ggplot(),
plot2 = ggplot()
)
# Plot 1 - Automatic scatterplot:
observe({
scatter.data <- data.frame(x = runif(input$slider), y = runif(input$slider))
react.vals$plot1 <- ggplot(scatter.data, aes(x, y)) + geom_point(color = "red", size = 4) +
scale_x_continuous("x", breaks = seq(0, 1, .2), limits = c(0, 1), expand = c(0,0)) +
scale_y_continuous("y", breaks = seq(0, 1, .2), limits = c(0, 1), expand = c(0,0)) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
})
observeEvent(react.vals$plot1, {
output$plot1 <- renderPlot({ react.vals$plot1 })
})
# Plot 2 - Manual scatterplot through clicking:
observeEvent(input$plot_click, {
new.point <- data.frame(x = input$plot_click$x,
y = input$plot_click$y)
react.vals$df <- rbind(react.vals$df, new.point)
})
observe({
react.vals$plot2 <- ggplot(react.vals$df, aes(x = x, y = y)) + geom_point(color = "red", size = 4) +
scale_x_continuous("x", breaks = seq(0, 1, .2), limits = c(0, 1), expand = c(0,0)) +
scale_y_continuous("y", breaks = seq(0, 1, .2), limits = c(0, 1), expand = c(0,0)) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
})
observeEvent(react.vals$plot2, {
output$plot2 <- renderPlot({ react.vals$plot2 })
})
}
shinyApp(ui, server)
Thanks in advance, jorge提前致谢,豪尔赫
You can use uiOutput
to define the characteristics of plotOutput
according to the active tabPanel
.您可以使用
uiOutput
定义的特性plotOutput
根据活动tabPanel
。 Below is your example adapted with uiOutput
:以下是您使用
uiOutput
改编的uiOutput
:
library(shiny)
library(shinydashboard)
library(ggplot2)
ui <- dashboardPage(
dashboardHeader(title = "Conditional plotOutput click", titleWidth = 450),
dashboardSidebar(disable = TRUE),
dashboardBody(
fluidRow(
tabBox(title = "Choose tab", id = "choose_tab", height = 250, selected = "Automatic",
tabPanel(title = "Automatic", id = "auto", sliderInput("slider", "Nobs:", 1, 10, 5)),
tabPanel(title = "Manual", id = "man")
),
box(title = "Plot", solidHeader = TRUE,
uiOutput("test")
)
)
)
)
server <- function(input, output) {
set.seed(123)
react.vals <- reactiveValues(
df = data.frame(x = numeric(), y = numeric()),
plot1 = ggplot(),
plot2 = ggplot()
)
observe({
if (input$choose_tab == "Automatic") {
output$test <- renderUI({
plotOutput("plot1", height = 250)
})
}
else if(input$choose_tab == "Manual") {
output$test <- renderUI({
plotOutput("plot2", height = 250, click = "plot_click")
})
}
})
# Plot 1 - Automatic scatterplot:
observe({
scatter.data <- data.frame(x = runif(input$slider), y = runif(input$slider))
react.vals$plot1 <- ggplot(scatter.data, aes(x, y)) + geom_point(color = "red", size = 4) +
scale_x_continuous("x", breaks = seq(0, 1, .2), limits = c(0, 1), expand = c(0,0)) +
scale_y_continuous("y", breaks = seq(0, 1, .2), limits = c(0, 1), expand = c(0,0)) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
})
observeEvent(react.vals$plot1, {
output$plot1 <- renderPlot({ react.vals$plot1 })
})
# Plot 2 - Manual scatterplot through clicking:
observeEvent(input$plot_click, {
new.point <- data.frame(x = input$plot_click$x,
y = input$plot_click$y)
react.vals$df <- rbind(react.vals$df, new.point)
})
observe({
react.vals$plot2 <- ggplot(react.vals$df, aes(x = x, y = y)) + geom_point(color = "red", size = 4) +
scale_x_continuous("x", breaks = seq(0, 1, .2), limits = c(0, 1), expand = c(0,0)) +
scale_y_continuous("y", breaks = seq(0, 1, .2), limits = c(0, 1), expand = c(0,0)) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
})
observeEvent(react.vals$plot2, {
output$plot2 <- renderPlot({ react.vals$plot2 })
})
}
shinyApp(ui, server)
Edit: Fixed a small typo in the R code.编辑:修复了 R 代码中的一个小错字。
Thanks, bretauv , this solves it!谢谢, bretauv ,这解决了!
I still needed to add two final changes to the code to have exactly what I wanted:我仍然需要对代码添加两个最终更改以完全满足我的要求:
box
(not needed anymore).box
的 plotOutput() (不再需要)。plot2
to plot1
inside the first renderUI()
call.plot2
到plot1
第一内侧renderUI()
调用。 Perhaps you want to edit your answer using these tips for future reference.也许您想使用这些提示编辑您的答案以供将来参考。
Thanks a lot!非常感谢! I've upvoted this answer.
我已经赞成这个答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.