Merge branch 'scale-log-base' into 3.1.0
This commit is contained in:
Коммит
98d09c8aa7
|
@ -2363,9 +2363,6 @@ d3 = function() {
|
||||||
}
|
}
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
function d3_scale_niceDefault() {
|
|
||||||
return Math;
|
|
||||||
}
|
|
||||||
d3.scale.linear = function() {
|
d3.scale.linear = function() {
|
||||||
return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3.interpolate, false);
|
return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3.interpolate, false);
|
||||||
};
|
};
|
||||||
|
@ -2471,10 +2468,9 @@ d3 = function() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
d3.scale.log = function() {
|
d3.scale.log = function() {
|
||||||
return d3_scale_log(d3.scale.linear(), d3_scale_logp);
|
return d3_scale_log(d3.scale.linear().domain([ 0, Math.LN10 ]), 10, d3_scale_logp, d3_scale_powp);
|
||||||
};
|
};
|
||||||
function d3_scale_log(linear, log) {
|
function d3_scale_log(linear, base, log, pow) {
|
||||||
var pow = log.pow;
|
|
||||||
function scale(x) {
|
function scale(x) {
|
||||||
return linear(log(x));
|
return linear(log(x));
|
||||||
}
|
}
|
||||||
|
@ -2483,25 +2479,30 @@ d3 = function() {
|
||||||
};
|
};
|
||||||
scale.domain = function(x) {
|
scale.domain = function(x) {
|
||||||
if (!arguments.length) return linear.domain().map(pow);
|
if (!arguments.length) return linear.domain().map(pow);
|
||||||
log = x[0] < 0 ? d3_scale_logn : d3_scale_logp;
|
if (x[0] < 0) log = d3_scale_logn, pow = d3_scale_pown; else log = d3_scale_logp,
|
||||||
pow = log.pow;
|
pow = d3_scale_powp;
|
||||||
linear.domain(x.map(log));
|
linear.domain(x.map(log));
|
||||||
return scale;
|
return scale;
|
||||||
};
|
};
|
||||||
|
scale.base = function(_) {
|
||||||
|
if (!arguments.length) return base;
|
||||||
|
base = +_;
|
||||||
|
return scale;
|
||||||
|
};
|
||||||
scale.nice = function() {
|
scale.nice = function() {
|
||||||
linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault));
|
linear.domain(d3_scale_nice(linear.domain(), d3_scale_logNice(base)));
|
||||||
return scale;
|
return scale;
|
||||||
};
|
};
|
||||||
scale.ticks = function() {
|
scale.ticks = function() {
|
||||||
var extent = d3_scaleExtent(linear.domain()), ticks = [];
|
var extent = d3_scaleExtent(linear.domain()), ticks = [];
|
||||||
if (extent.every(isFinite)) {
|
if (extent.every(isFinite)) {
|
||||||
var i = Math.floor(extent[0]), j = Math.ceil(extent[1]), u = pow(extent[0]), v = pow(extent[1]);
|
var b = Math.log(base), i = Math.floor(extent[0] / b), j = Math.ceil(extent[1] / b), u = pow(extent[0]), v = pow(extent[1]), n = base % 1 ? 2 : base;
|
||||||
if (log === d3_scale_logn) {
|
if (log === d3_scale_logn) {
|
||||||
ticks.push(pow(i));
|
ticks.push(-Math.pow(base, -i));
|
||||||
for (;i++ < j; ) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k);
|
for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(-Math.pow(base, -i) * k);
|
||||||
} else {
|
} else {
|
||||||
for (;i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k);
|
for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(Math.pow(base, i) * k);
|
||||||
ticks.push(pow(i));
|
ticks.push(Math.pow(base, i));
|
||||||
}
|
}
|
||||||
for (i = 0; ticks[i] < u; i++) {}
|
for (i = 0; ticks[i] < u; i++) {}
|
||||||
for (j = ticks.length; ticks[j - 1] > v; j--) {}
|
for (j = ticks.length; ticks[j - 1] > v; j--) {}
|
||||||
|
@ -2512,30 +2513,44 @@ d3 = function() {
|
||||||
scale.tickFormat = function(n, format) {
|
scale.tickFormat = function(n, format) {
|
||||||
if (arguments.length < 2) format = d3_scale_logFormat;
|
if (arguments.length < 2) format = d3_scale_logFormat;
|
||||||
if (!arguments.length) return format;
|
if (!arguments.length) return format;
|
||||||
var k = Math.max(.1, n / scale.ticks().length), f = log === d3_scale_logn ? (e = -1e-12,
|
var b = Math.log(base), k = Math.max(.1, n / scale.ticks().length), f = log === d3_scale_logn ? (e = -1e-12,
|
||||||
Math.floor) : (e = 1e-12, Math.ceil), e;
|
Math.floor) : (e = 1e-12, Math.ceil), e;
|
||||||
return function(d) {
|
return function(d) {
|
||||||
return d / pow(f(log(d) + e)) <= k ? format(d) : "";
|
return d / pow(b * f(log(d) / b + e)) <= k ? format(d) : "";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
scale.copy = function() {
|
scale.copy = function() {
|
||||||
return d3_scale_log(linear.copy(), log);
|
return d3_scale_log(linear.copy(), base, log, pow);
|
||||||
};
|
};
|
||||||
return d3_scale_linearRebind(scale, linear);
|
return d3_scale_linearRebind(scale, linear);
|
||||||
}
|
}
|
||||||
var d3_scale_logFormat = d3.format(".0e");
|
var d3_scale_logFormat = d3.format(".0e");
|
||||||
function d3_scale_logp(x) {
|
function d3_scale_logp(x) {
|
||||||
return Math.log(x < 0 ? 0 : x) / Math.LN10;
|
return Math.log(x < 0 ? 0 : x);
|
||||||
|
}
|
||||||
|
function d3_scale_powp(x) {
|
||||||
|
return Math.exp(x);
|
||||||
}
|
}
|
||||||
function d3_scale_logn(x) {
|
function d3_scale_logn(x) {
|
||||||
return -Math.log(x > 0 ? 0 : -x) / Math.LN10;
|
return -Math.log(x > 0 ? 0 : -x);
|
||||||
|
}
|
||||||
|
function d3_scale_pown(x) {
|
||||||
|
return -Math.exp(-x);
|
||||||
|
}
|
||||||
|
function d3_scale_logNice(base) {
|
||||||
|
base = Math.log(base);
|
||||||
|
var nice = {
|
||||||
|
floor: function(x) {
|
||||||
|
return Math.floor(x / base) * base;
|
||||||
|
},
|
||||||
|
ceil: function(x) {
|
||||||
|
return Math.ceil(x / base) * base;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return function() {
|
||||||
|
return nice;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
d3_scale_logp.pow = function(x) {
|
|
||||||
return Math.pow(10, x);
|
|
||||||
};
|
|
||||||
d3_scale_logn.pow = function(x) {
|
|
||||||
return -Math.pow(10, -x);
|
|
||||||
};
|
|
||||||
d3.scale.pow = function() {
|
d3.scale.pow = function() {
|
||||||
return d3_scale_pow(d3.scale.linear(), 1);
|
return d3_scale_pow(d3.scale.linear(), 1);
|
||||||
};
|
};
|
||||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,9 +1,8 @@
|
||||||
d3.scale.log = function() {
|
d3.scale.log = function() {
|
||||||
return d3_scale_log(d3.scale.linear(), d3_scale_logp);
|
return d3_scale_log(d3.scale.linear().domain([0, Math.LN10]), 10, d3_scale_logp, d3_scale_powp);
|
||||||
};
|
};
|
||||||
|
|
||||||
function d3_scale_log(linear, log) {
|
function d3_scale_log(linear, base, log, pow) {
|
||||||
var pow = log.pow;
|
|
||||||
|
|
||||||
function scale(x) {
|
function scale(x) {
|
||||||
return linear(log(x));
|
return linear(log(x));
|
||||||
|
@ -15,14 +14,20 @@ function d3_scale_log(linear, log) {
|
||||||
|
|
||||||
scale.domain = function(x) {
|
scale.domain = function(x) {
|
||||||
if (!arguments.length) return linear.domain().map(pow);
|
if (!arguments.length) return linear.domain().map(pow);
|
||||||
log = x[0] < 0 ? d3_scale_logn : d3_scale_logp;
|
if (x[0] < 0) log = d3_scale_logn, pow = d3_scale_pown;
|
||||||
pow = log.pow;
|
else log = d3_scale_logp, pow = d3_scale_powp;
|
||||||
linear.domain(x.map(log));
|
linear.domain(x.map(log));
|
||||||
return scale;
|
return scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
scale.base = function(_) {
|
||||||
|
if (!arguments.length) return base;
|
||||||
|
base = +_;
|
||||||
|
return scale;
|
||||||
|
};
|
||||||
|
|
||||||
scale.nice = function() {
|
scale.nice = function() {
|
||||||
linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault));
|
linear.domain(d3_scale_nice(linear.domain(), d3_scale_logNice(base)));
|
||||||
return scale;
|
return scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,16 +35,18 @@ function d3_scale_log(linear, log) {
|
||||||
var extent = d3_scaleExtent(linear.domain()),
|
var extent = d3_scaleExtent(linear.domain()),
|
||||||
ticks = [];
|
ticks = [];
|
||||||
if (extent.every(isFinite)) {
|
if (extent.every(isFinite)) {
|
||||||
var i = Math.floor(extent[0]),
|
var b = Math.log(base),
|
||||||
j = Math.ceil(extent[1]),
|
i = Math.floor(extent[0] / b),
|
||||||
|
j = Math.ceil(extent[1] / b),
|
||||||
u = pow(extent[0]),
|
u = pow(extent[0]),
|
||||||
v = pow(extent[1]);
|
v = pow(extent[1]),
|
||||||
|
n = base % 1 ? 2 : base;
|
||||||
if (log === d3_scale_logn) {
|
if (log === d3_scale_logn) {
|
||||||
ticks.push(pow(i));
|
ticks.push(-Math.pow(base, -i));
|
||||||
for (; i++ < j;) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k);
|
for (; i++ < j;) for (var k = n - 1; k > 0; k--) ticks.push(-Math.pow(base, -i) * k);
|
||||||
} else {
|
} else {
|
||||||
for (; i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k);
|
for (; i < j; i++) for (var k = 1; k < n; k++) ticks.push(Math.pow(base, i) * k);
|
||||||
ticks.push(pow(i));
|
ticks.push(Math.pow(base, i));
|
||||||
}
|
}
|
||||||
for (i = 0; ticks[i] < u; i++) {} // strip small values
|
for (i = 0; ticks[i] < u; i++) {} // strip small values
|
||||||
for (j = ticks.length; ticks[j - 1] > v; j--) {} // strip big values
|
for (j = ticks.length; ticks[j - 1] > v; j--) {} // strip big values
|
||||||
|
@ -51,16 +58,17 @@ function d3_scale_log(linear, log) {
|
||||||
scale.tickFormat = function(n, format) {
|
scale.tickFormat = function(n, format) {
|
||||||
if (arguments.length < 2) format = d3_scale_logFormat;
|
if (arguments.length < 2) format = d3_scale_logFormat;
|
||||||
if (!arguments.length) return format;
|
if (!arguments.length) return format;
|
||||||
var k = Math.max(.1, n / scale.ticks().length),
|
var b = Math.log(base),
|
||||||
|
k = Math.max(.1, n / scale.ticks().length),
|
||||||
f = log === d3_scale_logn ? (e = -1e-12, Math.floor) : (e = 1e-12, Math.ceil),
|
f = log === d3_scale_logn ? (e = -1e-12, Math.floor) : (e = 1e-12, Math.ceil),
|
||||||
e;
|
e;
|
||||||
return function(d) {
|
return function(d) {
|
||||||
return d / pow(f(log(d) + e)) <= k ? format(d) : "";
|
return d / pow(b * f(log(d) / b + e)) <= k ? format(d) : "";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
scale.copy = function() {
|
scale.copy = function() {
|
||||||
return d3_scale_log(linear.copy(), log);
|
return d3_scale_log(linear.copy(), base, log, pow);
|
||||||
};
|
};
|
||||||
|
|
||||||
return d3_scale_linearRebind(scale, linear);
|
return d3_scale_linearRebind(scale, linear);
|
||||||
|
@ -69,17 +77,26 @@ function d3_scale_log(linear, log) {
|
||||||
var d3_scale_logFormat = d3.format(".0e");
|
var d3_scale_logFormat = d3.format(".0e");
|
||||||
|
|
||||||
function d3_scale_logp(x) {
|
function d3_scale_logp(x) {
|
||||||
return Math.log(x < 0 ? 0 : x) / Math.LN10;
|
return Math.log(x < 0 ? 0 : x);
|
||||||
|
}
|
||||||
|
|
||||||
|
function d3_scale_powp(x) {
|
||||||
|
return Math.exp(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
function d3_scale_logn(x) {
|
function d3_scale_logn(x) {
|
||||||
return -Math.log(x > 0 ? 0 : -x) / Math.LN10;
|
return -Math.log(x > 0 ? 0 : -x);
|
||||||
}
|
}
|
||||||
|
|
||||||
d3_scale_logp.pow = function(x) {
|
function d3_scale_pown(x) {
|
||||||
return Math.pow(10, x);
|
return -Math.exp(-x);
|
||||||
};
|
}
|
||||||
|
|
||||||
d3_scale_logn.pow = function(x) {
|
function d3_scale_logNice(base) {
|
||||||
return -Math.pow(10, -x);
|
base = Math.log(base);
|
||||||
};
|
var nice = {
|
||||||
|
floor: function(x) { return Math.floor(x / base) * base; },
|
||||||
|
ceil: function(x) { return Math.ceil(x / base) * base; }
|
||||||
|
};
|
||||||
|
return function() { return nice; };
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,3 @@ function d3_scale_nice(domain, nice) {
|
||||||
|
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
function d3_scale_niceDefault() {
|
|
||||||
return Math;
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ suite.addBatch({
|
||||||
"domain": {
|
"domain": {
|
||||||
"defaults to [1, 10]": function(log) {
|
"defaults to [1, 10]": function(log) {
|
||||||
var x = log();
|
var x = log();
|
||||||
assert.deepEqual(x.domain(), [1, 10]);
|
assert.inDelta(x.domain(), [1, 10], 1e-6);
|
||||||
assert.inDelta(x(5), 0.69897, 1e-6);
|
assert.inDelta(x(5), 0.69897, 1e-6);
|
||||||
},
|
},
|
||||||
"coerces domain values to numbers": function(log) {
|
"coerces domain values to numbers": function(log) {
|
||||||
|
@ -216,30 +216,52 @@ suite.addBatch({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"base two": {
|
||||||
|
topic: function(log) {
|
||||||
|
return log().domain([1, 32]).base(2);
|
||||||
|
},
|
||||||
|
"generates ticks at powers of two": function(x) {
|
||||||
|
assert.deepEqual(x.ticks().map(x.tickFormat(10, d3.format("+,d"))), [
|
||||||
|
"+1", "+2", "+4", "+8", "+16", "+32"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"base e": {
|
||||||
|
topic: function(log) {
|
||||||
|
return log().domain([1, 32]).base(Math.E);
|
||||||
|
},
|
||||||
|
"generates ticks at powers of e": function(x) {
|
||||||
|
assert.deepEqual(x.ticks().map(x.tickFormat(10, d3.format("+.6r"))), [
|
||||||
|
"+1.00000", "+2.71828", "+7.38906", "+20.0855"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"nice": {
|
"nice": {
|
||||||
"can nice the domain, extending it to powers of ten": function(log) {
|
"can nice the domain, extending it to powers of ten": function(log) {
|
||||||
var x = log().domain([1.1, 10.9]).nice();
|
var x = log().domain([1.1, 10.9]).nice();
|
||||||
assert.deepEqual(x.domain(), [1, 100]);
|
assert.inDelta(x.domain(), [1, 100], 1e-6);
|
||||||
var x = log().domain([10.9, 1.1]).nice();
|
var x = log().domain([10.9, 1.1]).nice();
|
||||||
assert.deepEqual(x.domain(), [100, 1]);
|
assert.inDelta(x.domain(), [100, 1], 1e-6);
|
||||||
var x = log().domain([.7, 11.001]).nice();
|
var x = log().domain([.7, 11.001]).nice();
|
||||||
assert.deepEqual(x.domain(), [.1, 100]);
|
assert.inDelta(x.domain(), [.1, 100], 1e-6);
|
||||||
var x = log().domain([123.1, 6.7]).nice();
|
var x = log().domain([123.1, 6.7]).nice();
|
||||||
assert.deepEqual(x.domain(), [1000, 1]);
|
assert.inDelta(x.domain(), [1000, 1], 1e-6);
|
||||||
var x = log().domain([.01, .49]).nice();
|
var x = log().domain([.01, .49]).nice();
|
||||||
assert.deepEqual(x.domain(), [.01, 1]);
|
assert.inDelta(x.domain(), [.01, 1], 1e-6);
|
||||||
},
|
},
|
||||||
"works on degenerate domains": function(log) {
|
"works on degenerate domains": function(log) {
|
||||||
var x = log().domain([0, 0]).nice();
|
var x = log().domain([0, 0]).nice();
|
||||||
assert.deepEqual(x.domain(), [0, 0]);
|
assert.inDelta(x.domain(), [0, 0], 1e-6);
|
||||||
var x = log().domain([.5, .5]).nice();
|
var x = log().domain([.5, .5]).nice();
|
||||||
assert.inDelta(x.domain(), [.1, 1], 1e-6);
|
assert.inDelta(x.domain(), [.1, 1], 1e-6);
|
||||||
},
|
},
|
||||||
"nicing a polylog domain only affects the extent": function(log) {
|
"nicing a polylog domain only affects the extent": function(log) {
|
||||||
var x = log().domain([1.1, 1.5, 10.9]).nice();
|
var x = log().domain([1.1, 1.5, 10.9]).nice();
|
||||||
assert.deepEqual(x.domain(), [1, 1.5, 100]);
|
assert.inDelta(x.domain(), [1, 1.5, 100], 1e-6);
|
||||||
var x = log().domain([-123.1, -1.5, -.5]).nice();
|
var x = log().domain([-123.1, -1.5, -.5]).nice();
|
||||||
assert.deepEqual(x.domain(), [-1000, -1.5, -.1]);
|
assert.inDelta(x.domain(), [-1000, -1.5, -.1], 1e-6);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -247,24 +269,24 @@ suite.addBatch({
|
||||||
"changes to the domain are isolated": function(log) {
|
"changes to the domain are isolated": function(log) {
|
||||||
var x = log(), y = x.copy();
|
var x = log(), y = x.copy();
|
||||||
x.domain([10, 100]);
|
x.domain([10, 100]);
|
||||||
assert.deepEqual(y.domain(), [1, 10]);
|
assert.inDelta(y.domain(), [1, 10], 1e-6);
|
||||||
assert.equal(x(10), 0);
|
assert.inDelta(x(10), 0, 1e-6);
|
||||||
assert.equal(y(1), 0);
|
assert.inDelta(y(1), 0, 1e-6);
|
||||||
y.domain([100, 1000]);
|
y.domain([100, 1000]);
|
||||||
assert.equal(x(100), 1);
|
assert.inDelta(x(100), 1, 1e-6);
|
||||||
assert.equal(y(100), 0);
|
assert.inDelta(y(100), 0, 1e-6);
|
||||||
assert.deepEqual(x.domain(), [10, 100]);
|
assert.inDelta(x.domain(), [10, 100], 1e-6);
|
||||||
assert.deepEqual(y.domain().map(Math.round), [100, 1000]);
|
assert.inDelta(y.domain(), [100, 1000], 1e-6);
|
||||||
},
|
},
|
||||||
"changes to the range are isolated": function(log) {
|
"changes to the range are isolated": function(log) {
|
||||||
var x = log(), y = x.copy();
|
var x = log(), y = x.copy();
|
||||||
x.range([1, 2]);
|
x.range([1, 2]);
|
||||||
assert.equal(x.invert(1), 1);
|
assert.inDelta(x.invert(1), 1, 1e-6);
|
||||||
assert.equal(y.invert(1), 10);
|
assert.inDelta(y.invert(1), 10, 1e-6);
|
||||||
assert.deepEqual(y.range(), [0, 1]);
|
assert.deepEqual(y.range(), [0, 1]);
|
||||||
y.range([2, 3]);
|
y.range([2, 3]);
|
||||||
assert.equal(x.invert(2), 10);
|
assert.inDelta(x.invert(2), 10, 1e-6);
|
||||||
assert.equal(y.invert(2), 1);
|
assert.inDelta(y.invert(2), 1, 1e-6);
|
||||||
assert.deepEqual(x.range(), [1, 2]);
|
assert.deepEqual(x.range(), [1, 2]);
|
||||||
assert.deepEqual(y.range(), [2, 3]);
|
assert.deepEqual(y.range(), [2, 3]);
|
||||||
},
|
},
|
||||||
|
@ -279,7 +301,7 @@ suite.addBatch({
|
||||||
var x = log().clamp(true), y = x.copy();
|
var x = log().clamp(true), y = x.copy();
|
||||||
x.clamp(false);
|
x.clamp(false);
|
||||||
assert.inDelta(x(.5), -0.30103, 1e-6);
|
assert.inDelta(x(.5), -0.30103, 1e-6);
|
||||||
assert.equal(y(.5), 0);
|
assert.inDelta(y(.5), 0, 1e-6);
|
||||||
assert.isTrue(y.clamp());
|
assert.isTrue(y.clamp());
|
||||||
y.clamp(false);
|
y.clamp(false);
|
||||||
assert.inDelta(x(20), 1.30103, 1e-6);
|
assert.inDelta(x(20), 1.30103, 1e-6);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче