d3 / d3-format Goto Github PK
View Code? Open in Web Editor NEWFormat numbers for human consumption.
Home Page: https://d3js.org/d3-format
License: ISC License
Format numbers for human consumption.
Home Page: https://d3js.org/d3-format
License: ISC License
var value = 124.256
d3.format(',.f') was returning the actual value on
format(value) =124.256
but in version 4 same function is broken
d3.min.js:2 Uncaught Error: invalid format: ,.f
at new Xe (d3.min.js:2)
at He (d3.min.js:2)
at Object.n [as format] (d3.min.js:2)
at Object.locale.decimalFormat (com01.fwk:165)
I have created a PR #38 to push the new Arabic locales based on issue #36 and created test files to test them but I need to rebuild d3-format locally before pushing the test files to make sure that everything is fine but I do not know how ? the READMe file does not illustrate how to re-generate d3.format file after making any change.
In the example found in the documentation "~s"
is a valid format.
d3.format("~s")(1500); // "1.5
However upon using this with d3.v5 one is then presented with Uncaught Error: invalid format: ~s
When rounding to one decimal place, 17.45 should round to 17.5 but is instead rounding to 17.4.
> d3.format('.1f')(17.450)
"17.4"
> d3.format('.1f')(17.451)
"17.5"
The test only test currency with prefix as default
d3-format/test/format-type-s-test.js
Line 93 in 5b9efde
When using the fr default Locale, currency is suffix but is wrongly placed before the Si-prefix.
format("$.2s")(800000000) => 800 €M
Expected output is 800M €
It could be usefull to have getter to the default locale. Something like d3.formatLocale()
without args could do the job.
Why?
Because when you work on multilang graphics, it's simplier to handle a locale object, update it, and call locale.format
than the global format
function, and always setting the default locale of d3. For now I recreate the locale object with the format
and formatPrefix
functions. But it's something that the lib could do.
I can make the PR if you agree.
Consider a value recorded as "14 PPM defects" i.e. "14 defective parts per million".
The underlying value is 0.000014. D3 currently shows this on the axis as "14u" (the micro symbol).
When the axis title is "ppm defects", this actually implies "14 micro parts per million".
It would be helpful if it could display as "14 ppm" instead.
In other words, I'm proposing an additional "type" format, perhaps "u", which acts in the same way as "p", but multiplies by 1000000 and has a "ppm" sign.
Thanks very much :-)
Prior to wide-scale ES6 adoption, the locale definitions are not externally available. For example, they are not included in the built ES5 files. Only the pre-specified default locale is included. It would be helpful to be able to access the locale definitions for convenient specification and switching. (Note that this applies to d3-time-format as well.)
We recently updated datalib to support runtime locale switching (in particular, this was requested by Wikipedia folks for their Vega graph support), but this requires passing in a full JSON blob of locale settings. To make these settings accessible, one options for us is to build out a separate repo that contains a registry of locale definitions (i.e., one that can be included as a project dependency). However, that would simply replicate the work you've done here, and so seems both inelegant and prone to inconsistency due to code drift.
Any plans / thoughts in this regard? One option might be to include the locales in the build (though bloating the file size). Another might be a parallel build that exports just the locale definitions, perhaps as a single JSON file keyed by locale id.
Just like the title says - the "+" formatting adds a plus sign to 0, turning it into "+0" (https://jsfiddle.net/b7g9r739/). I'm using it to display the plus sign for positive values. Is this the correct behaviour?
Here it says:
a plus sign for positive and a minus sign for negative.
When visualising information, it would be quite useful to have the option of not just SI prefixes but also IEC binary prefixes, i.e. 1024 == Ki, 1048675 == Mi, etc.
I'm writing an application that displays something before the data is here. The data is lots of numbers and sometimes they're not there yet (waiting for network latency), so undefined
is passed to be displayed. Transformed to a number, it yields NaN
.
As it turns out, few humans understand what NaN
means and why this text would show up in a screen (even worse with text-transform: uppercase
both in English and French for different reasons).
As a consequence, I believe an empty string would be a better formatting of NaN
or undefined
than "NaN"
is.
Happy to send a PR if there is agreement here.
What do you think?
I want to load this module only, with RequireJS, does not work. The d3 object is invalid unless i receive the variable as "d3", but this not is a total solution because: What happen if i want load more individually modules?. This is my code:
define(['d3_format'], function(d3_format){ console.log(d3) });
And the message is:
d3 is not defined
Hello, This is Ayah Shamandi, bidi developer -Globalization team at IBM Egypt, we are responsible for adding globalization and bidi featuers at open source technologies which IBM products used.
and we noticed that D3.format supports different locales except Arabic ones, so I opened this isssue to request adding the missing ones.
and here is the list of locales I am going to add:
I was trying to use the D3 microlibraries with rollup, but once I imported something from d3-scale, I started getting an error about defaultLocale
being an undefined function. I dug into it and it seems that rollup is importing the call to defaultLocale
in defaultLocale.js
but not the function definition.
I set up a test project that illustrates the problem. https://github.com/darthmall/rollup-d3-format-test
it seems we could only get ".1%" format correctly and we could not get more decimal digits format for percentage such as ".11%" or ".1111%" format.
$("#testValue").append( ".11% 1234.56789:" + "<p>" + d3.format(".11%")(1234.56789) + "</p>");//123456.78900000000%
$("#testValue").append( ".1% 1234.56789:" + "<p>" + d3.format(".1%")(1234.56789) + "</p>");//123456.8%
$("#testValue").append( ".1111% 987.654321:" + "<p>" + d3.format(".1111%")(987.654321) + "</p>");//98765.43210000000544823706%
$("#testValue").append( ".1% 987.654321:" + "<p>" + d3.format(".1%")(987.654321) + "</p>");//98765.4%
$("#testValue").append( ".11% 987.654321 with round:" + "<p>" + d3.format(".11%")(d3.round(987.654321,4)) + "</p>");//98765.43000000001%
$("#testValue").append( ".11% 987.654321 with round:" + "<p>" + d3.round(987.654321,4) + "</p>");//987.6543
d3Format.format(".18f")(1.1)
gives 1.100000000000000089
d3Format.format(".18f")(1.2)
gives 1.199999999999999956
d3Format.format(".18f")(1.3)
gives 1.300000000000000044
... etc. which are all wrong.
This package claims to fix the problem of binary floating point yet it seems to suffer from it.
Can this problem be fixed? Or is there an alternative package that is precise for many decimal places or large numbers?
I use the bignumber.js package for precise calculations with 18 decimal places, but it would be great to be able to format the results nicely for the UI.
I'm trying to get this number formatting:
1000
-> '1k'
1500
-> '1.5k'
But doing format('s')
gives me instead:
1000
-> '1.00000k'
1500
-> '1.50000k'
I can try to remove the fixed precision (format('.0s')
), but that will break it for the 2nd number:
1000
-> '1k'
1500
-> '2k'
That seems to be happening because the default precision is set to 6 fixed points, and the minimum is 1. So .0s
really acts as .1s
, if I'm reading this section correctly:
https://github.com/d3/d3-format/blob/master/src/locale.js#L46
This feature seems to be showing up in the tickFormat block too:
https://bl.ocks.org/mbostock/9764126
In the middle axis (format('.0s')
), the top values show as repeated 2M
and 1M
due to the rounding, while ideally they would show 1.2M
, 1.4M
, etc.
Would be nice if there's an easy option to remove insignificant trailing 0s, regardless of the type. This option exists for type 'g' (type none), but not for SI and other modes.
Or maybe there's a way to do this currently that I didn't realise. :)
Might be nice for debugging and consistency with timeFormat.toString.
https://runkit.com/58a5c70825e6da001336e870/58ae0f92ef3db20014828aae
var d3Format = require("d3-format")
d3Format.format(".3e")(-Infinity) // returns "Infinity"
Is this expectated behavior?
It's not clear from the docs, why
d3.format('')(127) //gives 127
d3.format('g')(127) //gives 127.000
?
As D3 supports different locales, we need also to add numeral system to these locales
When users select a locale file they also expect to see numbers formated in a numeral system based on the selected locale.
for example: if we talk about users from saudi arabia, when they select ar-SA as their locale file, they expect to see arabic/ indic numerals - ٠١٢٣٤٥٦٧٨٩ - instead of European numerals - 0123456789 - .
on the other hand users from Tunisia, when selecting ar-TN, they expect to see European numerals
and to solve this problem, I suggest to
and for now as I am interesting to support Arabic users I will add one of 2 numerals types (European or arabic/indic) at each locale. (ar-*.json)
and for the remaining locales I will define numerals as european numerals.
how to tickformat decimal to fraction?
d3.format('.3s') format method convert points to million range.
https://jsfiddle.net/64fde19v/
Not sure if I am doing something wrong.
I have the following input data:
ticks = [-20, -15, -10, -5, 0, 5, 10, 15, 20]
I use a format: formatTickLabel = format(".1s")
applied to text:
lg.selectAll("text")
.data(ticks)
.enter()
.append("text")
.text(x => formatTickLabel(x));
Expected
I expect the ticks labels to be: -20 -15 -10 etc.
Actual
What I see is : -20 -20 -10 5 0 5 10 20 20.
Version 4 looks very exciting!
Sorry if I'm being presumptuous but do you think it might be useful to include text values? Then you can use the the justification, padding and minimum width on mixed types.
Also, would it be possible to include decimal place alignment in the alignment symbols?
When I execute the following:
[5,10,15,20].map(v => format('$.1s')(v * 1E9))
it returns:
["$5G", "$10G", "$20G", "$20G"]
However, to me it would make more sense if the combination of SI and currency would not result in G for giga, but B for billion, preferably localized.
Is support for this planned? Thanks.
Is there any chance of having the ability to format with an object rather than string, e.g.:
format({ precision: 2, type: 'f' })(1.234);
Rather than:
format(".2f")(1.234);
I think it would be nice to allow being that explicit.
I also have a use case for it where I want to convert from other types of format strings into d3-format style. It's easier to convert from "other" to the specifier object, rather than the extra step of making that object a string as well.
I can see it being possible directly in the format function, or if the FormatSpecifier class was exported and had a constructor that accepts either an object or string:
const specifier = new FormatSpecifier({ precision: 2, type: 'f'}).toString();
format(specifier)(1.2345);
I like this project a lot but I forced to use Numeral-js which has ordinal numbers support like 1st
, 2nd
etc.
Is there plan to support it? I can send a PR so we could discuss implementation.
Seems like it is reasonable, after all: d3/d3-path#10 (comment)
Proposed implementation:
function round(x, n) {
return n == null ? Math.round(x) : Math.round(x * (n = Math.pow(10, n))) / n;
}
For example:
var f = d3.format(",d");
f(1e20); // "100,000,000,000,000,000,000"
f(1e21); // "1e+21"
Because:
(1e20).toString(10); // "100000000000000000000"
(1e21).toString(10); // "1e+21"
Related #21.
If the input value is exactly -0, or if when rounded according to the format’s precision is equivalent to -0, we should treat it as exactly 0 rather than -0.
This is necessary because tick values can be slightly off due to floating point precision, so a value that is intended to be exactly 0 may instead be something like -1.7763568394002506e-16. I can’t seem to reproduce this in 4.0’s d3-scale, but it’s definitely the case in 3.x:
var y = d3.scale.linear().domain([1.575008840033951, -0.7414613146919857]);
y.ticks(10);
Returns:
[
-0.6000000000000001,
-0.4000000000000001,
-0.2000000000000001,
-8.881784197001253e-17,
0.1999999999999999,
0.3999999999999999,
0.5999999999999999,
0.7999999999999999,
1,
1.2,
1.4
]
Related d3/d3@4946a8c.
I'm trying to generate a custom bundle of D3 v4 using rollup:
https://github.com/Turbo87/rollup-d3-issue
Running npm run build
(or rollup -c
) will produce a bundled file at dist/d3.js
which looks fine on first glance. It includes the following function call:
defaultLocale({
decimal: ".",
thousands: ",",
grouping: [3],
currency: ["$", ""]
});
but the defaultLocale()
function is not defined anywhere in the bundle even though it's in the original code (at https://github.com/d3/d3-format/blob/v1.0.2/src/defaultLocale.js).
Note that if I add export { formatDefaultLocale } from 'd3-format';
to the d3.js
file we can work around this issue. This is not a good long-term solution though.
Cross-posted this as rollup/rollup#970
This way they can be loaded safely on demand.
For locales. See d3/d3-shape#23.
The format types that use number.toPrecision behave reasonably for large x, switching to exponent notation when the number of output digits is greater than the specified precision. For example:
var f = format(".3n");
f(9.99); // "9.99"
f(99.9); // "99.9"
f(999); // "999"
f(9990); // "9.99e+3"
f(99900); // "9.99e+4"
f(99900); // "9.99e+5"
But, they don’t behave symmetrically for small absolute values of x, since the specification of number.toPrecision says to only use exponent when |x| is less than 1e-6:
var f = format(".3n");
f(9.99); // "9.99"
f(0.999); // "0.999"
f(0.0999); // "0.0999"
f(0.00999); // "0.00999"
f(0.000999); // "0.000999"
f(0.0000999); // "0.0000999"
f(0.00000999); // "0.00000999"
f(0.000000999); // "9.99e-7"
I wonder whether this would be better, since it avoids displaying more than precision digits:
var f = format(".3n");
f(9.99) // "9.99"
f(0.999) // "9.99e-1"
f(0.0999) // "9.99e-2"
f(0.00999) // "9.99e-3"
f(0.000999) // "9.99e-4"
f(0.0000999) // "9.99e-5"
f(0.00000999) // "9.99e-6"
f(0.000000999) // "9.99e-7"
On the other hand, this makes the shift to exponent notation dependent on the number of significant digits and not the value of x, which means that for some x1 > x2, x1 is formatted in exponent notation and x2 is formatted in decimal notation:
var f = format(".3n");
f(0.099); // "9.99e-2"
f(0.090); // "0.09"
So maybe it’s better to make the threshold dependent on the precision, but independent of the number of significant digits? Like if precision is 3, then use 1e-3. Then the current threshold 1e-6 would remain the default if the default precision of 6 is used.
var fn = format(".3n"),
fe = format(".3e"),
f = function(x) { return (x < 1e-3 ? fe : fn)(x); };
f(0.999); // "0.999"
f(0.0999); // "0.0999"
f(0.0900); // "0.0900"
f(0.00999); // "0.00999"
f(0.000999); // "9.990e-4"
f(0.0000999); // "9.990e-5"
f(0.00000999); // "9.990e-6"
f(0.000000999); // "9.990e-7"
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.
6.4.1
through 6.4.4
.While I wouldn't expect d3-format to support scientific rounding rules, I would expect that it would apply a consistent set of rules. I know that this is a difficult problem to solve, partly due to the binary representation of floating point numbers.
All of these examples use the format function returned by
d3.format('.3r')
x.45500
cases return the common rounding result:Input | Output | Common | Scientific |
---|---|---|---|
1.45500 |
1.46 |
1.46 ✔️ |
1.45 |
2.45500 |
2.46 |
2.46 ✔️ |
2.45 |
3.45500 |
3.46 |
3.46 ✔️ |
3.45 |
4.45500 |
4.46 |
4.46 ✔️ |
4.45 |
5.45500 |
5.46 |
5.46 ✔️ |
5.45 |
6.45500 |
6.46 |
6.46 ✔️ |
6.45 |
7.45500 |
7.46 |
7.46 ✔️ |
7.45 |
8.45500 |
8.46 |
8.46 ✔️ |
8.45 |
9.45500 |
9.46 |
9.46 ✔️ |
9.45 |
x.55500
cases return a mix of common and scientific rounding results:Input | Output | Common | Scientific |
---|---|---|---|
1.55500 |
1.55 |
1.56 |
1.55 ✔️ |
2.55500 |
2.56 |
2.56 ✔️ |
2.55 |
3.55500 |
3.56 |
3.56 ✔️ |
3.55 |
4.55500 |
4.55 |
4.56 |
4.55 ✔️ |
5.55500 |
5.55 |
5.56 |
5.55 ✔️ |
6.55500 |
6.55 |
6.56 |
6.55 ✔️ |
7.55500 |
7.55 |
7.56 |
7.55 ✔️ |
8.55500 |
8.55 |
8.56 |
8.55 ✔️ |
9.55500 |
9.55 |
9.56 |
9.55 ✔️ |
x.55501
cases return the correct result, which is the same for common and scientific rounding methods:Input | Output | Common | Scientific |
---|---|---|---|
1.55501 |
1.56 |
1.56 ✔️ |
1.56 ✔️ |
2.55501 |
2.56 |
2.56 ✔️ |
2.56 ✔️ |
3.55501 |
3.56 |
3.56 ✔️ |
3.56 ✔️ |
4.55501 |
4.56 |
4.56 ✔️ |
4.56 ✔️ |
5.55501 |
5.56 |
5.56 ✔️ |
5.56 ✔️ |
6.55501 |
6.56 |
6.56 ✔️ |
6.56 ✔️ |
7.55501 |
7.56 |
7.56 ✔️ |
7.56 ✔️ |
8.55501 |
8.56 |
8.56 ✔️ |
8.56 ✔️ |
9.55501 |
9.56 |
9.56 ✔️ |
9.56 ✔️ |
Like in d3-time-format
, adding a parse method to the number formatters could be useful to get a number back when the representation is not a valid argument to construct numbers
var format = d3.formatPrefix(",.0", 1e-6);
format(0.00042); // "420µ"
format.parse("420µ"); // 0.00042
I am transpiling this package wirh ClojureScript, and faced a peculiar behaviour when using the SI prefix formatter (s
type). The prefix always rendered as undefined
, e.g. 1undefined
, 100undefined
, 42undefined
, etc. This was caused by the fact that prefixExponent
on line 84 was invariably undefined
. The issue appears to be that formatPrefixAuto.js
on line 10 expects prefixExponent
to be in (global) scope. The transpilier however copies the value in an attempt to alias the name, here's the transpiled code:
goog.provide("module$usr$src$node_modules$d3_format$src$formatPrefixAuto");
goog.require("module$usr$src$node_modules$d3_format$src$formatDecimal");
var prefixExponent$$module$usr$src$node_modules$d3_format$src$formatPrefixAuto;
var $jscompDefaultExport$$module$usr$src$node_modules$d3_format$src$formatPrefixAuto = function(x, p) {
/*snip*/
var i = exponent - (prefixExponent$$module$usr$src$node_modules$d3_format$src$formatPrefixAuto = /*snip*/)
/*snip*/
};
module$usr$src$node_modules$d3_format$src$formatPrefixAuto.prefixExponent = prefixExponent$$module$usr$src$node_modules$d3_format$src$formatPrefixAuto;
module$usr$src$node_modules$d3_format$src$formatPrefixAuto.default = $jscompDefaultExport$$module$usr$src$node_modules$d3_format$src$formatPrefixAuto;
...and prefixExponent$$module$usr$src$node_modules$d3_format$src$formatPrefixAuto
is never referenced again. I don't know if this is still an issue with Closure advanced optimisations (maybe it is, maybe it isn't).
I think that it's fair to say that formatPrefixAuto.js
is trying to expose its internals and it hasn't ended well in my case.
I can think of a couple of alternatives to fix the problem, both feel like hacks to me:
prefixExponent
Instead of exposing prefixExponent
as a primitive that is passed by value, wrap it in an object:
export var internals;
export default function(x, p) {
/*snip*/
var i = exponent - (internals.prefixExponent = /*snip*/) + 1
/*snip*/
}
Perhaps the intention was to attach it to the exported function? I.e.
export default function formatPrefixAuto(x, p) {
/*snip*/
var i = exponent - (formatPrefixAuto.prefixExponent = /*snip*/) + 1
/*snip*/
}
Instead of using some sneaky backdoor, go through a window at the front:
export default function(x, p, window) {
window = window || {};
/*snip*/
var i = exponent - (window.prefixExponent = /*snip*/) + 1
/*snip*/
}
(Okay, so the naming is a little cheeky, but you get the idea!)
Or accept an optional callback:
export default function(x, p, cb) {
var prefixExponent;
/*snip*/
var i = exponent - (prefixExponent = /*snip*/) + 1
/*snip*/
cb && cb(prefixExponent);
/*snip*/
}
Then locale.js
would need to do something like this:
var window = {};
value = formatType(Math.abs(value), precision, window);
valueSuffix = (type === "s" ? prefixes[8 + window.prefixExponent / 3] : "") + /*snip*/ "";
or
var prefixExponent;
value = formatType(Math.abs(value), precision, x => prefixExponent = x);
valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + /*snip*/ "";
formatPrefix should take a reference value and then compute the prefix based on what the s
format type would normally do. For example, if the value is 1e-6, it uses µ.
We also need a precisionPrefix function that takes a step and value and returns the appropriate precision to use with formatPrefix. For example, if step is 1e-7 and value is 1e-6, then the returned precision should be 1. The assumption is that value is the same value that is passed to formatPrefix and determines the units, and then step is scaled appropriately before calling precisionFixed.
var p = precisionPrefix(1e-7, 1e-6),
f = formatPrefix("." + p, 1e-6);
f(1e-7); // 0.1µ
f(2e-7); // 0.2µ
f(1e-6); // 1.0µ
Instead of today’s API, which requires you to (a) specify a prefix explicitly and (b) rescale the step before calling precisionFixed:
var p = precisionFixed(1e-7 / 1e-6),
f = formatPrefix("." + p, "µ");
f(1e-7); // 0.1µ
f(2e-7); // 0.2µ
f(1e-6); // 1.0µ
Also, this should be more accurate, since we can do the scaling in integer space, effectively:
var p = precisionFixed(1e-7) - 6,
f = formatPrefix("." + p, "µ");
f(1e-7); // 0.1µ
f(2e-7); // 0.2µ
f(1e-6); // 1.0µ
Alternatively, we could provide an API for returning a suggested prefix based on a given value, and another API (or the same API) for returning a scale factor / exponent for that suggested prefix. But I think the above is probably better?
Currently if I do d3.format("0.3s")(myString)
it will add trailing zeros, however in the case when working with population-based data, it adds trailing zeroes for data involving whole numbers (for example, 9 -> 9.00)
I can't really control what data is coming in so I'm getting floats like this e.g.: 34.21
to represent 34.21%. Except using the percentage hoverformats multiply that number by 100, outputting: 3421%
Is there a way to bypass that multiplication?
Hi,
Apparently the fr_FR locale contains a mistake for the thousands: it shouldn't be a dot but a no break space.
It's not registered on Bower, and if you point it to the repository, it doesn't pull the built version. (only worked with absolute link to package)
Is this just not implemented yet or is it intentional because it's not ready?
Hi there,
I really like how your library supports a lot of locales for formatting numbers.
I was wondering if there was a way to use the correct minus sign (instead of the hyphen character) for negative numbers? If not, I’d like to suggest this as an enhancement.
A bit of background: A hyphen is usually shorter than a minus and is aligned with the lowercase letters of a font (as it is used to break words across lines). A minus sign is longer (in most cases it’ll have the width of the plus sign) and is vertically aligned slightly higher (it is aligned with the figures, which in most fonts used in websites have the height of uppercase numbers). See the attached image for a comparison of plus
, minus
and hyphen
character.
Cheers and keep up the good work 🎉
On numerous occasions I've needed a formatter to change seconds into hh:mm:ss format, and googling indicates wider interest in a formatter to handle something similar. A few examples:
10 seconds: 0:10
100 seconds: 1:40
100.5 seconds: 1:40.5
100.5 seconds with 6 zero fills and rounding to zero decimals: 00:01:41
I this something that would fall within the scope of d3-format? While something similar can be accomplished with d3-time-format, I feel that this is more applicable to d3-format, as the underlying variable in this case is seconds, not a Date. If so I would be happy to write up a PR for the feature.
Hello, Since d3.format supports number formating, so it will be nice if it supports numeric shaping feature too.
Arabic and many other languages (Thai and Bengali) have classical shapes for digits “National Digits” that are different from the conventional Western Digits (European).
National digits have the same semantic meaning as the European digits, and the numbers they form are read from left to right (most significant digit on the left). The difference is only a difference in glyphs.
European Digits 0 1 2 3 4 5 6 7 8 9
Arabic-Indic Digits ٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩
From the Arabic user's point of view, Arabic-Indic numerals are the basic numerals used in almost all forms of documents such as most of government documents (IDs, birth certificates, driver's licenses, passports and household bills), bank statements, newspapers, calendars, road signs and menus.
Options for Arabic Numeric Shaping
There are 3 options which should be taken into consideration when implementing national numeric shaping support in any framework/technology. These options are:
• None: No shaping is performed, and the value appears as it is in the data source.
• National: Digit shapes are determined from the user’s language.
• Contextual: Digit shapes are determined from the preceding characters in the buffer. European digits follow strong Latin character and Arabic-Indic digits follow strong Arabic character. When there is no preceding strong characters, the base text direction attribute determines the digit shaping. (Arabic-Indic digits in RTL context and European digits in LTR context).
### Problem Statement
Most of the available frameworks/technologies lack the contextual shaping option of national digits. Contextual digit shaping is a very important feature as the Arabic users don’t expect to see Arabic-Indic numerals or European numerals only when they have mixed English and Arabic data.
For example, if a document has many paragraphs/charts some in Arabic and others in English, in the Arabic paragraphs/charts Arabic users expect to see national or Arabic-Indic numerals, and in the English ones Arabic users expect to see European numerals.
Since the mixed English and Arabic data cases are very common in Arabic region, the same case with numerals is very common too.
Hello,
If possible add option to use the Intl.NumberFormat instead of the current format.
Currently for the charts I use the d3-format and for the rest of the application I use the Intl.NumberFormat
If is possible to create an option to set the default locale I want to use to format the numbers with the Intl API.
d3.formatDefaultLocaleIntl('en-GB'); // if empty use the browser locale
P.S. also for the https://github.com/d3/d3-time-format to do the same would be great.
Thanks
Just ran across #21 trying to solve the same problem (no existing support for indian number formatting).
I've just used the google closure i18n lib to implement the en-IN
locale for everything except my d3 axis so I've already got access to CLDR data in my app and would like to continue using what I already have if possible. This would be a relatively common case as CLDR is part of unicode and the JSON packages are consumed by several existing JS i18n "engines", e.g.:
Any particular reason why d3 has defined its own locale JSON format (other than historical reasons) instead of using the Unicode CLDR system?
From what I can see:
Benefits of CLDR:
Cons of CLDR:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.