数据未传递到模块化闪亮tabPanel/navbarPage内的模块
我的可复制闪亮应用程序创建一些数据,这些数据应通过使用数据未传递到模块化闪亮tabPanel/navbarPage内的模块,r,shiny,shiny-reactivity,shinymodules,R,Shiny,Shiny Reactivity,Shinymodules,我的可复制闪亮应用程序创建一些数据,这些数据应通过使用lappy调用绘图模块进行绘图。因此,它包含主应用程序、模块化的页面用户界面/页面服务器,以及模块用户界面/模块服务器 当它未在选项卡面板/导航栏页面中实现时,它作为一个独立的应用程序工作。但是,在后一种设置中,创建数据(可通过代码的消息输出观察),但不通过绘图模块。为什么? 详细内容如下: 主应用程序是从ui和server调用的navbarPage 用于navbarPage(page\u ui和page\u server)的模块化页面(ta
lappy
调用绘图模块进行绘图。因此,它包含主应用程序、模块化的页面用户界面
/页面服务器
,以及模块用户界面
/模块服务器
当它未在选项卡面板
/导航栏页面
中实现时,它作为一个独立的应用程序工作。但是,在后一种设置中,创建数据(可通过代码的消息
输出观察),但不通过绘图模块。为什么?
详细内容如下:
ui
和server
调用的navbarPage
navbarPage
(page\u ui
和page\u server
)的模块化页面(tabPanel
),它通过单击“加载”按钮创建一些数据(DataPack
,一个包含三个元素的列表),并通过lappy
调用绘图模块(受来自的示例启发)module\u ui
和module\u server
)用于绘制DataPack
的每个列表元素,并在绘图模块内创建一些统计信息(AnalysedPack
)navbarPage
中时,代码不起作用:
library(shiny)
library(TTR)
# Single Plot Module to be repeated using lapply in Page_server
Module_ui <- function(id) {
ns <- NS(id)
uiOutput(ns("Plot"))
}
Module_Server <- function(
input, output, session,
DataPack, DataSetName, InputButton_GetData) {
AnalysedPack <- eventReactive(
InputButtton_GetData(), {
message(paste("Analysed Pack", DataSetName))
AnalysedPack <- runMean(DataPack()[[DataSetName]])
return(AnalysedPack)
})
output[['Plot']] <- renderUI({
fluidRow( renderPlot({
message(paste("Base_Plot", DataSetName))
plot(DataPack()[[DataSetName]])
lines(AnalysedPack(), col = "tomato", lwd = 2)}) )
})
}
# navbarPage Module as tabPanel
Page_ui <- function(id) {
ns <- NS(id)
tabPanel("Charts", fluidPage(
style = "padding-top: 140px;",
div(id = ns("placehere")),
absolutePanel(
top = 0, width = "97%", fixed = TRUE,
div(fluidRow(column(
6, fluidRow(h4("Data Generation")),
fluidRow(actionButton(ns("InputButton_GetData"),
"Load", width = "100%"))) )) ) ))
}
Page_server <- function(input, output, session) {
DataPack <- eventReactive(
input$InputButton_GetData, {
message("----- Creating new DataPack -----")
n <- round(runif(1, min = 100, max = 500))
message("Data length:", n)
DataPack <- NULL
DataPack$one <- rnorm(n)
DataPack$two <- rnorm(n)^2
DataPack$three <- sin(rnorm(n)^6)
return(DataPack)
})
InputButton_GetData_rx <-
reactive(input$InputButton_GetData)
observeEvent(
input$InputButton_GetData, {
lapply(names(DataPack()), function(DataSetName) {
id <- sprintf('Plot%s', DataSetName)
message("DataSetName: ", DataSetName)
message("id: ", id)
insertUI(
selector = "#placehere",
where = "beforeBegin",
ui = Module_ui(id))
message("callModule: ", id)
callModule(
Module_Server, id,
DataPack = DataPack,
DataSetName = DataSetName,
InputButton_GetData = InputButton_GetData_rx) })
})
}
# Main App with navbarPage
ui <- navbarPage(
"Navbar!",
Page_ui("someid"),
position = "fixed-bottom")
server <- function(input, output, session) {
callModule(Page_server, "someid")
}
shinyApp(ui, server)
为确保完整性,在顺序调用模块时(无lappy
),代码也能正常工作:
库(闪亮)
图书馆(TTR)
#要按顺序重复的单个绘图模块
模块ui您使用lappy
和navbarPage
的代码不会在适当的命名空间中生成ui,因为使用navbarPage
构造模块时,您的模块“更深一层”。我在下面添加了更新的代码片段
相关更改是使用会话$ns(id)
设置添加的UI组件的名称
库(闪亮)
图书馆(TTR)
#要按顺序重复的单个绘图模块
模块ui我在您的代码中发现了几个缺陷:1)insertUI
中的选择器
是\placehere
但您将其包装在ns()
中的页面ui
中,因此无法放置新的ui。您必须将#someid放置在此处
(自从您调用页面ui(“someid”)
)或删除ns()
。2) 你把一个renderPlot
放在renderUI
里面,我认为这不管用。将ui输出
替换为plotOutput
并删除renderUI
。但是,它仍然没有显示绘图,我想这是由于在insertUI
中创建的ID造成的。实际上,如果将p(“test”)
放入模块ui
(在带有plotOutput
的标记列表中),则“test”将显示三次。我还尝试在module\u ui
和renderText
中放置textfoutput
,但它没有显示任何内容。因此,我认为问题来自模块中lappy
中调用模块的方式,我不知道如何解决它。希望这有帮助使用的示例是一些原始代码的缩短版本,因此,使用renderUI
和renderPlot
的双输入项。这似乎不是问题所在,但是,您对缺少的html包装的看法是正确的,它的形式是fluidRow
,div$tag
,或taglist
(我更改了上面的代码)。为完整起见,我将发布代码,该代码在未包装在navbarPage
中时有效,这表明lappy
调用很好。调用模块本身或将变量传递到module\u ui
/module\u服务器
时一定有问题。
library(shiny)
library(TTR)
# Single Plot Module to be repeated using lapply in Page_server
Module_ui <- function(id) {
ns <- NS(id)
uiOutput(ns("Plot"))
}
Module_Server <- function(
input, output, session,
DataPack, DataSetName, InputButton_GetData, xlim) {
AnalysedPack <- eventReactive(c(
InputButton_GetData()), {
message(paste("Analysed Pack", DataSetName))
AnalysedPack <- runMean(DataPack()[[DataSetName]])
return(AnalysedPack)
})
output[['Plot']] <- renderUI({
# `fluidRow`, `div$tag`, or `taglist` necessary as wrapper for some html object
fluidRow( renderPlot({
message(paste("Base_Plot", DataSetName))
plot(DataPack()[[DataSetName]])
lines(AnalysedPack(), col = "tomato", lwd = 2) }) )
})
}
# navbarPage Module
Page_ui <- fluidPage(
style="padding-top: 140px;",
div(id = "placehere"),
absolutePanel(
top = 0, width = "97%", fixed = TRUE,
div(fluidRow(column(
6, fluidRow(h4("Data Generation")),
fluidRow(actionButton("InputButton_GetData",
"Load", width = "100%"))) )) )
)
Page_server <- function(input, output, session) {
DataPack <- eventReactive(
input$InputButton_GetData, {
message("----- Creating new DataPack -----")
n <- round(runif(1, min = 100, max = 500))
message("Data length:", n)
DataPack <- NULL
DataPack$one <- rnorm(n)
DataPack$two <- rnorm(n)^2
DataPack$three <- sin(rnorm(n)^6)
return(DataPack)
})
InputButton_GetData_rx <-
reactive(input$InputButton_GetData)
observeEvent(
input$InputButton_GetData, {
lapply(names(DataPack()), function(DataSetName) {
id <- sprintf('Plot%s', DataSetName)
message("DataSetName: ", DataSetName)
message("id: ", id)
insertUI(
selector = "#placehere",
where = "beforeBegin",
ui = Module_ui(id))
message("callModule: ", id)
callModule(
Module_Server, id,
DataPack = DataPack,
DataSetName = DataSetName,
InputButton_GetData = InputButton_GetData_rx) })
})
}
shinyApp(Page_ui, Page_server)
library(shiny)
library(TTR)
# Single Plot Module to be repeated sequentially
Module_ui <- function(id) {
ns <- NS(id)
plotOutput(ns("Plot"))
}
Module_Server <- function(
input, output, session,
DataPack, DataSetName, InputButton_GetData, xlim) {
AnalysedPack <- eventReactive(c(
InputButton_GetData()), {
message(paste("Analysed Pack", DataSetName))
AnalysedPack <- runMean(DataPack()[[DataSetName]])
return(AnalysedPack)
})
output$Plot <- renderPlot({
message(paste("Base_Plot", DataSetName))
plot(DataPack()[[DataSetName]])
lines(AnalysedPack(), col = "tomato", lwd = 2)
})
}
# navbarPage Module as tabPanel
Page_ui <- function(id) {
ns <- NS(id)
tabPanel("Charts", fluidPage(
style = "padding-top: 140px;",
absolutePanel(
top = 0, width = "97%", fixed = TRUE,
div(fluidRow(column(
6, fluidRow(h4("Data Generation")),
fluidRow(actionButton(ns("InputButton_GetData"),
"Load", width = "100%"))) )) ),
Module_ui(ns("Plot_1")), Module_ui(ns("Plot_2")), Module_ui(ns("Plot_3")) ))
}
Page_server <- function(input, output, session) {
DataPack <- eventReactive(
input$InputButton_GetData, {
message("----- Creating new DataPack -----")
n <- round(runif(1, min = 100, max = 500))
message("Data length:", n)
DataPack <- NULL
DataPack$one <- rnorm(n)
DataPack$two <- rnorm(n)^2
DataPack$three <- sin(rnorm(n)^6)
return(DataPack)
})
InputButton_GetData_rx <-
reactive(input$InputButton_GetData)
callModule(Module_Server, "Plot_1",
DataPack = DataPack,
DataSetName = "one",
InputButton_GetData = InputButton_GetData_rx)
callModule(Module_Server, "Plot_2",
DataPack = DataPack,
DataSetName = "two",
InputButton_GetData = InputButton_GetData_rx)
callModule(Module_Server, "Plot_3",
DataPack = DataPack,
DataSetName = "three",
InputButton_GetData = InputButton_GetData_rx)
}
# Main App
ui <- navbarPage(
"Navbar!",
Page_ui("some_ns"),
position = "fixed-bottom")
server <- function(input, output, session) {
callModule(Page_server, "some_ns")
}
shiny::shinyApp(ui, server)