无法获得flexdashboard模态Shiny反应性来处理NULL状态

时间:2017-04-28 23:42:19

标签: r shiny shinydashboard flexdashboard

首先,这是一个可重复性最小的例子:

假设我有以下flexdashboard应用 example.Rmd

---
title: "Test App"
output:
  flexdashboard::flex_dashboard:
    theme: ["lumen"]
    orientation: ["columns"]
runtime: shiny
---

```{r setup, include=FALSE}
source('modules.R')
```

Test
==================

Inputs {.sidebar data-width=250}
------------------

```{r}

## Modules:
globalInputs <- callModule(setup, "inputs")  # Note: you only need to call this one time!
callModule(chart, "modalChart", globalInputs)
## UI:
sidebar("inputs")

```

Column
-------------------------------------

### ModalTest

```{r}
chartUI2("modalChart")
```

这是我的 modules.R 文件:

sidebar <- function(id) {
  ns <- NS(id)
  tagList(
    helpText("Press the button below to pull up a modal:"),
    actionButton(ns("settings"), "Settings", icon = icon("cogs"), width = '100%')
  )
}

# setup function
setup <- function(input, output, session) {
  return(input)  ## Note, input in this case is a reactive list of values that you can index against with $ or [[""]]
}

# UI module for the popup Settings modal
modalUI <- function(id) {
  ns <- NS(id)
  withTags({  # UI elements for the modal go in here
    ## Note: you can use the fluidPage() and fluidRow() functions to define a column-based UI for the chart inputs below:
    fluidPage(
      fluidRow(sliderInput(ns("bins"), "Number of bins:",
                           min = 1,  max = 50, value = 30),
               textInput(ns("plotTitle"), label = "Plot Title", value = "This is a test")
      ))
  })
}


## UI module for the 2 buttons in the modal:
modalFooterUI <- function(id) {
  ns <- NS(id)
  tagList(
    modalButton("Cancel", icon("remove")),
    actionButton(ns("modalApply"), "Apply", icon = icon("check"))
  )
}

## chart module ----------------------------------------------------------------
chartUI2 <- function(id) {
  ns <- NS(id)
  plotOutput(ns("distPlot"))
}

chart <- function(input, output, session, setup) {

  observeEvent(setup$settings, {
    showModal(modalDialog(
      modalUI("inputs"),  # Call UI function defined in './modules/modal.R'; note the namespace 'inputs' is the same globally for the app
      title = "Settings",
      footer = modalFooterUI("inputs"),
      size = "l",
      easyClose = TRUE,
      fade = TRUE)
    )
  })

  output$distPlot <- renderPlot({
    if (setup$settings == 0)
      return(
        hist(faithful[, 2],
             breaks = 5,  # if the button hasn't been pressed, default
             main = 'This is the default title',
             col = 'darkgray',
             border = 'white')
      )
    isolate({
      x <- faithful[, 2]
      bins <- setup$bins
      hist(x,
           breaks = bins,
           main = setup$plotTitle,
           col = 'darkgray',
           border = 'white')
    })

  })
}

以下是我想要完成的事情:

  1. 当页面加载使用默认参数呈现distPlot时。这应该总是发生。
  2. 当我点击“设置”actionButton时,会弹出模态叠加层(但会将背景中的绘图保持原始状态)
  3. 允许用户更改弹出模式中的参数,但在用户点击“应用”按钮之前不要重新渲染绘图。
  4. 我想我已经找到了#1,但是当我点击“设置”按钮时,我收到错误Invalid breakpoints produced by 'breaks(x)': NULL。然后,我更改输入并且它什么都不做(除非我再次点击“设置actionButton”(这反过来会使用给定的输入渲染绘图)。

    我做错了什么?

    谢谢!

1 个答案:

答案 0 :(得分:1)

可能存在时间问题。当您按下设置按钮时,setup$settings变为1,因此renderPlot会尝试重新绘制。如果在设置滑块之前发生这种情况,setup$binsNULL,则会出错。

只有当用户按下模式中的“应用”按钮时,您才可以在if的第一个renderPlot中添加条件以使用setup$bins进行绘图:

output$distPlot <- renderPlot({
    if (setup$settings == 0 | !isTruthy(setup$modalApply)) {
        hist(faithful[, 2],
             breaks = 5,  # if the button hasn't been pressed, default
             main = 'This is the default title',
             col = 'darkgray',
             border = 'white')
      } else {
    isolate({
      x <- faithful[, 2]
      bins <- setup$bins
      hist(x,
           breaks = bins,
           main = setup$plotTitle,
           col = 'darkgray',
           border = 'white')
    })
{p> !isTruthy如果TRUEsetup$modalApply(模态尚未创建)或NULL(用户没有&#),则为0 39; t按下按钮)。 一旦用户按下Apply按钮,图表就会更新。

修改

为方便起见,您可以使用reactiveValues来保存所有绘图参数,包括默认参数。当用户单击“应用”按钮时,可以更新它,然后更新绘图:

 plot_params = reactiveValues(bins=5,title='This is the default title')


  output$distPlot <- renderPlot({
        hist(faithful[, 2],
             breaks = plot_params$bins,
             main = plot_params$title,
             col = 'darkgray',
             border = 'white')
  })

  observeEvent(setup$modalApply,{
    plot_params$bins = setup$bins
    plot_params$title = setup$plotTitle
  })