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,203 +0,0 @@
1
- /**
2
- * Constructs a new, empty rollup network layout. Layouts are not typically
3
- * constructed directly; instead, they are added to an existing panel via
4
- * {@link pv.Mark#add}.
5
- *
6
- * @class Implements a network visualization using a node-link diagram where
7
- * nodes are rolled up along two dimensions. This implementation is based on the
8
- * "PivotGraph" designed by Martin Wattenberg:
9
- *
10
- * <blockquote>The method is designed for graphs that are "multivariate", i.e.,
11
- * where each node is associated with several attributes. Unlike visualizations
12
- * which emphasize global graph topology, PivotGraph uses a simple grid-based
13
- * approach to focus on the relationship between node attributes &amp;
14
- * connections.</blockquote>
15
- *
16
- * This layout requires two psuedo-properties to be specified, which assign node
17
- * positions along the two dimensions {@link #x} and {@link #y}, corresponding
18
- * to the left and top properties, respectively. Typically, these functions are
19
- * specified using an {@link pv.Scale.ordinal}. Nodes that share the same
20
- * position in <i>x</i> and <i>y</i> are "rolled up" into a meta-node, and
21
- * similarly links are aggregated between meta-nodes. For example, to construct
22
- * a rollup to analyze links by gender and affiliation, first define two ordinal
23
- * scales:
24
- *
25
- * <pre>var x = pv.Scale.ordinal(nodes, function(d) d.gender).split(0, w),
26
- * y = pv.Scale.ordinal(nodes, function(d) d.aff).split(0, h);</pre>
27
- *
28
- * Next, define the position psuedo-properties:
29
- *
30
- * <pre> .x(function(d) x(d.gender))
31
- * .y(function(d) y(d.aff))</pre>
32
- *
33
- * Linear and other quantitative scales can alternatively be used to position
34
- * the nodes along either dimension. Note, however, that the rollup requires
35
- * that the positions match exactly, and thus ordinal scales are recommended to
36
- * avoid precision errors.
37
- *
38
- * <p>Note that because this layout provides a visualization of the rolled up
39
- * graph, the data properties for the mark prototypes (<tt>node</tt>,
40
- * <tt>link</tt> and <tt>label</tt>) are different from most other network
41
- * layouts: they reference the rolled-up nodes and links, rather than the nodes
42
- * and links of the full network. The underlying nodes and links for each
43
- * rolled-up node and link can be accessed via the <tt>nodes</tt> and
44
- * <tt>links</tt> attributes, respectively. The aggregated link values for
45
- * rolled-up links can similarly be accessed via the <tt>linkValue</tt>
46
- * attribute.
47
- *
48
- * <p>For undirected networks, links are duplicated in both directions. For
49
- * directed networks, use <tt>directed(true)</tt>. The graph is assumed to be
50
- * undirected by default.
51
- *
52
- * @extends pv.Layout.Network
53
- * @see <a href="http://www.research.ibm.com/visual/papers/pivotgraph.pdf"
54
- * >"Visual Exploration of Multivariate Graphs"</a> by M. Wattenberg, CHI 2006.
55
- */
56
- pv.Layout.Rollup = function() {
57
- pv.Layout.Network.call(this);
58
- var that = this,
59
- nodes, // cached rollup nodes
60
- links, // cached rollup links
61
- buildImplied = that.buildImplied;
62
-
63
- /** @private Cache layout state to optimize properties. */
64
- this.buildImplied = function(s) {
65
- buildImplied.call(this, s);
66
- nodes = s.$rollup.nodes;
67
- links = s.$rollup.links;
68
- };
69
-
70
- /* Render rollup nodes. */
71
- this.node
72
- .data(function() { return nodes; })
73
- .shapeSize(function(d) { return d.nodes.length * 20; });
74
-
75
- /* Render rollup links. */
76
- this.link
77
- .interpolate("polar")
78
- .eccentricity(.8);
79
-
80
- this.link.add = function(type) {
81
- return that.add(pv.Panel)
82
- .data(function() { return links; })
83
- .add(type)
84
- .extend(this);
85
- };
86
- };
87
-
88
- pv.Layout.Rollup.prototype = pv.extend(pv.Layout.Network)
89
- .property("directed", Boolean);
90
-
91
- /**
92
- * Whether the underlying network is directed. By default, the graph is assumed
93
- * to be undirected, and links are rendered in both directions. If the network
94
- * is directed, then forward links are drawn above the diagonal, while reverse
95
- * links are drawn below.
96
- *
97
- * @type boolean
98
- * @name pv.Layout.Rollup.prototype.directed
99
- */
100
-
101
- /**
102
- * Specifies the <i>x</i>-position function used to rollup nodes. The rolled up
103
- * nodes are positioned horizontally using the return values from the given
104
- * function. Typically the function is specified as an ordinal scale. For
105
- * single-dimension rollups, a constant value can be specified.
106
- *
107
- * @param {function} f the <i>x</i>-position function.
108
- * @returns {pv.Layout.Rollup} this.
109
- * @see pv.Scale.ordinal
110
- */
111
- pv.Layout.Rollup.prototype.x = function(f) {
112
- this.$x = pv.functor(f);
113
- return this;
114
- };
115
-
116
- /**
117
- * Specifies the <i>y</i>-position function used to rollup nodes. The rolled up
118
- * nodes are positioned vertically using the return values from the given
119
- * function. Typically the function is specified as an ordinal scale. For
120
- * single-dimension rollups, a constant value can be specified.
121
- *
122
- * @param {function} f the <i>y</i>-position function.
123
- * @returns {pv.Layout.Rollup} this.
124
- * @see pv.Scale.ordinal
125
- */
126
- pv.Layout.Rollup.prototype.y = function(f) {
127
- this.$y = pv.functor(f);
128
- return this;
129
- };
130
-
131
- /** @private */
132
- pv.Layout.Rollup.prototype.buildImplied = function(s) {
133
- if (pv.Layout.Network.prototype.buildImplied.call(this, s)) return;
134
-
135
- var nodes = s.nodes,
136
- links = s.links,
137
- directed = s.directed,
138
- n = nodes.length,
139
- x = [],
140
- y = [],
141
- rnindex = 0,
142
- rnodes = {},
143
- rlinks = {};
144
-
145
- /** @private */
146
- function id(i) {
147
- return x[i] + "," + y[i];
148
- }
149
-
150
- /* Iterate over the data, evaluating the x and y functions. */
151
- var stack = pv.Mark.stack, o = {parent: this};
152
- stack.unshift(null);
153
- for (var i = 0; i < n; i++) {
154
- o.index = i;
155
- stack[0] = nodes[i];
156
- x[i] = this.$x.apply(o, stack);
157
- y[i] = this.$y.apply(o, stack);
158
- }
159
- stack.shift();
160
-
161
- /* Compute rollup nodes. */
162
- for (var i = 0; i < nodes.length; i++) {
163
- var nodeId = id(i),
164
- rn = rnodes[nodeId];
165
- if (!rn) {
166
- rn = rnodes[nodeId] = pv.extend(nodes[i]);
167
- rn.index = rnindex++;
168
- rn.x = x[i];
169
- rn.y = y[i];
170
- rn.nodes = [];
171
- }
172
- rn.nodes.push(nodes[i]);
173
- }
174
-
175
- /* Compute rollup links. */
176
- for (var i = 0; i < links.length; i++) {
177
- var source = links[i].sourceNode,
178
- target = links[i].targetNode,
179
- rsource = rnodes[id(source.index)],
180
- rtarget = rnodes[id(target.index)],
181
- reverse = !directed && rsource.index > rtarget.index,
182
- linkId = reverse
183
- ? rtarget.index + "," + rsource.index
184
- : rsource.index + "," + rtarget.index,
185
- rl = rlinks[linkId];
186
- if (!rl) {
187
- rl = rlinks[linkId] = {
188
- sourceNode: rsource,
189
- targetNode: rtarget,
190
- linkValue: 0,
191
- links: []
192
- };
193
- }
194
- rl.links.push(links[i]);
195
- rl.linkValue += links[i].linkValue;
196
- }
197
-
198
- /* Export the rolled up nodes and links to the scene. */
199
- s.$rollup = {
200
- nodes: pv.values(rnodes),
201
- links: pv.values(rlinks)
202
- };
203
- };
@@ -1,391 +0,0 @@
1
- /**
2
- * Constructs a new, empty stack layout. Layouts are not typically constructed
3
- * directly; instead, they are added to an existing panel via
4
- * {@link pv.Mark#add}.
5
- *
6
- * @class Implements a layout for stacked visualizations, ranging from simple
7
- * stacked bar charts to more elaborate "streamgraphs" composed of stacked
8
- * areas. Stack layouts uses length as a visual encoding, as opposed to
9
- * position, as the layers do not share an aligned axis.
10
- *
11
- * <p>Marks can be stacked vertically or horizontally. For example,
12
- *
13
- * <pre>vis.add(pv.Layout.Stack)
14
- * .layers([[1, 1.2, 1.7, 1.5, 1.7],
15
- * [.5, 1, .8, 1.1, 1.3],
16
- * [.2, .5, .8, .9, 1]])
17
- * .x(function() this.index * 35)
18
- * .y(function(d) d * 40)
19
- * .layer.add(pv.Area);</pre>
20
- *
21
- * specifies a vertically-stacked area chart, using the default "bottom-left"
22
- * orientation with "zero" offset. This visualization can be easily changed into
23
- * a streamgraph using the "wiggle" offset, which attempts to minimize change in
24
- * slope weighted by layer thickness. See the {@link #offset} property for more
25
- * supported streamgraph algorithms.
26
- *
27
- * <p>In the simplest case, the layer data can be specified as a two-dimensional
28
- * array of numbers. The <tt>x</tt> and <tt>y</tt> psuedo-properties are used to
29
- * define the thickness of each layer at the given position, respectively; in
30
- * the above example of the "bottom-left" orientation, the <tt>x</tt> and
31
- * <tt>y</tt> psuedo-properties are equivalent to the <tt>left</tt> and
32
- * <tt>height</tt> properties that you might use if you implemented a stacked
33
- * area by hand.
34
- *
35
- * <p>The advantage of using the stack layout is that the baseline, i.e., the
36
- * <tt>bottom</tt> property is computed automatically using the specified offset
37
- * algorithm. In addition, the order of layers can be computed using a built-in
38
- * algorithm via the <tt>order</tt> property.
39
- *
40
- * <p>With the exception of the "expand" <tt>offset</tt>, the stack layout does
41
- * not perform any automatic scaling of data; the values returned from
42
- * <tt>x</tt> and <tt>y</tt> specify pixel sizes. To simplify scaling math, use
43
- * this layout in conjunction with {@link pv.Scale.linear} or similar.
44
- *
45
- * <p>In other cases, the <tt>values</tt> psuedo-property can be used to define
46
- * the data more flexibly. As with a typical panel &amp; area, the
47
- * <tt>layers</tt> property corresponds to the data in the enclosing panel,
48
- * while the <tt>values</tt> psuedo-property corresponds to the data for the
49
- * area within the panel. For example, given an array of data values:
50
- *
51
- * <pre>var crimea = [
52
- * { date: "4/1854", wounds: 0, other: 110, disease: 110 },
53
- * { date: "5/1854", wounds: 0, other: 95, disease: 105 },
54
- * { date: "6/1854", wounds: 0, other: 40, disease: 95 },
55
- * ...</pre>
56
- *
57
- * and a corresponding array of series names:
58
- *
59
- * <pre>var causes = ["wounds", "other", "disease"];</pre>
60
- *
61
- * Separate layers can be defined for each cause like so:
62
- *
63
- * <pre>vis.add(pv.Layout.Stack)
64
- * .layers(causes)
65
- * .values(crimea)
66
- * .x(function(d) x(d.date))
67
- * .y(function(d, p) y(d[p]))
68
- * .layer.add(pv.Area)
69
- * ...</pre>
70
- *
71
- * As with the panel &amp; area case, the datum that is passed to the
72
- * psuedo-properties <tt>x</tt> and <tt>y</tt> are the values (an element in
73
- * <tt>crimea</tt>); the second argument is the layer data (a string in
74
- * <tt>causes</tt>). Additional arguments specify the data of enclosing panels,
75
- * if any.
76
- *
77
- * @extends pv.Layout
78
- */
79
- pv.Layout.Stack = function() {
80
- pv.Layout.call(this);
81
- var that = this,
82
- /** @ignore */ none = function() { return null; },
83
- prop = {t: none, l: none, r: none, b: none, w: none, h: none},
84
- values,
85
- buildImplied = that.buildImplied;
86
-
87
- /** @private Proxy the given property on the layer. */
88
- function proxy(name) {
89
- return function() {
90
- return prop[name](this.parent.index, this.index);
91
- };
92
- }
93
-
94
- /** @private Compute the layout! */
95
- this.buildImplied = function(s) {
96
- buildImplied.call(this, s);
97
-
98
- var data = s.layers,
99
- n = data.length,
100
- m,
101
- orient = s.orient,
102
- horizontal = /^(top|bottom)\b/.test(orient),
103
- h = this.parent[horizontal ? "height" : "width"](),
104
- x = [],
105
- y = [],
106
- dy = [];
107
-
108
- /*
109
- * Iterate over the data, evaluating the values, x and y functions. The
110
- * context in which the x and y psuedo-properties are evaluated is a
111
- * pseudo-mark that is a grandchild of this layout.
112
- */
113
- var stack = pv.Mark.stack, o = {parent: {parent: this}};
114
- stack.unshift(null);
115
- values = [];
116
- for (var i = 0; i < n; i++) {
117
- dy[i] = [];
118
- y[i] = [];
119
- o.parent.index = i;
120
- stack[0] = data[i];
121
- values[i] = this.$values.apply(o.parent, stack);
122
- if (!i) m = values[i].length;
123
- stack.unshift(null);
124
- for (var j = 0; j < m; j++) {
125
- stack[0] = values[i][j];
126
- o.index = j;
127
- if (!i) x[j] = this.$x.apply(o, stack);
128
- dy[i][j] = this.$y.apply(o, stack);
129
- }
130
- stack.shift();
131
- }
132
- stack.shift();
133
-
134
- /* order */
135
- var index;
136
- switch (s.order) {
137
- case "inside-out": {
138
- var max = dy.map(function(v) { return pv.max.index(v); }),
139
- map = pv.range(n).sort(function(a, b) { return max[a] - max[b]; }),
140
- sums = dy.map(function(v) { return pv.sum(v); }),
141
- top = 0,
142
- bottom = 0,
143
- tops = [],
144
- bottoms = [];
145
- for (var i = 0; i < n; i++) {
146
- var j = map[i];
147
- if (top < bottom) {
148
- top += sums[j];
149
- tops.push(j);
150
- } else {
151
- bottom += sums[j];
152
- bottoms.push(j);
153
- }
154
- }
155
- index = bottoms.reverse().concat(tops);
156
- break;
157
- }
158
- case "reverse": index = pv.range(n - 1, -1, -1); break;
159
- default: index = pv.range(n); break;
160
- }
161
-
162
- /* offset */
163
- switch (s.offset) {
164
- case "silohouette": {
165
- for (var j = 0; j < m; j++) {
166
- var o = 0;
167
- for (var i = 0; i < n; i++) o += dy[i][j];
168
- y[index[0]][j] = (h - o) / 2;
169
- }
170
- break;
171
- }
172
- case "wiggle": {
173
- var o = 0;
174
- for (var i = 0; i < n; i++) o += dy[i][0];
175
- y[index[0]][0] = o = (h - o) / 2;
176
- for (var j = 1; j < m; j++) {
177
- var s1 = 0, s2 = 0, dx = x[j] - x[j - 1];
178
- for (var i = 0; i < n; i++) s1 += dy[i][j];
179
- for (var i = 0; i < n; i++) {
180
- var s3 = (dy[index[i]][j] - dy[index[i]][j - 1]) / (2 * dx);
181
- for (var k = 0; k < i; k++) {
182
- s3 += (dy[index[k]][j] - dy[index[k]][j - 1]) / dx;
183
- }
184
- s2 += s3 * dy[index[i]][j];
185
- }
186
- y[index[0]][j] = o -= s1 ? s2 / s1 * dx : 0;
187
- }
188
- break;
189
- }
190
- case "expand": {
191
- for (var j = 0; j < m; j++) {
192
- y[index[0]][j] = 0;
193
- var k = 0;
194
- for (var i = 0; i < n; i++) k += dy[i][j];
195
- if (k) {
196
- k = h / k;
197
- for (var i = 0; i < n; i++) dy[i][j] *= k;
198
- } else {
199
- k = h / n;
200
- for (var i = 0; i < n; i++) dy[i][j] = k;
201
- }
202
- }
203
- break;
204
- }
205
- default: {
206
- for (var j = 0; j < m; j++) y[index[0]][j] = 0;
207
- break;
208
- }
209
- }
210
-
211
- /* Propagate the offset to the other series. */
212
- for (var j = 0; j < m; j++) {
213
- var o = y[index[0]][j];
214
- for (var i = 1; i < n; i++) {
215
- o += dy[index[i - 1]][j];
216
- y[index[i]][j] = o;
217
- }
218
- }
219
-
220
- /* Find the property definitions for dynamic substitution. */
221
- var i = orient.indexOf("-"),
222
- pdy = horizontal ? "h" : "w",
223
- px = i < 0 ? (horizontal ? "l" : "b") : orient.charAt(i + 1),
224
- py = orient.charAt(0);
225
- for (var p in prop) prop[p] = none;
226
- prop[px] = function(i, j) { return x[j]; };
227
- prop[py] = function(i, j) { return y[i][j]; };
228
- prop[pdy] = function(i, j) { return dy[i][j]; };
229
- };
230
-
231
- /**
232
- * The layer prototype. This prototype is intended to be used with an area,
233
- * bar or panel mark (or subclass thereof). Other mark types may be possible,
234
- * though note that the stack layout is not currently designed to support
235
- * radial stacked visualizations using wedges.
236
- *
237
- * <p>The layer is not a direct child of the stack layout; a hidden panel is
238
- * used to replicate layers.
239
- *
240
- * @type pv.Mark
241
- * @name pv.Layout.Stack.prototype.layer
242
- */
243
- this.layer = new pv.Mark()
244
- .data(function() { return values[this.parent.index]; })
245
- .top(proxy("t"))
246
- .left(proxy("l"))
247
- .right(proxy("r"))
248
- .bottom(proxy("b"))
249
- .width(proxy("w"))
250
- .height(proxy("h"));
251
-
252
- this.layer.add = function(type) {
253
- return that.add(pv.Panel)
254
- .data(function() { return that.layers(); })
255
- .add(type)
256
- .extend(this);
257
- };
258
- };
259
-
260
- pv.Layout.Stack.prototype = pv.extend(pv.Layout)
261
- .property("orient", String)
262
- .property("offset", String)
263
- .property("order", String)
264
- .property("layers");
265
-
266
- /**
267
- * Default properties for stack layouts. The default orientation is
268
- * "bottom-left", the default offset is "zero", and the default layers is
269
- * <tt>[[]]</tt>.
270
- *
271
- * @type pv.Layout.Stack
272
- */
273
- pv.Layout.Stack.prototype.defaults = new pv.Layout.Stack()
274
- .extend(pv.Layout.prototype.defaults)
275
- .orient("bottom-left")
276
- .offset("zero")
277
- .layers([[]]);
278
-
279
- /** @private */
280
- pv.Layout.Stack.prototype.$x
281
- = /** @private */ pv.Layout.Stack.prototype.$y
282
- = function() { return 0; };
283
-
284
- /**
285
- * The x psuedo-property; determines the position of the value within the layer.
286
- * This typically corresponds to the independent variable. For example, with the
287
- * default "bottom-left" orientation, this function defines the "left" property.
288
- *
289
- * @param {function} f the x function.
290
- * @returns {pv.Layout.Stack} this.
291
- */
292
- pv.Layout.Stack.prototype.x = function(f) {
293
- /** @private */ this.$x = pv.functor(f);
294
- return this;
295
- };
296
-
297
- /**
298
- * The y psuedo-property; determines the thickness of the layer at the given
299
- * value. This typically corresponds to the dependent variable. For example,
300
- * with the default "bottom-left" orientation, this function defines the
301
- * "height" property.
302
- *
303
- * @param {function} f the y function.
304
- * @returns {pv.Layout.Stack} this.
305
- */
306
- pv.Layout.Stack.prototype.y = function(f) {
307
- /** @private */ this.$y = pv.functor(f);
308
- return this;
309
- };
310
-
311
- /** @private The default value function; identity. */
312
- pv.Layout.Stack.prototype.$values = pv.identity;
313
-
314
- /**
315
- * The values function; determines the values for a given layer. The default
316
- * value is the identity function, which assumes that the layers property is
317
- * specified as a two-dimensional (i.e., nested) array.
318
- *
319
- * @param {function} f the values function.
320
- * @returns {pv.Layout.Stack} this.
321
- */
322
- pv.Layout.Stack.prototype.values = function(f) {
323
- this.$values = pv.functor(f);
324
- return this;
325
- };
326
-
327
- /**
328
- * The layer data in row-major order. The value of this property is typically a
329
- * two-dimensional (i.e., nested) array, but any array can be used, provided the
330
- * values psuedo-property is defined accordingly.
331
- *
332
- * @type array[]
333
- * @name pv.Layout.Stack.prototype.layers
334
- */
335
-
336
- /**
337
- * The layer orientation. The following values are supported:<ul>
338
- *
339
- * <li>bottom-left == bottom
340
- * <li>bottom-right
341
- * <li>top-left == top
342
- * <li>top-right
343
- * <li>left-top
344
- * <li>left-bottom == left
345
- * <li>right-top
346
- * <li>right-bottom == right
347
- *
348
- * </ul>. The default value is "bottom-left", which means that the layers will
349
- * be built from the bottom-up, and the values within layers will be laid out
350
- * from left-to-right.
351
- *
352
- * <p>Note that with non-zero baselines, some orientations may give similar
353
- * results. For example, offset("silohouette") centers the layers, resulting in
354
- * a streamgraph. Thus, the orientations "bottom-left" and "top-left" will
355
- * produce similar results, differing only in the layer order.
356
- *
357
- * @type string
358
- * @name pv.Layout.Stack.prototype.orient
359
- */
360
-
361
- /**
362
- * The layer order. The following values are supported:<ul>
363
- *
364
- * <li><i>null</i> - use given layer order.
365
- * <li>inside-out - sort by maximum value, with balanced order.
366
- * <li>reverse - use reverse of given layer order.
367
- *
368
- * </ul>For details on the inside-out order algorithm, refer to "Stacked Graphs
369
- * -- Geometry &amp; Aesthetics" by L. Byron and M. Wattenberg, IEEE TVCG
370
- * November/December 2008.
371
- *
372
- * @type string
373
- * @name pv.Layout.Stack.prototype.order
374
- */
375
-
376
- /**
377
- * The layer offset; the y-position of the bottom of the lowest layer. The
378
- * following values are supported:<ul>
379
- *
380
- * <li>zero - use a zero baseline, i.e., the y-axis.
381
- * <li>silohouette - center the stream, i.e., ThemeRiver.
382
- * <li>wiggle - minimize weighted change in slope.
383
- * <li>expand - expand layers to fill the enclosing layout dimensions.
384
- *
385
- * </ul>For details on these offset algorithms, refer to "Stacked Graphs --
386
- * Geometry &amp; Aesthetics" by L. Byron and M. Wattenberg, IEEE TVCG
387
- * November/December 2008.
388
- *
389
- * @type string
390
- * @name pv.Layout.Stack.prototype.offset
391
- */