Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x 94x | import { d3Format } from "./Util"
 
export interface TickFormattingOptions {
    numDecimalPlaces?: number
    unit?: string
    noTrailingZeroes?: boolean
    noSpaceUnit?: boolean
    numberPrefixes?: boolean
    shortNumberPrefixes?: boolean
    showPlus?: boolean
}
 
// todo: Should this be numberSuffixes instead of Prefixes?
// todo: we should have unit tests for this one. lot's of great features but hard to see how to use all of them.
export function formatValue(
    value: number,
    options: TickFormattingOptions
): string {
    const noTrailingZeroes = options.noTrailingZeroes ?? true
    const numberPrefixes =
        (options.numberPrefixes || options.shortNumberPrefixes) ?? true
 
    const shortNumberPrefixes = options.shortNumberPrefixes ?? false
    const showPlus = options.showPlus ?? false
    const numDecimalPlaces = options.numDecimalPlaces ?? 2
    const unit = options.unit ?? ""
    const isNoSpaceUnit = options.noSpaceUnit ?? unit[0] === "%"
 
    let output: string = value.toString()
 
    const absValue = Math.abs(value)
    if (!isNoSpaceUnit && numberPrefixes && absValue >= 1e6) {
        if (!isFinite(absValue)) output = "Infinity"
        else if (absValue >= 1e12)
            output = formatValue(value / 1e12, {
                ...options,
                unit: shortNumberPrefixes ? "T" : "trillion",
                noSpaceUnit: shortNumberPrefixes,
                numDecimalPlaces: 2,
            })
        else if (absValue >= 1e9)
            output = formatValue(value / 1e9, {
                ...options,
                unit: shortNumberPrefixes ? "B" : "billion",
                noSpaceUnit: shortNumberPrefixes,
                numDecimalPlaces: 2,
            })
        else if (absValue >= 1e6)
            output = formatValue(value / 1e6, {
                ...options,
                unit: shortNumberPrefixes ? "M" : "million",
                noSpaceUnit: shortNumberPrefixes,
                numDecimalPlaces: 2,
            })
    } else if (!isNoSpaceUnit && shortNumberPrefixes && absValue >= 1e3) {
        output = formatValue(value / 1e3, {
            ...options,
            unit: "k",
            noSpaceUnit: true,
            numDecimalPlaces: 2,
        })
    } else {
        const targetDigits = Math.pow(10, -numDecimalPlaces)
 
        if (value !== 0 && Math.abs(value) < targetDigits) {
            if (value < 0) output = `>-${targetDigits}`
            else output = `<${targetDigits}`
        } else
            output = d3Format(`${showPlus ? "+" : ""},.${numDecimalPlaces}f`)(
                value
            )
 
        if (noTrailingZeroes) {
            // Convert e.g. 2.200 to 2.2
            const m = output.match(/(.*?[0-9,-]+.[0-9,]*?)0*$/)
            if (m) output = m[1]
            if (output[output.length - 1] === ".")
                output = output.slice(0, output.length - 1)
        }
    }
 
    if (unit === "$" || unit === "£") output = unit + output
    else if (isNoSpaceUnit) output = output + unit
    else if (unit.length > 0) output = output + " " + unit
 
    return output
}
  |