在 d3 中显示具有最大精度但固定长度的整数(使用 SI 表示法)
Display integers with max precision but fixed length in d3 (use SI notation)
我正在使用 d3 来显示群组中的人数。根据用户的过滤方式,可以超过100k或个位数
我尝试了d3.format(".2s"),大部分时间都运行良好,但我有两个问题:
- 当数字<10时,显示8 .0,我需要显示8
- 当号码在100到999之间时,去掉最后一位,所以442人显示为440
我理想的格式函数将在固定的最大数目 characters/numbers 中以尽可能高的精度显示整数。所以如果我想将显示限制为 3 numbers/4 个字符,它将:
- 最多显示999
- 从 1000 到 1049 显示 1k
- 从 1050 到 1099 显示 1.1k
- 显示 123k 从 123'000 到 123'499
- ...
有没有办法指定最大显示尺寸而不是特定精度?
(在任何数学家对精度持如此傲慢的态度之前,数字显示只是为了给出指示,用户始终可以选择查看真实数字,而不会损失任何精度;)
您可以通过指定自定义格式化函数来实现。如果我没理解错的话,它应该是这样的:
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 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>
我正在使用 d3 来显示群组中的人数。根据用户的过滤方式,可以超过100k或个位数
我尝试了d3.format(".2s"),大部分时间都运行良好,但我有两个问题:
- 当数字<10时,显示8 .0,我需要显示8
- 当号码在100到999之间时,去掉最后一位,所以442人显示为440
我理想的格式函数将在固定的最大数目 characters/numbers 中以尽可能高的精度显示整数。所以如果我想将显示限制为 3 numbers/4 个字符,它将:
- 最多显示999
- 从 1000 到 1049 显示 1k
- 从 1050 到 1099 显示 1.1k
- 显示 123k 从 123'000 到 123'499
- ...
有没有办法指定最大显示尺寸而不是特定精度?
(在任何数学家对精度持如此傲慢的态度之前,数字显示只是为了给出指示,用户始终可以选择查看真实数字,而不会损失任何精度;)
您可以通过指定自定义格式化函数来实现。如果我没理解错的话,它应该是这样的:
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 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>