在 R Shiny 中的垂直 noUiSliderInput 上将标签自定义为指数文本格式
Customize labels to an exponential text format on a vertical noUiSliderInput in R Shiny
我在我的应用程序中使用垂直 noUiSliderInput
我想将 noUiSliderInput
的 pips
中定义的标签从常规数字替换为 10^x
的文本字符串,其中 x 是原始标签。
滑块具有以下属性(一些背景信息):
- 在我的
server
中构建为 uiOutput
- 它是线性的,但仅次于对数
ggplot
。因此,如果我的实际数据范围为 0.1(10^-1 ) 到 1000 (10^3).
- 这样线性滑块可以跟随对数图
- min 和 max 取决于用户从
selectInput
菜单打开的数据文件中的值范围,该菜单加载文件,计算滑块的新最小值和最大值,并使其重新呈现。
我知道它最有可能通过 javascript 实现,但到目前为止我的尝试甚至没有接近任何效果。
我在这里看到了这个示例,用于将常规滑块替换为文字标签,但将上标的幂更改为 10 是另一回事,到目前为止,我无法通过该示例定位 noUislider。
服务器文件
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)
}
UI 文件
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)
编辑
我还没有找到如何在 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
这是一个处理 min
、max
和 value
是反应值的情况的应用程序。这个想法是为了避免 renderUI
:应用程序以初始滑块开始,这三个值在 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)
我在我的应用程序中使用垂直 noUiSliderInput
我想将 noUiSliderInput
的 pips
中定义的标签从常规数字替换为 10^x
的文本字符串,其中 x 是原始标签。
滑块具有以下属性(一些背景信息):
- 在我的
server
中构建为 - 它是线性的,但仅次于对数
ggplot
。因此,如果我的实际数据范围为 0.1(10^-1 ) 到 1000 (10^3). - 这样线性滑块可以跟随对数图
- min 和 max 取决于用户从
selectInput
菜单打开的数据文件中的值范围,该菜单加载文件,计算滑块的新最小值和最大值,并使其重新呈现。
uiOutput
我知道它最有可能通过 javascript 实现,但到目前为止我的尝试甚至没有接近任何效果。
我在这里看到了这个示例,用于将常规滑块替换为文字标签,但将上标的幂更改为 10 是另一回事,到目前为止,我无法通过该示例定位 noUislider。
服务器文件
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)
}
UI 文件
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)
编辑
我还没有找到如何在 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
这是一个处理 min
、max
和 value
是反应值的情况的应用程序。这个想法是为了避免 renderUI
:应用程序以初始滑块开始,这三个值在 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)