or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-d3-format

Format numbers for human consumption with extensive localization support and Python-style format specification syntax

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/d3-format@3.1.x

To install, run

npx @tessl/cli install tessl/npm-d3-format@3.1.0

index.mddocs/

d3-format

d3-format is a comprehensive JavaScript library for formatting numbers for human consumption, modeled after Python 3's format specification mini-language. It provides sophisticated number formatting capabilities including fixed-point notation, scientific notation, percentage formatting, currency formatting, localization support, and SI prefix formatting.

Package Information

  • Package Name: d3-format
  • Package Type: npm
  • Language: JavaScript (ES modules)
  • Installation: npm install d3-format

Core Imports

import { format, formatPrefix, formatLocale, formatDefaultLocale, formatSpecifier, FormatSpecifier, precisionFixed, precisionPrefix, precisionRound } from "d3-format";

For CommonJS:

const { format, formatPrefix, formatLocale, formatDefaultLocale, formatSpecifier, FormatSpecifier, precisionFixed, precisionPrefix, precisionRound } = require("d3-format");

Basic Usage

import { format, formatPrefix } from "d3-format";

// Create formatters using format specification strings
const percentage = format(".0%");  // percentage with no decimal places
const currency = format("$,.2f");  // currency with thousands separator
const scientific = format(".2e");  // scientific notation
const rounded = format(".3r");     // rounded to 3 significant digits
const siPrefix = format(".2s");    // SI prefix notation

// Format numbers
console.log(percentage(0.123));     // "12%"
console.log(currency(1234.56));     // "$1,234.56"
console.log(scientific(12345));     // "1.23e+4"
console.log(rounded(1234.56789));   // "1,230"
console.log(siPrefix(42e6));        // "42M"

// Format with consistent SI prefix
const prefixFormatter = formatPrefix(",.0", 1e-6);
console.log(prefixFormatter(0.00042));  // "420µ"
console.log(prefixFormatter(0.0042));   // "4,200µ"

Architecture

d3-format is built around several key components:

  • Format Specification: Python-style mini-language for defining number formats ([fill]align][sign][symbol][0][width][,][.precision][~][type])
  • Locale System: Internationalization support with 59+ built-in locales for different regions and currencies
  • Precision Utilities: Helper functions for calculating appropriate precision based on data characteristics
  • SI Prefix Support: Automatic scaling and labeling with metric prefixes (y, z, a, f, p, n, µ, m, k, M, G, T, P, E, Z, Y)

Capabilities

Number Formatting

Core formatting functionality that converts numbers to formatted strings based on format specifications.

/**
 * Creates a number formatter function using the default locale
 * @param specifier - Format specification string
 * @returns Function that formats numbers to strings
 */
function format(specifier: string): (value: number) => string;

/**
 * Creates a prefix formatter with consistent SI scaling
 * @param specifier - Format specification string
 * @param value - Reference value for determining SI prefix
 * @returns Function that formats numbers with consistent prefix
 */
function formatPrefix(specifier: string, value: number): (value: number) => string;

