滑块跳过值:使用文本框作为替代?

时间:2016-08-24 12:28:59

标签: r shiny

我对Shiny很新。

请考虑以下事项:

ui.R

library(shiny)
shinyUI(fluidPage(

  titlePanel("The Linear Equation y = 0.1x"),

  # Sidebar with a slider input for number of bins
  sidebarLayout(
    sidebarPanel(
      sliderInput("x",
                  "X-value:",
                  min = 0,
                  max = 100,
                  value = 0,
                  step = 0.1)
    ),

    # Show a plot of the generated distribution
    mainPanel(
      plotOutput("linPlot")
    )
  )
))

server.R

library(shiny)
library(ggplot2)

shinyServer(function(input, output, session) {

  f <- function(x){
    0.1*x
  }


  output$linPlot <- renderPlot({

    point_f <- data.frame(x = input$x, 
                        y = f(input$x))

    ggplot(NULL, aes(x = x)) + 
      stat_function(data = data.frame(x = c(0, 100)), 
                    fun = f, geom = 'line', col = 'blue') +
      geom_point(data = point_f, aes(x = x, y = y),
                 size = 4, col = 'blue') 

  })

  session$onSessionEnded(function() { stopApp() })

})

enter image description here

我遇到的主要问题是滑块不允许选择EACH 0.1。也就是说,当用户使用滑块时,跳过各种值。我希望这个应用程序的用户想要选择一个特定的十分作为一个值,并且滑块无法选择精确的十分之一的事实对我来说是不可接受的。

我认为这不是使用滑块的任何选项的可解决问题,所以我还想在侧边栏面板中添加一个文本框,其中包含以下内容:

  • 文本框中的值可以用作输入来执行滑块的操作(因此滑块和文本输入中的值input$x应该相同)。
  • 当滑块移动时,文本框会更改其值以匹配滑块的值。
  • 随着文本框值的更改,滑块会移动以匹配文本框的值。
  • 区间[0,100]之外的值对于文本框是不可接受的,理想情况下会吐出错误。
  • 文本框的输入必须是数字,并且格式为ab.c,其中a,b和c中的每一个都是一位数字。

理想情况下,如果滑块可以单独处理这个问题,那就太好了,但我没有找到任何暗示它可以的东西。

我知道这涉及textInput,但我不确定如何超越这一步。

1 个答案:

答案 0 :(得分:0)

如果我理解你,你需要观察并更新如下:

library(shiny)

ui=shinyUI(fluidPage(

  titlePanel("The Linear Equation y = 0.1x"),

  # Sidebar with a slider input for number of bins
  sidebarLayout(
    sidebarPanel(
      sliderInput("x",
                  "X-value:",
                  min = 0,
                  max = 100,
                  value = 0,
                  step = 0.1),
      numericInput("x_txt","X-value:",min = 0,
                   max = 100,
                   value = 0,
                   step = 0.1)
    ),

    # Show a plot of the generated distribution
    mainPanel(
      plotOutput("linPlot")
    )
  )
))

library(shiny)
library(ggplot2)

server=shinyServer(function(input, output, session) {

  f <- function(x){
    0.1*x
  }
  observeEvent(input$x,{
    if(input$x!=input$x_txt){
    updateNumericInput(session,"x_txt",value = input$x)
    }
  })

  observeEvent(input$x_txt,{
    if( is.numeric(input$x_txt) & input$x_txt>=0 & input$x_txt<=100){


    if(input$x!=input$x_txt){
    updateNumericInput(session,"x",value = input$x_txt)
    }}else{
      updateNumericInput(session,"x_txt",value = input$x)
    }
  })

  point_x=reactive({

  })


  output$linPlot <- renderPlot({

    point_f <- data.frame(x = input$x, 
                          y = f(input$x))

    ggplot(NULL, aes(x = x)) + 
      stat_function(data = data.frame(x = c(0, 100)), 
                    fun = f, geom = 'line', col = 'blue') +
      geom_point(data = point_f, aes(x = x, y = y),
                 size = 4, col = 'blue') 

  })

  session$onSessionEnded(function() { stopApp() })

})

shinyApp(ui,server)