Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement binary prefixes #70

Closed
wants to merge 5 commits into from
Closed

Implement binary prefixes #70

wants to merge 5 commits into from

Conversation

runarberg
Copy link

Closes: #33

@runarberg
Copy link
Author

runarberg commented May 6, 2019

There are a few considerations:

  • Is the B name adequate for this type or is there perhaps a better one?
  • 1001Ki is a possible output with enough precision format(".4B") (as opposed to 0.98Mi with format(.3B); implemented here). Is this desirable behavior. Personally I find it confusing, but this is how e.g. human-format does it.
  • Should I append the tests to the tests/format-type-b-test.js rather then creating the confusingly named tests/format-type-bi-test.js?

I tried to remain consistent in style with the rest of the code base, however I’m not used to writing this terse code so pardon my mistakes 😉

Finally, @mbostock thanks for considering this PR. I’m big fan of your work 😎

@haf
Copy link
Contributor

haf commented Jul 12, 2019

Nice PR; I hope it gets reviewed! @mbostock

export default function(x, p) {
var binaryExponent = 0;

while (Math.round(x) >= 1024 && binaryExponent < 80) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a closed form for doing this, rather than needing a loop?

Copy link
Member

@mbostock mbostock Jul 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also it looks like this will hang if you try to format Infinity, but I didn’t test it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn’t investigate any closed forms. I wouldn’t be surprised if one existed using the power of 2. But this loop will run at most 8 times as far as I can tell, even for Infinity.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a test that confirms that infinity does not hang indefinitely. However if someone can point out a closed form, it would probably be preferable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds right; I was too hasty reading the code. Thanks.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be possible to use Math.log2 here?

(or the IE-compatible equivalent Math.log(number) / Math.log(2))

src/formatBinaryPrefixAuto.js Outdated Show resolved Hide resolved
src/formatBinaryPrefixAuto.js Show resolved Hide resolved
test/format-type-bi-test.js Outdated Show resolved Hide resolved

export default function(x, p) {
var binaryExponent = 0;
if (x === Infinity) return binaryPrefixExponent = 0, x;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is confusing.

Why not

if (x === Infinity) return Infinity;

?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presumably because it needs to set the exported binaryPrefixExponent (note, not binaryExponent).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aaaahhhhh I see. Side effects. Thanks for pointing that out 🙏

var tape = require("tape"),
format = require("../");

tape("format(\"B\") outputs binary-prefix notation with default precision 6", function(test) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great comprehensive tests!

src/locale.js Show resolved Hide resolved
@curran
Copy link

curran commented Jul 8, 2020

Suggest to close this in favor of #96

@Fil
Copy link
Member

Fil commented Jul 10, 2020

closed in favor of #96

@Fil Fil closed this Jul 10, 2020
@runarberg
Copy link
Author

Should this be reopened since #96 is still being discussed?

@grotlue
Copy link

grotlue commented Aug 21, 2023

@Fil @curran Hey 👋 Is there any chance this issue will be reopened, as #96 seems to be blocked by the currency discussions?
I would really love this prefix, using d3 for Plotly graphs displaying traffic.

@curran
Copy link

curran commented Aug 21, 2023

It looks like that PR #96 is stalled. It has a ton of changes in it. I don't remember the context for all this, but it seems that the PR has grown too large to ever merge. I feel like we need to take a step back and consider the use case(s) and a smaller subset of changes to consider.

@grotlue Is there a particular subset of the changes that interest you? The tests are great - https://github.com/d3/d3-format/pull/96/files - maybe you could identify specific tests that are less ... controversial than all of them together? Then maybe a new smaller PR could be opened that only adds a small part of the feature that would be sensible to add to the library and maintain in the long term, and would be of value to a lot of people.

The other alternative is to author a new NPM package separate from mainline D3 that implements the features from that PR.

@runarberg
Copy link
Author

runarberg commented Aug 22, 2023

I don’t understand why d3-format needs a currency format since Intl.NumberFormat has a pretty good currency formatting and along with { notation: "compact" } gives a strict superset of the benefits of the currency portion of #96 (Intl.NumberFormat also much better localization, and supports much more currencies).

const usdFormat = new Intl.NumberFormat(
  "en-US",
  {
    style: "currency",
    currency: "USD",
    currencyDisplay: "symbol",
    notation: "compact",
  }
);

usdFormat.format(1_000_000)
// => "$1M"

However there is no vanilla way to get binary prefixes (or any SI prefixes) with Intl.NumberFormat. You can use e.g. { style: "unit", unit: "kilobyte" }, however you have to round the number your self before passing it into the format, and the prefixes provided are all SI-based (not binary; so kB as opposed to KiB).

That said, since this PR was closed, I simply rolled my own way of achieving binary prefixes in my own code. #96 (comment)

@Fil Fil mentioned this pull request Aug 23, 2023
@grotlue
Copy link

grotlue commented Sep 19, 2023

Hi @runarberg, @Fil, @curran,

thanks a lot for your replies. I had a look at it again and the changes @runarberg mentioned in #33 (comment) and updated in runarberg@3f2383d would be sufficient for my use case. Anything preventing from merging them?

@grotlue
Copy link

grotlue commented Jul 18, 2024

Hi @runarberg @Fil @curran, can this be merged?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Binary prefixes
6 participants