如何使用 SI 符号格式化 noUiSlider 的刻度标签?

Sté*_*ent 6 javascript r shiny nouislider shinywidgets

这是我的 noUiSlider 的样子:

在此输入图像描述

我想将刻度标签格式化为:1000 -> 1K、900000 -> 900K、5000000 -> 5M 等;即用适当的 SI 符号缩写数字。

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)
Run Code Online (Sandbox Code Playgroud)

Sté*_*ent 4

我们需要pips使用 JavaScript 设置选项,以便能够将函数传递给子format选项:

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述