mapbox / mapbox/mapbox-gl-js

Add support for compact number notation

Open
#12,917 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

cross-platform :tv: feature :green_apple:
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-formatted volume)
  • 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.