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,135 +0,0 @@
1
- /**
2
- * Returns a new categorical color encoding using the specified colors. The
3
- * arguments to this method are an array of colors; see {@link pv.color}. For
4
- * example, to create a categorical color encoding using the <tt>species</tt>
5
- * attribute:
6
- *
7
- * <pre>pv.colors("red", "green", "blue").by(function(d) d.species)</pre>
8
- *
9
- * The result of this expression can be used as a fill- or stroke-style
10
- * property. This assumes that the data's <tt>species</tt> attribute is a
11
- * string.
12
- *
13
- * @param {string} colors... categorical colors.
14
- * @see pv.Scale.ordinal
15
- * @returns {pv.Scale.ordinal} an ordinal color scale.
16
- */
17
- pv.colors = function() {
18
- var scale = pv.Scale.ordinal();
19
- scale.range.apply(scale, arguments);
20
- return scale;
21
- };
22
-
23
- /**
24
- * A collection of standard color palettes for categorical encoding.
25
- *
26
- * @namespace A collection of standard color palettes for categorical encoding.
27
- */
28
- pv.Colors = {};
29
-
30
- /**
31
- * Returns a new 10-color scheme. The arguments to this constructor are
32
- * optional, and equivalent to calling {@link pv.Scale.OrdinalScale#domain}. The
33
- * following colors are used:
34
- *
35
- * <div style="background:#1f77b4;">#1f77b4</div>
36
- * <div style="background:#ff7f0e;">#ff7f0e</div>
37
- * <div style="background:#2ca02c;">#2ca02c</div>
38
- * <div style="background:#d62728;">#d62728</div>
39
- * <div style="background:#9467bd;">#9467bd</div>
40
- * <div style="background:#8c564b;">#8c564b</div>
41
- * <div style="background:#e377c2;">#e377c2</div>
42
- * <div style="background:#7f7f7f;">#7f7f7f</div>
43
- * <div style="background:#bcbd22;">#bcbd22</div>
44
- * <div style="background:#17becf;">#17becf</div>
45
- *
46
- * @param {number...} domain... domain values.
47
- * @returns {pv.Scale.ordinal} a new ordinal color scale.
48
- * @see pv.color
49
- */
50
- pv.Colors.category10 = function() {
51
- var scale = pv.colors(
52
- "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
53
- "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf");
54
- scale.domain.apply(scale, arguments);
55
- return scale;
56
- };
57
-
58
- /**
59
- * Returns a new 20-color scheme. The arguments to this constructor are
60
- * optional, and equivalent to calling {@link pv.Scale.OrdinalScale#domain}. The
61
- * following colors are used:
62
- *
63
- * <div style="background:#1f77b4;">#1f77b4</div>
64
- * <div style="background:#aec7e8;">#aec7e8</div>
65
- * <div style="background:#ff7f0e;">#ff7f0e</div>
66
- * <div style="background:#ffbb78;">#ffbb78</div>
67
- * <div style="background:#2ca02c;">#2ca02c</div>
68
- * <div style="background:#98df8a;">#98df8a</div>
69
- * <div style="background:#d62728;">#d62728</div>
70
- * <div style="background:#ff9896;">#ff9896</div>
71
- * <div style="background:#9467bd;">#9467bd</div>
72
- * <div style="background:#c5b0d5;">#c5b0d5</div>
73
- * <div style="background:#8c564b;">#8c564b</div>
74
- * <div style="background:#c49c94;">#c49c94</div>
75
- * <div style="background:#e377c2;">#e377c2</div>
76
- * <div style="background:#f7b6d2;">#f7b6d2</div>
77
- * <div style="background:#7f7f7f;">#7f7f7f</div>
78
- * <div style="background:#c7c7c7;">#c7c7c7</div>
79
- * <div style="background:#bcbd22;">#bcbd22</div>
80
- * <div style="background:#dbdb8d;">#dbdb8d</div>
81
- * <div style="background:#17becf;">#17becf</div>
82
- * <div style="background:#9edae5;">#9edae5</div>
83
- *
84
- * @param {number...} domain... domain values.
85
- * @returns {pv.Scale.ordinal} a new ordinal color scale.
86
- * @see pv.color
87
- */
88
- pv.Colors.category20 = function() {
89
- var scale = pv.colors(
90
- "#1f77b4", "#aec7e8", "#ff7f0e", "#ffbb78", "#2ca02c",
91
- "#98df8a", "#d62728", "#ff9896", "#9467bd", "#c5b0d5",
92
- "#8c564b", "#c49c94", "#e377c2", "#f7b6d2", "#7f7f7f",
93
- "#c7c7c7", "#bcbd22", "#dbdb8d", "#17becf", "#9edae5");
94
- scale.domain.apply(scale, arguments);
95
- return scale;
96
- };
97
-
98
- /**
99
- * Returns a new alternative 19-color scheme. The arguments to this constructor
100
- * are optional, and equivalent to calling
101
- * {@link pv.Scale.OrdinalScale#domain}. The following colors are used:
102
- *
103
- * <div style="background:#9c9ede;">#9c9ede</div>
104
- * <div style="background:#7375b5;">#7375b5</div>
105
- * <div style="background:#4a5584;">#4a5584</div>
106
- * <div style="background:#cedb9c;">#cedb9c</div>
107
- * <div style="background:#b5cf6b;">#b5cf6b</div>
108
- * <div style="background:#8ca252;">#8ca252</div>
109
- * <div style="background:#637939;">#637939</div>
110
- * <div style="background:#e7cb94;">#e7cb94</div>
111
- * <div style="background:#e7ba52;">#e7ba52</div>
112
- * <div style="background:#bd9e39;">#bd9e39</div>
113
- * <div style="background:#8c6d31;">#8c6d31</div>
114
- * <div style="background:#e7969c;">#e7969c</div>
115
- * <div style="background:#d6616b;">#d6616b</div>
116
- * <div style="background:#ad494a;">#ad494a</div>
117
- * <div style="background:#843c39;">#843c39</div>
118
- * <div style="background:#de9ed6;">#de9ed6</div>
119
- * <div style="background:#ce6dbd;">#ce6dbd</div>
120
- * <div style="background:#a55194;">#a55194</div>
121
- * <div style="background:#7b4173;">#7b4173</div>
122
- *
123
- * @param {number...} domain... domain values.
124
- * @returns {pv.Scale.ordinal} a new ordinal color scale.
125
- * @see pv.color
126
- */
127
- pv.Colors.category19 = function() {
128
- var scale = pv.colors(
129
- "#9c9ede", "#7375b5", "#4a5584", "#cedb9c", "#b5cf6b",
130
- "#8ca252", "#637939", "#e7cb94", "#e7ba52", "#bd9e39",
131
- "#8c6d31", "#e7969c", "#d6616b", "#ad494a", "#843c39",
132
- "#de9ed6", "#ce6dbd", "#a55194", "#7b4173");
133
- scale.domain.apply(scale, arguments);
134
- return scale;
135
- };
@@ -1,17 +0,0 @@
1
- /**
2
- * Returns a linear color ramp from the specified <tt>start</tt> color to the
3
- * specified <tt>end</tt> color. The color arguments may be specified either as
4
- * <tt>string</tt>s or as {@link pv.Color}s. This is equivalent to:
5
- *
6
- * <pre> pv.Scale.linear().domain(0, 1).range(...)</pre>
7
- *
8
- * @param {string} start the start color; may be a <tt>pv.Color</tt>.
9
- * @param {string} end the end color; may be a <tt>pv.Color</tt>.
10
- * @returns {Function} a color ramp from <tt>start</tt> to <tt>end</tt>.
11
- * @see pv.Scale.linear
12
- */
13
- pv.ramp = function(start, end) {
14
- var scale = pv.Scale.linear();
15
- scale.range.apply(scale, arguments);
16
- return scale;
17
- };
@@ -1,277 +0,0 @@
1
- /**
2
- * @private A private variant of Array.prototype.map that supports the index
3
- * property.
4
- */
5
- pv.map = function(array, f) {
6
- var o = {};
7
- return f
8
- ? array.map(function(d, i) { o.index = i; return f.call(o, d); })
9
- : array.slice();
10
- };
11
-
12
- /**
13
- * Concatenates the specified array with itself <i>n</i> times. For example,
14
- * <tt>pv.repeat([1, 2])</tt> returns [1, 2, 1, 2].
15
- *
16
- * @param {array} a an array.
17
- * @param {number} [n] the number of times to repeat; defaults to two.
18
- * @returns {array} an array that repeats the specified array.
19
- */
20
- pv.repeat = function(array, n) {
21
- if (arguments.length == 1) n = 2;
22
- return pv.blend(pv.range(n).map(function() { return array; }));
23
- };
24
-
25
- /**
26
- * Given two arrays <tt>a</tt> and <tt>b</tt>, <style
27
- * type="text/css">sub{line-height:0}</style> returns an array of all possible
28
- * pairs of elements [a<sub>i</sub>, b<sub>j</sub>]. The outer loop is on array
29
- * <i>a</i>, while the inner loop is on <i>b</i>, such that the order of
30
- * returned elements is [a<sub>0</sub>, b<sub>0</sub>], [a<sub>0</sub>,
31
- * b<sub>1</sub>], ... [a<sub>0</sub>, b<sub>m</sub>], [a<sub>1</sub>,
32
- * b<sub>0</sub>], [a<sub>1</sub>, b<sub>1</sub>], ... [a<sub>1</sub>,
33
- * b<sub>m</sub>], ... [a<sub>n</sub>, b<sub>m</sub>]. If either array is empty,
34
- * an empty array is returned.
35
- *
36
- * @param {array} a an array.
37
- * @param {array} b an array.
38
- * @returns {array} an array of pairs of elements in <tt>a</tt> and <tt>b</tt>.
39
- */
40
- pv.cross = function(a, b) {
41
- var array = [];
42
- for (var i = 0, n = a.length, m = b.length; i < n; i++) {
43
- for (var j = 0, x = a[i]; j < m; j++) {
44
- array.push([x, b[j]]);
45
- }
46
- }
47
- return array;
48
- };
49
-
50
- /**
51
- * Given the specified array of arrays, concatenates the arrays into a single
52
- * array. If the individual arrays are explicitly known, an alternative to blend
53
- * is to use JavaScript's <tt>concat</tt> method directly. These two equivalent
54
- * expressions:<ul>
55
- *
56
- * <li><tt>pv.blend([[1, 2, 3], ["a", "b", "c"]])</tt>
57
- * <li><tt>[1, 2, 3].concat(["a", "b", "c"])</tt>
58
- *
59
- * </ul>return [1, 2, 3, "a", "b", "c"].
60
- *
61
- * @param {array[]} arrays an array of arrays.
62
- * @returns {array} an array containing all the elements of each array in
63
- * <tt>arrays</tt>.
64
- */
65
- pv.blend = function(arrays) {
66
- return Array.prototype.concat.apply([], arrays);
67
- };
68
-
69
- /**
70
- * Given the specified array of arrays, <style
71
- * type="text/css">sub{line-height:0}</style> transposes each element
72
- * array<sub>ij</sub> with array<sub>ji</sub>. If the array has dimensions
73
- * <i>n</i>&times;<i>m</i>, it will have dimensions <i>m</i>&times;<i>n</i>
74
- * after this method returns. This method transposes the elements of the array
75
- * in place, mutating the array, and returning a reference to the array.
76
- *
77
- * @param {array[]} arrays an array of arrays.
78
- * @returns {array[]} the passed-in array, after transposing the elements.
79
- */
80
- pv.transpose = function(arrays) {
81
- var n = arrays.length, m = pv.max(arrays, function(d) { return d.length; });
82
-
83
- if (m > n) {
84
- arrays.length = m;
85
- for (var i = n; i < m; i++) {
86
- arrays[i] = new Array(n);
87
- }
88
- for (var i = 0; i < n; i++) {
89
- for (var j = i + 1; j < m; j++) {
90
- var t = arrays[i][j];
91
- arrays[i][j] = arrays[j][i];
92
- arrays[j][i] = t;
93
- }
94
- }
95
- } else {
96
- for (var i = 0; i < m; i++) {
97
- arrays[i].length = n;
98
- }
99
- for (var i = 0; i < n; i++) {
100
- for (var j = 0; j < i; j++) {
101
- var t = arrays[i][j];
102
- arrays[i][j] = arrays[j][i];
103
- arrays[j][i] = t;
104
- }
105
- }
106
- }
107
-
108
- arrays.length = m;
109
- for (var i = 0; i < m; i++) {
110
- arrays[i].length = n;
111
- }
112
-
113
- return arrays;
114
- };
115
-
116
- /**
117
- * Returns a normalized copy of the specified array, such that the sum of the
118
- * returned elements sum to one. If the specified array is not an array of
119
- * numbers, an optional accessor function <tt>f</tt> can be specified to map the
120
- * elements to numbers. For example, if <tt>array</tt> is an array of objects,
121
- * and each object has a numeric property "foo", the expression
122
- *
123
- * <pre>pv.normalize(array, function(d) d.foo)</pre>
124
- *
125
- * returns a normalized array on the "foo" property. If an accessor function is
126
- * not specified, the identity function is used. Accessor functions can refer to
127
- * <tt>this.index</tt>.
128
- *
129
- * @param {array} array an array of objects, or numbers.
130
- * @param {function} [f] an optional accessor function.
131
- * @returns {number[]} an array of numbers that sums to one.
132
- */
133
- pv.normalize = function(array, f) {
134
- var norm = pv.map(array, f), sum = pv.sum(norm);
135
- for (var i = 0; i < norm.length; i++) norm[i] /= sum;
136
- return norm;
137
- };
138
-
139
- /**
140
- * Returns a permutation of the specified array, using the specified array of
141
- * indexes. The returned array contains the corresponding element in
142
- * <tt>array</tt> for each index in <tt>indexes</tt>, in order. For example,
143
- *
144
- * <pre>pv.permute(["a", "b", "c"], [1, 2, 0])</pre>
145
- *
146
- * returns <tt>["b", "c", "a"]</tt>. It is acceptable for the array of indexes
147
- * to be a different length from the array of elements, and for indexes to be
148
- * duplicated or omitted. The optional accessor function <tt>f</tt> can be used
149
- * to perform a simultaneous mapping of the array elements. Accessor functions
150
- * can refer to <tt>this.index</tt>.
151
- *
152
- * @param {array} array an array.
153
- * @param {number[]} indexes an array of indexes into <tt>array</tt>.
154
- * @param {function} [f] an optional accessor function.
155
- * @returns {array} an array of elements from <tt>array</tt>; a permutation.
156
- */
157
- pv.permute = function(array, indexes, f) {
158
- if (!f) f = pv.identity;
159
- var p = new Array(indexes.length), o = {};
160
- indexes.forEach(function(j, i) { o.index = j; p[i] = f.call(o, array[j]); });
161
- return p;
162
- };
163
-
164
- /**
165
- * Returns a map from key to index for the specified <tt>keys</tt> array. For
166
- * example,
167
- *
168
- * <pre>pv.numerate(["a", "b", "c"])</pre>
169
- *
170
- * returns <tt>{a: 0, b: 1, c: 2}</tt>. Note that since JavaScript maps only
171
- * support string keys, <tt>keys</tt> must contain strings, or other values that
172
- * naturally map to distinct string values. Alternatively, an optional accessor
173
- * function <tt>f</tt> can be specified to compute the string key for the given
174
- * element. Accessor functions can refer to <tt>this.index</tt>.
175
- *
176
- * @param {array} keys an array, usually of string keys.
177
- * @param {function} [f] an optional key function.
178
- * @returns a map from key to index.
179
- */
180
- pv.numerate = function(keys, f) {
181
- if (!f) f = pv.identity;
182
- var map = {}, o = {};
183
- keys.forEach(function(x, i) { o.index = i; map[f.call(o, x)] = i; });
184
- return map;
185
- };
186
-
187
- /**
188
- * Returns the unique elements in the specified array, in the order they appear.
189
- * Note that since JavaScript maps only support string keys, <tt>array</tt> must
190
- * contain strings, or other values that naturally map to distinct string
191
- * values. Alternatively, an optional accessor function <tt>f</tt> can be
192
- * specified to compute the string key for the given element. Accessor functions
193
- * can refer to <tt>this.index</tt>.
194
- *
195
- * @param {array} array an array, usually of string keys.
196
- * @param {function} [f] an optional key function.
197
- * @returns {array} the unique values.
198
- */
199
- pv.uniq = function(array, f) {
200
- if (!f) f = pv.identity;
201
- var map = {}, keys = [], o = {}, y;
202
- array.forEach(function(x, i) {
203
- o.index = i;
204
- y = f.call(o, x);
205
- if (!(y in map)) map[y] = keys.push(y);
206
- });
207
- return keys;
208
- };
209
-
210
- /**
211
- * The comparator function for natural order. This can be used in conjunction with
212
- * the built-in array <tt>sort</tt> method to sort elements by their natural
213
- * order, ascending. Note that if no comparator function is specified to the
214
- * built-in <tt>sort</tt> method, the default order is lexicographic, <i>not</i>
215
- * natural!
216
- *
217
- * @see <a
218
- * href="http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/sort">Array.sort</a>.
219
- * @param a an element to compare.
220
- * @param b an element to compare.
221
- * @returns {number} negative if a &lt; b; positive if a &gt; b; otherwise 0.
222
- */
223
- pv.naturalOrder = function(a, b) {
224
- return (a < b) ? -1 : ((a > b) ? 1 : 0);
225
- };
226
-
227
- /**
228
- * The comparator function for reverse natural order. This can be used in
229
- * conjunction with the built-in array <tt>sort</tt> method to sort elements by
230
- * their natural order, descending. Note that if no comparator function is
231
- * specified to the built-in <tt>sort</tt> method, the default order is
232
- * lexicographic, <i>not</i> natural!
233
- *
234
- * @see #naturalOrder
235
- * @param a an element to compare.
236
- * @param b an element to compare.
237
- * @returns {number} negative if a &lt; b; positive if a &gt; b; otherwise 0.
238
- */
239
- pv.reverseOrder = function(b, a) {
240
- return (a < b) ? -1 : ((a > b) ? 1 : 0);
241
- };
242
-
243
- /**
244
- * Searches the specified array of numbers for the specified value using the
245
- * binary search algorithm. The array must be sorted (as by the <tt>sort</tt>
246
- * method) prior to making this call. If it is not sorted, the results are
247
- * undefined. If the array contains multiple elements with the specified value,
248
- * there is no guarantee which one will be found.
249
- *
250
- * <p>The <i>insertion point</i> is defined as the point at which the value
251
- * would be inserted into the array: the index of the first element greater than
252
- * the value, or <tt>array.length</tt>, if all elements in the array are less
253
- * than the specified value. Note that this guarantees that the return value
254
- * will be nonnegative if and only if the value is found.
255
- *
256
- * @param {number[]} array the array to be searched.
257
- * @param {number} value the value to be searched for.
258
- * @returns the index of the search value, if it is contained in the array;
259
- * otherwise, (-(<i>insertion point</i>) - 1).
260
- * @param {function} [f] an optional key function.
261
- */
262
- pv.search = function(array, value, f) {
263
- if (!f) f = pv.identity;
264
- var low = 0, high = array.length - 1;
265
- while (low <= high) {
266
- var mid = (low + high) >> 1, midValue = f(array[mid]);
267
- if (midValue < value) low = mid + 1;
268
- else if (midValue > value) high = mid - 1;
269
- else return mid;
270
- }
271
- return -low - 1;
272
- };
273
-
274
- pv.search.index = function(array, value, f) {
275
- var i = pv.search(array, value, f);
276
- return (i < 0) ? (-i - 1) : i;
277
- };
@@ -1,380 +0,0 @@
1
- /**
2
- * Returns a {@link pv.Dom} operator for the given map. This is a convenience
3
- * factory method, equivalent to <tt>new pv.Dom(map)</tt>. To apply the operator
4
- * and retrieve the root node, call {@link pv.Dom#root}; to retrieve all nodes
5
- * flattened, use {@link pv.Dom#nodes}.
6
- *
7
- * @see pv.Dom
8
- * @param map a map from which to construct a DOM.
9
- * @returns {pv.Dom} a DOM operator for the specified map.
10
- */
11
- pv.dom = function(map) {
12
- return new pv.Dom(map);
13
- };
14
-
15
- /**
16
- * Constructs a DOM operator for the specified map. This constructor should not
17
- * be invoked directly; use {@link pv.dom} instead.
18
- *
19
- * @class Represets a DOM operator for the specified map. This allows easy
20
- * transformation of a hierarchical JavaScript object (such as a JSON map) to a
21
- * W3C Document Object Model hierarchy. For more information on which attributes
22
- * and methods from the specification are supported, see {@link pv.Dom.Node}.
23
- *
24
- * <p>Leaves in the map are determined using an associated <i>leaf</i> function;
25
- * see {@link #leaf}. By default, leaves are any value whose type is not
26
- * "object", such as numbers or strings.
27
- *
28
- * @param map a map from which to construct a DOM.
29
- */
30
- pv.Dom = function(map) {
31
- this.$map = map;
32
- };
33
-
34
- /** @private The default leaf function. */
35
- pv.Dom.prototype.$leaf = function(n) {
36
- return typeof n != "object";
37
- };
38
-
39
- /**
40
- * Sets or gets the leaf function for this DOM operator. The leaf function
41
- * identifies which values in the map are leaves, and which are internal nodes.
42
- * By default, objects are considered internal nodes, and primitives (such as
43
- * numbers and strings) are considered leaves.
44
- *
45
- * @param {function} f the new leaf function.
46
- * @returns the current leaf function, or <tt>this</tt>.
47
- */
48
- pv.Dom.prototype.leaf = function(f) {
49
- if (arguments.length) {
50
- this.$leaf = f;
51
- return this;
52
- }
53
- return this.$leaf;
54
- };
55
-
56
- /**
57
- * Applies the DOM operator, returning the root node.
58
- *
59
- * @returns {pv.Dom.Node} the root node.
60
- * @param {string} [nodeName] optional node name for the root.
61
- */
62
- pv.Dom.prototype.root = function(nodeName) {
63
- var leaf = this.$leaf, root = recurse(this.$map);
64
-
65
- /** @private */
66
- function recurse(map) {
67
- var n = new pv.Dom.Node();
68
- for (var k in map) {
69
- var v = map[k];
70
- n.appendChild(leaf(v) ? new pv.Dom.Node(v) : recurse(v)).nodeName = k;
71
- }
72
- return n;
73
- }
74
-
75
- root.nodeName = nodeName;
76
- return root;
77
- };
78
-
79
- /**
80
- * Applies the DOM operator, returning the array of all nodes in preorder
81
- * traversal.
82
- *
83
- * @returns {array} the array of nodes in preorder traversal.
84
- */
85
- pv.Dom.prototype.nodes = function() {
86
- return this.root().nodes();
87
- };
88
-
89
- /**
90
- * Constructs a DOM node for the specified value. Instances of this class are
91
- * not typically created directly; instead they are generated from a JavaScript
92
- * map using the {@link pv.Dom} operator.
93
- *
94
- * @class Represents a <tt>Node</tt> in the W3C Document Object Model.
95
- */
96
- pv.Dom.Node = function(value) {
97
- this.nodeValue = value;
98
- this.childNodes = [];
99
- };
100
-
101
- /**
102
- * The node name. When generated from a map, the node name corresponds to the
103
- * key at the given level in the map. Note that the root node has no associated
104
- * key, and thus has an undefined node name (and no <tt>parentNode</tt>).
105
- *
106
- * @type string
107
- * @field pv.Dom.Node.prototype.nodeName
108
- */
109
-
110
- /**
111
- * The node value. When generated from a map, node value corresponds to the leaf
112
- * value for leaf nodes, and is undefined for internal nodes.
113
- *
114
- * @field pv.Dom.Node.prototype.nodeValue
115
- */
116
-
117
- /**
118
- * The array of child nodes. This array is empty for leaf nodes. An easy way to
119
- * check if child nodes exist is to query <tt>firstChild</tt>.
120
- *
121
- * @type array
122
- * @field pv.Dom.Node.prototype.childNodes
123
- */
124
-
125
- /**
126
- * The parent node, which is null for root nodes.
127
- *
128
- * @type pv.Dom.Node
129
- */
130
- pv.Dom.Node.prototype.parentNode = null;
131
-
132
- /**
133
- * The first child, which is null for leaf nodes.
134
- *
135
- * @type pv.Dom.Node
136
- */
137
- pv.Dom.Node.prototype.firstChild = null;
138
-
139
- /**
140
- * The last child, which is null for leaf nodes.
141
- *
142
- * @type pv.Dom.Node
143
- */
144
- pv.Dom.Node.prototype.lastChild = null;
145
-
146
- /**
147
- * The previous sibling node, which is null for the first child.
148
- *
149
- * @type pv.Dom.Node
150
- */
151
- pv.Dom.Node.prototype.previousSibling = null;
152
-
153
- /**
154
- * The next sibling node, which is null for the last child.
155
- *
156
- * @type pv.Dom.Node
157
- */
158
- pv.Dom.Node.prototype.nextSibling = null;
159
-
160
- /**
161
- * Removes the specified child node from this node.
162
- *
163
- * @throws Error if the specified child is not a child of this node.
164
- * @returns {pv.Dom.Node} the removed child.
165
- */
166
- pv.Dom.Node.prototype.removeChild = function(n) {
167
- var i = this.childNodes.indexOf(n);
168
- if (i == -1) throw new Error("child not found");
169
- this.childNodes.splice(i, 1);
170
- if (n.previousSibling) n.previousSibling.nextSibling = n.nextSibling;
171
- else this.firstChild = n.nextSibling;
172
- if (n.nextSibling) n.nextSibling.previousSibling = n.previousSibling;
173
- else this.lastChild = n.previousSibling;
174
- delete n.nextSibling;
175
- delete n.previousSibling;
176
- delete n.parentNode;
177
- return n;
178
- };
179
-
180
- /**
181
- * Appends the specified child node to this node. If the specified child is
182
- * already part of the DOM, the child is first removed before being added to
183
- * this node.
184
- *
185
- * @returns {pv.Dom.Node} the appended child.
186
- */
187
- pv.Dom.Node.prototype.appendChild = function(n) {
188
- if (n.parentNode) n.parentNode.removeChild(n);
189
- n.parentNode = this;
190
- n.previousSibling = this.lastChild;
191
- if (this.lastChild) this.lastChild.nextSibling = n;
192
- else this.firstChild = n;
193
- this.lastChild = n;
194
- this.childNodes.push(n);
195
- return n;
196
- };
197
-
198
- /**
199
- * Inserts the specified child <i>n</i> before the given reference child
200
- * <i>r</i> of this node. If <i>r</i> is null, this method is equivalent to
201
- * {@link #appendChild}. If <i>n</i> is already part of the DOM, it is first
202
- * removed before being inserted.
203
- *
204
- * @throws Error if <i>r</i> is non-null and not a child of this node.
205
- * @returns {pv.Dom.Node} the inserted child.
206
- */
207
- pv.Dom.Node.prototype.insertBefore = function(n, r) {
208
- if (!r) return this.appendChild(n);
209
- var i = this.childNodes.indexOf(r);
210
- if (i == -1) throw new Error("child not found");
211
- if (n.parentNode) n.parentNode.removeChild(n);
212
- n.parentNode = this;
213
- n.nextSibling = r;
214
- n.previousSibling = r.previousSibling;
215
- if (r.previousSibling) {
216
- r.previousSibling.nextSibling = n;
217
- } else {
218
- if (r == this.lastChild) this.lastChild = n;
219
- this.firstChild = n;
220
- }
221
- this.childNodes.splice(i, 0, n);
222
- return n;
223
- };
224
-
225
- /**
226
- * Replaces the specified child <i>r</i> of this node with the node <i>n</i>. If
227
- * <i>n</i> is already part of the DOM, it is first removed before being added.
228
- *
229
- * @throws Error if <i>r</i> is not a child of this node.
230
- */
231
- pv.Dom.Node.prototype.replaceChild = function(n, r) {
232
- var i = this.childNodes.indexOf(r);
233
- if (i == -1) throw new Error("child not found");
234
- if (n.parentNode) n.parentNode.removeChild(n);
235
- n.parentNode = this;
236
- n.nextSibling = r.nextSibling;
237
- n.previousSibling = r.previousSibling;
238
- if (r.previousSibling) r.previousSibling.nextSibling = n;
239
- else this.firstChild = n;
240
- if (r.nextSibling) r.nextSibling.previousSibling = n;
241
- else this.lastChild = n;
242
- this.childNodes[i] = n;
243
- return r;
244
- };
245
-
246
- /**
247
- * Visits each node in the tree in preorder traversal, applying the specified
248
- * function <i>f</i>. The arguments to the function are:<ol>
249
- *
250
- * <li>The current node.
251
- * <li>The current depth, starting at 0 for the root node.</ol>
252
- *
253
- * @param {function} f a function to apply to each node.
254
- */
255
- pv.Dom.Node.prototype.visitBefore = function(f) {
256
- function visit(n, i) {
257
- f(n, i);
258
- for (var c = n.firstChild; c; c = c.nextSibling) {
259
- visit(c, i + 1);
260
- }
261
- }
262
- visit(this, 0);
263
- };
264
-
265
- /**
266
- * Visits each node in the tree in postorder traversal, applying the specified
267
- * function <i>f</i>. The arguments to the function are:<ol>
268
- *
269
- * <li>The current node.
270
- * <li>The current depth, starting at 0 for the root node.</ol>
271
- *
272
- * @param {function} f a function to apply to each node.
273
- */
274
- pv.Dom.Node.prototype.visitAfter = function(f) {
275
- function visit(n, i) {
276
- for (var c = n.firstChild; c; c = c.nextSibling) {
277
- visit(c, i + 1);
278
- }
279
- f(n, i);
280
- }
281
- visit(this, 0);
282
- };
283
-
284
- /**
285
- * Sorts child nodes of this node, and all descendent nodes recursively, using
286
- * the specified comparator function <tt>f</tt>. The comparator function is
287
- * passed two nodes to compare.
288
- *
289
- * <p>Note: during the sort operation, the comparator function should not rely
290
- * on the tree being well-formed; the values of <tt>previousSibling</tt> and
291
- * <tt>nextSibling</tt> for the nodes being compared are not defined during the
292
- * sort operation.
293
- *
294
- * @param {function} f a comparator function.
295
- * @returns this.
296
- */
297
- pv.Dom.Node.prototype.sort = function(f) {
298
- if (this.firstChild) {
299
- this.childNodes.sort(f);
300
- var p = this.firstChild = this.childNodes[0], c;
301
- delete p.previousSibling;
302
- for (var i = 1; i < this.childNodes.length; i++) {
303
- p.sort(f);
304
- c = this.childNodes[i];
305
- c.previousSibling = p;
306
- p = p.nextSibling = c;
307
- }
308
- this.lastChild = p;
309
- delete p.nextSibling;
310
- p.sort(f);
311
- }
312
- return this;
313
- };
314
-
315
- /**
316
- * Reverses all sibling nodes.
317
- *
318
- * @returns this.
319
- */
320
- pv.Dom.Node.prototype.reverse = function() {
321
- var childNodes = [];
322
- this.visitAfter(function(n) {
323
- while (n.lastChild) childNodes.push(n.removeChild(n.lastChild));
324
- for (var c; c = childNodes.pop();) n.insertBefore(c, n.firstChild);
325
- });
326
- return this;
327
- };
328
-
329
- /** Returns all descendants of this node in preorder traversal. */
330
- pv.Dom.Node.prototype.nodes = function() {
331
- var array = [];
332
-
333
- /** @private */
334
- function flatten(node) {
335
- array.push(node);
336
- node.childNodes.forEach(flatten);
337
- }
338
-
339
- flatten(this, array);
340
- return array;
341
- };
342
-
343
- /**
344
- * Toggles the child nodes of this node. If this node is not yet toggled, this
345
- * method removes all child nodes and appends them to a new <tt>toggled</tt>
346
- * array attribute on this node. Otherwise, if this node is toggled, this method
347
- * re-adds all toggled child nodes and deletes the <tt>toggled</tt> attribute.
348
- *
349
- * <p>This method has no effect if the node has no child nodes.
350
- *
351
- * @param {boolean} [recursive] whether the toggle should apply to descendants.
352
- */
353
- pv.Dom.Node.prototype.toggle = function(recursive) {
354
- if (recursive) return this.toggled
355
- ? this.visitBefore(function(n) { if (n.toggled) n.toggle(); })
356
- : this.visitAfter(function(n) { if (!n.toggled) n.toggle(); });
357
- var n = this;
358
- if (n.toggled) {
359
- for (var c; c = n.toggled.pop();) n.appendChild(c);
360
- delete n.toggled;
361
- } else if (n.lastChild) {
362
- n.toggled = [];
363
- while (n.lastChild) n.toggled.push(n.removeChild(n.lastChild));
364
- }
365
- };
366
-
367
- /**
368
- * Given a flat array of values, returns a simple DOM with each value wrapped by
369
- * a node that is a child of the root node.
370
- *
371
- * @param {array} values.
372
- * @returns {array} nodes.
373
- */
374
- pv.nodes = function(values) {
375
- var root = new pv.Dom.Node();
376
- for (var i = 0; i < values.length; i++) {
377
- root.appendChild(new pv.Dom.Node(values[i]));
378
- }
379
- return root.nodes();
380
- };