// 升序
d3.ascending = function (a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
};
// 降序
d3.descending = function (a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
};
// 最小值
d3.min = function (array, f) {
var i = -1,
n = array.length,
a, b;
if (arguments.length === 1) {
while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
while (++i < n)
if ((b = array[i]) != null && a > b) a = b;
} else {
while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
while (++i < n)
if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
}
return a;
};
// 最大值
d3.max = function (array, f) {
var i = -1,
n = array.length,
a, b;
if (arguments.length === 1) {
while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
while (++i < n)
if ((b = array[i]) != null && b > a) a = b;
} else {
while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
while (++i < n)
if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
}
return a;
};
// 范围
d3.extent = function (array, f) {
var i = -1,
n = array.length,
a, b, c;
if (arguments.length === 1) {
while (++i < n && ((a = c = array[i]) == null || a != a)) a = c = undefined;
while (++i < n)
if ((b = array[i]) != null) {
if (a > b) a = b;
if (c < b) c = b;
}
} else {
while (++i < n && ((a = c = f.call(array, array[i], i)) == null || a != a)) a = undefined;
while (++i < n)
if ((b = f.call(array, array[i], i)) != null) {
if (a > b) a = b;
if (c < b) c = b;
}
}
return [a, c];
};
// 和
d3.sum = function (array, f) {
var s = 0,
n = array.length,
a, i = -1;
if (arguments.length === 1) {
while (++i < n)
if (!isNaN(a = +array[i])) s += a;
} else {
while (++i < n)
if (!isNaN(a = +f.call(array, array[i], i))) s += a;
}
return s;
};
function d3_number(x) {
return x != null && !isNaN(x);
}
// 平均值
d3.mean = function (array, f) {
var n = array.length,
a, m = 0,
i = -1,
j = 0;
if (arguments.length === 1) {
while (++i < n)
if (d3_number(a = array[i])) m += (a - m) / ++j;
} else {
while (++i < n)
if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j;
}
return j ? m : undefined;
};
// 分位数
d3.quantile = function (values, p) {
var H = (values.length - 1) * p + 1,
h = Math.floor(H),
v = +values[h - 1],
e = H - h;
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;
};
// 二等分线
d3.bisector = function (f) {
return {
left: function (a, x, lo, hi) {
if (arguments.length < 3) lo = 0;
if (arguments.length < 4) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (f.call(a, a[mid], mid) < x) lo = mid + 1;
else hi = mid;
}
return lo;
},
right: function (a, x, lo, hi) {
if (arguments.length < 3) lo = 0;
if (arguments.length < 4) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (x < f.call(a, a[mid], mid)) hi = mid;
else lo = mid + 1;
}
return lo;
}
};
};
var d3_bisector = d3.bisector(function (d) {
return d;
});
d3.bisectLeft = d3_bisector.left;
d3.bisect = d3.bisectRight = d3_bisector.right;
// 混序
d3.shuffle = function (array) {
var m = array.length,
t, i;
while (m) {
i = Math.random() * m-- | 0;
t = array[m], array[m] = array[i], array[i] = t;
}
return array;
};
// 序列改变
d3.permute = function (array, indexes) {
var permutes = [],
i = -1,
n = indexes.length;
while (++i < n) permutes[i] = array[indexes[i]];
return permutes;
};
d3.zip = function () {
if (!(n = arguments.length)) return [];
for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m;) {
for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n;) {
zip[j] = arguments[j][i];
}
}
return zips;
};
function d3_zipLength(d) {
return d.length;
}
// 转置
d3.transpose = function (matrix) {
return d3.zip.apply(d3, matrix);
};