Merge branch 'fix-mean-string' into 3.4.13

This commit is contained in:
Mike Bostock 2014-10-16 23:00:51 -07:00
Родитель 84e242f9e9 eaed66d4b6
Коммит a18b3f33dc
12 изменённых файлов: 100 добавлений и 25 удалений

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

@ -88,14 +88,17 @@
return s;
};
function d3_number(x) {
return x != null && !isNaN(x);
return x === null ? NaN : +x;
}
function d3_numeric(x) {
return !isNaN(x);
}
d3.mean = function(array, f) {
var s = 0, n = array.length, a, i = -1, j = n;
if (arguments.length === 1) {
while (++i < n) if (d3_number(a = array[i])) s += a; else --j;
while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j;
} else {
while (++i < n) if (d3_number(a = f.call(array, array[i], i))) s += a; else --j;
while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j;
}
return j ? s / j : undefined;
};
@ -104,9 +107,13 @@
return e ? v + e * (values[h] - v) : v;
};
d3.median = function(array, f) {
if (arguments.length > 1) array = array.map(f);
array = array.filter(d3_number);
return array.length ? d3.quantile(array.sort(d3_ascending), .5) : undefined;
var array1 = [], n = array.length, a, i = -1;
if (arguments.length === 1) {
while (++i < n) if (d3_numeric(a = d3_number(array[i]))) array1.push(a);
} else {
while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) array1.push(a);
}
return array1.length ? d3.quantile(array1.sort(d3_ascending), .5) : undefined;
};
function d3_bisector(compare) {
return {
@ -2122,7 +2129,7 @@
return t.reverse().join(locale_thousands);
} : d3_identity;
return function(specifier) {
var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false;
var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "-", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false;
if (precision) precision = +precision.substring(1);
if (zfill || fill === "0" && align === "=") {
zfill = fill = "0";
@ -2174,7 +2181,7 @@
return function(value) {
var fullSuffix = suffix;
if (integer && value % 1) return "";
var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign;
var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign === "-" ? "" : sign;
if (scale < 0) {
var unit = d3.formatPrefix(value, precision);
value = unit.scale(value);
@ -7676,7 +7683,7 @@
}
scale.domain = function(x) {
if (!arguments.length) return domain;
domain = x.filter(d3_number).sort(d3_ascending);
domain = x.map(d3_number).filter(d3_numeric).sort(d3_ascending);
return rescale();
};
scale.range = function(x) {

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

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

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

@ -7,9 +7,9 @@ d3.mean = function(array, f) {
i = -1,
j = n;
if (arguments.length === 1) {
while (++i < n) if (d3_number(a = array[i])) s += a; else --j;
while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j;
} else {
while (++i < n) if (d3_number(a = f.call(array, array[i], i))) s += a; else --j;
while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j;
}
return j ? s / j : undefined;
};

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

@ -3,7 +3,16 @@ import "ascending";
import "quantile";
d3.median = function(array, f) {
if (arguments.length > 1) array = array.map(f);
array = array.filter(d3_number);
return array.length ? d3.quantile(array.sort(d3_ascending), .5) : undefined;
var array1 = [],
n = array.length,
a,
i = -1;
if (arguments.length === 1) {
while (++i < n) if (d3_numeric(a = d3_number(array[i]))) array1.push(a);
} else {
while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) array1.push(a);
}
return array1.length ? d3.quantile(array1.sort(d3_ascending), .5) : undefined;
};

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

@ -25,7 +25,7 @@ function d3_locale_numberFormat(locale) {
var match = d3_format_re.exec(specifier),
fill = match[1] || " ",
align = match[2] || ">",
sign = match[3] || "",
sign = match[3] || "-",
symbol = match[4] || "",
zfill = match[5],
width = +match[6],
@ -80,7 +80,7 @@ function d3_locale_numberFormat(locale) {
if (integer && (value % 1)) return "";
// Convert negative to positive, and record the sign prefix.
var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign;
var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign === "-" ? "" : sign;
// Apply the scale, computing it from the value's exponent for si format.
// Preserve the existing suffix, if any, such as the currency symbol.

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

@ -1,3 +1,7 @@
function d3_number(x) {
return x != null && !isNaN(x);
return x === null ? NaN : +x;
}
function d3_numeric(x) {
return !isNaN(x);
}

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

@ -25,7 +25,7 @@ function d3_scale_quantile(domain, range) {
scale.domain = function(x) {
if (!arguments.length) return domain;
domain = x.filter(d3_number).sort(d3_ascending);
domain = x.map(d3_number).filter(d3_numeric).sort(d3_ascending);
return rescale();
};

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

@ -1,6 +1,7 @@
var vows = require("vows"),
load = require("../load"),
assert = require("../assert");
assert = require("../assert"),
OneTimeNumber = require("./one-time-number");
var suite = vows.describe("d3.mean");
@ -28,6 +29,17 @@ suite.addBatch({
"applies the optional accessor function": function(mean) {
assert.equal(mean([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return mean(d); }), 4.5);
assert.equal(mean([1, 2, 3, 4, 5], function(d, i) { return i; }), 2);
},
"coerces values to numbers": function(mean) {
assert.equal(mean(["1"]), 1);
assert.equal(mean(["5", "1", "2", "3", "4"]), 3);
assert.equal(mean(["20", "3"]), 11.5);
assert.equal(mean(["3", "20"]), 11.5);
},
"coerces values exactly once": function(mean) {
var array = [1, new OneTimeNumber(3)];
assert.equal(mean(array), 2);
assert.equal(mean(array), 1);
}
}
});

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

@ -1,6 +1,7 @@
var vows = require("vows"),
load = require("../load"),
assert = require("../assert");
assert = require("../assert"),
OneTimeNumber = require("./one-time-number");
var suite = vows.describe("d3.median");
@ -32,6 +33,19 @@ suite.addBatch({
"applies the optional accessor function": function(median) {
assert.equal(median([[1, 2, 3, 4, 5], [2, 4, 6, 8, 10]], function(d) { return median(d); }), 4.5);
assert.equal(median([1, 2, 3, 4, 5], function(d, i) { return i; }), 2);
},
"coerces strings to numbers": function(median) {
assert.equal(median(["1"]), 1);
assert.equal(median(["5", "1", "2", "3", "4"]), 3);
assert.equal(median(["20", "3"]), 11.5);
assert.equal(median(["3", "20"]), 11.5);
assert.equal(median(["2", "3", "20"]), 3);
assert.equal(median(["20", "3", "2"]), 3);
},
"coerces values exactly once": function(median) {
var array = [1, new OneTimeNumber(3)];
assert.equal(median(array), 2);
assert.equal(median(array), 1);
}
}
});

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

@ -0,0 +1,11 @@
module.exports = OneTimeNumber;
function OneTimeNumber(value) {
this.value = value;
}
OneTimeNumber.prototype.valueOf = function() {
var v = this.value;
this.value = NaN;
return v;
};

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

@ -371,6 +371,16 @@ suite.addBatch({
assert.strictEqual(format(" 13,d")(0), " 0");
assert.strictEqual(format(" 21,d")(0), " 0");
},
"explicitly only use a sign for negative numbers": function(format) {
assert.strictEqual(format("-1,d")(-1), "-1");
assert.strictEqual(format("-1,d")(0), "0");
assert.strictEqual(format("-2,d")(0), " 0");
assert.strictEqual(format("-3,d")(0), " 0");
assert.strictEqual(format("-5,d")(0), " 0");
assert.strictEqual(format("-8,d")(0), " 0");
assert.strictEqual(format("-13,d")(0), " 0");
assert.strictEqual(format("-21,d")(0), " 0");
},
"can format negative zero": function(format) {
assert.strictEqual(format("1d")(-0), "-0");
assert.strictEqual(format("1f")(-0), "-0");

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

@ -29,6 +29,14 @@ suite.addBatch({
var x = quantile().domain([6, 3, 7, 8, 8, 13, 20, 15, 16, 10]);
assert.deepEqual(x.domain(), [3, 6, 7, 8, 8, 10, 13, 15, 16, 20]);
},
"domain values are coerced to numbers": function(quantile) {
var x = quantile().domain(["6", "13", "20"]);
assert.deepEqual(x.domain(), [6, 13, 20]);
},
"domain values are allowed to be zero": function(quantile) {
var x = quantile().domain([1, 2, 0, 0, null]);
assert.deepEqual(x.domain(), [0, 0, 1, 2]);
},
"non-numeric domain values are ignored": function(quantile) {
var x = quantile().domain([6, 3, NaN, undefined, 7, 8, 8, 13, null, 20, 15, 16, 10, NaN]);
assert.deepEqual(x.domain(), [3, 6, 7, 8, 8, 10, 13, 15, 16, 20]);