imageOutput在conditionalPanel中单击

use*_*808 7 r shiny

我正在构建一个闪亮的应用程序,用户点击图像,然后将它们推进到另一个图像.这似乎相对简单,但在用户查看第一张图片之前,他们需要输入他们的电子邮件地址.为了实现这一点,我一直在使用conditionalPanel只有在用户点击动作按钮后才显示第一张图像的地方.但是,当图像的面板嵌入其中时conditionalPanel,click参数imageOutput似乎停止工作.

我有一个目录images,其中包含9个图像,带有文件名1.png, 2.png...9.png(顺便说一句,如果有一种上传这个目录的方法,使这个例子更容易复制,我很乐意接受建议!).以下MWE - 不包含该conditionalPanel元素 - 效果很好:

library(shiny)

## User interface
ui <- fluidPage(
  h1("MWE",align="center"),
  fluidRow(
    column(4, conditionalPanel(condition = "input.signingo == 0", 
                               wellPanel(
                             textInput("who",label = "Please enter your email address.", value=""),
                             actionButton("signingo",label="Go.")
                           ))
),

column(6, align="center",
                        wellPanel(
                          imageOutput("image", height = 175, width = 116, click = "photo_click")
                        )
)
  )

) 

server <- function(input, output){

  values <- reactiveValues(i = 0, selections = sample(1:9,1))

  ## Load image
  output$image <- renderImage({
filename <- normalizePath(file.path(paste0('images/',values$selections,".png")))

# Return a list containing the filename and alt text
list(src = filename,
     alt = paste(input$name))

  }, deleteFile = FALSE)

## Function to increment counter by one and to randomly select new image
  click.function <- function(){isolate({
    values$i <- values$i + 1
values$selections <- sample(1:9,1)
  })}

  ## Move on
  observeEvent(input$photo_click,{click.function() })

}
shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)

但是,当我包含conditionalPanel元素时,单击图像似乎不再产生新图像.这是我正在使用的代码:

  library(shiny)

  ## User interface
  ui <- fluidPage(
h1("MWE",align="center"),
fluidRow(
  column(4, conditionalPanel(condition = "input.signingo == 0", 
                             wellPanel(
                               textInput("who",label = "Please enter your email address.", value=""),
                               actionButton("signingo",label="Go.")
                             ))
  ),

  column(6, align="center",
         conditionalPanel(condition = "input.signingo > 0", 
                          wellPanel(
                            imageOutput("image", height = 175, width = 116, click = "photo_click")
                          ))
  )
)
)

  server <- function(input, output){

values <- reactiveValues(i = 0, selections = sample(1:9,1))

## Load image
output$image <- renderImage({
  filename <- normalizePath(file.path(paste0('images/',values$selections,".png")))

  # Return a list containing the filename and alt text
  list(src = filename,
       alt = paste(input$name))

}, deleteFile = FALSE)

## Function to increment counter by one and to randomly select new image
click.function <- function(){isolate({
  values$i <- values$i + 1
  values$selections <- sample(1:9,1)
})}

## Move on
observeEvent(input$photo_click,{click.function() })
}
shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)

问题是虽然第一个conditionalPanel似乎正在完成其工作 - 用户首先看到"请输入您的电子邮件地址",并且只在点击"开始"后才看到第一个图像 - 点击图像不再提升用户转到下一张图片.任何想法都将非常感激.

Mic*_*jka 4

为了测试目的,我使用以下代码生成了 9 个 png 文件,其中数字从 1 到 9

for (i in 1:9) {
  #png(paste0(i, ".png"), bg = "grey") # you can manipulate the size of graphics 
  png(paste0(i, ".png"), bg = "grey", height = 400, width = 400) 
  plot(1:10, type = "n", axes = F, xlab = "", ylab = "")
  text(5,5, i, cex = 15, col = i)
  box()
  dev.off()
}
Run Code Online (Sandbox Code Playgroud)

我还在您的代码中做了一些更改:

  • 相反,条件面板有一个动态 UI,它取决于value$i

  • 最初value$i设置为-1textInput显示一个按钮

  • 如果用户输入包含该按钮的字符串@并按下该按钮,则 的值value$i将增加 1,并显示绘图输出。

  • 如果输入的字符串不包含@警告,则显示(shinyBS


该问题是由于plotOutput使用参数height和调整大小而引起的width。然后不会input$photo_click返回值,或者更准确地说,它返回NULL。如果不调整绘图大小,一切都会正常进行。因此,解决方案之一是放入plotOutputadiv并使用非常简单的方法CSS 来设置所需的输出大小。

您可以按如下方式调整 div 的大小:

div(style = "background:red; height: 400; width: 400;", 
            imageOutput("image", click = "photo_click")
          )
Run Code Online (Sandbox Code Playgroud)

您可以使用div 中height和的值width以及 png 文件的大小来获得所需的结果。

 ... 
 png(paste0(i, ".png"), bg = "grey", height = 400, width = 400) 
 ...
Run Code Online (Sandbox Code Playgroud)

背景颜色设置为红色,png 文件设置为灰色,以便于定位。

我希望这个解决方案对您有所帮助:


library(shiny)
library(shinyBS)

## User interface
ui <- fluidPage(
  uiOutput("dynamic")
)

server <- function(input, output, session){


  output$dynamic <- renderUI({
    if (values$i == -1) { 
      list(
        h1("MWE", align = "center"),
        wellPanel(
           textInput("who", label = "Please enter your email address.", value = ""),
           actionButton("signingo", label = "Go."),
           bsAlert("alert")
        )
      )
    }
    else {
      fluidRow(
        column(4),
        column(6,
          # imageOutput("image", height = 175, width = 116, click = "photo_click")
          # Setting a custom height and width causes the problem.

          # You can wrap imageOutput into a div. 
          div(style = "background:red; height: 400; width: 400;", 
            imageOutput("image", click = "photo_click")
          )
        )
      )
    }
  })

  # values$i changed to -1
  values <- reactiveValues(i = -1, selections = sample(1:9,1))

  ## Load image
  output$image <- renderImage({
    filename <- normalizePath(file.path(paste0('images/',values$selections,".png")))
    #filename <- paste0("/Users/User/Downloads/images/", values$selections, ".png")

    # Return a list containing the filename and alt text
    # list(src = filename,
    #      alt = paste(input$name)) # I don't know what is input$name

    list(src = filename,
         alt = paste(values$i))

  }, deleteFile = FALSE)

  ## Function to increment counter by one and to randomly select new image
  click.function <- function(){ # isolate({
    values$i <- values$i + 1
    values$selections <- sample(1:9,1)
  # })
}

  # increment once values$i (from -1 to 0) to close the first menu.
  observeEvent(input$signingo, {
    #if (input$who != "") 
    # Require that the inputed string includes @
    if (gregexpr(pattern = "@", input$who) != -1) { 
      click.function()
      closeAlert(session, "Alert")

    } else {
      # If the inputed string doesen't contain @ create a warning
      createAlert(session, "alert", "Alert", title = "Not valid email",
                  content = "", dismiss = T, style = "warning")
    }
  })

  observeEvent(input$photo_click, {
    click.function() 
  })
}
shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)