rubyvis 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
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
- })();