You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
1.9 KiB
75 lines
1.9 KiB
import {slice} from "./array"; |
|
import bisect from "./bisect"; |
|
import constant from "./constant"; |
|
import extent from "./extent"; |
|
import identity from "./identity"; |
|
import range from "./range"; |
|
import {tickStep} from "./ticks"; |
|
import sturges from "./threshold/sturges"; |
|
|
|
export default function() { |
|
var value = identity, |
|
domain = extent, |
|
threshold = sturges; |
|
|
|
function histogram(data) { |
|
var i, |
|
n = data.length, |
|
x, |
|
values = new Array(n); |
|
|
|
for (i = 0; i < n; ++i) { |
|
values[i] = value(data[i], i, data); |
|
} |
|
|
|
var xz = domain(values), |
|
x0 = xz[0], |
|
x1 = xz[1], |
|
tz = threshold(values, x0, x1); |
|
|
|
// Convert number of thresholds into uniform thresholds. |
|
if (!Array.isArray(tz)) { |
|
tz = tickStep(x0, x1, tz); |
|
tz = range(Math.ceil(x0 / tz) * tz, x1, tz); // exclusive |
|
} |
|
|
|
// Remove any thresholds outside the domain. |
|
var m = tz.length; |
|
while (tz[0] <= x0) tz.shift(), --m; |
|
while (tz[m - 1] > x1) tz.pop(), --m; |
|
|
|
var bins = new Array(m + 1), |
|
bin; |
|
|
|
// Initialize bins. |
|
for (i = 0; i <= m; ++i) { |
|
bin = bins[i] = []; |
|
bin.x0 = i > 0 ? tz[i - 1] : x0; |
|
bin.x1 = i < m ? tz[i] : x1; |
|
} |
|
|
|
// Assign data to bins by value, ignoring any outside the domain. |
|
for (i = 0; i < n; ++i) { |
|
x = values[i]; |
|
if (x0 <= x && x <= x1) { |
|
bins[bisect(tz, x, 0, m)].push(data[i]); |
|
} |
|
} |
|
|
|
return bins; |
|
} |
|
|
|
histogram.value = function(_) { |
|
return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value; |
|
}; |
|
|
|
histogram.domain = function(_) { |
|
return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain; |
|
}; |
|
|
|
histogram.thresholds = function(_) { |
|
return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold; |
|
}; |
|
|
|
return histogram; |
|
}
|
|
|