0

I found this thread and it got me halfway to where I need to be and I'm wondering if anyone knows how I can adjust the solution to fit my needs.

So if I have some values in the thousands, and some values in the millions, does anyone know how I can set all of the ticks to be formatted in the millions? For instance, if I have a value for 800k it would show up as 0.8million instead.

This is what I get when using the above solution without adjusting it. enter image description here

Community
  • 1
  • 1

1 Answers1

0

You don't need to use a SI prefix in this case. Given this domain:

var scale = d3.scaleLinear().domain([200000,1800000])

Going from 200 thousand to 1.8 million, you can simply divide the tick value by 1,000,000 and add a "million" string.

Here is the demo:

var svg = d3.select("body")
 .append("svg")
 .attr("width", 600)
 .attr("height", 100);
 
var scale = d3.scaleLinear().domain([200000,1800000]).range([20,550]);

var axis = d3.axisBottom(scale).tickFormat(function(d){return d/1000000 + " Million"});

var gX = svg.append("g").attr("transform", "translate(20, 50)").call(axis);
<script src="https://d3js.org/d3.v4.min.js"></script>

EDIT: According to the comments, you want to show "million" only in the last tick. Thus, we have to check if the tick is the last one and conditionally formatting it:

var axis = d3.axisBottom(scale).tickFormat(function(d){
    if(this.parentNode.nextSibling){
        return d/1000000;
    } else { 
        return d/1000000 + " Million";
    }
});

Here is the demo:

var svg = d3.select("body")
 .append("svg")
 .attr("width", 600)
 .attr("height", 100);
 
var scale = d3.scaleLinear().domain([200000,1800000]).range([20,550]);

var axis = d3.axisBottom(scale).tickFormat(function(d){
 if(this.parentNode.nextSibling){
return d/1000000} else { return d/1000000  + " Million"}});

var gX = svg.append("g").attr("transform", "translate(20, 50)").call(axis);
<script src="https://d3js.org/d3.v4.min.js"></script>
Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
  • Is there a way to do it without adjusting the domain and range? I need it set a certain way for the chart to be responsive – Jugal Patel Oct 11 '16 at 22:27
  • The domain doesn't matter, it was just an example in the snippet. Whatever the value, if you divide it by 1000000 and add " million", you'll have it in millions. – Gerardo Furtado Oct 12 '16 at 00:56
  • nice that works perfectly then! do you know how i can have it so that only the top-most tick on the y axis has the " Million" label and the rest dont? – Jugal Patel Oct 12 '16 at 16:02
  • It also gives me "1 Million" instead of "1.0 Million". Do you know how I can get the latter? I tried setting this: var formatValue = d3.format(".2"); and then using: .tickFormat(function(d){return formatValue(d/1000000) + " mil"}) but im still getting the 1 instead of the 1.0, sorry am still getting used to d3 – Jugal Patel Oct 12 '16 at 16:26
  • Oops, sorry I figured out the formatting, just needed to set (".2") to be (".1f") instead. All I need to do now is to only have "Million" showing up on the top-most tick instead of the others. Having some trouble selecting just that tick with d3 – Jugal Patel Oct 12 '16 at 16:32