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

Indian Number System format #21

Closed
mbostock opened this issue Apr 30, 2016 · 18 comments
Closed

Indian Number System format #21

mbostock opened this issue Apr 30, 2016 · 18 comments

Comments

@mbostock
Copy link
Member

In India, the number system is formatted like this

1 (One)
10 (Ten)
100 (Hundred)
1,000 (Thousand)
10,000 (Ten Thousand)
1,00,000 (One Lakh)
10,00,000 (Ten Lakhs)
1,00,00,000 (One Crore)
10,00,00,000 (Ten Crores)
1,00,00,00,000 (Hundred Crores)
10,00,00,00,000 (Thousand Crores)
1,00,00,00,00,000 (Ten Thousand Crores)
10,00,00,00,00,000 (One Lakh Crore)

and it goes on.

The grouping is 2 except at the beginning. Thousand is written as 1,000 and not as 10,00

Names are not important but I couldn't figure out grouping variable in the pull request I submitted for en-IN locale #2816

It was mentioned that the array will be cycled through so I can't put [2,3] How do we solve this?

Copied from d3/d3#2817 by @rohithdaka.

@curran
Copy link

curran commented Apr 30, 2016

This is great! Makes me so happy. Thanks for adding this issue.

@mbostock
Copy link
Member Author

I haven’t added it yet. Just copying a request from mbostock/d3. I’m not sure yet how best to implement this. It makes me wonder if locales should be specified as code rather than as declarative data, though that introduces different problems.

@curran
Copy link

curran commented Apr 30, 2016

Here's a first stab an an implementation http://bl.ocks.org/curran/70348c8af4c1959c1289a20ff0a63490

screen shot 2016-04-30 at 9 35 13 pm

@rohithdaka
Copy link

How about notation like this? grouping: [<,2,3]

I failed to try to tamper with the code in the repo for the grouping here

If we encounter '<' as grouping[0] then we will cycle through only the next number. If there is no character then we will cycle through the whole list.

Is there any test that I can use to try this fix and not break other parts of d3-format ?

@harshit-khandelwal-1
Copy link

The format function in the link http://bl.ocks.org/curran/70348c8af4c1959c1289a20ff0a63490 doesn't work for all cases. A modified version of that would help. Here it is.
function format(n){
var negative=false;
var str = String(n);
if (str[0]=="-"){
str=str.substring(1,str.length);
negative=true;
}
var arr = [];
var i = str.indexOf(".");
if(i == -1){
i = str.length-1;
}
else {
for(var j = str.length - 1; j > i; j--){
arr.push(str[j]);
}
arr.push(str[i]);
i=i-1;
}
for(var n = 0; i >= 0; i--, n++){
if(n > 2 && (n%2==1)){
arr.push(",");
}
arr.push(str[i]);
}
if(negative)
arr.push("-");
return arr.reverse().join("");
}

@curran
Copy link

curran commented Jun 17, 2016

@Harshit20051 Thank you for your fixes! I updated the original example with variations of your modifications to handle the "10000" and negative number cases correctly. Here's the current result:

image

Here's the function:

function format(n){
  var negative = n < 0;
  var str = negative ? String(-n) : String(n);
  var arr = [];
  var i = str.indexOf(".");

  // Handle decimal points
  if(i === -1){
    i = str.length;
  } else {

    // Add the digits after the decimal point.
    for(var j = str.length - 1; j > i; j--){
      arr.push(str[j]);
    }
    arr.push(".");
  }
  i--;

  // Insert commas.
  for(var n = 0; i >= 0; i--, n++){
    if(n > 2 && (n % 2 === 1)){
      arr.push(",");
    }
    arr.push(str[i]);
  }

  if(negative){
    arr.push("-");
  }

  return arr.reverse().join("");
}

Maybe it would make sense to have most locales defined as declarative data, but add a hook for also defining locales such as this one as code.

@mbostock
Copy link
Member Author

It’s nice for the locales to be strictly declarative. It means they can be defined as JSON, and if you load them from another host, you’re not running arbitrary code. @rohithdaka’s suggestion of using a special string in the grouping array to allow cycling seems like a clever solution that could work.

The closest you can get right now is to just have a really long grouping definition:

[3, 2, 2, 2, 2, 2, 2, 2, 2, 2]

If you want to support arbitrarily large numbers, then we could do something like this:

[3, 2, "*"]

