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,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
- };