I'm using d3 to display the number of persons in a group. Based on how the user filter, it can be more than 100k or a single digit number
I tried d3.format(".2s"), and it works well most of the time, but I have two problems:
My ideal format function would display the integer with the maximum precision possible in a fixed maximum number of characters/numbers. so if I want to limit the display to 3 numbers/4 chars, it would:
is there a way to specify a maximum display size instead of a specific precision?
(and before any mathematician burns me to have such a cavalier attitude to precision, the number display is to give an indication, the users always have an option to see the real number, without any loss of precision ;)
You can achieve it by specifying custom formatting function. If I understand you correctly, it should look like this:
function customFormat(value) {
var formattedValue = value;
if (value > 999 && value < 100000) {
if (value % 1000 < 50) {
formattedValue = d3.format('.0s')(value);
} else {
formattedValue = d3.format('.2s')(value);
}
} else if (value >= 100000) {
formattedValue = d3.format('.3s')(value);
}
return formattedValue;
}
Little demo how it works:
var svgOne = d3.select("#scale-one")
.append("svg")
.attr("width", 500)
.attr("height", 50)
.append("g")
.attr("transform", "translate(20,0)");
var svgTwo = d3.select("#scale-two")
.append("svg")
.attr("width", 500)
.attr("height", 100)
.append("g")
.attr("transform", "translate(20,0)");
var x = d3.scaleLinear()
.range([0,490])
.domain([0,2000]);
function customFormat(value) {
var formattedValue = value;
if (value > 999 && value < 100000) {
if (value % 1000 < 50) {
formattedValue = d3.format('.0s')(value);
} else {
formattedValue = d3.format('.2s')(value);
}
} else if (value >= 100000) {
formattedValue = d3.format('.3s')(value);
}
return formattedValue;
}
var xAxis = d3.axisBottom(x)
.tickValues([8, 777, 1049, 1750])
.tickFormat(customFormat);
var xLargeNumbers = d3.scaleLinear()
.range([0,490])
.domain([123000, 126000]);
var xAxisLargeNumbers = d3.axisBottom(xLargeNumbers)
.tickValues([123499, 123999])
.tickFormat(customFormat);
svgOne.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0,5)")
.call(xAxis);
svgTwo.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0,5)")
.call(xAxisLargeNumbers);
<script src="https://d3js.org/d3.v4.js"></script>
<div>Ticks: [8, 777, 1049, 1750] -</div>
<div id="scale-one"></div>
<div>Ticks: [123499, 123999] -</div>
<div id="scale-two"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With