代码之家  ›  专栏  ›  技术社区  ›  Mark

使用javascript在执行math.pow(10,x)时更改r shining错误中的nouisider标记,当x=0

  •  0
  • Mark  · 技术社区  · 5 年前

    在之前的问题中 here 我已经到了一个我有 noUiSliderInput 这使得它的标签在 javascript .

    剩下的问题是 名词输入 当输入为0时跳至10,因此应跳至1。(10^0是1,而不是10)。我怀疑数学有问题。原因是Pow(10,x),但我不确定

    更新: 滑块跳到最大值的初始问题已通过更改 JavaScript 代码,它现在从 shiny 作为滑块的最小值、最大值和值的输入。 我已经在问题中更改了应用程序的代码,以表示当前的情况。

    端更新

    在这里用一秒钟来模拟行为。 sliderInput numericInput 使nouisliderinput所需的所有三个值都改变的框

    在我的真实中 app 这个 名词输入 链接到 plot 以及任何数据 column 用户选择 情节 . 因此,无论用户选择绘制什么数据,都需要 名词输入 update 它的 range . 这个 slider 也链接到 datatable 使用先前创建的设置(数据中某些列的阈值数据表),以及当用户单击 可计算的 条目,它将 更新 选择要绘制的数据的下拉列表(因此 名词输入 范围 )以及门槛的高度( 名词输入 value )应该基于 可计算的 .

    一次触发三个变化,范围(即最小和最大 名词输入 )以及 名词输入 .

    我设法弄到一个假人 应用程序 它可以模拟这种行为,除了 价值 名词输入 当前更新错误 JavaScript 似乎是这样。

    示意图大致如下 enter image description here

    在那里你可以看到点击 table 将值发送到 名词输入 值和参数的参数名称 selectInput 然后获取数据,将其发送到 情节 ,并发送最小值,最大值: 范围 名词输入 . 它是这样构建的,因为用户还可以选择参数( columns )来自 选择输入 直接(其中许多不在阈值表中)

    App到目前为止:

    library(shiny)
    library(shinyWidgets)
    library(shinyjs)
    
    js <- function(Min, Max, Start){
      sprintf(paste(
        "var slider = document.getElementById('Histoslider').noUiSlider;",
        "slider.updateOptions({",
        "  start: %s,",
        "  range: {min: %s, max: %s},",
        "  format: wNumb({", 
        "    encoder: function(x){return parseFloat(Math.pow(10,x));}", 
        "  })", 
        "});",
        "var pipsValues = $('.noUi-value');",
        "pipsValues.each(function(){$(this).html('10<sup>'+$(this).attr('data-value')+'</sup>')});",
        sep = "\n"
      ), Start, Min, Max)
    }
    
    ui <- fluidPage(
      useShinyjs(),
      tags$br(),
      fluidRow(
        column(4,
               uiOutput('TestSliderOut'), 
               actionButton(inputId = "UpdateSlider", label = 'Update')
        ),
        column(6, 
               sliderInput("slider2", label = NULL, min = -5, max = 20, value= c(1, 5), step = 1),
               numericInput(inputId = 'SlMin', label = 'Min', value = 1, min = -5, max = 20),
               numericInput(inputId = 'SlMax', label = 'Max', value = 5, min = -5, max = 20),
               numericInput(inputId = 'SlVal', label = 'Val', value = 3, min = -5, max = 20),
               br(),
               h5('Update counter'),
               verbatimTextOutput(outputId = "updates"),
               h5('slider value'),
               verbatimTextOutput(outputId = 'ouputval')
        )
      )
    )
    
    
    
    server <- function(input, output, session) {
    
      values <- reactiveValues( Counter = 0)
    
      output$TestSliderOut <- renderUI({
        noUiSliderInput(
          inputId = "Histoslider", label = "Slider vertical:",
          min = -2, max = 4, step = 0.01,
          value = 0, margin = 100, 
          pips = list(mode="range", density=2),
          orientation = "vertical", 
          width = "300px", height = "300px",   direction = "rtl", 
          behaviour = "tap"
        )
      })
    
      observeEvent(input$slider2, {
        ## simulates the change of multipe parameters of the slider: min, max, value
        newvalue <- (input$slider2[2]-input$slider2[1])/2+input$slider2[1]
        updateNumericInput(session, inputId = 'SlMin', value = input$slider2[1])
        updateNumericInput(session, inputId = 'SlMax', value = input$slider2[2])
        updateNumericInput(session, inputId = 'SlVal', value = newvalue)
    
      })
    
      observe({
        updateNoUiSliderInput(session, inputId = 'Histoslider', range = c(input$SlMin, input$SlMax), value = input$SlVal)
        shinyjs::delay(1, {  ## delay the javascript so that it runs after the slider has updated its values
          runjs(js(input$SlMin, input$SlMax, input$SlVal))     })
      })
    
      output$updates <- renderPrint(values$Counter)
    
    
      output$ouputval <- renderPrint(input$Histoslider)
    
      observeEvent(input$SlMin, { values$nouiMin <- input$SlMin })
      observeEvent(input$SlMax, { values$nouiMax <- input$SlMax })
      observeEvent(input$SlVal, { values$nouiVal <- input$SlVal })
    
      observeEvent(input$Histoslider, {
        print('changing code')
        runjs(js(values$nouiMin, values$nouiMax, values$nouiVal))     ## fires ones on first build of the slider
      }, once = TRUE)
    
    }
    
    shinyApp(ui, server)
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   Stéphane Laurent    5 年前

    嗯,看起来确实很奇怪。它似乎是通过使用 set 方法(设置滑块的值),而不是更新 start 选项:

    js <- function(Min, Max, Start){
      sprintf(paste(
        "var slider = document.getElementById('Histoslider').noUiSlider;",
        "slider.updateOptions({",
        "  range: {min: %s, max: %s},",
        "  format: wNumb({", 
        "    decimals: 2,",
        "    encoder: function(x){return parseFloat(Math.pow(10,x));}", 
        "  })", 
        "});",
        "slider.set(%s);",
        "var pipsValues = $('.noUi-value');",
        "pipsValues.each(function(){$(this).html('10<sup>'+$(this).attr('data-value')+'</sup>')});",
        sep = "\n"
      ), Min, Max, Start)
    }
    

    请注意 updateNoUiSliderInput 在您的代码中是无用的,因为滑块是由JS代码更新的。所以替换

      observe({
        updateNoUiSliderInput(session, inputId = 'Histoslider', range = c(input$SlMin, input$SlMax), value = input$SlVal)
        shinyjs::delay(1, {  ## delay the javascript so that it runs after the slider has updated its values
          runjs(js(input$SlMin, input$SlMax, input$SlVal))     })
      })
    

    具有

      observeEvent(list(input$SlMin, input$SlMax, input$SlVal), {
          runjs(js(input$SlMin, input$SlMax, input$SlVal))     
      }, ignoreInit = TRUE)