Format Specification Syntax: [fill][align][sign][symbol][0][width][,][.precision][~][type]

  • fill: Any character for padding (default: space)
  • align: < (left), > (right, default), ^ (center), = (sign-aware)
  • sign: - (default), + (always), ( (parentheses for negative), (space)
  • symbol: $ (currency), # (prefix for binary/octal/hex)
  • 0: Enable zero-padding
  • width: Minimum field width
  • ,: Enable grouping separator
  • precision: .n decimal places or significant digits
  • ~: Trim trailing zeros
  • type: Format type (see below)

Format Types:

  • e - Scientific notation (1.23e+4)
  • f - Fixed-point notation (1234.56)
  • g - General format (decimal or scientific)
  • r - Rounded decimal notation
  • s - SI-prefix notation (42M, 1.5k)
  • % - Percentage (multiply by 100)
  • p - Percentage with significant digits
  • b - Binary integer
  • o - Octal integer
  • d - Decimal integer
  • x - Lowercase hexadecimal
  • X - Uppercase hexadecimal
  • c - Character data
  • n - Shorthand for ,g
  • `` (empty) - Shorthand for ~g

Locale Management

Internationalization system for number formatting with regional conventions.

/**
 * Creates a locale object for custom formatting rules
 * @param definition - Locale definition with decimal, thousands, grouping, currency, etc.
 * @returns Locale object with format and formatPrefix methods
 */
function formatLocale(definition: LocaleDefinition): Locale;

/**
 * Sets the default locale and updates global format/formatPrefix functions
 * @param definition - Locale definition object
 * @returns Locale object
 */
function formatDefaultLocale(definition: LocaleDefinition): Locale;

interface LocaleDefinition {
  /** Decimal point character (e.g., ".") */
  decimal: string;
  /** Group separator character (e.g., ",") */
  thousands: string;
  /** Array of group sizes (e.g., [3] for thousands) */
  grouping: number[];
  /** Currency prefix and suffix (e.g., ["$", ""]) */
  currency: [string, string];
  /** Optional: array of 10 strings to replace numerals 0-9 */
  numerals?: string[];
  /** Optional: percent symbol (default "%") */
  percent?: string;
  /** Optional: minus sign (default "−") */
  minus?: string;
  /** Optional: not-a-number representation (default "NaN") */
  nan?: string;
}

interface Locale {
  /** Creates formatter using this locale's rules */
  format(specifier: string): (value: number) => string;
  /** Creates prefix formatter using this locale's rules */
  formatPrefix(specifier: string, value: number): (value: number) => string;
}

Format Specifier Parsing

Tools for parsing and constructing format specification strings.

/**
 * Parses a format specifier string into its components
 * @param specifier - Format specification string
 * @returns FormatSpecifier object with exposed fields
 * @throws Error for invalid format specifiers
 */
function formatSpecifier(specifier: string): FormatSpecifier;

/**
 * Creates a format specifier object from properties
 * @param specifier - Object with format specification properties
 */
class FormatSpecifier {
  constructor(specifier: {
    fill?: string;
    align?: string;
    sign?: string;
    symbol?: string;
    zero?: boolean;
    width?: number;
    comma?: boolean;
    precision?: number;
    trim?: boolean;
    type?: string;
  });
  
  /** Fill character for padding (default " ") */
  fill: string;
  /** Alignment: "<", ">", "^", "=" (default ">") */
  align: string;
  /** Sign: "-", "+", "(", " " (default "-") */
  sign: string;
  /** Symbol: "", "$", "#" (default "") */
  symbol: string;
  /** Zero-padding enabled (default false) */
  zero: boolean;
  /** Minimum field width (default undefined) */
  width: number | undefined;
  /** Comma grouping enabled (default false) */
  comma: boolean;
  /** Precision value (default undefined) */
  precision: number | undefined;
  /** Trim trailing zeros (default false) */
  trim: boolean;
  /** Format type: "e", "f", "g", etc. (default "") */
  type: string;
  
  /** Reconstructs the format specifier string */
  toString(): string;
}

Precision Utilities

Helper functions for calculating appropriate precision based on data characteristics.

/**
 * Calculates decimal precision for fixed-point notation
 * @param step - Minimum absolute difference between values
 * @returns Number of decimal places needed
 */
function precisionFixed(step: number): number;

/**
 * Calculates precision for SI-prefix formatting
 * @param step - Minimum absolute difference between values
 * @param value - Reference value for determining SI prefix
 * @returns Number of decimal places needed
 */
function precisionPrefix(step: number, value: number): number;

/**
 * Calculates precision for significant digit formatting
 * @param step - Minimum absolute difference between values
 * @param max - Largest absolute value to be formatted
 * @returns Number of significant digits needed
 */
function precisionRound(step: number, max: number): number;

Usage Examples

Advanced Formatting

import { format } from "d3-format";

// Custom alignment and padding
const rightPadded = format(">20");    // Right-aligned, min width 20
const leftPadded = format("<20");     // Left-aligned, min width 20
const centered = format("^20");       // Centered, min width 20
const zeroPadded = format("020");     // Zero-padded, width 20

console.log(rightPadded(42));         // "                  42"
console.log(leftPadded(42));          // "42                  "
console.log(centered(42));            // "         42         "
console.log(zeroPadded(42));          // "00000000000000000042"

// Sign control
const alwaysSign = format("+");       // Always show sign
const parentheses = format("(");      // Parentheses for negative
const spaceSign = format(" ");        // Space for positive

console.log(alwaysSign(42));          // "+42"
console.log(alwaysSign(-42));         // "-42"
console.log(parentheses(-42));        // "(42)"
console.log(spaceSign(42));           // " 42"

// Hexadecimal with prefix
const hex = format("#x");             // Prefixed lowercase hex
const HEX = format("#X");             // Prefixed uppercase hex

console.log(hex(255));                // "0xff"
console.log(HEX(255));                // "0XFF"

Working with Locales

import { formatLocale, formatDefaultLocale } from "d3-format";

// Create custom locale
const frenchLocale = formatLocale({
  decimal: ",",
  thousands: " ",
  grouping: [3],
  currency: ["", " €"],
  percent: " %"
});

const frFormat = frenchLocale.format("$,.2f");
console.log(frFormat(1234.56));       // "1 234,56 €"

// Set as default locale
formatDefaultLocale({
  decimal: ",",
  thousands: ".",
  grouping: [3],
  currency: ["R$ ", ""]
});

// Global format now uses new locale
const globalFormat = format("$,.2f");
console.log(globalFormat(1234.56));   // "R$ 1.234,56"

Precision Calculation

import { format, precisionFixed, precisionPrefix, precisionRound } from "d3-format";

// Calculate appropriate precision for fixed-point formatting
const data = [1.0, 1.5, 2.0];
const step = 0.5;
const fixedPrecision = precisionFixed(step);
const fixedFormat = format(`.${fixedPrecision}f`);

data.forEach(d => console.log(fixedFormat(d)));
// "1.0", "1.5", "2.0"

// Calculate precision for SI-prefix formatting
const values = [1.1e6, 1.2e6, 1.3e6];
const prefixStep = 1e5;
const prefixPrecision = precisionPrefix(prefixStep, 1.3e6);
const prefixFormat = formatPrefix(`.${prefixPrecision}`, 1.3e6);

values.forEach(v => console.log(prefixFormat(v)));
// "1.1M", "1.2M", "1.3M"

// Calculate precision for significant digit formatting
const roundStep = 0.01;
const maxValue = 1.01;
const roundPrecision = precisionRound(roundStep, maxValue);
const roundFormat = format(`.${roundPrecision}r`);

[0.99, 1.0, 1.01].forEach(v => console.log(roundFormat(v)));
// "0.990", "1.00", "1.01"

Working with Format Specifiers

import { formatSpecifier, FormatSpecifier, format } from "d3-format";

// Parse existing specifier
const spec = formatSpecifier("$,.2f");
console.log(spec.symbol);             // "$"
console.log(spec.comma);              // true
console.log(spec.precision);          // 2
console.log(spec.type);               // "f"

// Modify and create new format
spec.precision = 0;
const newFormat = format(spec.toString());
console.log(newFormat(1234.56));      // "$1,235"

// Create specifier from scratch
const customSpec = new FormatSpecifier({
  align: "^",
  width: 10,
  type: "s",
  precision: 1
});

const customFormat = format(customSpec.toString());
console.log(customFormat(42000));     // "   42k   "

SI Prefixes

The library supports full SI prefix notation with the following prefixes:

PrefixSymbolFactorName
yy10⁻²⁴yocto
zz10⁻²¹zepto
aa10⁻¹⁸atto
ff10⁻¹⁵femto
pp10⁻¹²pico
nn10⁻⁹nano
µµ10⁻⁶micro
mm10⁻³milli
10⁰
kk10³kilo
MM10⁶mega
GG10⁹giga
TT10¹²tera
PP10¹⁵peta
EE10¹⁸exa
ZZ10²¹zetta
YY10²⁴yotta

Error Handling

  • formatSpecifier() throws an Error for invalid format specification strings
  • Invalid format types default to "g" with precision 12 and trim enabled
  • NaN values are formatted using the locale's nan property (default "NaN")
  • Infinite values are formatted as "Infinity" or "-Infinity"