rubyvis 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +13 -0
  4. data/Gemfile +8 -0
  5. data/Gemfile.lock +37 -0
  6. data/History.txt +6 -0
  7. data/LICENSE.txt +23 -0
  8. data/{README.txt → README.md} +15 -12
  9. data/Rakefile +4 -11
  10. data/lib/rubyvis.rb +1 -1
  11. data/lib/rubyvis/scale/quantitative.rb +14 -18
  12. data/lib/rubyvis/scene/svg_label.rb +1 -1
  13. data/rubyvis.gemspec +21 -0
  14. data/spec/anchor_spec.rb +2 -1
  15. data/spec/line_spec.rb +2 -2
  16. data/spec/scale_linear_datetime_spec.rb +23 -8
  17. data/spec/spec_helper.rb +2 -1
  18. metadata +31 -214
  19. data/.gemtest +0 -0
  20. data/vendor/protovis/protovis-r3.3.js +0 -287
  21. data/vendor/protovis/src/behavior/Behavior.js +0 -32
  22. data/vendor/protovis/src/behavior/Drag.js +0 -112
  23. data/vendor/protovis/src/behavior/Pan.js +0 -110
  24. data/vendor/protovis/src/behavior/Point.js +0 -157
  25. data/vendor/protovis/src/behavior/Resize.js +0 -104
  26. data/vendor/protovis/src/behavior/Select.js +0 -100
  27. data/vendor/protovis/src/behavior/Zoom.js +0 -85
  28. data/vendor/protovis/src/color/Color.js +0 -598
  29. data/vendor/protovis/src/color/Colors.js +0 -135
  30. data/vendor/protovis/src/color/Ramp.js +0 -17
  31. data/vendor/protovis/src/data/Arrays.js +0 -277
  32. data/vendor/protovis/src/data/Dom.js +0 -380
  33. data/vendor/protovis/src/data/Flatten.js +0 -146
  34. data/vendor/protovis/src/data/Histogram.js +0 -120
  35. data/vendor/protovis/src/data/LinearScale.js +0 -54
  36. data/vendor/protovis/src/data/LogScale.js +0 -142
  37. data/vendor/protovis/src/data/Nest.js +0 -257
  38. data/vendor/protovis/src/data/Numbers.js +0 -313
  39. data/vendor/protovis/src/data/Objects.js +0 -78
  40. data/vendor/protovis/src/data/OrdinalScale.js +0 -267
  41. data/vendor/protovis/src/data/QuantileScale.js +0 -180
  42. data/vendor/protovis/src/data/QuantitativeScale.js +0 -440
  43. data/vendor/protovis/src/data/RootScale.js +0 -55
  44. data/vendor/protovis/src/data/Scale.js +0 -86
  45. data/vendor/protovis/src/data/Transform.js +0 -109
  46. data/vendor/protovis/src/data/Tree.js +0 -124
  47. data/vendor/protovis/src/data/Vector.js +0 -118
  48. data/vendor/protovis/src/geo/Geo.js +0 -5
  49. data/vendor/protovis/src/geo/GeoScale.js +0 -307
  50. data/vendor/protovis/src/geo/LatLng.js +0 -23
  51. data/vendor/protovis/src/geo/Projection.js +0 -43
  52. data/vendor/protovis/src/geo/Projections.js +0 -117
  53. data/vendor/protovis/src/lang/Array.js +0 -112
  54. data/vendor/protovis/src/lang/init.js +0 -26
  55. data/vendor/protovis/src/layout/Arc.js +0 -178
  56. data/vendor/protovis/src/layout/Bullet.js +0 -164
  57. data/vendor/protovis/src/layout/Cluster.js +0 -205
  58. data/vendor/protovis/src/layout/Force.js +0 -309
  59. data/vendor/protovis/src/layout/Grid.js +0 -119
  60. data/vendor/protovis/src/layout/Hierarchy.js +0 -249
  61. data/vendor/protovis/src/layout/Horizon.js +0 -159
  62. data/vendor/protovis/src/layout/Indent.js +0 -83
  63. data/vendor/protovis/src/layout/Layout.js +0 -56
  64. data/vendor/protovis/src/layout/Matrix.js +0 -177
  65. data/vendor/protovis/src/layout/Network.js +0 -302
  66. data/vendor/protovis/src/layout/Pack.js +0 -323
  67. data/vendor/protovis/src/layout/Partition.js +0 -203
  68. data/vendor/protovis/src/layout/Rollup.js +0 -203
  69. data/vendor/protovis/src/layout/Stack.js +0 -391
  70. data/vendor/protovis/src/layout/Tree.js +0 -282
  71. data/vendor/protovis/src/layout/Treemap.js +0 -347
  72. data/vendor/protovis/src/mark/Anchor.js +0 -81
  73. data/vendor/protovis/src/mark/Area.js +0 -268
  74. data/vendor/protovis/src/mark/Bar.js +0 -93
  75. data/vendor/protovis/src/mark/Dot.js +0 -212
  76. data/vendor/protovis/src/mark/Ease.js +0 -150
  77. data/vendor/protovis/src/mark/Image.js +0 -154
  78. data/vendor/protovis/src/mark/Label.js +0 -155
  79. data/vendor/protovis/src/mark/Line.js +0 -195
  80. data/vendor/protovis/src/mark/Mark.js +0 -1237
  81. data/vendor/protovis/src/mark/Panel.js +0 -273
  82. data/vendor/protovis/src/mark/Rule.js +0 -143
  83. data/vendor/protovis/src/mark/Transient.js +0 -7
  84. data/vendor/protovis/src/mark/Transition.js +0 -195
  85. data/vendor/protovis/src/mark/Wedge.js +0 -244
  86. data/vendor/protovis/src/physics/BoundConstraint.js +0 -75
  87. data/vendor/protovis/src/physics/ChargeForce.js +0 -184
  88. data/vendor/protovis/src/physics/CollisionConstraint.js +0 -113
  89. data/vendor/protovis/src/physics/Constraint.js +0 -26
  90. data/vendor/protovis/src/physics/DragForce.js +0 -49
  91. data/vendor/protovis/src/physics/Force.js +0 -25
  92. data/vendor/protovis/src/physics/Particle.js +0 -81
  93. data/vendor/protovis/src/physics/PositionConstraint.js +0 -72
  94. data/vendor/protovis/src/physics/Quadtree.js +0 -195
  95. data/vendor/protovis/src/physics/Simulation.js +0 -159
  96. data/vendor/protovis/src/physics/SpringForce.js +0 -141
  97. data/vendor/protovis/src/pv-internals.js +0 -154
  98. data/vendor/protovis/src/pv.js +0 -95
  99. data/vendor/protovis/src/scene/SvgArea.js +0 -172
  100. data/vendor/protovis/src/scene/SvgBar.js +0 -28
  101. data/vendor/protovis/src/scene/SvgCurve.js +0 -354
  102. data/vendor/protovis/src/scene/SvgDot.js +0 -81
  103. data/vendor/protovis/src/scene/SvgImage.js +0 -45
  104. data/vendor/protovis/src/scene/SvgLabel.js +0 -46
  105. data/vendor/protovis/src/scene/SvgLine.js +0 -159
  106. data/vendor/protovis/src/scene/SvgPanel.js +0 -126
  107. data/vendor/protovis/src/scene/SvgRule.js +0 -26
  108. data/vendor/protovis/src/scene/SvgScene.js +0 -185
  109. data/vendor/protovis/src/scene/SvgWedge.js +0 -66
  110. data/vendor/protovis/src/text/DateFormat.js +0 -262
  111. data/vendor/protovis/src/text/Format.js +0 -78
  112. data/vendor/protovis/src/text/NumberFormat.js +0 -227
  113. data/vendor/protovis/src/text/TimeFormat.js +0 -115
