Spaces:
Running
Running
| import "../arrays/bisect"; | |
| import "../arrays/min"; | |
| import "../arrays/max"; | |
| import "../core/functor"; | |
| import "layout"; | |
| d3.layout.histogram = function() { | |
| var frequency = true, | |
| valuer = Number, | |
| ranger = d3_layout_histogramRange, | |
| binner = d3_layout_histogramBinSturges; | |
| function histogram(data, i) { | |
| var bins = [], | |
| values = data.map(valuer, this), | |
| range = ranger.call(this, values, i), | |
| thresholds = binner.call(this, range, values, i), | |
| bin, | |
| i = -1, | |
| n = values.length, | |
| m = thresholds.length - 1, | |
| k = frequency ? 1 : 1 / n, | |
| x; | |
| // Initialize the bins. | |
| while (++i < m) { | |
| bin = bins[i] = []; | |
| bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); | |
| bin.y = 0; | |
| } | |
| // Fill the bins, ignoring values outside the range. | |
| if (m > 0) { | |
| i = -1; while(++i < n) { | |
| x = values[i]; | |
| if (x >= range[0] && x <= range[1]) { | |
| bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; | |
| bin.y += k; | |
| bin.push(data[i]); | |
| } | |
| } | |
| } | |
| return bins; | |
| } | |
| // Specifies how to extract a value from the associated data. The default | |
| // value function is `Number`, which is equivalent to the identity function. | |
| histogram.value = function(x) { | |
| if (!arguments.length) return valuer; | |
| valuer = x; | |
| return histogram; | |
| }; | |
| // Specifies the range of the histogram. Values outside the specified range | |
| // will be ignored. The argument `x` may be specified either as a two-element | |
| // array representing the minimum and maximum value of the range, or as a | |
| // function that returns the range given the array of values and the current | |
| // index `i`. The default range is the extent (minimum and maximum) of the | |
| // values. | |
| histogram.range = function(x) { | |
| if (!arguments.length) return ranger; | |
| ranger = d3_functor(x); | |
| return histogram; | |
| }; | |
| // Specifies how to bin values in the histogram. The argument `x` may be | |
| // specified as a number, in which case the range of values will be split | |
| // uniformly into the given number of bins. Or, `x` may be an array of | |
| // threshold values, defining the bins; the specified array must contain the | |
| // rightmost (upper) value, thus specifying n + 1 values for n bins. Or, `x` | |
| // may be a function which is evaluated, being passed the range, the array of | |
| // values, and the current index `i`, returning an array of thresholds. The | |
| // default bin function will divide the values into uniform bins using | |
| // Sturges' formula. | |
| histogram.bins = function(x) { | |
| if (!arguments.length) return binner; | |
| binner = typeof x === "number" | |
| ? function(range) { return d3_layout_histogramBinFixed(range, x); } | |
| : d3_functor(x); | |
| return histogram; | |
| }; | |
| // Specifies whether the histogram's `y` value is a count (frequency) or a | |
| // probability (density). The default value is true. | |
| histogram.frequency = function(x) { | |
| if (!arguments.length) return frequency; | |
| frequency = !!x; | |
| return histogram; | |
| }; | |
| return histogram; | |
| }; | |
| function d3_layout_histogramBinSturges(range, values) { | |
| return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); | |
| } | |
| function d3_layout_histogramBinFixed(range, n) { | |
| var x = -1, | |
| b = +range[0], | |
| m = (range[1] - b) / n, | |
| f = []; | |
| while (++x <= n) f[x] = m * x + b; | |
| return f; | |
| } | |
| function d3_layout_histogramRange(values) { | |
| return [d3.min(values), d3.max(values)]; | |
| } | |