如何访问swipeR中的输入?

pb3s4cty  于 2023-10-13  发布在  其他
关注(0)|答案(1)|浏览(113)

我试过在swipeR函数中放入sliderInput,但我无法访问它,因为它就像是图像的一部分。我预料到这种行为,没有什么不寻常的。
我的代码:

# swipeR example ####
library(swipeR)
library(shiny)
library(ggplot2)

wrapper <- swipeRwrapper(
  
  div(
    style = "border: 2px solid #008cba; padding: 8px; margin: 0 75px;",
    div(id = "div1", style="box-shadow: 0 0 10px 5px;", sliderInput(inputId = "slider1", label = "Slider:", value = 15, min = 10, max = 25)),
    plotOutput("ggplot1", width = "400px", height = "300px"),
    align = "center"
  ),
  
  div(
    plotOutput("ggplot2", width = "500px", height = "400px"),
    align = "center"
  )
  
)

ui <- fluidPage(

  HTML("
  <script>
  $(function() {
    $('#div1').addClass('swiper-no-swiping');
  })
  </script>
  "),
  
  tags$script(HTML('
    document.getElementById("CAROUSEL").addEventListener("click", function() {
      document.getElementById("div1").focus();
    });
  ')),
  
  tags$head(
    tags$style(HTML(
      ".shiny-plot-output {border: 2px solid royalblue;}"
    ))
  ),
  
  br(),
  
  fluidRow(
    
    column(
      12,
      swipeR(
        wrapper, height = "450px", width = "80%", effect = "cube", speed = 2000,
        navigationColor = "black", rewind = TRUE, id = "CAROUSEL"
      )
    ),
    
    column(
      12,
      br(), br(), br(),
    ),
    
    column(
      3, align = "center",
      actionButton(
        "btn1", "Scatter plot", class = "btn-primary",
        onclick = "document.getElementById('CAROUSEL').swiper.slideTo(0);"
      )
    ),
    
    column(
      3, align = "center",
      actionButton(
        "btn2", "Line chart", class = "btn-primary",
        onclick = "document.getElementById('CAROUSEL').swiper.slideTo(1);"
      )
    )
    
  )
  
)

server <- function(input, output, session) {
  
  output[["ggplot1"]] <- renderPlot({
    ggplot(mtcars, aes(wt, mpg)) + geom_point() +
      labs(title = "My plot title size by sliderInput") + 
      theme(plot.title = element_text(size = input$slider1), 
            panel.border = element_rect(fill = NA, color = "firebrick"))
  }, width = 400, height = 300)
  output[["ggplot2"]] <- renderPlot({
    ggplot(economics, aes(date, unemploy)) + geom_line()
  }, width = 500, height = 400)
  
}

shinyApp(ui, server)

我试着用JavaScript让滑块工作,但我不能。
如何使用swipeR内部的输入?

ycl3bljg

ycl3bljg1#

这里的主要问题是swipeR函数捕获整个UI,就好像它是一个图像或静态幻灯片一样。它的设计并没有像滑块这样的动态输入控件,因此这是一个挑战。尝试的JavaScript解决方案似乎也没有达到预期的效果。
为了解决这个问题,让swipeR内部的输入仍然可以交互,我们需要做一些改变并使用JavaScript。使用JavaScript防止单击滑块时的滑动操作。我们将通过在单击滑块时停止事件传播来实现这一点。将此JavaScript包含在Shiny UI中。
尝试在您的Shiny应用程序UI的fluidPage中插入以下JavaScript代码script,以防止滑块单击时的滑动操作:

tags$script(HTML('
  $(document).on("mousedown", "#slider1", function(event) {
    event.stopPropagation();
  });
'))

下面是修改后的完整代码实现:

# swipeR example ####
library(swipeR)
library(shiny)
library(ggplot2)

wrapper <- swipeRwrapper(

  div(
    style = "border: 2px solid #008cba; padding: 8px; margin: 0 75px;",
    sliderInput(inputId = "slider1", label = "Slider:", value = 15, min = 10, max = 25),
    plotOutput("ggplot1", width = "400px", height = "300px"),
    align = "center"
  ),

  div(
    plotOutput("ggplot2", width = "500px", height = "400px"),
    align = "center"
  )

)

ui <- fluidPage(

  tags$script(HTML('
    $(document).on("mousedown", "#slider1", function(event) {
      event.stopPropagation();
    });
  ')),

  tags$head(
    tags$style(HTML(
      ".shiny-plot-output {border: 2px solid royalblue;}"
    ))
  ),

  br(),

  fluidRow(

    column(
      12,
      swipeR(
        wrapper, height = "450px", width = "80%", effect = "cube", speed = 2000,
        navigationColor = "black", rewind = TRUE, id = "CAROUSEL"
      )
    ),

    column(
      12,
      br(), br(), br(),
    ),

    column(
      3, align = "center",
      actionButton(
        "btn1", "Scatter plot", class = "btn-primary",
        onclick = "document.getElementById('CAROUSEL').swiper.slideTo(0);"
      )
    ),

    column(
      3, align = "center",
      actionButton(
        "btn2", "Line chart", class = "btn-primary",
        onclick = "document.getElementById('CAROUSEL').swiper.slideTo(1);"
      )
    )

  )

)

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

  output[["ggplot1"]] <- renderPlot({
    ggplot(mtcars, aes(wt, mpg)) + geom_point() +
      labs(title = "My plot title size by sliderInput") +
      theme(plot.title = element_text(size = input$slider1),
            panel.border = element_rect(fill = NA, color = "firebrick"))
  }, width = 400, height = 300)

  output[["ggplot2"]] <- renderPlot({
    ggplot(economics, aes(date, unemploy)) + geom_line()
  }, width = 500, height = 400)

}

shinyApp(ui, server)

我已经更新了你的解决方案,现在你应该能够允许用户在swipeR元素内与slider交互,同时在其余区域保持swipe functionality

更新了持久化问题代码:

好吧,嗯,然后尝试preventswipe event从被触发的sliderInput div代替。使用Shiny的tags$div函数将类swiper-no-swiping直接添加到包含sliderInputdiv中。这是一个由Swiper提供的内置类,它可以在与具有此类的元素交互时防止滑动。然后直接将swiper-no-swiping class应用于div,包裹sliderInput
像这样修改 Package 器:

wrapper <- swipeRwrapper(

  div(
    style = "border: 2px solid #008cba; padding: 8px; margin: 0 75px;",
    tags$div(class = "swiper-no-swiping", sliderInput(inputId = "slider1", label = "Slider:", value = 15, min = 10, max = 25)),
    plotOutput("ggplot1", width = "400px", height = "300px"),
    align = "center"
  ),

  div(
    plotOutput("ggplot2", width = "500px", height = "400px"),
    align = "center"
  )

)

您可以删除添加swiper-no-swiping类的JavaScript代码,因为您现在是直接添加它。
更新后的`fluidPage``现在看起来像这样:

ui <- fluidPage(

  tags$head(
    tags$style(HTML(
      ".shiny-plot-output {border: 2px solid royalblue;}"
    ))
  ),

  br(),

  fluidRow(

    column(
      12,
      swipeR(
        wrapper, height = "450px", width = "80%", effect = "cube", speed = 2000,
        navigationColor = "black", rewind = TRUE, id = "CAROUSEL"
      )
    ),

    column(
      12,
      br(), br(), br(),
    ),

    column(
      3, align = "center",
      actionButton(
        "btn1", "Scatter plot", class = "btn-primary",
        onclick = "document.getElementById('CAROUSEL').swiper.slideTo(0);"
      )
    ),

    column(
      3, align = "center",
      actionButton(
        "btn2", "Line chart", class = "btn-primary",
        onclick = "document.getElementById('CAROUSEL').swiper.slideTo(1);"
      )
    )

  )

)

现在,通过将swiper-no-swiping类直接添加到包含滑块的div中,您可以通知Swiper防止在此特定元素上滑动。这应该允许您与滑块交互而不触发滑动事件。

相关问题