Here is how my noUiSlider looks like:
I would like to format the tick labels as: 1000 -> 1K, 900000 -> 900K, 5000000 -> 5M, etc; i.e. abbreviating the number with the appropriate SI symbol.
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
tags$br(),
noUiSliderInput(
inputId = "noui",
label = "Slider vertical:",
value = 50,
orientation = "vertical",
range = list("min" = list(0),
"25%" = list(1000, 500),
"50%" = list(10000, 50000),
"75%" = list(4000000, 500000),
"max" = list(10000000)),
pips = list(
mode = "values",
values = list(0, 500, 1000, 900000, 5000000, 10000000),
density = 4
),
format = wNumbFormat(decimals = 0),
width = "300px", height = "300px"
),
verbatimTextOutput(outputId = "res")
)
server <- function(input, output, session) {
output$res <- renderPrint(input$noui)
}
shinyApp(ui, server)
We need to set the pips
option with JavaScript, to be able to pass a function to the format
suboption:
library(shiny)
library(shinyWidgets)
library(shinyjs)
abbreviateNumber <- '
const SI_SYMBOLS = ["", "k", "M", "G", "T", "P", "E"];
const abbreviateNumber = (number, minDigits, maxDigits) => {
if (number === 0) return number;
// determines SI symbol
const tier = Math.floor(Math.log10(Math.abs(number)) / 3);
// get suffix and determine scale
const suffix = SI_SYMBOLS[tier];
const scale = 10 ** (tier * 3);
// scale the number
const scaled = number / scale;
// format number and add suffix
return scaled.toLocaleString(undefined, {
minimumFractionDigits: minDigits,
maximumFractionDigits: maxDigits,
}) + suffix;
};' # https://stackoverflow.com/a/65324090/1100107
js <- paste(
"var slider = document.getElementById('noui').noUiSlider;",
"slider.pips({",
" mode: 'values',",
" values: [0, 500, 1000, 900000, 5000000, 10000000],",
" density: 4,",
" format: {",
" to: function(x) {return abbreviateNumber(x);}",
" }",
"});",
sep = "\n"
)
ui <- fluidPage(
useShinyjs(),
tags$head(
tags$script(HTML(abbreviateNumber))
),
tags$br(),
noUiSliderInput(
inputId = "noui",
label = "Slider vertical:",
value = 50,
orientation = "vertical",
range = list("min" = list(0),
"25%" = list(1000, 500),
"50%" = list(10000, 50000),
"75%" = list(4000000, 500000),
"max" = list(10000000)),
format = wNumbFormat(decimals = 0),
width = "300px", height = "300px"
),
verbatimTextOutput(outputId = "res")
)
server <- function(input, output, session) {
observeEvent(input$noui, {
runjs(js)
}, once = TRUE)
output$res <- renderPrint(input$noui)
}
shinyApp(ui, server)