rubyvis 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +13 -0
  4. data/Gemfile +8 -0
  5. data/Gemfile.lock +37 -0
  6. data/History.txt +6 -0
  7. data/LICENSE.txt +23 -0
  8. data/{README.txt → README.md} +15 -12
  9. data/Rakefile +4 -11
  10. data/lib/rubyvis.rb +1 -1
  11. data/lib/rubyvis/scale/quantitative.rb +14 -18
  12. data/lib/rubyvis/scene/svg_label.rb +1 -1
  13. data/rubyvis.gemspec +21 -0
  14. data/spec/anchor_spec.rb +2 -1
  15. data/spec/line_spec.rb +2 -2
  16. data/spec/scale_linear_datetime_spec.rb +23 -8
  17. data/spec/spec_helper.rb +2 -1
  18. metadata +31 -214
  19. data/.gemtest +0 -0
  20. data/vendor/protovis/protovis-r3.3.js +0 -287
  21. data/vendor/protovis/src/behavior/Behavior.js +0 -32
  22. data/vendor/protovis/src/behavior/Drag.js +0 -112
  23. data/vendor/protovis/src/behavior/Pan.js +0 -110
  24. data/vendor/protovis/src/behavior/Point.js +0 -157
  25. data/vendor/protovis/src/behavior/Resize.js +0 -104
  26. data/vendor/protovis/src/behavior/Select.js +0 -100
  27. data/vendor/protovis/src/behavior/Zoom.js +0 -85
  28. data/vendor/protovis/src/color/Color.js +0 -598
  29. data/vendor/protovis/src/color/Colors.js +0 -135
  30. data/vendor/protovis/src/color/Ramp.js +0 -17
  31. data/vendor/protovis/src/data/Arrays.js +0 -277
  32. data/vendor/protovis/src/data/Dom.js +0 -380
  33. data/vendor/protovis/src/data/Flatten.js +0 -146
  34. data/vendor/protovis/src/data/Histogram.js +0 -120
  35. data/vendor/protovis/src/data/LinearScale.js +0 -54
  36. data/vendor/protovis/src/data/LogScale.js +0 -142
  37. data/vendor/protovis/src/data/Nest.js +0 -257
  38. data/vendor/protovis/src/data/Numbers.js +0 -313
  39. data/vendor/protovis/src/data/Objects.js +0 -78
  40. data/vendor/protovis/src/data/OrdinalScale.js +0 -267
  41. data/vendor/protovis/src/data/QuantileScale.js +0 -180
  42. data/vendor/protovis/src/data/QuantitativeScale.js +0 -440
  43. data/vendor/protovis/src/data/RootScale.js +0 -55
  44. data/vendor/protovis/src/data/Scale.js +0 -86
  45. data/vendor/protovis/src/data/Transform.js +0 -109
  46. data/vendor/protovis/src/data/Tree.js +0 -124
  47. data/vendor/protovis/src/data/Vector.js +0 -118
  48. data/vendor/protovis/src/geo/Geo.js +0 -5
  49. data/vendor/protovis/src/geo/GeoScale.js +0 -307
  50. data/vendor/protovis/src/geo/LatLng.js +0 -23
  51. data/vendor/protovis/src/geo/Projection.js +0 -43
  52. data/vendor/protovis/src/geo/Projections.js +0 -117
  53. data/vendor/protovis/src/lang/Array.js +0 -112
  54. data/vendor/protovis/src/lang/init.js +0 -26
  55. data/vendor/protovis/src/layout/Arc.js +0 -178
  56. data/vendor/protovis/src/layout/Bullet.js +0 -164
  57. data/vendor/protovis/src/layout/Cluster.js +0 -205
  58. data/vendor/protovis/src/layout/Force.js +0 -309
  59. data/vendor/protovis/src/layout/Grid.js +0 -119
  60. data/vendor/protovis/src/layout/Hierarchy.js +0 -249
  61. data/vendor/protovis/src/layout/Horizon.js +0 -159
  62. data/vendor/protovis/src/layout/Indent.js +0 -83
  63. data/vendor/protovis/src/layout/Layout.js +0 -56
  64. data/vendor/protovis/src/layout/Matrix.js +0 -177
  65. data/vendor/protovis/src/layout/Network.js +0 -302
  66. data/vendor/protovis/src/layout/Pack.js +0 -323
  67. data/vendor/protovis/src/layout/Partition.js +0 -203
  68. data/vendor/protovis/src/layout/Rollup.js +0 -203
  69. data/vendor/protovis/src/layout/Stack.js +0 -391
  70. data/vendor/protovis/src/layout/Tree.js +0 -282
  71. data/vendor/protovis/src/layout/Treemap.js +0 -347
  72. data/vendor/protovis/src/mark/Anchor.js +0 -81
  73. data/vendor/protovis/src/mark/Area.js +0 -268
  74. data/vendor/protovis/src/mark/Bar.js +0 -93
  75. data/vendor/protovis/src/mark/Dot.js +0 -212
  76. data/vendor/protovis/src/mark/Ease.js +0 -150
  77. data/vendor/protovis/src/mark/Image.js +0 -154
  78. data/vendor/protovis/src/mark/Label.js +0 -155
  79. data/vendor/protovis/src/mark/Line.js +0 -195
  80. data/vendor/protovis/src/mark/Mark.js +0 -1237
  81. data/vendor/protovis/src/mark/Panel.js +0 -273
  82. data/vendor/protovis/src/mark/Rule.js +0 -143
  83. data/vendor/protovis/src/mark/Transient.js +0 -7
  84. data/vendor/protovis/src/mark/Transition.js +0 -195
  85. data/vendor/protovis/src/mark/Wedge.js +0 -244
  86. data/vendor/protovis/src/physics/BoundConstraint.js +0 -75
  87. data/vendor/protovis/src/physics/ChargeForce.js +0 -184
  88. data/vendor/protovis/src/physics/CollisionConstraint.js +0 -113
  89. data/vendor/protovis/src/physics/Constraint.js +0 -26
  90. data/vendor/protovis/src/physics/DragForce.js +0 -49
  91. data/vendor/protovis/src/physics/Force.js +0 -25
  92. data/vendor/protovis/src/physics/Particle.js +0 -81
  93. data/vendor/protovis/src/physics/PositionConstraint.js +0 -72
  94. data/vendor/protovis/src/physics/Quadtree.js +0 -195
  95. data/vendor/protovis/src/physics/Simulation.js +0 -159
  96. data/vendor/protovis/src/physics/SpringForce.js +0 -141
  97. data/vendor/protovis/src/pv-internals.js +0 -154
  98. data/vendor/protovis/src/pv.js +0 -95
  99. data/vendor/protovis/src/scene/SvgArea.js +0 -172
  100. data/vendor/protovis/src/scene/SvgBar.js +0 -28
  101. data/vendor/protovis/src/scene/SvgCurve.js +0 -354
  102. data/vendor/protovis/src/scene/SvgDot.js +0 -81
  103. data/vendor/protovis/src/scene/SvgImage.js +0 -45
  104. data/vendor/protovis/src/scene/SvgLabel.js +0 -46
  105. data/vendor/protovis/src/scene/SvgLine.js +0 -159
  106. data/vendor/protovis/src/scene/SvgPanel.js +0 -126
  107. data/vendor/protovis/src/scene/SvgRule.js +0 -26
  108. data/vendor/protovis/src/scene/SvgScene.js +0 -185
  109. data/vendor/protovis/src/scene/SvgWedge.js +0 -66
  110. data/vendor/protovis/src/text/DateFormat.js +0 -262
  111. data/vendor/protovis/src/text/Format.js +0 -78
  112. data/vendor/protovis/src/text/NumberFormat.js +0 -227
  113. data/vendor/protovis/src/text/TimeFormat.js +0 -115
@@ -1,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
- };