Consistent SI-prefix for ticks. Fixes #1746.

When a SI-prefix format (type "s") is passed to scale.tickFormat, compute a
suitable SI-prefix based on the maximum value in the range, and then use that
prefix for all ticks rather than computing the SI-prefix on a per-tick basis.
This commit is contained in:
Mike Bostock 2014-03-23 21:37:34 -07:00
Родитель d6ca25e87d
Коммит 91531cf7ff
4 изменённых файлов: 52 добавлений и 11 удалений

20
d3.js поставляемый
Просмотреть файл

@ -7471,9 +7471,23 @@
}
function d3_scale_linearTickFormat(domain, m, format) {
var range = d3_scale_linearTickRange(domain, m);
return d3.format(format ? format.replace(d3_format_re, function(a, b, c, d, e, f, g, h, i, j) {
return [ b, c, d, e, f, g, h, i || "." + d3_scale_linearFormatPrecision(j, range), j ].join("");
}) : ",." + d3_scale_linearPrecision(range[2]) + "f");
if (format) {
var match = d3_format_re.exec(format);
match.shift();
if (match[8] === "s") {
var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1])) * (match[7] ? Math.pow(10, -match[7].substring(1)) : 1));
match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2])), match[8] = "f";
format = d3.format(match.join(""));
return function(d) {
return format(prefix.scale(d)) + prefix.symbol;
};
}
if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range);
format = match.join("");
} else {
format = ",." + d3_scale_linearPrecision(range[2]) + "f";
}
return d3.format(format);
}
var d3_scale_linearFormatSignificant = {
s: 1,

8
d3.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -4,6 +4,7 @@ import "../interpolate/interpolate";
import "../interpolate/round";
import "../interpolate/uninterpolate";
import "../format/format";
import "../math/abs";
import "bilinear";
import "nice";
import "polylinear";
@ -116,9 +117,23 @@ function d3_scale_linearTicks(domain, m) {
function d3_scale_linearTickFormat(domain, m, format) {
var range = d3_scale_linearTickRange(domain, m);
return d3.format(format
? format.replace(d3_format_re, function(a, b, c, d, e, f, g, h, i, j) { return [b, c, d, e, f, g, h, i || "." + d3_scale_linearFormatPrecision(j, range), j].join(""); })
: ",." + d3_scale_linearPrecision(range[2]) + "f");
if (format) {
var match = d3_format_re.exec(format);
match.shift();
if (match[8] === "s") {
var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1])) * (match[7] ? Math.pow(10, -match[7].substring(1)) : 1));
match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2])), match[8] = "f";
format = d3.format(match.join(""));
return function(d) {
return format(prefix.scale(d)) + prefix.symbol;
};
}
if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range);
format = match.join("");
} else {
format = ",." + d3_scale_linearPrecision(range[2]) + "f";
}
return d3.format(format);
}
var d3_scale_linearFormatSignificant = {s: 1, g: 1, p: 1, r: 1, e: 1};

Просмотреть файл

@ -216,11 +216,23 @@ suite.addBatch({
"tickFormat": {
"applies automatic precision when not explicitly specified": function(d3) {
var x = d3.scale.linear();
assert.strictEqual(x.tickFormat(10, "f")(Math.PI), "3.1")
assert.strictEqual(x.tickFormat(10, "f")(Math.PI), "3.1");
assert.strictEqual(x.tickFormat(100, "f")(Math.PI), "3.14");
assert.strictEqual(x.tickFormat(100, "$f")(Math.PI), "$3.14");
assert.strictEqual(x.domain([0, 100]).tickFormat(100, "%")(Math.PI), "314%");
},
"applies fixed-scale SI-prefix notation": function(d3) {
var x = d3.scale.linear().domain([0, 1e6]);
assert.deepEqual(x.ticks(10).map(x.tickFormat(10, "s")), ["0.0M", "0.1M", "0.2M", "0.3M", "0.4M", "0.5M", "0.6M", "0.7M", "0.8M", "0.9M", "1.0M"]);
assert.deepEqual(x.ticks(10).map(x.tickFormat(10, "+$s")), ["+$0.0M", "+$0.1M", "+$0.2M", "+$0.3M", "+$0.4M", "+$0.5M", "+$0.6M", "+$0.7M", "+$0.8M", "+$0.9M", "+$1.0M"]);
assert.deepEqual(x.ticks(10).map(x.tickFormat(10, ".1s")), ["0k", "100k", "200k", "300k", "400k", "500k", "600k", "700k", "800k", "900k", "1000k"]);
var x = d3.scale.linear().domain([0, 1e5]);
assert.deepEqual(x.ticks(10).map(x.tickFormat(10, "s")), ["0k", "10k", "20k", "30k", "40k", "50k", "60k", "70k", "80k", "90k", "100k"]);
assert.deepEqual(x.ticks(10).map(x.tickFormat(10, ".-1s")), ["0.00M", "0.01M", "0.02M", "0.03M", "0.04M", "0.05M", "0.06M", "0.07M", "0.08M", "0.09M", "0.10M"]);
var x = d3.scale.linear().domain([0, 1e-4]);
assert.deepEqual(x.ticks(10).map(x.tickFormat(10, "s")), ["0.00m", "0.01m", "0.02m", "0.03m", "0.04m", "0.05m", "0.06m", "0.07m", "0.08m", "0.09m", "0.10m"]);
assert.deepEqual(x.ticks(10).map(x.tickFormat(10, ".2s")), ["0µ", "10µ", "20µ", "30µ", "40µ", "50µ", "60µ", "70µ", "80µ", "90µ", "100µ"]);
},
"if count is not specified, defaults to 10": function(d3) {
var x = d3.scale.linear();
assert.strictEqual(x.tickFormat()(Math.PI), "3.1");