在前面的SO问题here中,我谈到了一个noUiSliderInput,该标签在javascript的帮助下将其标签更新为科学记数格式。

剩下的问题是,当输入为0时noUiSliderInput会跳到10,因此它应该跳到1。(10 ^ 0是1,而不是10)。我怀疑Math.pow(10,x)出了问题,但我不确定

更新:
通过更改javascript代码已解决了滑块跳到最大值的最初问题,该代码现在将shiny中的值用作滑块的最小值,最大值和值的输入。
我已在问题中更改了应用程序的代码以表示当前情况。

#END更新#

在此使用第二个sliderInputnumericInput框模拟行为,这会导致noUiSliderInput所需的所有三个值都被改变

在我真正的app中,noUiSliderInput链接到plot,并且用户选择将任何数据column链接到plot。因此,无论用户选择绘制什么数据,都需要noUiSliderInputupdate它是rangeslider也链接到具有较早创建的设置(数据中某些列的阈值的数据表)的datatable,并且当用户单击datatable条目时,它会在update下拉列表中向下选择将要绘制的数据(以及noUiSliderInput range),以及阈值(noUiSliderInput value)应基于datatable中的值的高度。

这会立即触发三个变化,即范围(即noUiSliderInput的最小值和最大值)以及noUiSliderInput的值。

我设法得到了一个模拟该行为的伪app,除了valuenoUiSliderInput似乎被当前的javascript更新了错误。

示意图大致如下
javascript - 当x = 0时执行Math.pow(10,x)时,使用JavaScript更改R Shiny错误中的noUIslider标签-LMLPHP

在这里,您可以看到单击table将发送一个值到noUiSliderInput值,以及一个参数名给参数selectInput,然后该参数名将获取数据,将其发送到plot,然后将其发送给最小,最大:rangenoUiSliderInput
之所以这样构建,是因为用户还可以直接从columns中选择参数(selectInput)(其中许多不在阈值表中)

到目前为止的应用程式:

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)

最佳答案

嗯,看起来确实很奇怪。似乎可以通过使用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)

关于javascript - 当x = 0时执行Math.pow(10,x)时,使用JavaScript更改R Shiny错误中的noUIslider标签,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54618717/

10-12 17:58