I am using d3-format's format function to round some numbers (yes, I know this isn't necessary).
When I format negative numbers, I get a string of a negative number, as expected. However, when I convert it back into a number using the shorthand, it returns NaN. This is not what should happen. I should get back a regular negative number.
import {format} from "d3-format"; //version 3.1.0
let numberFormatter = d3.format(".3f");
let neg = -2.333;
let negString = "-2.333";
let d3negString = numberFormatter(neg);
//the strings look the same
console.log(d3negString) // "-2.333"
console.log(negString) // "-2.333"
//both strings have the same type of 'string'
console.log(typeof negString === typeof d3negString); // true
//but they are not equal
console.log(negString === d3negString); // false
//normal strings work as expected
console.log(isNaN( negString)); // false
//but strings from d3-format function returns NaN
console.log(isNaN( d3negString)); // true
It says that both strings have the same type 'string', however their values are not equal?? Even though the text is equal?
What is the true type of d3-formatted number strings? They can't just be normal strings, right? Why is it returning NaN? Is this a bug?
MacOS Big Sur
Chrome 96.0.4664.110
[email protected]
CodePudding user response:
The change log of d3, shows that in version 2.0.0 the following was changed:
Change the default minus sign to the minus sign (−) instead of hyphen-minus (-).
In this thread on D3's github are some interesting comments:
D3 did use the minus sign originally, but people complained about that, too (e.g., #595), primarily because there was an expectation that d3.format would use the same symbol as JavaScript’s
number.toString. The minus sign was thus replaced with hyphen-minus in 2.10.0 (da3131c, #756).
And:
This is now available as an opt-in by specifying the locale’s
minusproperty. And I’m considering making the minus sign the default (again) in the next major version.
CodePudding user response:
The reason this doesn't work is because the 'minus' characters, despite appearing identical, are different unicode symbols.
Luckily, d3 provides a way to change the default minus character to whatever you choose using the formatLocale function.]
'HYPHEN-MINUS' U 002D unicode character is recognized as a 'negative sign'.
// import {format} from 'd3-format' //do not directly import format with default settings
import { formatLocale} from "d3-format"
const format = formatLocale({ minus: "\u002D"}).format
let numberFormatter = d3.format(".3f");
let neg = -2.333;
let negString = "-2.333";
let d3negString = numberFormatter(neg);
console.log(d3negString) // "-2.333"
console.log(negString) // "-2.333"
console.log(typeof negString === typeof d3negString); // true
console.log(negString === d3negString); // true
console.log(isNaN( negString)); // false
console.log(isNaN( d3negString)); // false
The larger moral of the story is that d3-format's goal is NOT to round numbers - it is to make number look nice as text. To prevent problems, use Math.round() or "-2.3333".toFixed(3) // => -2.333 to round numbers in javascript.
