diff --git a/docs/features/formats.md b/docs/features/formats.md index 8455dd5902..36d65d0bfc 100644 --- a/docs/features/formats.md +++ b/docs/features/formats.md @@ -9,6 +9,14 @@ import * as d3 from "d3"; These helper functions are provided for convenience as a **tickFormat** option for the [axis mark](../marks/axis.md), as the **text** option for a [text mark](../marks/text.md), or other use. See also [d3-format](https://d3js.org/d3-format), [d3-time-format](https://d3js.org/d3-time-format), and JavaScript’s built-in [date formatting](https://observablehq.com/@mbostock/date-formatting) and [number formatting](https://observablehq.com/@mbostock/number-formatting). +## formatNumber(*locale*) {#formatNumber} + +```js +Plot.formatNumber("en-US")(Math.PI) // "3.142" +``` + +Returns a function that formats a given number according to the specified *locale*. The *locale* is a [BCP 47 language tag](https://tools.ietf.org/html/bcp47) and defaults to U.S. English. + ## formatIsoDate(*date*) {#formatIsoDate} ```js diff --git a/src/format.d.ts b/src/format.d.ts index 160041cd36..c073bfa07b 100644 --- a/src/format.d.ts +++ b/src/format.d.ts @@ -1,3 +1,13 @@ +/** + * Returns a function that formats a given number according to the specified + * *locale*. + * + * [1]: https://tools.ietf.org/html/bcp47 + * + * @param locale - a [BCP 47 language tag][1]; defaults to U.S. English. + */ +export function formatNumber(locale?: string): (i: number) => string; + /** * Returns a function that formats a given month number (from 0 = January to 11 * = December) according to the specified *locale* and *format*. diff --git a/src/index.js b/src/index.js index 9d8c162260..c3a87668ae 100644 --- a/src/index.js +++ b/src/index.js @@ -53,6 +53,6 @@ export {select, selectFirst, selectLast, selectMaxX, selectMaxY, selectMinX, sel export {stackX, stackX1, stackX2, stackY, stackY1, stackY2} from "./transforms/stack.js"; export {treeNode, treeLink} from "./transforms/tree.js"; export {pointer, pointerX, pointerY} from "./interactions/pointer.js"; -export {formatIsoDate, formatWeekday, formatMonth} from "./format.js"; +export {formatIsoDate, formatNumber, formatWeekday, formatMonth} from "./format.js"; export {scale} from "./scales.js"; export {legend} from "./legends.js"; diff --git a/src/marks/axis.js b/src/marks/axis.js index a36f1f6aa3..406ff70dd5 100644 --- a/src/marks/axis.js +++ b/src/marks/axis.js @@ -652,7 +652,7 @@ function inferTextChannel(scale, data, ticks, tickFormat, anchor) { // possible, or the default ISO format (2014-01-26). TODO We need a better way // to infer whether the ordinal scale is UTC or local time. export function inferTickFormat(scale, data, ticks, tickFormat, anchor) { - return typeof tickFormat === "function" + return typeof tickFormat === "function" && !(scale.type === "log" && scale.tickFormat) ? tickFormat : tickFormat === undefined && data && isTemporal(data) ? inferTimeFormat(scale.type, data, anchor) ?? formatDefault diff --git a/test/output/logTickFormatFunction.svg b/test/output/logTickFormatFunction.svg new file mode 100644 index 0000000000..f8e3c26905 --- /dev/null +++ b/test/output/logTickFormatFunction.svg @@ -0,0 +1,82 @@ + + + + + 1 + 2 + + + + + + + + 10 + 20 + + + + + + + + 100 + 200 + + + + + + + + 1,000 + 2,000 + + + + \ No newline at end of file diff --git a/test/plots/index.ts b/test/plots/index.ts index 13231ea454..907109e590 100644 --- a/test/plots/index.ts +++ b/test/plots/index.ts @@ -152,6 +152,7 @@ export * from "./linear-regression-cars.js"; export * from "./linear-regression-mtcars.js"; export * from "./linear-regression-penguins.js"; export * from "./log-degenerate.js"; +export * from "./log-tick-format.js"; export * from "./long-labels.js"; export * from "./markers.js"; export * from "./markov-chain.js"; diff --git a/test/plots/log-tick-format.ts b/test/plots/log-tick-format.ts new file mode 100644 index 0000000000..1ba376892e --- /dev/null +++ b/test/plots/log-tick-format.ts @@ -0,0 +1,5 @@ +import * as Plot from "@observablehq/plot"; + +export async function logTickFormatFunction() { + return Plot.plot({x: {type: "log", domain: [1, 4200], tickFormat: Plot.formatNumber()}}); +}