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,273 +0,0 @@
1
- /**
2
- * Constructs a new, empty panel with default properties. Panels, with the
3
- * exception of the root panel, are not typically constructed directly; instead,
4
- * they are added to an existing panel or mark via {@link pv.Mark#add}.
5
- *
6
- * @class Represents a container mark. Panels allow repeated or nested
7
- * structures, commonly used in small multiple displays where a small
8
- * visualization is tiled to facilitate comparison across one or more
9
- * dimensions. Other types of visualizations may benefit from repeated and
10
- * possibly overlapping structure as well, such as stacked area charts. Panels
11
- * can also offset the position of marks to provide padding from surrounding
12
- * content.
13
- *
14
- * <p>All Protovis displays have at least one panel; this is the root panel to
15
- * which marks are rendered. The box model properties (four margins, width and
16
- * height) are used to offset the positions of contained marks. The data
17
- * property determines the panel count: a panel is generated once per associated
18
- * datum. When nested panels are used, property functions can declare additional
19
- * arguments to access the data associated with enclosing panels.
20
- *
21
- * <p>Panels can be rendered inline, facilitating the creation of sparklines.
22
- * This allows designers to reuse browser layout features, such as text flow and
23
- * tables; designers can also overlay HTML elements such as rich text and
24
- * images.
25
- *
26
- * <p>All panels have a <tt>children</tt> array (possibly empty) containing the
27
- * child marks in the order they were added. Panels also have a <tt>root</tt>
28
- * field which points to the root (outermost) panel; the root panel's root field
29
- * points to itself.
30
- *
31
- * <p>See also the <a href="../../api/">Protovis guide</a>.
32
- *
33
- * @extends pv.Bar
34
- */
35
- pv.Panel = function() {
36
- pv.Bar.call(this);
37
-
38
- /**
39
- * The child marks; zero or more {@link pv.Mark}s in the order they were
40
- * added.
41
- *
42
- * @see #add
43
- * @type pv.Mark[]
44
- */
45
- this.children = [];
46
- this.root = this;
47
-
48
- /**
49
- * The internal $dom field is set by the Protovis loader; see lang/init.js. It
50
- * refers to the script element that contains the Protovis specification, so
51
- * that the panel knows where in the DOM to insert the generated SVG element.
52
- *
53
- * @private
54
- */
55
- this.$dom = pv.$ && pv.$.s;
56
- };
57
-
58
- pv.Panel.prototype = pv.extend(pv.Bar)
59
- .property("transform")
60
- .property("overflow", String)
61
- .property("canvas", function(c) {
62
- return (typeof c == "string")
63
- ? document.getElementById(c)
64
- : c; // assume that c is the passed-in element
65
- });
66
-
67
- pv.Panel.prototype.type = "panel";
68
-
69
- /**
70
- * The canvas element; either the string ID of the canvas element in the current
71
- * document, or a reference to the canvas element itself. If null, a canvas
72
- * element will be created and inserted into the document at the location of the
73
- * script element containing the current Protovis specification. This property
74
- * only applies to root panels and is ignored on nested panels.
75
- *
76
- * <p>Note: the "canvas" element here refers to a <tt>div</tt> (or other suitable
77
- * HTML container element), <i>not</i> a <tt>canvas</tt> element. The name of
78
- * this property is a historical anachronism from the first implementation that
79
- * used HTML 5 canvas, rather than SVG.
80
- *
81
- * @type string
82
- * @name pv.Panel.prototype.canvas
83
- */
84
-
85
- /**
86
- * Specifies whether child marks are clipped when they overflow this panel.
87
- * This affects the clipping of all this panel's descendant marks.
88
- *
89
- * @type string
90
- * @name pv.Panel.prototype.overflow
91
- * @see <a href="http://www.w3.org/TR/CSS2/visufx.html#overflow">CSS2</a>
92
- */
93
-
94
- /**
95
- * The transform to be applied to child marks. The default transform is
96
- * identity, which has no effect. Note that the panel's own fill and stroke are
97
- * not affected by the transform, and panel's transform only affects the
98
- * <tt>scale</tt> of child marks, not the panel itself.
99
- *
100
- * @type pv.Transform
101
- * @name pv.Panel.prototype.transform
102
- * @see pv.Mark#scale
103
- */
104
-
105
- /**
106
- * Default properties for panels. By default, the margins are zero, the fill
107
- * style is transparent.
108
- *
109
- * @type pv.Panel
110
- */
111
- pv.Panel.prototype.defaults = new pv.Panel()
112
- .extend(pv.Bar.prototype.defaults)
113
- .fillStyle(null) // override Bar default
114
- .overflow("visible");
115
-
116
- /**
117
- * Returns an anchor with the specified name. This method is overridden such
118
- * that adding to a panel's anchor adds to the panel, rather than to the panel's
119
- * parent.
120
- *
121
- * @param {string} name the anchor name; either a string or a property function.
122
- * @returns {pv.Anchor} the new anchor.
123
- */
124
- pv.Panel.prototype.anchor = function(name) {
125
- var anchor = pv.Bar.prototype.anchor.call(this, name);
126
- anchor.parent = this;
127
- return anchor;
128
- };
129
-
130
- /**
131
- * Adds a new mark of the specified type to this panel. Unlike the normal
132
- * {@link Mark#add} behavior, adding a mark to a panel does not cause the mark
133
- * to inherit from the panel. Since the contained marks are offset by the panel
134
- * margins already, inheriting properties is generally undesirable; of course,
135
- * it is always possible to change this behavior by calling {@link Mark#extend}
136
- * explicitly.
137
- *
138
- * @param {function} type the type of the new mark to add.
139
- * @returns {pv.Mark} the new mark.
140
- */
141
- pv.Panel.prototype.add = function(type) {
142
- var child = new type();
143
- child.parent = this;
144
- child.root = this.root;
145
- child.childIndex = this.children.length;
146
- this.children.push(child);
147
- return child;
148
- };
149
-
150
- /** @private Bind this panel, then any child marks recursively. */
151
- pv.Panel.prototype.bind = function() {
152
- pv.Mark.prototype.bind.call(this);
153
- for (var i = 0; i < this.children.length; i++) {
154
- this.children[i].bind();
155
- }
156
- };
157
-
158
- /**
159
- * @private Evaluates all of the properties for this panel for the specified
160
- * instance <tt>s</tt> in the scene graph, including recursively building the
161
- * scene graph for child marks.
162
- *
163
- * @param s a node in the scene graph; the instance of the panel to build.
164
- * @see Mark#scene
165
- */
166
- pv.Panel.prototype.buildInstance = function(s) {
167
- pv.Bar.prototype.buildInstance.call(this, s);
168
- if (!s.visible) return;
169
- if (!s.children) s.children = [];
170
-
171
- /*
172
- * Multiply the current scale factor by this panel's transform. Also clear the
173
- * default index as we recurse into child marks; it will be reset to the
174
- * current index when the next panel instance is built.
175
- */
176
- var scale = this.scale * s.transform.k, child, n = this.children.length;
177
- pv.Mark.prototype.index = -1;
178
-
179
- /*
180
- * Build each child, passing in the parent (this panel) scene graph node. The
181
- * child mark's scene is initialized from the corresponding entry in the
182
- * existing scene graph, such that properties from the previous build can be
183
- * reused; this is largely to facilitate the recycling of SVG elements.
184
- */
185
- for (var i = 0; i < n; i++) {
186
- child = this.children[i];
187
- child.scene = s.children[i]; // possibly undefined
188
- child.scale = scale;
189
- child.build();
190
- }
191
-
192
- /*
193
- * Once the child marks have been built, the new scene graph nodes are removed
194
- * from the child marks and placed into the scene graph. The nodes cannot
195
- * remain on the child nodes because this panel (or a parent panel) may be
196
- * instantiated multiple times!
197
- */
198
- for (var i = 0; i < n; i++) {
199
- child = this.children[i];
200
- s.children[i] = child.scene;
201
- delete child.scene;
202
- delete child.scale;
203
- }
204
-
205
- /* Delete any expired child scenes. */
206
- s.children.length = n;
207
- };
208
-
209
- /**
210
- * @private Computes the implied properties for this panel for the specified
211
- * instance <tt>s</tt> in the scene graph. Panels have two implied
212
- * properties:<ul>
213
- *
214
- * <li>The <tt>canvas</tt> property references the DOM element, typically a DIV,
215
- * that contains the SVG element that is used to display the visualization. This
216
- * property may be specified as a string, referring to the unique ID of the
217
- * element in the DOM. The string is converted to a reference to the DOM
218
- * element. The width and height of the SVG element is inferred from this DOM
219
- * element. If no canvas property is specified, a new SVG element is created and
220
- * inserted into the document, using the panel dimensions; see
221
- * {@link #createCanvas}.
222
- *
223
- * <li>The <tt>children</tt> array, while not a property per se, contains the
224
- * scene graph for each child mark. This array is initialized to be empty, and
225
- * is populated above in {@link #buildInstance}.
226
- *
227
- * </ul>The current implementation creates the SVG element, if necessary, during
228
- * the build phase; in the future, it may be preferrable to move this to the
229
- * update phase, although then the canvas property would be undefined. In
230
- * addition, DOM inspection is necessary to define the implied width and height
231
- * properties that may be inferred from the DOM.
232
- *
233
- * @param s a node in the scene graph; the instance of the panel to build.
234
- */
235
- pv.Panel.prototype.buildImplied = function(s) {
236
- if (!this.parent) {
237
- var c = s.canvas;
238
- if (c) {
239
- /* Clear the container if it's not associated with this panel. */
240
- if (c.$panel != this) {
241
- c.$panel = this;
242
- while (c.lastChild) c.removeChild(c.lastChild);
243
- }
244
-
245
- /* If width and height weren't specified, inspect the container. */
246
- var w, h;
247
- if (s.width == null) {
248
- w = parseFloat(pv.css(c, "width"));
249
- s.width = w - s.left - s.right;
250
- }
251
- if (s.height == null) {
252
- h = parseFloat(pv.css(c, "height"));
253
- s.height = h - s.top - s.bottom;
254
- }
255
- } else {
256
- var cache = this.$canvas || (this.$canvas = []);
257
- if (!(c = cache[this.index])) {
258
- c = cache[this.index] = document.createElement("span");
259
- if (this.$dom) { // script element for text/javascript+protovis
260
- this.$dom.parentNode.insertBefore(c, this.$dom);
261
- } else { // find the last element in the body
262
- var n = document.body;
263
- while (n.lastChild && n.lastChild.tagName) n = n.lastChild;
264
- if (n != document.body) n = n.parentNode;
265
- n.appendChild(c);
266
- }
267
- }
268
- }
269
- s.canvas = c;
270
- }
271
- if (!s.transform) s.transform = pv.Transform.identity;
272
- pv.Mark.prototype.buildImplied.call(this, s);
273
- };
@@ -1,143 +0,0 @@
1
- /**
2
- * Constructs a new rule with default properties. Rules are not typically
3
- * constructed directly, but by adding to a panel or an existing mark via
4
- * {@link pv.Mark#add}.
5
- *
6
- * @class Represents a horizontal or vertical rule. Rules are frequently used
7
- * for axes and grid lines. For example, specifying only the bottom property
8
- * draws horizontal rules, while specifying only the left draws vertical
9
- * rules. Rules can also be used as thin bars. The visual style is controlled in
10
- * the same manner as lines.
11
- *
12
- * <p>Rules are positioned exclusively the standard box model properties. The
13
- * following combinations of properties are supported:
14
- *
15
- * <table>
16
- * <thead><th style="width:12em;">Properties</th><th>Orientation</th></thead>
17
- * <tbody>
18
- * <tr><td>left</td><td>vertical</td></tr>
19
- * <tr><td>right</td><td>vertical</td></tr>
20
- * <tr><td>left, bottom, top</td><td>vertical</td></tr>
21
- * <tr><td>right, bottom, top</td><td>vertical</td></tr>
22
- * <tr><td>top</td><td>horizontal</td></tr>
23
- * <tr><td>bottom</td><td>horizontal</td></tr>
24
- * <tr><td>top, left, right</td><td>horizontal</td></tr>
25
- * <tr><td>bottom, left, right</td><td>horizontal</td></tr>
26
- * <tr><td>left, top, height</td><td>vertical</td></tr>
27
- * <tr><td>left, bottom, height</td><td>vertical</td></tr>
28
- * <tr><td>right, top, height</td><td>vertical</td></tr>
29
- * <tr><td>right, bottom, height</td><td>vertical</td></tr>
30
- * <tr><td>left, top, width</td><td>horizontal</td></tr>
31
- * <tr><td>left, bottom, width</td><td>horizontal</td></tr>
32
- * <tr><td>right, top, width</td><td>horizontal</td></tr>
33
- * <tr><td>right, bottom, width</td><td>horizontal</td></tr>
34
- * </tbody>
35
- * </table>
36
- *
37
- * <p>Small rules can be used as tick marks; alternatively, a {@link Dot} with
38
- * the "tick" shape can be used.
39
- *
40
- * <p>See also the <a href="../../api/Rule.html">Rule guide</a>.
41
- *
42
- * @see pv.Line
43
- * @extends pv.Mark
44
- */
45
- pv.Rule = function() {
46
- pv.Mark.call(this);
47
- };
48
-
49
- pv.Rule.prototype = pv.extend(pv.Mark)
50
- .property("width", Number)
51
- .property("height", Number)
52
- .property("lineWidth", Number)
53
- .property("strokeStyle", pv.color);
54
-
55
- pv.Rule.prototype.type = "rule";
56
-
57
- /**
58
- * The width of the rule, in pixels. If the left position is specified, the rule
59
- * extends rightward from the left edge; if the right position is specified, the
60
- * rule extends leftward from the right edge.
61
- *
62
- * @type number
63
- * @name pv.Rule.prototype.width
64
- */
65
-
66
- /**
67
- * The height of the rule, in pixels. If the bottom position is specified, the
68
- * rule extends upward from the bottom edge; if the top position is specified,
69
- * the rule extends downward from the top edge.
70
- *
71
- * @type number
72
- * @name pv.Rule.prototype.height
73
- */
74
-
75
- /**
76
- * The width of stroked lines, in pixels; used in conjunction with
77
- * <tt>strokeStyle</tt> to stroke the rule. The default value is 1 pixel.
78
- *
79
- * @type number
80
- * @name pv.Rule.prototype.lineWidth
81
- */
82
-
83
- /**
84
- * The style of stroked lines; used in conjunction with <tt>lineWidth</tt> to
85
- * stroke the rule. The default value of this property is black.
86
- *
87
- * @type string
88
- * @name pv.Rule.prototype.strokeStyle
89
- * @see pv.color
90
- */
91
-
92
- /**
93
- * Default properties for rules. By default, a single-pixel black line is
94
- * stroked.
95
- *
96
- * @type pv.Rule
97
- */
98
- pv.Rule.prototype.defaults = new pv.Rule()
99
- .extend(pv.Mark.prototype.defaults)
100
- .lineWidth(1)
101
- .strokeStyle("black")
102
- .antialias(false);
103
-
104
- /**
105
- * Constructs a new rule anchor with default properties. Rules support five
106
- * different anchors:<ul>
107
- *
108
- * <li>top
109
- * <li>left
110
- * <li>center
111
- * <li>bottom
112
- * <li>right
113
- *
114
- * </ul>In addition to positioning properties (left, right, top bottom), the
115
- * anchors support text rendering properties (text-align, text-baseline). Text is
116
- * rendered to appear outside the rule. Note that this behavior is different
117
- * from other mark anchors, which default to rendering text <i>inside</i> the
118
- * mark.
119
- *
120
- * <p>For consistency with the other mark types, the anchor positions are
121
- * defined in terms of their opposite edge. For example, the top anchor defines
122
- * the bottom property, such that a bar added to the top anchor grows upward.
123
- *
124
- * @param {string} name the anchor name; either a string or a property function.
125
- * @returns {pv.Anchor}
126
- */
127
- pv.Rule.prototype.anchor = pv.Line.prototype.anchor;
128
-
129
- /** @private Sets width or height based on orientation. */
130
- pv.Rule.prototype.buildImplied = function(s) {
131
- var l = s.left, r = s.right, t = s.top, b = s.bottom;
132
-
133
- /* Determine horizontal or vertical orientation. */
134
- if ((s.width != null)
135
- || ((l == null) && (r == null))
136
- || ((r != null) && (l != null))) {
137
- s.height = 0;
138
- } else {
139
- s.width = 0;
140
- }
141
-
142
- pv.Mark.prototype.buildImplied.call(this, s);
143
- };
@@ -1,7 +0,0 @@
1
- pv.Transient = function(mark) {
2
- pv.Mark.call(this);
3
- this.fillStyle(null).strokeStyle(null).textStyle(null);
4
- this.on = function(state) { return mark.on(state); };
5
- };
6
-
7
- pv.Transient.prototype = pv.extend(pv.Mark);
@@ -1,195 +0,0 @@
1
- pv.Transition = function(mark) {
2
- var that = this,
3
- ease = pv.ease("cubic-in-out"),
4
- duration = 250,
5
- timer;
6
-
7
- var interpolated = {
8
- top: 1,
9
- left: 1,
10
- right: 1,
11
- bottom: 1,
12
- width: 1,
13
- height: 1,
14
- innerRadius: 1,
15
- outerRadius: 1,
16
- radius: 1,
17
- startAngle: 1,
18
- endAngle: 1,
19
- angle: 1,
20
- fillStyle: 1,
21
- strokeStyle: 1,
22
- lineWidth: 1,
23
- eccentricity: 1,
24
- tension: 1,
25
- textAngle: 1,
26
- textStyle: 1,
27
- textMargin: 1
28
- };
29
-
30
- var defaults = new pv.Transient();
31
-
32
- var none = pv.Color.transparent;
33
-
34
- /** @private */
35
- function ids(marks) {
36
- var map = {};
37
- for (var i = 0; i < marks.length; i++) {
38
- var mark = marks[i];
39
- if (mark.id) map[mark.id] = mark;
40
- }
41
- return map;
42
- }
43
-
44
- /** @private */
45
- function interpolateProperty(list, name, before, after) {
46
- if (name in interpolated) {
47
- var i = pv.Scale.interpolator(before[name], after[name]);
48
- var f = function(t) { before[name] = i(t); }
49
- } else {
50
- var f = function(t) { if (t > .5) before[name] = after[name]; }
51
- }
52
- f.next = list.head;
53
- list.head = f;
54
- }
55
-
56
- /** @private */
57
- function interpolateInstance(list, before, after) {
58
- for (var name in before) {
59
- if (name == "children") continue; // not a property
60
- if (before[name] == after[name]) continue; // unchanged
61
- interpolateProperty(list, name, before, after);
62
- }
63
- if (before.children) {
64
- for (var j = 0; j < before.children.length; j++) {
65
- interpolate(list, before.children[j], after.children[j]);
66
- }
67
- }
68
- }
69
-
70
- /** @private */
71
- function interpolate(list, before, after) {
72
- var mark = before.mark, bi = ids(before), ai = ids(after);
73
- for (var i = 0; i < before.length; i++) {
74
- var b = before[i], a = b.id ? ai[b.id] : after[i];
75
- b.index = i;
76
- if (!b.visible) continue;
77
- if (!(a && a.visible)) {
78
- var o = override(before, i, mark.$exit, after);
79
-
80
- /*
81
- * After the transition finishes, we need to do a little cleanup to
82
- * insure that the final state of the scenegraph is consistent with the
83
- * "after" render. For instances that were removed, we need to remove
84
- * them from the scenegraph; for instances that became invisible, we
85
- * need to mark them invisible. See the cleanup method for details.
86
- */
87
- b.transition = a ? 2 : (after.push(o), 1);
88
- a = o;
89
- }
90
- interpolateInstance(list, b, a);
91
- }
92
- for (var i = 0; i < after.length; i++) {
93
- var a = after[i], b = a.id ? bi[a.id] : before[i];
94
- if (!(b && b.visible) && a.visible) {
95
- var o = override(after, i, mark.$enter, before);
96
- if (!b) before.push(o);
97
- else before[b.index] = o;
98
- interpolateInstance(list, o, a);
99
- }
100
- }
101
- }
102
-
103
- /** @private */
104
- function override(scene, index, proto, other) {
105
- var s = pv.extend(scene[index]),
106
- m = scene.mark,
107
- r = m.root.scene,
108
- p = (proto || defaults).$properties,
109
- t;
110
-
111
- /* Correct the target reference, if this is an anchor. */
112
- if (other.target && (t = other.target[other.length])) {
113
- scene = pv.extend(scene);
114
- scene.target = pv.extend(other.target);
115
- scene.target[index] = t;
116
- }
117
-
118
- /* Determine the set of properties to evaluate. */
119
- var seen = {};
120
- for (var i = 0; i < p.length; i++) seen[p[i].name] = 1;
121
- p = m.binds.optional
122
- .filter(function(p) { return !(p.name in seen); })
123
- .concat(p);
124
-
125
- /* Evaluate the properties and update any implied ones. */
126
- m.context(scene, index, function() {
127
- this.buildProperties(s, p);
128
- this.buildImplied(s);
129
- });
130
-
131
- /* Restore the root scene. This should probably be done by context(). */
132
- m.root.scene = r;
133
- return s;
134
- }
135
-
136
- /** @private */
137
- function cleanup(scene) {
138
- for (var i = 0, j = 0; i < scene.length; i++) {
139
- var s = scene[i];
140
- if (s.transition != 1) {
141
- scene[j++] = s;
142
- if (s.transition == 2) s.visible = false;
143
- if (s.children) s.children.forEach(cleanup);
144
- }
145
- }
146
- scene.length = j;
147
- }
148
-
149
- that.ease = function(x) {
150
- return arguments.length
151
- ? (ease = typeof x == "function" ? x : pv.ease(x), that)
152
- : ease;
153
- };
154
-
155
- that.duration = function(x) {
156
- return arguments.length
157
- ? (duration = Number(x), that)
158
- : duration;
159
- };
160
-
161
- that.start = function() {
162
- // TODO allow partial rendering
163
- if (mark.parent) fail();
164
-
165
- // TODO allow parallel and sequenced transitions
166
- if (mark.$transition) mark.$transition.stop();
167
- mark.$transition = that;
168
-
169
- // TODO clearing the scene like this forces total re-build
170
- var i = pv.Mark.prototype.index, before = mark.scene, after;
171
- mark.scene = null;
172
- mark.bind();
173
- mark.build();
174
- after = mark.scene;
175
- mark.scene = before;
176
- pv.Mark.prototype.index = i;
177
-
178
- var start = Date.now(), list = {};
179
- interpolate(list, before, after);
180
- timer = setInterval(function() {
181
- var t = Math.max(0, Math.min(1, (Date.now() - start) / duration)),
182
- e = ease(t);
183
- for (var i = list.head; i; i = i.next) i(e);
184
- if (t == 1) {
185
- cleanup(mark.scene);
186
- that.stop();
187
- }
188
- pv.Scene.updateAll(before);
189
- }, 24);
190
- };
191
-
192
- that.stop = function() {
193
- clearInterval(timer);
194
- };
195
- };