Here the "*" is a special signifier that can only appear as the last entry in the grouping definition, and it means to repeat the last group value indefinitely (rather than cycling). This is basically the mirror of @rohithdaka’s suggestion but I think it more closely matches the current definition.

I suppose it’d be nice to allow more arbitrary repeating sequences but without any other examples to go on, it’s hard to generalize. Trying to keep things simple.

mbostock added a commit that referenced this issue Jun 24, 2016
@rohithdaka
Copy link

Thank you for taking a look at this issue. I have lots of locale json files (that belong to several languages in India), should I submit them with [3,2,"*"] or [3,2,2,2,2,2,2,2,2,2,2] ?

practically speaking a array of length 30 (One 3 and twenty-nine 2s) should be good as 10^62 is the highest number that was given a name in many Indian languages. Please advice.

@mbostock
Copy link
Member Author

Well, in fact d3-format doesn’t currently support decimal notation values greater than or equal to 1e21; internally, we use number.toString(10) which behaves inconsistently with number.toString(2), number.toString(8) and number.toString(16).

I suppose we should fix that, but I think it would either require a hack (like using number.toString(20) and then expanding the result) or writing our own decimal formatter (which would be slow and possibly prone to rounding problems).

@rohithdaka
Copy link

rohithdaka commented Jun 29, 2016

Got it. I will submit with an array of length 10 (One 3 and Nine 2s), just like you suggested in the beginning. Thank you :)

@mbostock
Copy link
Member Author

Sounds good!

@curran
Copy link

curran commented Jan 31, 2017

This is still unsolved?

Perhaps it would be worth creating a D3 plugin with the bit of code I made for the Indian number formatting? Seems a shame to special case this one, but would better to have a solution be an npm install away, rather than a copy-paste job from https://bl.ocks.org/curran/70348c8af4c1959c1289a20ff0a63490

@curran
Copy link

curran commented Jan 31, 2017

OK, here's what I've got so far https://github.com/curran/d3-format-india

@mbostock Just give the word and I'll transfer it to github.com/d3/d3-format-india

@curran
Copy link

curran commented Jan 31, 2017

Here's an interesting regex-based solution by @vkbansal

https://vkbansal.me/blog/format-indian-currency-in-js/

(1234567.8).toFixed(2).replace(/(\d)(?=(\d{2})+\d\.)/g, '$1,') // "12,34,567.80"

@vkbansal
Copy link

@curran why make this d3 specific. This can be used independent of d3.

@curran
Copy link

curran commented Jan 31, 2017

Right, the module could be used independently of D3. It is already like that. It's just set up as a "D3 Plugin" for convenient use within D3. That doesn't preclude using it as a standalone module, independent of D3.

@mbostock
Copy link
Member Author

I think there was never a followup pull request, but it seems like this should work:

{
  "decimal": ".",
  "thousands": ",",
  "grouping": [3, 2, 2, 2, 2, 2, 2, 2, 2, 2],
  "currency": ["", ""]
}

Review #35?

@Liggliluff
Copy link

Sorry for writing on this closed issue.

But I'm trying to find information about the Indian digit groupings, because there seems to be two ways of doing Indian numbers.

One-word system:
thousand - lakh - crore - arab - kharab - nil - padma - shankh - ald - ank - jald - madh - parardh - ant - …
Each, except thousand, is a magnitude of 100, and represents ",00" in the formatting. So one shankh is 1,00,00,00,00,00,00,00,000.
[3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, …]

Lakh-crore system:
thousand - lakh - crore - thousand crore - lakh crore - crore crore - thousand crore crore - lakh crore crore - crore crore crore - …
Thousand is ",000" - lakh is ",00,000" - crore is ",00,00,000". So one lakh crore crore is "1,00,000,00,00,000,00,00,000"
[3, 2, 2, 3, 2, 2, 3, 2, 2, 3, 2, 2, 3, …]

Because I've seen numbers formatted in both systems at different places. The lakh-crore pattern is less common to find, but it fits the lakh-crore speech pattern.

I wonder if there's more information about this that I could read more about. This is a bit interesting to see.

And there's also a third system (lakh-arab system) counting up to arab instead of crore, but functions the same as the lakh-crore system.
One thousand arab arab is "1,000,00,00,00,000,00,00,00,000"
[3, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 3, …]

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

No branches or pull requests

6 participants