javascript - 在 x = 0 时执行 Math.pow(10,x) 时使用 javascript 更改 R Shiny 错误中的 noUIslider 标签

标签 javascript r shiny nouislider

在较早的 SO 问题中 here我已经到了我有一个 noUiSliderInput 的地步,它在 javascript 的帮助下将其标签更新为科学记数法格式。

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

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

#结束更新#

这里使用第二个 sliderInputnumericInput 框来模拟行为,这会导致 noUiSliderInput 所需的所有三个值发生变化

在我的真实 app 中,noUiSliderInput 链接到一个 plot,以及用户选择的任何数据 column 绘图。因此,无论用户选择绘制什么数据,都需要 noUiSliderInput更新它的范围slider 还链接到一个 datatable,它具有先前创建的设置(数据中某些列的阈值数据表),并且当用户单击 datatable 条目,它将更新 选择要绘制的数据的下拉列表(以及 noUiSliderInput range) ,以及阈值 (noUiSliderInput value) 的高度应基于 datatable 中的值。

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

我设法得到一个模拟此行为的虚拟 app,除了 noUiSliderInputvalue 被当前 更新错误code>javascript 似乎。

原理图大概是这样的 enter image description here

你可以看到点击table会发送一个值给noUiSliderInput值,一个参数名给参数selectInput ,然后获取数据,将其发送到 plot,并将最小值、最大值:range 发送到 noUiSliderInput。 它是这样构建的,因为用户还可以直接从 selectInput 中选择参数(columns)(其中许多不在阈值表中)

到目前为止的应用:

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 方法(设置 slider 的值)而不是更新 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 没有用,因为 slider 是由 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/

相关文章:

javascript - 计算数组中字符串的出现次数(javascript)

javascript - 使用 splice 在 Angular JS 中“取消编辑”

javascript - DT 表中的 Shiny 小部件

R data.table - 将单个 ID 的多个组转换为多个列

r - 在 Shiny /rmarkdown 演示文稿中不显示幻灯片编号?

javascript - 无法将映射键图标添加到 Leaflet 中的 L.easyButton

javascript - 使用 JS 创建用户屏幕截图并通过 ajax 问题发送到服务器

r - R中的非阻塞式 socket ?

r - 使用 Shiny 的应用程序创建响应式(Reactive)数据框