javascript - 在 R Shiny 中的垂直 noUiSliderInput 上将标签自定义为指数文本格式

标签 javascript r shiny nouislider

我在我的应用中使用垂直 noUiSliderInput

我想将 noUiSliderInputpips 中定义的标签从常规数字替换为 10^x 的文本字符串,其中x 是原始标签。

slider 具有以下属性(一些背景信息):

  • 它在我的服务器中构建为uiOutput
  • 它是线性的,但紧挨着对数 ggplot。因此,如果我的实际数据范围为 0.1 (10^-1) 到 1000 (10^3)​​,我将 slider 值设置为实际的 “幂数”,例如 -1 到 3 .
  • 这样线性 slider 可以跟随对数图
  • min 和 max 取决于用户从 selectInput 菜单打开的数据文件中的值范围,该菜单加载文件,并为 slider 计算新的 min 和 max,并使其重新呈现.

我知道它最有可能通过 javascript 实现,但到目前为止,我的尝试甚至没有接近任何效果。

我在这里看到这个例子是用一个普通的 slider 来用文字替换标签,但是把 10 改为上标的幂是另一回事,到目前为止我还不能用这个例子来定位 noUislider。 SO question

Current look

Desired look

服务器文件

server <- function(input, output, session) {
  values <- reactiveValues( 
    minimum = 1
  )

  observeEvent(input$Button1, { 
    values$minimum <- sample(1:5, 1)
  })

  observe({ values$maximum <- values$minimum + 5})

  output$sliderout <- renderUI({ 
    noUiSliderInput(
      inputId = "YOUR_SLIDER_ID", 
      label = "Slider vertical:",
      min = values$minimum, 
      max = values$maximum,
      step = 0.1,
      value = values$minimum,
      orientation = "vertical",
      pips = list(
        mode = "range",
        density = 10
      ),
      width = "100px", height = "300px"
    )})
  output$res2 <- renderPrint(input$noui2)
}

界面文件

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
 # includeScript("slider.js"), ## line to open file with javascript

  tags$br(),
  div(class = 'myslider', uiOutput('sliderout')),
  actionButton(inputId = 'Button1', label = 'Change slider'),
  verbatimTextOutput(outputId = "res2")
)

最佳答案

这就是我设法实现的目标。只有一个问题:1000 呈现为 1000.000000000002。我不知道该如何处理。

library(shiny)
library(shinyWidgets)
library(shinyjs)

js <- paste(
  "var slider = document.getElementById('noui').noUiSlider;",
  "slider.updateOptions({", 
  "  format: wNumb({", 
  "    encoder: function(x){return Math.pow(10,x);}", 
  "  })", 
  "});",
  "slider.pips({",
  "  mode: 'range',", 
  "  density: 2,", 
  "  format: {", 
  "    to: function(x){return '10^' + x;}",
  "  }",
  "});",
  sep = "\n"
)

ui <- fluidPage(
  useShinyjs(),
  tags$br(),

  noUiSliderInput(
    inputId = "noui", label = "Slider vertical:",
    min = -2, max = 4, step = 1,
    value = 0, margin = 100,
    orientation = "vertical", 
    width = "300px", height = "300px"
  ),

  verbatimTextOutput(outputId = "res")

)

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

  output$res <- renderPrint(input$noui)

  observeEvent(input$noui, {
    runjs(js)
  }, once = TRUE)

}

shinyApp(ui, server)

enter image description here

编辑

我还没有找到如何借助 format 选项获取 HTML 点值。这是使用上标获取 10^x 的方法:

var pipsValues = $('.noUi-value');
pipsValues.each(function(){$(this).html('10<sup>'+$(this).attr('data-value')+'</sup>')});

即完整的JS代码为:

js <- paste(
  "var slider = document.getElementById('noui').noUiSlider;",
  "slider.updateOptions({", 
  "  format: wNumb({", 
  "    encoder: function(x){return parseFloat(Math.pow(10,x).toPrecision(2));}", 
  "  })", 
  "});",
  "slider.pips({",
  "  mode: 'range',", 
  "  density: 2", 
  "});",
  "var pipsValues = $('.noUi-value');",
  "pipsValues.each(function(){$(this).html('10<sup>'+$(this).attr('data-value')+'</sup>')});",
  sep = "\n"
)

编辑 2

这是一个处理 minmaxvalue 是 react 值的情况的应用程序。这个想法是为了避免 renderUI:应用程序从一个初始 slider 开始,这三个值在 updateOptions 方法的帮助下由 Javascript 更新。

library(shiny)
library(shinyWidgets)
library(shinyjs)

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

ui <- fluidPage(
  useShinyjs(),

  actionButton("btn", "Sample"),

  tags$br(),

  noUiSliderInput(
    inputId = "noui", label = "Slider vertical:",
    min = -2, max = 4, step = 1,
    value = 0, margin = 100, 
    pips = list(mode="range", density=2),
    orientation = "vertical", 
    width = "300px", height = "300px", 
    behaviour = "tap"
  ),

  verbatimTextOutput(outputId = "res")

)

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

  Values <- eventReactive(input$btn, {
    Min <- sample(-5:5, 1)
    Max <- Min + 6
    Start <- sample(Min:Max, 1)
    list(min = Min, max = Max, start = Start)
  }, ignoreNULL = FALSE)

  observe({
    if(!is.null(input$noui)){
      values <- Values()
      runjs(js(values$min,values$max,values$start))
    }
  })

  output$res <- renderPrint(input$noui)

}

shinyApp(ui, server)

enter image description here

关于javascript - 在 R Shiny 中的垂直 noUiSliderInput 上将标签自定义为指数文本格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54556304/

相关文章:

javascript - selectizeInput 带有图像/图标

javascript - R Shiny + plotly : change color of a trace with javascript without affecting markers and legend in multiple plots

javascript - 实体仪表图表在页面/容器调整大小时丢失系列渲染 [ng-highcharts + Angular ]

javascript - 关于NodeJS缓冲区

javascript - 根据子元素的值更改父元素的 CSS

javascript - 动画显示谷歌地图和谷歌街景的路线

r - 如何在 ggplot() 内的交互(...)参数中混合非标准和标准评估?

r - 在 [R] 中绘制类(预测)的时间序列列表

唯一值上的 R ifelse 循环总是解析为 FALSE

r - 如何将 Material 切换与shinydashboard一起使用[R]