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.


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).


This is now available as an opt-in by specifying the locale’s minus property. And I’m considering making the minus sign the default (again) in the next major version.

Related Query

More Query from same tag