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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.travis.yml +13 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +37 -0
- data/History.txt +6 -0
- data/LICENSE.txt +23 -0
- data/{README.txt → README.md} +15 -12
- data/Rakefile +4 -11
- data/lib/rubyvis.rb +1 -1
- data/lib/rubyvis/scale/quantitative.rb +14 -18
- data/lib/rubyvis/scene/svg_label.rb +1 -1
- data/rubyvis.gemspec +21 -0
- data/spec/anchor_spec.rb +2 -1
- data/spec/line_spec.rb +2 -2
- data/spec/scale_linear_datetime_spec.rb +23 -8
- data/spec/spec_helper.rb +2 -1
- metadata +31 -214
- data/.gemtest +0 -0
- data/vendor/protovis/protovis-r3.3.js +0 -287
- data/vendor/protovis/src/behavior/Behavior.js +0 -32
- data/vendor/protovis/src/behavior/Drag.js +0 -112
- data/vendor/protovis/src/behavior/Pan.js +0 -110
- data/vendor/protovis/src/behavior/Point.js +0 -157
- data/vendor/protovis/src/behavior/Resize.js +0 -104
- data/vendor/protovis/src/behavior/Select.js +0 -100
- data/vendor/protovis/src/behavior/Zoom.js +0 -85
- data/vendor/protovis/src/color/Color.js +0 -598
- data/vendor/protovis/src/color/Colors.js +0 -135
- data/vendor/protovis/src/color/Ramp.js +0 -17
- data/vendor/protovis/src/data/Arrays.js +0 -277
- data/vendor/protovis/src/data/Dom.js +0 -380
- data/vendor/protovis/src/data/Flatten.js +0 -146
- data/vendor/protovis/src/data/Histogram.js +0 -120
- data/vendor/protovis/src/data/LinearScale.js +0 -54
- data/vendor/protovis/src/data/LogScale.js +0 -142
- data/vendor/protovis/src/data/Nest.js +0 -257
- data/vendor/protovis/src/data/Numbers.js +0 -313
- data/vendor/protovis/src/data/Objects.js +0 -78
- data/vendor/protovis/src/data/OrdinalScale.js +0 -267
- data/vendor/protovis/src/data/QuantileScale.js +0 -180
- data/vendor/protovis/src/data/QuantitativeScale.js +0 -440
- data/vendor/protovis/src/data/RootScale.js +0 -55
- data/vendor/protovis/src/data/Scale.js +0 -86
- data/vendor/protovis/src/data/Transform.js +0 -109
- data/vendor/protovis/src/data/Tree.js +0 -124
- data/vendor/protovis/src/data/Vector.js +0 -118
- data/vendor/protovis/src/geo/Geo.js +0 -5
- data/vendor/protovis/src/geo/GeoScale.js +0 -307
- data/vendor/protovis/src/geo/LatLng.js +0 -23
- data/vendor/protovis/src/geo/Projection.js +0 -43
- data/vendor/protovis/src/geo/Projections.js +0 -117
- data/vendor/protovis/src/lang/Array.js +0 -112
- data/vendor/protovis/src/lang/init.js +0 -26
- data/vendor/protovis/src/layout/Arc.js +0 -178
- data/vendor/protovis/src/layout/Bullet.js +0 -164
- data/vendor/protovis/src/layout/Cluster.js +0 -205
- data/vendor/protovis/src/layout/Force.js +0 -309
- data/vendor/protovis/src/layout/Grid.js +0 -119
- data/vendor/protovis/src/layout/Hierarchy.js +0 -249
- data/vendor/protovis/src/layout/Horizon.js +0 -159
- data/vendor/protovis/src/layout/Indent.js +0 -83
- data/vendor/protovis/src/layout/Layout.js +0 -56
- data/vendor/protovis/src/layout/Matrix.js +0 -177
- data/vendor/protovis/src/layout/Network.js +0 -302
- data/vendor/protovis/src/layout/Pack.js +0 -323
- data/vendor/protovis/src/layout/Partition.js +0 -203
- data/vendor/protovis/src/layout/Rollup.js +0 -203
- data/vendor/protovis/src/layout/Stack.js +0 -391
- data/vendor/protovis/src/layout/Tree.js +0 -282
- data/vendor/protovis/src/layout/Treemap.js +0 -347
- data/vendor/protovis/src/mark/Anchor.js +0 -81
- data/vendor/protovis/src/mark/Area.js +0 -268
- data/vendor/protovis/src/mark/Bar.js +0 -93
- data/vendor/protovis/src/mark/Dot.js +0 -212
- data/vendor/protovis/src/mark/Ease.js +0 -150
- data/vendor/protovis/src/mark/Image.js +0 -154
- data/vendor/protovis/src/mark/Label.js +0 -155
- data/vendor/protovis/src/mark/Line.js +0 -195
- data/vendor/protovis/src/mark/Mark.js +0 -1237
- data/vendor/protovis/src/mark/Panel.js +0 -273
- data/vendor/protovis/src/mark/Rule.js +0 -143
- data/vendor/protovis/src/mark/Transient.js +0 -7
- data/vendor/protovis/src/mark/Transition.js +0 -195
- data/vendor/protovis/src/mark/Wedge.js +0 -244
- data/vendor/protovis/src/physics/BoundConstraint.js +0 -75
- data/vendor/protovis/src/physics/ChargeForce.js +0 -184
- data/vendor/protovis/src/physics/CollisionConstraint.js +0 -113
- data/vendor/protovis/src/physics/Constraint.js +0 -26
- data/vendor/protovis/src/physics/DragForce.js +0 -49
- data/vendor/protovis/src/physics/Force.js +0 -25
- data/vendor/protovis/src/physics/Particle.js +0 -81
- data/vendor/protovis/src/physics/PositionConstraint.js +0 -72
- data/vendor/protovis/src/physics/Quadtree.js +0 -195
- data/vendor/protovis/src/physics/Simulation.js +0 -159
- data/vendor/protovis/src/physics/SpringForce.js +0 -141
- data/vendor/protovis/src/pv-internals.js +0 -154
- data/vendor/protovis/src/pv.js +0 -95
- data/vendor/protovis/src/scene/SvgArea.js +0 -172
- data/vendor/protovis/src/scene/SvgBar.js +0 -28
- data/vendor/protovis/src/scene/SvgCurve.js +0 -354
- data/vendor/protovis/src/scene/SvgDot.js +0 -81
- data/vendor/protovis/src/scene/SvgImage.js +0 -45
- data/vendor/protovis/src/scene/SvgLabel.js +0 -46
- data/vendor/protovis/src/scene/SvgLine.js +0 -159
- data/vendor/protovis/src/scene/SvgPanel.js +0 -126
- data/vendor/protovis/src/scene/SvgRule.js +0 -26
- data/vendor/protovis/src/scene/SvgScene.js +0 -185
- data/vendor/protovis/src/scene/SvgWedge.js +0 -66
- data/vendor/protovis/src/text/DateFormat.js +0 -262
- data/vendor/protovis/src/text/Format.js +0 -78
- data/vendor/protovis/src/text/NumberFormat.js +0 -227
- 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>×<i>m</i>, it will have dimensions <i>m</i>×<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 < b; positive if a > 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 < b; positive if a > 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
|
-
};
|