rubyvis 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +9 -1
- data/Manifest.txt +9 -4
- data/README.txt +59 -8
- data/examples/antibiotics/antibiotics.rb +16 -8
- data/examples/area.rb +6 -49
- data/examples/bar_column_chart.rb +4 -0
- data/examples/crimea/{crimea.rb → crimea_data.rb} +0 -0
- data/examples/crimea/crimea_grouped_bar.rb +2 -2
- data/examples/crimea/crimea_line.rb +1 -1
- data/examples/dot.rb +7 -8
- data/examples/first.rb +4 -0
- data/examples/grouped_charts.rb +3 -0
- data/examples/line.rb +19 -61
- data/examples/line_and_step.rb +4 -0
- data/examples/nested_grid.rb +53 -0
- data/examples/scatterplot.rb +2 -0
- data/examples/second.rb +14 -2
- data/examples/third.rb +9 -6
- data/lib/rubyvis/color/color.rb +8 -6
- data/lib/rubyvis/color/colors.rb +4 -6
- data/lib/rubyvis/format/number.rb +2 -2
- data/lib/rubyvis/internals.rb +15 -3
- data/lib/rubyvis/javascript_behaviour.rb +20 -8
- data/lib/rubyvis/layout/stack.rb +13 -16
- data/lib/rubyvis/mark/anchor.rb +64 -2
- data/lib/rubyvis/mark/area.rb +4 -3
- data/lib/rubyvis/mark/bar.rb +51 -2
- data/lib/rubyvis/mark/dot.rb +88 -5
- data/lib/rubyvis/mark/label.rb +94 -3
- data/lib/rubyvis/mark/line.rb +3 -2
- data/lib/rubyvis/mark/panel.rb +1 -0
- data/lib/rubyvis/mark/rule.rb +2 -1
- data/lib/rubyvis/mark/wedge.rb +2 -1
- data/lib/rubyvis/mark.rb +419 -54
- data/lib/rubyvis/nest.rb +20 -20
- data/lib/rubyvis/scale/linear.rb +1 -1
- data/lib/rubyvis/scale/log.rb +1 -1
- data/lib/rubyvis/scale/ordinal.rb +120 -8
- data/lib/rubyvis/scale/quantitative.rb +159 -15
- data/lib/rubyvis/scale.rb +1 -1
- data/lib/rubyvis/scene/svg_area.rb +12 -12
- data/lib/rubyvis/scene/svg_line.rb +5 -5
- data/lib/rubyvis/scene/svg_panel.rb +1 -1
- data/lib/rubyvis/scene/svg_scene.rb +1 -1
- data/lib/rubyvis.rb +35 -6
- data/spec/anchor_spec.rb +15 -15
- data/web/Rakefile +34 -0
- data/web/build_site.rb +86 -0
- data/web/examples.haml +26 -0
- data/web/index.haml +97 -0
- data/web/style.css +82 -0
- data.tar.gz.sig +0 -0
- metadata +14 -9
- metadata.gz.sig +0 -0
- data/lib/rubyvis/label.rb +0 -1
- data/web/first.svg +0 -1
- data/web/index.html +0 -48
data/lib/rubyvis/mark.rb
CHANGED
@@ -1,11 +1,131 @@
|
|
1
1
|
module Rubyvis
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
# Constructs a new mark with default properties. Marks, with the exception of
|
3
|
+
# the root panel, are not typically constructed directly; instead, they are
|
4
|
+
# added to a panel or an existing mark via Mark#add
|
5
|
+
#
|
6
|
+
# Represents a data-driven graphical mark. The +Mark+ class is
|
7
|
+
# the base class for all graphical marks in Protovis; it does not provide any
|
8
|
+
# specific rendering functionality, but together with Panel establishes
|
9
|
+
# the core framework.
|
10
|
+
#
|
11
|
+
# Concrete mark types include familiar visual elements such as bars, lines
|
12
|
+
# and labels. Although a bar mark may be used to construct a bar chart, marks
|
13
|
+
# know nothing about charts; it is only through their specification and
|
14
|
+
# composition that charts are produced. These building blocks permit many
|
15
|
+
# combinatorial possibilities.
|
16
|
+
#
|
17
|
+
# Marks are associated with <b>data</b>: a mark is generated once per
|
18
|
+
# associated datum, mapping the datum to visual <b>properties</b> such as
|
19
|
+
# position and color. Thus, a single mark specification represents a set of
|
20
|
+
# visual elements that share the same data and visual encoding. The type of
|
21
|
+
# mark defines the names of properties and their meaning. A property may be
|
22
|
+
# static, ignoring the associated datum and returning a constant; or, it may be
|
23
|
+
# dynamic, derived from the associated datum or index. Such dynamic encodings
|
24
|
+
# can be specified succinctly using anonymous functions. Special properties
|
25
|
+
# called event handlers can be registered to add interactivity.
|
26
|
+
#
|
27
|
+
# Protovis uses <b>inheritance</b> to simplify the specification of related
|
28
|
+
# marks: a new mark can be derived from an existing mark, inheriting its
|
29
|
+
# properties. The new mark can then override properties to specify new
|
30
|
+
# behavior, potentially in terms of the old behavior. In this way, the old mark
|
31
|
+
# serves as the <b>prototype</b> for the new mark. Most mark types share the
|
32
|
+
# same basic properties for consistency and to facilitate inheritance.
|
33
|
+
#
|
34
|
+
# The prioritization of redundant properties is as follows:<ol>
|
35
|
+
#
|
36
|
+
# <li>If the <tt>width</tt> property is not specified (i.e., null), its value
|
37
|
+
# is the width of the parent panel, minus this mark's left and right margins;
|
38
|
+
# the left and right margins are zero if not specified.
|
39
|
+
#
|
40
|
+
# <li>Otherwise, if the <tt>right</tt> margin is not specified, its value is
|
41
|
+
# the width of the parent panel, minus this mark's width and left margin; the
|
42
|
+
# left margin is zero if not specified.
|
43
|
+
#
|
44
|
+
# <li>Otherwise, if the <tt>left</tt> property is not specified, its value is
|
45
|
+
# the width of the parent panel, minus this mark's width and the right margin.
|
46
|
+
#
|
47
|
+
# </ol>This prioritization is then duplicated for the <tt>height</tt>,
|
48
|
+
# <tt>bottom</tt> and <tt>top</tt> properties, respectively.
|
49
|
+
#
|
50
|
+
# While most properties are <i>variable</i>, some mark types, such as lines
|
51
|
+
# and areas, generate a single visual element rather than a distinct visual
|
52
|
+
# element per datum. With these marks, some properties may be <b>fixed</b>.
|
53
|
+
# Fixed properties can vary per mark, but not <i>per datum</i>! These
|
54
|
+
# properties are evaluated solely for the first (0-index) datum, and typically
|
55
|
+
# are specified as a constant. However, it is valid to use a function if the
|
56
|
+
# property varies between panels or is dynamically generated.
|
57
|
+
#
|
6
58
|
class Mark
|
59
|
+
# Hash storing properties names for current Mark type.
|
7
60
|
@properties={}
|
61
|
+
|
62
|
+
# The enclosing parent panel. The parent panel is generally undefined only for the root panel; however, it is possible to create "offscreen" marks that are used only for inheritance purposes.
|
63
|
+
# @attr [Panel]
|
64
|
+
attr_accessor :parent
|
65
|
+
|
66
|
+
# The root parent panel. This may be undefined for "offscreen" marks that are
|
67
|
+
# created for inheritance purposes only.
|
68
|
+
#
|
69
|
+
# @attr [Panel]
|
70
|
+
attr_accessor :root
|
71
|
+
|
72
|
+
# The child index. -1 if the enclosing parent panel is null; otherwise, the
|
73
|
+
# zero-based index of this mark into the parent panel's <tt>children</tt>
|
74
|
+
# array.
|
75
|
+
# @attr [Number]
|
76
|
+
attr_accessor :child_index
|
77
|
+
|
78
|
+
|
79
|
+
# The scene graph. The scene graph is an array of objects; each object
|
80
|
+
# (or "node") corresponds to an instance of this mark and an element in the
|
81
|
+
# data array. The scene graph can be traversed to lookup previously-evaluated
|
82
|
+
# properties.
|
83
|
+
attr_accessor :scene
|
84
|
+
|
85
|
+
# The mark prototype, possibly undefined, from which to inherit property
|
86
|
+
# functions. The mark prototype is not necessarily of the same type as this
|
87
|
+
# mark. Any properties defined on this mark will override properties inherited
|
88
|
+
# either from the prototype or from the type-specific defaults.
|
89
|
+
# @attr [Mark]
|
90
|
+
attr_accessor :proto
|
91
|
+
|
92
|
+
# The mark anchor target, possibly undefined.
|
93
|
+
# @attr [Mark]
|
94
|
+
attr_accessor :target
|
95
|
+
|
96
|
+
# The current scale factor, based on any enclosing transforms. The current
|
97
|
+
# scale can be used to create scale-independent graphics. For example, to
|
98
|
+
# define a dot that has a radius of 10 irrespective of any zooming, say:
|
99
|
+
#
|
100
|
+
# <pre>dot.shape_radius(lambda { 10 / self.scale})</pre>
|
101
|
+
#
|
102
|
+
# Note that the stroke width and font size are defined irrespective of scale
|
103
|
+
# (i.e., in screen space) already. Also note that when a transform is applied
|
104
|
+
# to a panel, the scale affects only the child marks, not the panel itself.
|
105
|
+
# @attr [Float]
|
106
|
+
# @see Panel#transform
|
107
|
+
attr_accessor :scale
|
108
|
+
|
109
|
+
# Array with stores properties values
|
110
|
+
attr_reader :_properties
|
111
|
+
|
112
|
+
# OpenStruct which store values for scenes
|
113
|
+
attr_accessor :binds
|
8
114
|
|
115
|
+
|
116
|
+
# Defines a setter-getter for the specified property.
|
117
|
+
#
|
118
|
+
# If a cast function has been assigned to the specified property name, the
|
119
|
+
# property function is wrapped by the cast function, or, if a constant is
|
120
|
+
# specified, the constant is immediately cast. Note, however, that if the
|
121
|
+
# property value is null, the cast function is not invoked.
|
122
|
+
#
|
123
|
+
# Parameters:
|
124
|
+
# * @param [String] name the property name.
|
125
|
+
# * @param [Boolean] +def+ whether is a property or a def.
|
126
|
+
# * @param [Proc] +cast+ the cast function for this property.
|
127
|
+
# * @param [Class] +klass+ the klass on which property will be added
|
128
|
+
|
9
129
|
def self.property_method(name, _def, func=nil, klass=nil)
|
10
130
|
return if klass.method_defined? name
|
11
131
|
klass.send(:define_method, name) do |*arguments|
|
@@ -43,6 +163,7 @@ module Rubyvis
|
|
43
163
|
end
|
44
164
|
end
|
45
165
|
|
166
|
+
# Creates a dinamic property using property_method().
|
46
167
|
def self.attr_accessor_dsl(*attr)
|
47
168
|
attr.each do |sym|
|
48
169
|
if sym.is_a? Array
|
@@ -60,34 +181,58 @@ module Rubyvis
|
|
60
181
|
end
|
61
182
|
end
|
62
183
|
|
184
|
+
# Delete index
|
185
|
+
# @private
|
63
186
|
def delete_index
|
64
187
|
@index=nil
|
65
188
|
@index_defined=false
|
66
189
|
end
|
190
|
+
|
191
|
+
# The mark index. The value of this field depends on which instance (i.e.,
|
192
|
+
# which element of the data array) is currently being evaluated. During the
|
193
|
+
# build phase, the index is incremented over each datum; when handling events,
|
194
|
+
# the index is set to the instance that triggered the event.
|
195
|
+
# @return [Integer]
|
67
196
|
def index
|
68
197
|
@index
|
69
198
|
end
|
70
|
-
|
199
|
+
# Returns true if index attribute is set and not deleted
|
71
200
|
def index_defined?
|
72
201
|
@index_defined
|
73
202
|
end
|
203
|
+
# Set index attribute.
|
74
204
|
def index=(v)
|
75
205
|
@index_defined=true
|
76
206
|
@index=v
|
77
207
|
v
|
78
208
|
end
|
79
209
|
|
80
|
-
|
210
|
+
# Sets the value of the property <i>name</i> to <i>v</i>
|
81
211
|
def property_value(name,v)
|
82
212
|
prop=Property.new({:name=>name, :id=>Rubyvis.id, :value=>v})
|
83
213
|
@_properties.delete_if{|v1| v1.name==name}
|
84
214
|
@_properties.push(prop)
|
85
215
|
#@_properties_values[name]=v
|
86
|
-
|
216
|
+
prop
|
87
217
|
end
|
218
|
+
|
219
|
+
# Alias for setting the left, right, top and bottom properties simultaneously.
|
220
|
+
#
|
221
|
+
# @see Mark#left
|
222
|
+
# @see Mark#right
|
223
|
+
# @see Mark#top
|
224
|
+
# @see Mark#bottom
|
225
|
+
# @return [Mark] self
|
88
226
|
def margin(n)
|
89
227
|
self.left(n).right(n).top(n).bottom(n)
|
90
228
|
end
|
229
|
+
|
230
|
+
|
231
|
+
# @private Returns the current instance of this mark in the scene graph.
|
232
|
+
# This is typically equivalent to <tt>this.scene[this.index]</tt>, however if the scene or index is unset, the default instance of the mark is returned. If no default is set, the default is the last instance.
|
233
|
+
# Similarly, if the scene or index of the parent panel is unset, the default instance of this mark in the last instance of the enclosing panel is returned, and so on.
|
234
|
+
#
|
235
|
+
# @return a node in the scene graph.
|
91
236
|
def instance(default_index=nil)
|
92
237
|
scene=self.scene
|
93
238
|
scene||=self.parent.instance(-1).children[self.child_index]
|
@@ -97,46 +242,143 @@ module Rubyvis
|
|
97
242
|
scene[index<0 ? scene.size-1: index]
|
98
243
|
end
|
99
244
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
245
|
+
##
|
246
|
+
# :section: Marks properties
|
247
|
+
##
|
248
|
+
|
249
|
+
##
|
250
|
+
# :attr: data
|
251
|
+
# The data property; an array of objects. The size of the array determines the number of marks that will be instantiated; each element in the array will be passed to property functions to compute the property values. Typically, the data property is specified as a constant array, such as
|
252
|
+
# m.data([1, 2, 3, 4, 5])
|
253
|
+
# However, it is perfectly acceptable to define the data property as a
|
254
|
+
# proc. This function might compute the data dynamically, allowing
|
255
|
+
# different data to be used per enclosing panel. For instance, in the stacked
|
256
|
+
# area graph example (see Mark#scene), the data function on the area mark
|
257
|
+
# dereferences each series.
|
258
|
+
|
259
|
+
##
|
260
|
+
# :attr: visible
|
261
|
+
# The visible property; a boolean determining whether or not the mark instance
|
262
|
+
# is visible. If a mark instance is not visible, its other properties will not
|
263
|
+
# be evaluated. Similarly, for panels no child marks will be rendered.
|
264
|
+
|
265
|
+
##
|
266
|
+
# :attr: left
|
267
|
+
# The left margin; the distance, in pixels, between the left edge of the
|
268
|
+
# enclosing panel and the left edge of this mark. Note that in some cases this
|
269
|
+
# property may be redundant with the right property, or with the conjunction of
|
270
|
+
# right and width.
|
271
|
+
|
272
|
+
##
|
273
|
+
# :attr: right
|
274
|
+
# The right margin; the distance, in pixels, between the right edge of the
|
275
|
+
# enclosing panel and the right edge of this mark. Note that in some cases this
|
276
|
+
# property may be redundant with the left property, or with the conjunction of
|
277
|
+
# left and width.
|
278
|
+
|
279
|
+
##
|
280
|
+
# :attr: top
|
281
|
+
# The top margin; the distance, in pixels, between the top edge of the
|
282
|
+
# enclosing panel and the top edge of this mark. Note that in some cases this
|
283
|
+
# property may be redundant with the bottom property, or with the conjunction
|
284
|
+
# of bottom and height.
|
285
|
+
|
286
|
+
##
|
287
|
+
# :attr: bottom
|
288
|
+
# The bottom margin; the distance, in pixels, between the bottom edge of the
|
289
|
+
# enclosing panel and the bottom edge of this mark. Note that in some cases
|
290
|
+
# this property may be redundant with the top property, or with the conjunction
|
291
|
+
# of top and height.
|
292
|
+
|
293
|
+
##
|
294
|
+
# :attr: cursor
|
295
|
+
# The cursor property; corresponds to the CSS cursor property. This is
|
296
|
+
# typically used in conjunction with event handlers to indicate interactivity.
|
297
|
+
# See {CSS 2 cursor}[http://www.w3.org/TR/CSS2/ui.html#propdef-cursor]
|
298
|
+
|
299
|
+
##
|
300
|
+
# :attr: title
|
301
|
+
# The title property; corresponds to the HTML/SVG title property, allowing the
|
302
|
+
# general of simple plain text tooltips.
|
303
|
+
|
304
|
+
|
305
|
+
##
|
306
|
+
# :attr: events
|
307
|
+
# The events property; corresponds to the SVG pointer-events property,
|
308
|
+
# specifying how the mark should participate in mouse events. The default value
|
309
|
+
# is "painted". Supported values are:
|
310
|
+
#
|
311
|
+
# <p>"painted": The given mark may receive events when the mouse is over a
|
312
|
+
# "painted" area. The painted areas are the interior (i.e., fill) of the mark
|
313
|
+
# if a 'fillStyle' is specified, and the perimeter (i.e., stroke) of the mark
|
314
|
+
# if a 'strokeStyle' is specified.
|
315
|
+
#
|
316
|
+
# <p>"all": The given mark may receive events when the mouse is over either the
|
317
|
+
# interior (i.e., fill) or the perimeter (i.e., stroke) of the mark, regardless
|
318
|
+
# of the specified fillStyle and strokeStyle.
|
319
|
+
#
|
320
|
+
# <p>"none": The given mark may not receive events.
|
321
|
+
|
322
|
+
##
|
323
|
+
# :attr: reverse
|
324
|
+
# The reverse property; a boolean determining whether marks are ordered from
|
325
|
+
# front-to-back or back-to-front. SVG does not support explicit z-ordering;
|
326
|
+
# shapes are rendered in the order they appear. Thus, by default, marks are
|
327
|
+
# rendered in data order. Setting the reverse property to false reverses the
|
328
|
+
# order in which they are rendered; however, the properties are still evaluated
|
329
|
+
# (i.e., built) in forward order.
|
104
330
|
|
331
|
+
##
|
332
|
+
# :attr: id
|
333
|
+
# The instance identifier, for correspondence across animated transitions. If
|
334
|
+
# no identifier is specified, correspondence is determined using the mark
|
335
|
+
# index. Identifiers are not global, but local to a given mark.
|
105
336
|
|
106
|
-
|
337
|
+
#
|
338
|
+
|
339
|
+
attr_accessor_dsl :data, :visible, :left, :right, :top, :bottom, :cursor, :title, :reverse, :antialias, :events, :id
|
107
340
|
|
108
341
|
@scene=nil
|
109
342
|
@stack=[]
|
110
343
|
@index=nil
|
111
344
|
|
345
|
+
# @private Records which properties are defined on this mark type.
|
112
346
|
def self.properties
|
113
347
|
@properties
|
114
348
|
end
|
349
|
+
# Common index for all marks
|
115
350
|
def Mark.index
|
116
351
|
@index
|
117
352
|
end
|
353
|
+
|
354
|
+
# Set common index for all marks
|
118
355
|
def Mark.index=(v)
|
119
356
|
@index=v
|
120
357
|
end
|
121
|
-
|
122
|
-
|
123
|
-
|
358
|
+
# Get common scene for all marks
|
124
359
|
def self.scene
|
125
360
|
@scene
|
126
361
|
end
|
362
|
+
# Set common scene for all marks
|
127
363
|
def self.scene=(v)
|
128
364
|
@scene=v
|
129
365
|
end
|
366
|
+
|
367
|
+
|
368
|
+
# Return properties for current mark
|
130
369
|
def properties
|
131
370
|
(self.class).properties
|
132
371
|
end
|
372
|
+
# Get common stack for all marks
|
133
373
|
def Mark.stack
|
134
374
|
@stack
|
135
375
|
end
|
376
|
+
# Set common stack for all marks
|
136
377
|
def Mark.stack=(v)
|
137
378
|
@stack=v
|
138
379
|
end
|
139
380
|
|
381
|
+
# Create a new Mark
|
140
382
|
def initialize(opts=Hash.new)
|
141
383
|
@_properties=[]
|
142
384
|
opts.each {|k,v|
|
@@ -148,20 +390,39 @@ module Rubyvis
|
|
148
390
|
@index_defined = true
|
149
391
|
@scale=1
|
150
392
|
@scene=nil
|
151
|
-
|
152
393
|
end
|
394
|
+
|
395
|
+
|
396
|
+
# The mark type; a lower name. The type name controls rendering
|
397
|
+
# behavior, and unless the rendering engine is extended, must be one of the
|
398
|
+
# built-in concrete mark types: area, bar, dot, image, label, line, panel,
|
399
|
+
# rule, or wedge.
|
153
400
|
def type
|
154
401
|
"mark"
|
155
402
|
end
|
403
|
+
|
404
|
+
# Default properties for all mark types. By default, the data array is the
|
405
|
+
# parent data as a single-element array; if the data property is not
|
406
|
+
# specified, this causes each mark to be instantiated as a singleton
|
407
|
+
# with the parents datum. The visible property is true by default,
|
408
|
+
# and the reverse property is false.
|
156
409
|
def self.defaults
|
157
410
|
Mark.new({:data=>lambda {|d| [d]}, :visible=>true, :antialias=>true, :events=>'painted'})
|
158
411
|
end
|
412
|
+
|
413
|
+
# Sets the prototype of this mark to the specified mark. Any properties not
|
414
|
+
# defined on this mark may be inherited from the specified prototype mark,
|
415
|
+
# or its prototype, and so on. The prototype mark need not be the same
|
416
|
+
# type of mark as this mark. (Note that for inheritance to be useful,
|
417
|
+
# properties with the same name on different mark types should
|
418
|
+
# have equivalent meaning.)
|
159
419
|
def extend(proto)
|
160
420
|
@proto=proto
|
161
421
|
@target=proto.target
|
162
422
|
self
|
163
423
|
end
|
164
|
-
|
424
|
+
# Find the instances of this mark that match source.
|
425
|
+
# @see Anchor
|
165
426
|
def instances(source)
|
166
427
|
mark = self
|
167
428
|
_index = []
|
@@ -188,11 +449,24 @@ module Rubyvis
|
|
188
449
|
s.right = s.top = s.left = s.bottom = 0;
|
189
450
|
return [s];
|
190
451
|
end
|
191
|
-
|
452
|
+
scene
|
192
453
|
end
|
454
|
+
|
455
|
+
|
456
|
+
#Returns the previous instance of this mark in the scene graph, or
|
457
|
+
# null if this is the first instance.
|
458
|
+
#
|
459
|
+
# @return a node in the scene graph, or null.
|
193
460
|
def sibling
|
194
461
|
(self.index==0) ? nil: self.scene[self.index-1]
|
195
462
|
end
|
463
|
+
|
464
|
+
|
465
|
+
# Returns the current instance in the scene graph of this mark,
|
466
|
+
# in the previous instance of the enclosing parent panel.
|
467
|
+
# May return null if this instance could not be found.
|
468
|
+
#
|
469
|
+
# @return a node in the scene graph, or null.
|
196
470
|
def cousin
|
197
471
|
par=self.parent
|
198
472
|
s= par ? par.sibling : nil
|
@@ -201,29 +475,60 @@ module Rubyvis
|
|
201
475
|
def add(type)
|
202
476
|
parent.add(type).extend(self)
|
203
477
|
end
|
478
|
+
# Returns an anchor with the specified name. All marks support the five
|
479
|
+
# standard anchor names:
|
480
|
+
# * top
|
481
|
+
# * left
|
482
|
+
# * center
|
483
|
+
# * bottom
|
484
|
+
# * right
|
485
|
+
#
|
486
|
+
# In addition to positioning properties (left, right, top bottom), the
|
487
|
+
# anchors support text rendering properties (text-align, text-baseline).
|
488
|
+
# Text is rendered to appear inside the mark by default.
|
489
|
+
#
|
490
|
+
# To facilitate stacking, anchors are defined in terms of their opposite
|
491
|
+
# edge. For example, the top anchor defines the bottom property,
|
492
|
+
# such that the mark extends upwards; the bottom anchor instead defines
|
493
|
+
# the top property, such that the mark extends downwards. See also Layout::Stack
|
494
|
+
#
|
495
|
+
# While anchor names are typically constants, the anchor name is a true
|
496
|
+
# property, which means you can specify a function to compute the anchor name
|
497
|
+
# dynamically. See the Anchor#name property for details.
|
498
|
+
#
|
499
|
+
# @param [String] name the anchor name; either a string or a property function.
|
500
|
+
# @return [Anchor] the new anchor.
|
204
501
|
def anchor(name='center')
|
205
502
|
mark_anchor(name)
|
206
503
|
end
|
207
|
-
|
208
|
-
|
504
|
+
# Implementation of mark anchor
|
505
|
+
def mark_anchor(name="center") # :nodoc:
|
506
|
+
anchor=Rubyvis::Anchor.
|
507
|
+
new(self).
|
508
|
+
name(name).
|
509
|
+
data(lambda {
|
209
510
|
pp self.scene.target if $DEBUG
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
511
|
+
a=self.scene.target.map {|s| puts "s:#{s.data}" if $DEBUG; s.data}
|
512
|
+
p a if $DEBUG
|
513
|
+
a
|
514
|
+
}).
|
515
|
+
visible(lambda {
|
516
|
+
self.scene.target[self.index].visible
|
517
|
+
}).
|
518
|
+
id(lambda {self.scene.target[self.index].id}).
|
519
|
+
left(lambda {
|
520
|
+
s = self.scene.target[self.index]
|
521
|
+
w = s.width
|
522
|
+
w||=0
|
523
|
+
if ['bottom','top','center'].include?(self.name)
|
524
|
+
s.left + w / 2.0
|
525
|
+
elsif self.name=='left'
|
526
|
+
nil
|
527
|
+
else
|
528
|
+
s.left + w
|
529
|
+
end
|
530
|
+
}).
|
531
|
+
top(lambda {
|
227
532
|
s = self.scene.target[self.index]
|
228
533
|
h = s.height
|
229
534
|
h||= 0
|
@@ -261,12 +566,19 @@ module Rubyvis
|
|
261
566
|
end
|
262
567
|
|
263
568
|
|
264
|
-
|
265
|
-
|
569
|
+
# Computes the implied properties for this mark for the specified
|
570
|
+
# instance <tt>s</tt> in the scene graph. Implied properties are those with
|
571
|
+
# dependencies on multiple other properties; for example, the width property
|
572
|
+
# may be implied if the left and right properties are set. This method can be
|
573
|
+
# overridden by concrete mark types to define new implied properties, if
|
574
|
+
# necessary.
|
575
|
+
#
|
576
|
+
# @param s a node in the scene graph; the instance of the mark to build.
|
577
|
+
def build_implied(s) # :nodoc:
|
266
578
|
mark_build_implied(s)
|
267
579
|
end
|
268
|
-
|
269
|
-
def mark_build_implied(s)
|
580
|
+
|
581
|
+
def mark_build_implied(s) # :nodoc:
|
270
582
|
l=s.left
|
271
583
|
r=s.right
|
272
584
|
t=s.top
|
@@ -330,6 +642,17 @@ module Rubyvis
|
|
330
642
|
s.fill_style=Rubyvis::Color.transparent if prop[:fill_style] and !s.fill_style
|
331
643
|
s.stroke_style=Rubyvis::Color.transparent if prop[:stroke_style] and !s.stroke_style
|
332
644
|
end
|
645
|
+
# Renders this mark, including recursively rendering all child marks if this is
|
646
|
+
# a panel. This method finds all instances of this mark and renders them. This
|
647
|
+
# method descends recursively to the level of the mark to be rendered, finding
|
648
|
+
# all visible instances of the mark. After the marks are rendered, the scene
|
649
|
+
# and index attributes are removed from the mark to restore them to a clean
|
650
|
+
# state.
|
651
|
+
#
|
652
|
+
# <p>If an enclosing panel has an index property set (as is the case inside in
|
653
|
+
# an event handler), then only instances of this mark inside the given instance
|
654
|
+
# of the panel will be rendered; otherwise, all visible instances of the mark
|
655
|
+
# will be rendered.
|
333
656
|
def render
|
334
657
|
parent=self.parent
|
335
658
|
@stack=Mark.stack
|
@@ -351,7 +674,7 @@ module Rubyvis
|
|
351
674
|
|
352
675
|
end
|
353
676
|
|
354
|
-
def render_render(mark,depth,scale)
|
677
|
+
def render_render(mark,depth,scale) # :nodoc:
|
355
678
|
mark.scale=scale
|
356
679
|
if (depth < @indexes.size)
|
357
680
|
@stack.unshift(nil)
|
@@ -367,14 +690,14 @@ module Rubyvis
|
|
367
690
|
stack.shift
|
368
691
|
else
|
369
692
|
mark.build
|
370
|
-
|
371
|
-
|
693
|
+
Rubyvis.Scene.scale = scale;
|
694
|
+
Rubyvis.Scene.update_all(mark.scene);
|
372
695
|
end
|
373
696
|
mark.scale=nil
|
374
697
|
end
|
375
698
|
|
376
699
|
|
377
|
-
def render_instance(mark,depth,scale)
|
700
|
+
def render_instance(mark,depth,scale) # :nodoc:
|
378
701
|
s=mark.scene[mark.index]
|
379
702
|
if s.visible
|
380
703
|
child_index=@indexes[depth]
|
@@ -397,7 +720,6 @@ module Rubyvis
|
|
397
720
|
|
398
721
|
end
|
399
722
|
end
|
400
|
-
private :render_render, :render_instance
|
401
723
|
def bind_bind(mark)
|
402
724
|
begin
|
403
725
|
mark._properties.each {|v|
|
@@ -419,12 +741,14 @@ module Rubyvis
|
|
419
741
|
}
|
420
742
|
end while(mark = mark.proto)
|
421
743
|
end
|
422
|
-
|
423
|
-
|
744
|
+
private :bind_bind, :render_render, :render_instance
|
745
|
+
# @private In the bind phase, inherited property definitions are cached so they
|
746
|
+
# do not need to be queried during build.
|
424
747
|
def bind
|
425
748
|
mark_bind
|
426
749
|
end
|
427
|
-
|
750
|
+
|
751
|
+
def mark_bind() # :nodoc:
|
428
752
|
@seen={}
|
429
753
|
@types={1=>[],2=>[],3=>[]}
|
430
754
|
@_data=nil
|
@@ -517,6 +841,38 @@ module Rubyvis
|
|
517
841
|
end
|
518
842
|
end
|
519
843
|
|
844
|
+
# Evaluates properties and computes implied properties. Properties are
|
845
|
+
# stored in the Mark.scene array for each instance of this mark.
|
846
|
+
#
|
847
|
+
# As marks are built recursively, the Mark.index property is updated to
|
848
|
+
# match the current index into the data array for each mark. Note that the
|
849
|
+
# index property is only set for the mark currently being built and its
|
850
|
+
# enclosing parent panels. The index property for other marks is unset, but is
|
851
|
+
# inherited from the global +Mark+ class prototype. This allows mark
|
852
|
+
# properties to refer to properties on other marks <i>in the same panel</i>
|
853
|
+
# conveniently; however, in general it is better to reference mark instances
|
854
|
+
# specifically through the scene graph rather than depending on the magical
|
855
|
+
# behavior of Mark#index.
|
856
|
+
#
|
857
|
+
# The root scene array has a special property, <tt>data</tt>, which stores
|
858
|
+
# the current data stack. The first element in this stack is the current datum,
|
859
|
+
# followed by the datum of the enclosing parent panel, and so on. The data
|
860
|
+
# stack should not be accessed directly; instead, property functions are passed
|
861
|
+
# the current data stack as arguments.
|
862
|
+
#
|
863
|
+
# <p>The evaluation of the <tt>data</tt> and <tt>visible</tt> properties is
|
864
|
+
# special. The <tt>data</tt> property is evaluated first; unlike the other
|
865
|
+
# properties, the data stack is from the parent panel, rather than the current
|
866
|
+
# mark, since the data is not defined until the data property is evaluated.
|
867
|
+
# The <tt>visible</tt> property is subsequently evaluated for each instance;
|
868
|
+
# only if true will the {@link #buildInstance} method be called, evaluating
|
869
|
+
# other properties and recursively building the scene graph.
|
870
|
+
#
|
871
|
+
# <p>If this mark is being re-built, any old instances of this mark that no
|
872
|
+
# longer exist (because the new data array contains fewer elements) will be
|
873
|
+
# cleared using {@link #clearInstance}.
|
874
|
+
#
|
875
|
+
# @param parent the instance of the parent panel from the scene graph.
|
520
876
|
def build
|
521
877
|
scene=self.scene
|
522
878
|
stack=Mark.stack
|
@@ -563,17 +919,26 @@ module Rubyvis
|
|
563
919
|
stack.shift()
|
564
920
|
self
|
565
921
|
end
|
566
|
-
|
567
|
-
def build_instance(s)
|
922
|
+
# @private
|
923
|
+
def build_instance(s) # :nodoc:
|
568
924
|
mark_build_instance(s)
|
569
925
|
end
|
570
|
-
|
926
|
+
# @private
|
927
|
+
def mark_build_instance(s1) # :nodoc:
|
571
928
|
build_properties(s1, self.binds.required)
|
572
929
|
if s1.visible
|
573
930
|
build_properties(s1, self.binds.optional)
|
574
931
|
build_implied(s1)
|
575
932
|
end
|
576
933
|
end
|
934
|
+
|
935
|
+
|
936
|
+
|
937
|
+
# Evaluates the specified array of properties for the specified
|
938
|
+
# instance <tt>s</tt> in the scene graph.
|
939
|
+
#
|
940
|
+
# @param s a node in the scene graph; the instance of the mark to build.
|
941
|
+
# @param properties an array of properties.
|
577
942
|
def build_properties(ss, props)
|
578
943
|
#p props
|
579
944
|
props.each do |prop|
|
@@ -585,11 +950,11 @@ module Rubyvis
|
|
585
950
|
end
|
586
951
|
ss.send((prop.name.to_s+"=").to_sym, v)
|
587
952
|
end
|
588
|
-
# p ss
|
589
953
|
end
|
954
|
+
# @todo implement
|
590
955
|
def event(type,handler)
|
591
956
|
#@_handlers[type]=handler
|
592
|
-
|
957
|
+
self
|
593
958
|
end
|
594
959
|
end
|
595
960
|
end
|