source: Dev/trunk/d3/src/layout/histogram.js @ 76

Last change on this file since 76 was 76, checked in by fpvanagthoven, 14 years ago

d3

File size: 3.3 KB
Line 
1d3.layout.histogram = function() {
2  var frequency = true,
3      valuer = Number,
4      ranger = d3_layout_histogramRange,
5      binner = d3_layout_histogramBinSturges;
6
7  function histogram(data, i) {
8    var bins = [],
9        values = data.map(valuer, this),
10        range = ranger.call(this, values, i),
11        thresholds = binner.call(this, range, values, i),
12        bin,
13        i = -1,
14        n = values.length,
15        m = thresholds.length - 1,
16        k = frequency ? 1 : 1 / n,
17        x;
18
19    // Initialize the bins.
20    while (++i < m) {
21      bin = bins[i] = [];
22      bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]);
23      bin.y = 0;
24    }
25
26    // Fill the bins, ignoring values outside the range.
27    i = -1; while(++i < n) {
28      x = values[i];
29      if ((x >= range[0]) && (x <= range[1])) {
30        bin = bins[d3.bisect(thresholds, x, 1, m) - 1];
31        bin.y += k;
32        bin.push(data[i]);
33      }
34    }
35
36    return bins;
37  }
38
39  // Specifies how to extract a value from the associated data. The default
40  // value function is `Number`, which is equivalent to the identity function.
41  histogram.value = function(x) {
42    if (!arguments.length) return valuer;
43    valuer = x;
44    return histogram;
45  };
46
47  // Specifies the range of the histogram. Values outside the specified range
48  // will be ignored. The argument `x` may be specified either as a two-element
49  // array representing the minimum and maximum value of the range, or as a
50  // function that returns the range given the array of values and the current
51  // index `i`. The default range is the extent (minimum and maximum) of the
52  // values.
53  histogram.range = function(x) {
54    if (!arguments.length) return ranger;
55    ranger = d3.functor(x);
56    return histogram;
57  };
58
59  // Specifies how to bin values in the histogram. The argument `x` may be
60  // specified as a number, in which case the range of values will be split
61  // uniformly into the given number of bins. Or, `x` may be an array of
62  // threshold values, defining the bins; the specified array must contain the
63  // rightmost (upper) value, thus specifying n + 1 values for n bins. Or, `x`
64  // may be a function which is evaluated, being passed the range, the array of
65  // values, and the current index `i`, returning an array of thresholds. The
66  // default bin function will divide the values into uniform bins using
67  // Sturges' formula.
68  histogram.bins = function(x) {
69    if (!arguments.length) return binner;
70    binner = typeof x === "number"
71        ? function(range) { return d3_layout_histogramBinFixed(range, x); }
72        : d3.functor(x);
73    return histogram;
74  };
75
76  // Specifies whether the histogram's `y` value is a count (frequency) or a
77  // probability (density). The default value is true.
78  histogram.frequency = function(x) {
79    if (!arguments.length) return frequency;
80    frequency = !!x;
81    return histogram;
82  };
83
84  return histogram;
85};
86
87function d3_layout_histogramBinSturges(range, values) {
88  return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));
89}
90
91function d3_layout_histogramBinFixed(range, n) {
92  var x = -1,
93      b = +range[0],
94      m = (range[1] - b) / n,
95      f = [];
96  while (++x <= n) f[x] = m * x + b;
97  return f;
98}
99
100function d3_layout_histogramRange(values) {
101  return [d3.min(values), d3.max(values)];
102}
Note: See TracBrowser for help on using the repository browser.