d3-format
d3-format copied to clipboard
Implement Binary prefix, Currency prefix (Merge #70 #81)
This branch merges #70 and #81 which were targeting the same set of lines.
hmmm something went wrong in my repo when I tried to fix the credits on a commit 😰
The currency “prefix” feature is misnamed: this is not a prefix, it’s a symbol, or even a suffix based on how it’s formatted. In the case of SI, it’s called a prefix because it’s used at the start of a word: for example, “k” stands for kilo as in “kilogram” or “kilobyte”. Since we don’t talk about “kilodollars” and we’re using the “k” symbol at the end, I don’t think it’s appropriate to call it a prefix. (In retrospect, d3.formatPrefix should probably have been named to d3.formatSi, but that ship has sailed.)
More generally, I’m wary of adding new localization features to this library. The binary prefixes seem reasonable because they correspond closely to the existing SI prefixes and are well-defined, but the currency formatting feature feels… a little ad hoc and I question how useful it is for all locales. In the long run, I’d prefer to use the standard JavaScript APIs for number and date localization and I’m generally opposed to expanding the surface area of this library.
Should we go ahead with #70 since there is no consensus on adding currency formatting?
@Fil @curran Any plan on this? As there are open source data visualization tools that depend on d3format and if this "human consumption filesize" introduce in d3format, then it will be very helpful to the community.
@nimisha1921 I’ve just been rolling my own using Math.log2 and Intl.NumberFormat:
const PREFIXES = ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'];
function binaryFormatParts(num: number) {
if (!Number.isFinite(num) || Math.abs(num) < 1) {
return [num, 0];
}
const exponent = Math.log2(Math.abs(num));
const prefix = Math.min(Math.trunc(exponent / 10), PREFIXES.length - 1);
return [num / 2 ** (prefix * 10), prefix];
}
export function binaryFormat(num: number): string {
const [x, prefix] = binaryFormatParts(num);
const displayNumber = new Intl.NumberFormat('default', {
maximumFractionDigits: 2,
style: 'decimal',
}).format(x);
return `${displayNumber} ${PREFIXES[prefix]}B`;
}
@Fil @mbostock @curran Any plan or timeline for merging this PR??
I have no say as to whether it gets merged or not. Looks good to me at a high level, but I have not considered all the details and rammifications it may have for the future.
Closing, following @runarberg’s comment https://github.com/d3/d3-format/pull/70#issuecomment-1689033180 (one should use Intl.NumberFormat instead).