3

Newbie Alert! My experience with JavaScript and SVG is EXTREMELY dated and I am completely new to d3.

I've just learned that d3.format('s') will display a number like 160,000 to 160k and a number like 20,000,000,000 to 20G. AWESOME!! There is just one teeny-tiny problem. This is a format for Scientific Notation in Bytes. I assume (maybe incorrectly) there must be an additional parameter that d3 uses to display numbers in Thousands (16T) and Millions (160M) and Billions (20B) instead of Bytes. No?

I have found another question how to get localizable or customizable si codes with d3.format and have looked at other similar questions but have yet to find what I believe to be the real answer. If what I am trying to do is not a feature in d3 but there is a work-around, I might need a little help implementing it.

I have been stepping through the d3 code to try to understand how to use the the other input parameters, si codes, prefix, type, etc. and even tried to glean some information from a tutorial here: D3.format tutorial through examples

It's become pretty clear that one needs to be an expert in D3 alone. So, in the absence of time, I'm asking for a D3 guru to please help.

Community
  • 1
  • 1
Patricia
  • 5,019
  • 14
  • 72
  • 152
  • 1
    See issue [#2241 *d3.format() for number abbreviations (similar to SI-prefix)*](https://github.com/d3/d3/issues/2241). – altocumulus Dec 29 '16 at 19:12
  • 1
    @Patricia just a little correction: K, M, G etc are not *"Scientific Notation in Bytes"*, as you said. That's the metric prefix of Système International d'unités for **everything**. So, using SI prefixes, 1000 meters is 1Km (kilometer), 1000000 meters is 1Mm (megameter), and so on. That also applies to mass (grams), volume (litres), temperature (Kelvins), energy (Joules), etc... – Gerardo Furtado Dec 30 '16 at 00:29
  • @GerardoFurtado - Good to know! Knowing that, means that localization is really what I want to do here? Yes? – Patricia Dec 30 '16 at 17:06
  • 1
    https://stackoverflow.com/a/75066143/8614532 This answer can be a solution. – Aditya Jan 10 '23 at 06:30

1 Answers1

3

Here's a custom formatting function adapted from another question:

function getFormatter(digits) {
  var notations = [
    // { value: 1E12, suffix: "T" }, what you'll use for trillion?
    { value: 1E9,  suffix: "B" },
    { value: 1E6,  suffix: "M" },
    { value: 1E3,  suffix: "T" }        
  ]

  rx = /\.0+$|(\.[0-9]*[1-9])0+$/

  return function(num) {
        var notation
    for (var i = 0; i < notations.length; i++) {
      notation = notations[i]
      if (num >= notation.value) {
        var value = num / notation.value
        value = value.toFixed(digits)
        value = value.replace(rx, "$1")
        return value + notation.suffix
      }
    }
  }
}


var numbers = [
  20000000000,
  160020,
  18200000
]

d3.select('body')
  .append('ul')
  .selectAll('li')
  .data(numbers)
  .enter()
  .append('li')
  .text(getFormatter(2))
span {
  display:
}
<script src="https://d3js.org/d3.v4.min.js"></script>

Hopefully only the notations variable is relevant to your problem. But let me know if you need any further clarification. Good luck!

Community
  • 1
  • 1
cvsguimaraes
  • 12,910
  • 9
  • 49
  • 73