在前面的SO问题here中,我谈到了一个noUiSliderInput
,该标签在javascript
的帮助下将其标签更新为科学记数格式。
剩下的问题是,当输入为0时noUiSliderInput
会跳到10,因此它应该跳到1。(10 ^ 0是1,而不是10)。我怀疑Math.pow(10,x)出了问题,但我不确定
更新:
通过更改javascript
代码已解决了滑块跳到最大值的最初问题,该代码现在将shiny
中的值用作滑块的最小值,最大值和值的输入。
我已在问题中更改了应用程序的代码以表示当前情况。
#END更新#
在此使用第二个sliderInput
和numericInput
框模拟行为,这会导致noUiSliderInput所需的所有三个值都被改变
在我真正的app
中,noUiSliderInput
链接到plot
,并且用户选择将任何数据column
链接到plot
。因此,无论用户选择绘制什么数据,都需要noUiSliderInput
到update
它是range
。 slider
也链接到具有较早创建的设置(数据中某些列的阈值的数据表)的datatable
,并且当用户单击datatable
条目时,它会在update
下拉列表中向下选择将要绘制的数据(以及noUiSliderInput
range
),以及阈值(noUiSliderInput
value
)应基于datatable
中的值的高度。
这会立即触发三个变化,即范围(即noUiSliderInput
的最小值和最大值)以及noUiSliderInput
的值。
我设法得到了一个模拟该行为的伪app
,除了value
的noUiSliderInput
似乎被当前的javascript
更新了错误。
示意图大致如下
在这里,您可以看到单击table
将发送一个值到noUiSliderInput
值,以及一个参数名给参数selectInput
,然后该参数名将获取数据,将其发送到plot
,然后将其发送给最小,最大:range
至noUiSliderInput
。
之所以这样构建,是因为用户还可以直接从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/