Add support for compact number notation
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
Motivation
We are using server-side clusters in our solution. These clusters provide a number of points (12345). For display, we translate this into a compact version ("12K"). This is equivalent to using Intl.NumberFormat with the following arguments: {notation: "compact", compactDisplay: "short"}.
We don't have control over the server-side clustering. Sometimes when zooming out, these clusters get too close, so we apply client-side clustering, using a sum to show the total number of points:
- Main text layer
text-field:["get", "formattedVolume"](compact-formattedvolume) - Source
clusterProperties:{ volumeSum: ["+", ["get", "volume"]] } - Cluster text layer
text-field:["get", "volumeSum"]
I would like volumeSum to have the same compact format as formattedVolume. This is not possible with the current implementation of number-format (though there is a convoluted workaround). Would it be possible to add a notation option to that expression?
Design Alternatives
Currently I am able to get the intended output using the following expression:
"text-field": [
"case",
["all", [">=", ["abs", ["get", "volumeSum"]], 1e9]],
["concat", ["to-string", ["round", ["/", ["number", ["get", "volumeSum"]], ["number", 1e9]]]], "B"],
["all", [">=", ["abs", ["get", "volumeSum"]], 1e6]],
["concat", ["to-string", ["round", ["/", ["number", ["get", "volumeSum"]], ["number", 1e6]]]], "M"],
["all", [">=", ["abs", ["get", "volumeSum"]], 1e3]],
["concat", ["to-string", ["round", ["/", ["number", ["get", "volumeSum"]], ["number", 1e3]]]], "K"],
["get", "volumeSum"],
]
This expression, however, is not localizable.
Design / implementation
Add notation and possibly compactDisplay options to the number-format function, and create the Intl.NumberFormat formatter with these arguments, so that I can now format my text fields like so:
- Main text layer
text-field:["number-format", ["get", "volume"], {notation: "compact"}] - Source
clusterProperties:{ volumeSum: ["+", ["get", "volume"]] } - Cluster text layer
text-field:["number-format", ["get", "volumeSum"], {notation: "compact"}]
const num = 123_456_789.123;
new Intl.NumberFormat("en", {notation: "compact", compactDisplay: "short"}).format(num); // "123M"
new Intl.NumberFormat("fr", {notation: "compact", compactDisplay: "short"}).format(num); // "123 M"
new Intl.NumberFormat("en", {notation: "compact", compactDisplay: "long"}).format(num); // "123 million"
new Intl.NumberFormat("fr", {notation: "compact", compactDisplay: "long"}).format(num); // "123 millions"
new Intl.NumberFormat("en", {notation: "compact"}).format(num); // "123M"
new Intl.NumberFormat("fr", {notation: "compact"}).format(num); // "123 M"
new Intl.NumberFormat("en", {notation: "scientific"}).format(num); // "1.235E8"
new Intl.NumberFormat("en", {notation: "engineering"}).format(num); // "123.457E6"
new Intl.NumberFormat("en", {notation: "standard"}).format(num); // "123,456,789.123"
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the number-format expression implementation and inspect how its options are passed to Intl.NumberFormat. Add support for notation and, if included, compactDisplay so compact, scientific, engineering, and standard formats work with localization. Validate the requested text-field examples and confirm the formatted cluster and volume values match the documented output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100