# charts.format The text on a chart: tick labels for numbers, dates and money, SI-prefixed values for compact labels, and percentages. A group, because each is one way of labelling an axis and `charts.axis` picks between them. Every number goes through `text.format-decimal`, so there is never an exponent (`1e-7`), never binary noise (`0.30000000000000004`) and never `-0`, and all three languages print the same text. Rounding is half away from zero on the exact double (`math.round-float`). The minus sign is the ASCII hyphen, not d3-format's U+2212. - **formatTick(value, step)** uses the fewest decimal places (0 to 12) that write the tick *step* exactly, so every label on an axis has the same number of places: with a step of 0.5 the ticks read `0.0`, `0.5`, `1.0` (d3's `precisionFixed`). Thousands are grouped with commas: `1,000`. A step of 0, as for a single tick, uses the places the value needs. A step that no 12-place decimal writes exactly (a third) gets 12 places. - **formatSi(value, significant)** writes the value with an SI prefix and that many significant digits, then drops trailing zeros: 1200 is `1.2k`, 3,400,000 is `3.4M`, 1000 is `1k`, 0.0015 is `1.5m`, 0.5 is `500m`. Prefixes run from y (1e-24) to Y (1e24), with µ (U+00B5) for micro, as d3-format writes them. The prefix is chosen from the exponent, found by comparing against exact powers of ten, not `log10`; a value that rounds up across a prefix boundary moves to the next prefix (999.96 to 3 digits is `1k`, not `1000`). With fewer significant digits than the whole part has, the value rounds to tens or hundreds (12 to 1 digit is `10`). "G" is giga, as SI says; finance's "B" for billions is not used. - **formatPercent(value, decimals)** takes a fraction (0.123 is 12.3%) and keeps fixed places: `50.00%`. Multiplying by 100 adds binary noise (0.145 x 100 is 14.499999999999998), so the product is cleaned at 12 decimal places before being rounded to the places asked for: 0.145 is `15%`, which is what anyone reading 0.145 expects, where rounding the raw product says 14%. No thousands grouping. - **formatDate(iso, label)** labels a date for the tick interval it stands for: day and week ticks `23 Sep` (no leading zero), month `Sep 2026`, quarter `Q3 2026` (calendar quarters), year `2026`. English abbreviations and no locale lookup, so every language agrees. The date is checked strictly by `dates.add-days`. - **formatMoneyTick(minor, currency)** labels a tick on an axis whose data are integer minor units. A tick can fall between them, so it is rounded half away from zero to a whole minor unit and printed by `money.format` with the currency's own digits and symbol: 50000 GBP is `£500.00`, 1500 JPY is `¥1,500`. Sources: d3-format (Mike Bostock), `precisionFixed` and the `s` type (https://github.com/d3/d3-format); BIPM, The International System of Units (SI), 9th edition, 2019, table 7 (prefixes).