@@ -1,257 +0,0 @@
1
- /**
2
- * Returns a {@link pv.Nest} operator for the specified array. This is a
3
- * convenience factory method, equivalent to <tt>new pv.Nest(array)</tt>.
4
- *
5
- * @see pv.Nest
6
- * @param {array} array an array of elements to nest.
7
- * @returns {pv.Nest} a nest operator for the specified array.
8
- */
9
- pv.nest = function(array) {
10
- return new pv.Nest(array);
11
- };
12
-
13
- /**
14
- * Constructs a nest operator for the specified array. This constructor should
15
- * not be invoked directly; use {@link pv.nest} instead.
16
- *
17
- * @class Represents a {@link Nest} operator for the specified array. Nesting
18
- * allows elements in an array to be grouped into a hierarchical tree
19
- * structure. The levels in the tree are specified by <i>key</i> functions. The
20
- * leaf nodes of the tree can be sorted by value, while the internal nodes can
21
- * be sorted by key. Finally, the tree can be returned either has a
22
- * multidimensional array via {@link #entries}, or as a hierarchical map via
23
- * {@link #map}. The {@link #rollup} routine similarly returns a map, collapsing
24
- * the elements in each leaf node using a summary function.
25
- *
26
- * <p>For example, consider the following tabular data structure of Barley
27
- * yields, from various sites in Minnesota during 1931-2:
28
- *
29
- * <pre>{ yield: 27.00, variety: "Manchuria", year: 1931, site: "University Farm" },
30
- * { yield: 48.87, variety: "Manchuria", year: 1931, site: "Waseca" },
31
- * { yield: 27.43, variety: "Manchuria", year: 1931, site: "Morris" }, ...</pre>
32
- *
33
- * To facilitate visualization, it may be useful to nest the elements first by
34
- * year, and then by variety, as follows:
35
- *
36
- * <pre>var nest = pv.nest(yields)
37
- * .key(function(d) d.year)
38
- * .key(function(d) d.variety)
39
- * .entries();</pre>
40
- *
41
- * This returns a nested array. Each element of the outer array is a key-values
42
- * pair, listing the values for each distinct key:
43
- *
44
- * <pre>{ key: 1931, values: [
45
- * { key: "Manchuria", values: [
46
- * { yield: 27.00, variety: "Manchuria", year: 1931, site: "University Farm" },
47
- * { yield: 48.87, variety: "Manchuria", year: 1931, site: "Waseca" },
48
- * { yield: 27.43, variety: "Manchuria", year: 1931, site: "Morris" },
49
- * ...
50
- * ] },
51
- * { key: "Glabron", values: [
52
- * { yield: 43.07, variety: "Glabron", year: 1931, site: "University Farm" },
53
- * { yield: 55.20, variety: "Glabron", year: 1931, site: "Waseca" },
54
- * ...
55
- * ] },
56
- * ] },
57
- * { key: 1932, values: ... }</pre>
58
- *
59
- * Further details, including sorting and rollup, is provided below on the
60
- * corresponding methods.
61
- *
62
- * @param {array} array an array of elements to nest.
63
- */
64
- pv.Nest = function(array) {
65
- this.array = array;
66
- this.keys = [];
67
- };
68
-
69
- /**
70
- * Nests using the specified key function. Multiple keys may be added to the
71
- * nest; the array elements will be nested in the order keys are specified.
72
- *
73
- * @param {function} key a key function; must return a string or suitable map
74
- * key.
75
- * @returns {pv.Nest} this.
76
- */
77
- pv.Nest.prototype.key = function(key) {
78
- this.keys.push(key);
79
- return this;
80
- };
81
-
82
- /**
83
- * Sorts the previously-added keys. The natural sort order is used by default
84
- * (see {@link pv.naturalOrder}); if an alternative order is desired,
85
- * <tt>order</tt> should be a comparator function. If this method is not called
86
- * (i.e., keys are <i>unsorted</i>), keys will appear in the order they appear
87
- * in the underlying elements array. For example,
88
- *
89
- * <pre>pv.nest(yields)
90
- * .key(function(d) d.year)
91
- * .key(function(d) d.variety)
92
- * .sortKeys()
93
- * .entries()</pre>
94
- *
95
- * groups yield data by year, then variety, and sorts the variety groups
96
- * lexicographically (since the variety attribute is a string).
97
- *
98
- * <p>Key sort order is only used in conjunction with {@link #entries}, which
99
- * returns an array of key-values pairs. If the nest is used to construct a
100
- * {@link #map} instead, keys are unsorted.
101
- *
102
- * @param {function} [order] an optional comparator function.
103
- * @returns {pv.Nest} this.
104
- */
105
- pv.Nest.prototype.sortKeys = function(order) {
106
- this.keys[this.keys.length - 1].order = order || pv.naturalOrder;
107
- return this;
108
- };
109
-
110
- /**
111
- * Sorts the leaf values. The natural sort order is used by default (see
112
- * {@link pv.naturalOrder}); if an alternative order is desired, <tt>order</tt>
113
- * should be a comparator function. If this method is not called (i.e., values
114
- * are <i>unsorted</i>), values will appear in the order they appear in the
115
- * underlying elements array. For example,
116
- *
117
- * <pre>pv.nest(yields)
118
- * .key(function(d) d.year)
119
- * .key(function(d) d.variety)
120
- * .sortValues(function(a, b) a.yield - b.yield)
121
- * .entries()</pre>
122
- *
123
- * groups yield data by year, then variety, and sorts the values for each
124
- * variety group by yield.
125
- *
126
- * <p>Value sort order, unlike keys, applies to both {@link #entries} and
127
- * {@link #map}. It has no effect on {@link #rollup}.
128
- *
129
- * @param {function} [order] an optional comparator function.
130
- * @returns {pv.Nest} this.
131
- */
132
- pv.Nest.prototype.sortValues = function(order) {
133
- this.order = order || pv.naturalOrder;
134
- return this;
135
- };
136
-
137
- /**
138
- * Returns a hierarchical map of values. Each key adds one level to the
139
- * hierarchy. With only a single key, the returned map will have a key for each
140
- * distinct value of the key function; the correspond value with be an array of
141
- * elements with that key value. If a second key is added, this will be a nested
142
- * map. For example:
143
- *
144
- * <pre>pv.nest(yields)
145
- * .key(function(d) d.variety)
146
- * .key(function(d) d.site)
147
- * .map()</pre>
148
- *
149
- * returns a map <tt>m</tt> such that <tt>m[variety][site]</tt> is an array, a subset of
150
- * <tt>yields</tt>, with each element having the given variety and site.
151
- *
152
- * @returns a hierarchical map of values.
153
- */
154
- pv.Nest.prototype.map = function() {
155
- var map = {}, values = [];
156
-
157
- /* Build the map. */
158
- for (var i, j = 0; j < this.array.length; j++) {
159
- var x = this.array[j];
160
- var m = map;
161
- for (i = 0; i < this.keys.length - 1; i++) {
162
- var k = this.keys[i](x);
163
- if (!m[k]) m[k] = {};
164
- m = m[k];
165
- }
166
- k = this.keys[i](x);
167
- if (!m[k]) {
168
- var a = [];
169
- values.push(a);
170
- m[k] = a;
171
- }
172
- m[k].push(x);
173
- }
174
-
175
- /* Sort each leaf array. */
176
- if (this.order) {
177
- for (var i = 0; i < values.length; i++) {
178
- values[i].sort(this.order);
179
- }
180
- }
181
-
182
- return map;
183
- };
184
-
185
- /**
186
- * Returns a hierarchical nested array. This method is similar to
187
- * {@link pv.entries}, but works recursively on the entire hierarchy. Rather
188
- * than returning a map like {@link #map}, this method returns a nested
189
- * array. Each element of the array has a <tt>key</tt> and <tt>values</tt>
190
- * field. For leaf nodes, the <tt>values</tt> array will be a subset of the
191
- * underlying elements array; for non-leaf nodes, the <tt>values</tt> array will
192
- * contain more key-values pairs.
193
- *
194
- * <p>For an example usage, see the {@link Nest} constructor.
195
- *
196
- * @returns a hierarchical nested array.
197
- */
198
- pv.Nest.prototype.entries = function() {
199
-
200
- /** Recursively extracts the entries for the given map. */
201
- function entries(map) {
202
- var array = [];
203
- for (var k in map) {
204
- var v = map[k];
205
- array.push({ key: k, values: (v instanceof Array) ? v : entries(v) });
206
- };
207
- return array;
208
- }
209
-
210
- /** Recursively sorts the values for the given key-values array. */
211
- function sort(array, i) {
212
- var o = this.keys[i].order;
213
- if (o) array.sort(function(a, b) { return o(a.key, b.key); });
214
- if (++i < this.keys.length) {
215
- for (var j = 0; j < array.length; j++) {
216
- sort.call(this, array[j].values, i);
217
- }
218
- }
219
- return array;
220
- }
221
-
222
- return sort.call(this, entries(this.map()), 0);
223
- };
224
-
225
- /**
226
- * Returns a rollup map. The behavior of this method is the same as
227
- * {@link #map}, except that the leaf values are replaced with the return value
228
- * of the specified rollup function <tt>f</tt>. For example,
229
- *
230
- * <pre>pv.nest(yields)
231
- * .key(function(d) d.site)
232
- * .rollup(function(v) pv.median(v, function(d) d.yield))</pre>
233
- *
234
- * first groups yield data by site, and then returns a map from site to median
235
- * yield for the given site.
236
- *
237
- * @see #map
238
- * @param {function} f a rollup function.
239
- * @returns a hierarchical map, with the leaf values computed by <tt>f</tt>.
240
- */
241
- pv.Nest.prototype.rollup = function(f) {
242
-
243
- /** Recursively descends to the leaf nodes (arrays) and does rollup. */
244
- function rollup(map) {
245
- for (var key in map) {
246
- var value = map[key];
247
- if (value instanceof Array) {
248
- map[key] = f(value);
249
- } else {
250
- rollup(value);
251
- }
252
- }
253
- return map;
254
- }
255
-
256
- return rollup(this.map());
257
- };
@@ -1,313 +0,0 @@
1
- /**
2
- * Returns an array of numbers, starting at <tt>start</tt>, incrementing by
3
- * <tt>step</tt>, until <tt>stop</tt> is reached. The stop value is
4
- * exclusive. If only a single argument is specified, this value is interpeted
5
- * as the <i>stop</i> value, with the <i>start</i> value as zero. If only two
6
- * arguments are specified, the step value is implied to be one.
7
- *
8
- * <p>The method is modeled after the built-in <tt>range</tt> method from
9
- * Python. See the Python documentation for more details.
10
- *
11
- * @see <a href="http://docs.python.org/library/functions.html#range">Python range</a>
12
- * @param {number} [start] the start value.
13
- * @param {number} stop the stop value.
14
- * @param {number} [step] the step value.
15
- * @returns {number[]} an array of numbers.
16
- */
17
- pv.range = function(start, stop, step) {
18
- if (arguments.length == 1) {
19
- stop = start;
20
- start = 0;
21
- }
22
- if (step == undefined) step = 1;
23
- if ((stop - start) / step == Infinity) throw new Error("range must be finite");
24
- var array = [], i = 0, j;
25
- stop -= (stop - start) * 1e-10; // floating point precision!
26
- if (step < 0) {
27
- while ((j = start + step * i++) > stop) {
28
- array.push(j);
29
- }
30
- } else {
31
- while ((j = start + step * i++) < stop) {
32
- array.push(j);
33
- }
34
- }
35
- return array;
36
- };
37
-
38
- /**
39
- * Returns a random number in the range [<tt>start</tt>, <tt>stop</tt>) that is
40
- * a multiple of <tt>step</tt>. More specifically, the returned number is of the
41
- * form <tt>start</tt> + <i>n</i> * <tt>step</tt>, where <i>n</i> is a
42
- * nonnegative integer. If <tt>step</tt> is not specified, it defaults to 1,
43
- * returning a random integer if <tt>start</tt> is also an integer.
44
- *
45
- * @param {number} [start] the start value value.
46
- * @param {number} stop the stop value.
47
- * @param {number} [step] the step value.
48
- * @returns {number} a random number between <i>start</i> and <i>stop</i>.
49
- */
50
- pv.random = function(start, stop, step) {
51
- if (arguments.length == 1) {
52
- stop = start;
53
- start = 0;
54
- }
55
- if (step == undefined) step = 1;
56
- return step
57
- ? (Math.floor(Math.random() * (stop - start) / step) * step + start)
58
- : (Math.random() * (stop - start) + start);
59
- };
60
-
61
- /**
62
- * Returns the sum of the specified array. If the specified array is not an
63
- * array of numbers, an optional accessor function <tt>f</tt> can be specified
64
- * to map the elements to numbers. See {@link #normalize} for an example.
65
- * Accessor functions can refer to <tt>this.index</tt>.
66
- *
67
- * @param {array} array an array of objects, or numbers.
68
- * @param {function} [f] an optional accessor function.
69
- * @returns {number} the sum of the specified array.
70
- */
71
- pv.sum = function(array, f) {
72
- var o = {};
73
- return array.reduce(f
74
- ? function(p, d, i) { o.index = i; return p + f.call(o, d); }
75
- : function(p, d) { return p + d; }, 0);
76
- };
77
-
78
- /**
79
- * Returns the maximum value of the specified array. If the specified array is
80
- * not an array of numbers, an optional accessor function <tt>f</tt> can be
81
- * specified to map the elements to numbers. See {@link #normalize} for an
82
- * example. Accessor functions can refer to <tt>this.index</tt>.
83
- *
84
- * @param {array} array an array of objects, or numbers.
85
- * @param {function} [f] an optional accessor function.
86
- * @returns {number} the maximum value of the specified array.
87
- */
88
- pv.max = function(array, f) {
89
- if (f == pv.index) return array.length - 1;
90
- return Math.max.apply(null, f ? pv.map(array, f) : array);
91
- };
92
-
93
- /**
94
- * Returns the index of the maximum value of the specified array. If the
95
- * specified array is not an array of numbers, an optional accessor function
96
- * <tt>f</tt> can be specified to map the elements to numbers. See
97
- * {@link #normalize} for an example. Accessor functions can refer to
98
- * <tt>this.index</tt>.
99
- *
100
- * @param {array} array an array of objects, or numbers.
101
- * @param {function} [f] an optional accessor function.
102
- * @returns {number} the index of the maximum value of the specified array.
103
- */
104
- pv.max.index = function(array, f) {
105
- if (!array.length) return -1;
106
- if (f == pv.index) return array.length - 1;
107
- if (!f) f = pv.identity;
108
- var maxi = 0, maxx = -Infinity, o = {};
109
- for (var i = 0; i < array.length; i++) {
110
- o.index = i;
111
- var x = f.call(o, array[i]);
112
- if (x > maxx) {
113
- maxx = x;
114
- maxi = i;
115
- }
116
- }
117
- return maxi;
118
- }
119
-
120
- /**
121
- * Returns the minimum value of the specified array of numbers. If the specified
122
- * array is not an array of numbers, an optional accessor function <tt>f</tt>
123
- * can be specified to map the elements to numbers. See {@link #normalize} for
124
- * an example. Accessor functions can refer to <tt>this.index</tt>.
125
- *
126
- * @param {array} array an array of objects, or numbers.
127
- * @param {function} [f] an optional accessor function.
128
- * @returns {number} the minimum value of the specified array.
129
- */
130
- pv.min = function(array, f) {
131
- if (f == pv.index) return 0;
132
- return Math.min.apply(null, f ? pv.map(array, f) : array);
133
- };
134
-
135
- /**
136
- * Returns the index of the minimum value of the specified array. If the
137
- * specified array is not an array of numbers, an optional accessor function
138
- * <tt>f</tt> can be specified to map the elements to numbers. See
139
- * {@link #normalize} for an example. Accessor functions can refer to
140
- * <tt>this.index</tt>.
141
- *
142
- * @param {array} array an array of objects, or numbers.
143
- * @param {function} [f] an optional accessor function.
144
- * @returns {number} the index of the minimum value of the specified array.
145
- */
146
- pv.min.index = function(array, f) {
147
- if (!array.length) return -1;
148
- if (f == pv.index) return 0;
149
- if (!f) f = pv.identity;
150
- var mini = 0, minx = Infinity, o = {};
151
- for (var i = 0; i < array.length; i++) {
152
- o.index = i;
153
- var x = f.call(o, array[i]);
154
- if (x < minx) {
155
- minx = x;
156
- mini = i;
157
- }
158
- }
159
- return mini;
160
- }
161
-
162
- /**
163
- * Returns the arithmetic mean, or average, of the specified array. If the
164
- * specified array is not an array of numbers, an optional accessor function
165
- * <tt>f</tt> can be specified to map the elements to numbers. See
166
- * {@link #normalize} for an example. Accessor functions can refer to
167
- * <tt>this.index</tt>.
168
- *
169
- * @param {array} array an array of objects, or numbers.
170
- * @param {function} [f] an optional accessor function.
171
- * @returns {number} the mean of the specified array.
172
- */
173
- pv.mean = function(array, f) {
174
- return pv.sum(array, f) / array.length;
175
- };
176
-
177
- /**
178
- * Returns the median of the specified array. If the specified array is not an
179
- * array of numbers, an optional accessor function <tt>f</tt> can be specified
180
- * to map the elements to numbers. See {@link #normalize} for an example.
181
- * Accessor functions can refer to <tt>this.index</tt>.
182
- *
183
- * @param {array} array an array of objects, or numbers.
184
- * @param {function} [f] an optional accessor function.
185
- * @returns {number} the median of the specified array.
186
- */
187
- pv.median = function(array, f) {
188
- if (f == pv.index) return (array.length - 1) / 2;
189
- array = pv.map(array, f).sort(pv.naturalOrder);
190
- if (array.length % 2) return array[Math.floor(array.length / 2)];
191
- var i = array.length / 2;
192
- return (array[i - 1] + array[i]) / 2;
193
- };
194
-
195
- /**
196
- * Returns the unweighted variance of the specified array. If the specified
197
- * array is not an array of numbers, an optional accessor function <tt>f</tt>
198
- * can be specified to map the elements to numbers. See {@link #normalize} for
199
- * an example. Accessor functions can refer to <tt>this.index</tt>.
200
- *
201
- * @param {array} array an array of objects, or numbers.
202
- * @param {function} [f] an optional accessor function.
203
- * @returns {number} the variance of the specified array.
204
- */
205
- pv.variance = function(array, f) {
206
- if (array.length < 1) return NaN;
207
- if (array.length == 1) return 0;
208
- var mean = pv.mean(array, f), sum = 0, o = {};
209
- if (!f) f = pv.identity;
210
- for (var i = 0; i < array.length; i++) {
211
- o.index = i;
212
- var d = f.call(o, array[i]) - mean;
213
- sum += d * d;
214
- }
215
- return sum;
216
- };
217
-
218
- /**
219
- * Returns an unbiased estimation of the standard deviation of a population,
220
- * given the specified random sample. If the specified array is not an array of
221
- * numbers, an optional accessor function <tt>f</tt> can be specified to map the
222
- * elements to numbers. See {@link #normalize} for an example. Accessor
223
- * functions can refer to <tt>this.index</tt>.
224
- *
225
- * @param {array} array an array of objects, or numbers.
226
- * @param {function} [f] an optional accessor function.
227
- * @returns {number} the standard deviation of the specified array.
228
- */
229
- pv.deviation = function(array, f) {
230
- return Math.sqrt(pv.variance(array, f) / (array.length - 1));
231
- };
232
-
233
- /**
234
- * Returns the logarithm with a given base value.
235
- *
236
- * @param {number} x the number for which to compute the logarithm.
237
- * @param {number} b the base of the logarithm.
238
- * @returns {number} the logarithm value.
239
- */
240
- pv.log = function(x, b) {
241
- return Math.log(x) / Math.log(b);
242
- };
243
-
244
- /**
245
- * Computes a zero-symmetric logarithm. Computes the logarithm of the absolute
246
- * value of the input, and determines the sign of the output according to the
247
- * sign of the input value.
248
- *
249
- * @param {number} x the number for which to compute the logarithm.
250
- * @param {number} b the base of the logarithm.
251
- * @returns {number} the symmetric log value.
252
- */
253
- pv.logSymmetric = function(x, b) {
254
- return (x == 0) ? 0 : ((x < 0) ? -pv.log(-x, b) : pv.log(x, b));
255
- };
256
-
257
- /**
258
- * Computes a zero-symmetric logarithm, with adjustment to values between zero
259
- * and the logarithm base. This adjustment introduces distortion for values less
260
- * than the base number, but enables simultaneous plotting of log-transformed
261
- * data involving both positive and negative numbers.
262
- *
263
- * @param {number} x the number for which to compute the logarithm.
264
- * @param {number} b the base of the logarithm.
265
- * @returns {number} the adjusted, symmetric log value.
266
- */
267
- pv.logAdjusted = function(x, b) {
268
- if (!isFinite(x)) return x;
269
- var negative = x < 0;
270
- if (x < b) x += (b - x) / b;
271
- return negative ? -pv.log(x, b) : pv.log(x, b);
272
- };
273
-
274
- /**
275
- * Rounds an input value down according to its logarithm. The method takes the
276
- * floor of the logarithm of the value and then uses the resulting value as an
277
- * exponent for the base value.
278
- *
279
- * @param {number} x the number for which to compute the logarithm floor.
280
- * @param {number} b the base of the logarithm.
281
- * @returns {number} the rounded-by-logarithm value.
282
- */
283
- pv.logFloor = function(x, b) {
284
- return (x > 0)
285
- ? Math.pow(b, Math.floor(pv.log(x, b)))
286
- : -Math.pow(b, -Math.floor(-pv.log(-x, b)));
287
- };
288
-
289
- /**
290
- * Rounds an input value up according to its logarithm. The method takes the
291
- * ceiling of the logarithm of the value and then uses the resulting value as an
292
- * exponent for the base value.
293
- *
294
- * @param {number} x the number for which to compute the logarithm ceiling.
295
- * @param {number} b the base of the logarithm.
296
- * @returns {number} the rounded-by-logarithm value.
297
- */
298
- pv.logCeil = function(x, b) {
299
- return (x > 0)
300
- ? Math.pow(b, Math.ceil(pv.log(x, b)))
301
- : -Math.pow(b, -Math.ceil(-pv.log(-x, b)));
302
- };
303
-
304
- (function() {
305
- var radians = Math.PI / 180,
306
- degrees = 180 / Math.PI;
307
-
308
- /** Returns the number of radians corresponding to the specified degrees. */
309
- pv.radians = function(degrees) { return radians * degrees; };
310
-
311
- /** Returns the number of degrees corresponding to the specified radians. */
312
- pv.degrees = function(radians) { return degrees * radians; };
313
- })();