Class: Rubyvis::Mark
- Defined in:
- lib/rubyvis/mark.rb,
lib/rubyvis/mark/shorcut_methods.rb
Overview
Constructs a new mark with default properties. Marks, with the exception of the root panel, are not typically constructed directly; instead, they are added to a panel or an existing mark via Mark#add
Represents a data-driven graphical mark. The Mark
class is the base class for all graphical marks in Protovis; it does not provide any specific rendering functionality, but together with Panel establishes the core framework.
Concrete mark types include familiar visual elements such as bars, lines and labels. Although a bar mark may be used to construct a bar chart, marks know nothing about charts; it is only through their specification and composition that charts are produced. These building blocks permit many combinatorial possibilities.
Marks are associated with data: a mark is generated once per associated datum, mapping the datum to visual properties such as position and color. Thus, a single mark specification represents a set of visual elements that share the same data and visual encoding. The type of mark defines the names of properties and their meaning. A property may be static, ignoring the associated datum and returning a constant; or, it may be dynamic, derived from the associated datum or index. Such dynamic encodings can be specified succinctly using anonymous functions. Special properties called event handlers can be registered to add interactivity.
Protovis uses inheritance to simplify the specification of related marks: a new mark can be derived from an existing mark, inheriting its properties. The new mark can then override properties to specify new behavior, potentially in terms of the old behavior. In this way, the old mark serves as the prototype for the new mark. Most mark types share the same basic properties for consistency and to facilitate inheritance.
The prioritization of redundant properties is as follows:<ol>
<li>If the width
property is not specified (i.e., null), its value is the width of the parent panel, minus this mark’s left and right margins; the left and right margins are zero if not specified.
<li>Otherwise, if the right
margin is not specified, its value is the width of the parent panel, minus this mark’s width and left margin; the left margin is zero if not specified.
<li>Otherwise, if the left
property is not specified, its value is the width of the parent panel, minus this mark’s width and the right margin.
</ol>This prioritization is then duplicated for the height
, bottom
and top
properties, respectively.
While most properties are variable, some mark types, such as lines and areas, generate a single visual element rather than a distinct visual element per datum. With these marks, some properties may be fixed. Fixed properties can vary per mark, but not per datum! These properties are evaluated solely for the first (0-index) datum, and typically are specified as a constant. However, it is valid to use a function if the property varies between panels or is dynamically generated.
‘RBP’ API
Since version 0.2.0, you could use a new API to use marks , similar to one described on Brown’s “Ruby Best Practices”.
Set properties using blocks
You could use a block to set a property, without using explicitly lambda statement. So
area.width {|d| d*20}
is the same as
area.width lambda {|d| d*20}
Shortcuts methods
The protovis API uses the chain method aproach. Every method which set a value on a object returns the same object. I maintain this approach, and you can do
area.width(10).height(20).top(lambda {|d| d*10})
To add a mark to another, you need to use add
method. This methods returns the new mark, so you can still use the chain methods API,
area.width(10).height(20). # object is 'area'
add(Rubyvis::Label). # object changed to new label
text('hi') # text refers to new label
In the spirit of RBP, I created several methods as shortcut for add
: area(), bar(), dot(), image(), label(), line(), panel(), rule() and wedge(). If you provide a block, it will be executed inside the context of current of new mark depending on block’s parameter.
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Parameter references the new mark
Example
*Without parameter*
vis=Rubyvis::Panel.new do
area do
width 10 # width changed for area
height 10 # height changed for area
end
end
*Without parameter*
vis=Rubyvis::Panel.new do
area do |a|
width 10 # width changed for panel
a.height 10 # height changed for area
end
end
Instance Attribute Summary collapse
-
#_properties ⇒ Object
readonly
Array with stores properties values.
-
#binds ⇒ Object
OpenStruct which store values for scenes.
-
#child_index ⇒ Object
The child index.
- #parent ⇒ Object
-
#proto ⇒ Object
The mark prototype, possibly undefined, from which to inherit property functions.
-
#root ⇒ Object
The root parent panel.
-
#scale ⇒ Object
The current scale factor, based on any enclosing transforms.
-
#scene ⇒ Object
The scene graph.
-
#target ⇒ Object
The mark anchor target, possibly undefined.
Class Method Summary collapse
-
.attr_accessor_dsl(*attr) ⇒ Object
Creates a dinamic property using property_method().
-
.defaults ⇒ Object
Default properties for all mark types.
-
.index ⇒ Object
Common index for all marks.
-
.index=(v) ⇒ Object
Set common index for all marks.
-
.mark_method(name, mark) ⇒ Object
Create a new Mark method shorcut.
- .properties ⇒ Object
-
.property_method(name, _def, func = nil, klass = nil) ⇒ Object
Defines a setter-getter for the specified property.
-
.scene ⇒ Object
Get common scene for all marks.
-
.scene=(v) ⇒ Object
Set common scene for all marks.
-
.stack ⇒ Object
Get common stack for all marks.
-
.stack=(v) ⇒ Object
Set common stack for all marks.
Instance Method Summary collapse
-
#add(type) ⇒ Object
Adds a new mark of the specified type to the enclosing parent panel, whilst simultaneously setting the prototype of the new mark to be this mark.
-
#anchor(name = 'center') ⇒ Anchor
Returns an anchor with the specified name.
-
#area ⇒ Object
:method: area(opts, &block).
-
#bar ⇒ Object
:method: bar(opts,&block).
-
#bind ⇒ Object
do not need to be queried during build.
-
#build ⇒ Object
Evaluates properties and computes implied properties.
-
#build_implied(s) ⇒ Object
Computes the implied properties for this mark for the specified instance
s
in the scene graph. - #build_instance(s) ⇒ Object
-
#build_properties(ss, props) ⇒ Object
Evaluates the specified array of properties for the specified instance
s
in the scene graph. -
#context(scene, index, f) ⇒ Object
:nodoc:.
-
#context_apply(scene, index) ⇒ Object
:nodoc:.
-
#context_clear(scene, index) ⇒ Object
:nodoc:.
-
#cousin ⇒ Object
Returns the current instance in the scene graph of this mark, in the previous instance of the enclosing parent panel.
-
#delete_index ⇒ Object
Delete index.
-
#dot ⇒ Object
:method: dot(opts,&block).
- #event(type, handler) ⇒ Object
-
#execute(&block) ⇒ Object
Execute a block using this mark as a reference Example bar.execute |b| b.width 10 b.add(Rubyvis::Label) end.
-
#first ⇒ Object
Returns the first instance of this mark in the scene graph.
-
#image ⇒ Object
:method: image(opts,&block).
-
#index ⇒ Integer
The mark index.
-
#index=(v) ⇒ Object
Set index attribute.
-
#index_defined? ⇒ Boolean
Returns true if index attribute is set and not deleted.
-
#initialize(opts = Hash.new, &block) ⇒ Mark
constructor
Create a new Mark.
-
#instance(default_index = nil) ⇒ Object
Returns the current instance of this mark in the scene graph.
-
#instances(source) ⇒ Object
Find the instances of this mark that match source.
-
#label ⇒ Object
:method: label(opts,&block).
-
#last ⇒ Object
Returns the last instance of this mark in the scene graph.
-
#layout_arc ⇒ Object
:method: layout_arc(opts,&block).
-
#layout_cluster ⇒ Object
:method: layout_cluster(opts,&block) .
-
#layout_grid ⇒ Object
:method: layout_grid(opts,&block).
-
#layout_horizon ⇒ Object
:method: layout_horizon(opts,&block).
-
#layout_indent ⇒ Object
:method: layout_indent(opts,&block) .
-
#layout_matrix ⇒ Object
:method: layout_matrix(opts,&block).
-
#layout_pack ⇒ Object
:method: layout_pack(opts,&block) .
-
#layout_partition ⇒ Object
:method: layout_partition(opts,&block) .
-
#layout_partition_fill ⇒ Object
:method: layout_partition_fill(opts,&block) .
-
#layout_stack ⇒ Object
:method: layout_stack(opts,&block) .
-
#layout_tree ⇒ Object
:method: layout_tree(opts,&block).
-
#layout_treemap ⇒ Object
:method: layout_treemap(opts,&block) .
-
#line ⇒ Object
:method: line(opts,&block).
-
#margin(n) ⇒ Mark
Alias for setting the left, right, top and bottom properties simultaneously.
-
#mark_anchor(name = "center") ⇒ Object
Implementation of mark anchor.
-
#mark_bind ⇒ Object
:nodoc:.
-
#mark_build_implied(s) ⇒ Object
:nodoc:.
- #mark_build_instance(s1) ⇒ Object
-
#mark_build_properties(ss, props) ⇒ Object
:nodoc:.
-
#mark_extend(proto) ⇒ Object
Sets the prototype of this mark to the specified mark.
-
#panel ⇒ Object
:method: panel(opts,&block).
-
#properties ⇒ Object
Return properties for current mark.
-
#property_value(name, v) ⇒ Object
Sets the value of the property name to v.
-
#render ⇒ Object
Renders this mark, including recursively rendering all child marks if this is a panel.
-
#rule ⇒ Object
:method: rule(opts,&block).
-
#sibling ⇒ Object
Returns the previous instance of this mark in the scene graph, or nil if this is the first instance.
-
#type ⇒ Object
The mark type; a lower name.
-
#wedge ⇒ Object
:method: wedge(opts,&block) .
Constructor Details
#initialize(opts = Hash.new, &block) ⇒ Mark
Create a new Mark
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 |
# File 'lib/rubyvis/mark.rb', line 447 def initialize(opts=Hash.new, &block) @_properties=[] opts.each {|k,v| self.send("#{k}=",v) if self.respond_to? k } @defs={} @child_index=-1 @index=-1 @index_defined = true @scale=1 @scene=nil if block execute(&block) #block.arity<1 ? self.instance_eval(&block) : block.call(self) end end |
Instance Attribute Details
#_properties ⇒ Object (readonly)
Array with stores properties values
165 166 167 |
# File 'lib/rubyvis/mark.rb', line 165 def _properties @_properties end |
#binds ⇒ Object
OpenStruct which store values for scenes
168 169 170 |
# File 'lib/rubyvis/mark.rb', line 168 def binds @binds end |
#child_index ⇒ Object
The child index. -1 if the enclosing parent panel is nil; otherwise, the zero-based index of this mark into the parent panel’s children
array.
131 132 133 |
# File 'lib/rubyvis/mark.rb', line 131 def child_index @child_index end |
#parent ⇒ Object
119 120 121 |
# File 'lib/rubyvis/mark.rb', line 119 def parent @parent end |
#proto ⇒ Object
The mark prototype, possibly undefined, from which to inherit property functions. The mark prototype is not necessarily of the same type as this mark. Any properties defined on this mark will override properties inherited either from the prototype or from the type-specific defaults.
145 146 147 |
# File 'lib/rubyvis/mark.rb', line 145 def proto @proto end |
#root ⇒ Object
The root parent panel. This may be undefined for “offscreen” marks that are created for inheritance purposes only.
125 126 127 |
# File 'lib/rubyvis/mark.rb', line 125 def root @root end |
#scale ⇒ Object
The current scale factor, based on any enclosing transforms. The current scale can be used to create scale-independent graphics. For example, to define a dot that has a radius of 10 irrespective of any zooming, say:
<pre>dot.shape_radius(lambda { 10 / self.scale})</pre>
Note that the stroke width and font size are defined irrespective of scale (i.e., in screen space) already. Also note that when a transform is applied to a panel, the scale affects only the child marks, not the panel itself.
162 163 164 |
# File 'lib/rubyvis/mark.rb', line 162 def scale @scale end |
#scene ⇒ Object
The scene graph. The scene graph is an array of objects; each object (or “node”) corresponds to an instance of this mark and an element in the data array. The scene graph can be traversed to lookup previously-evaluated properties.
138 139 140 |
# File 'lib/rubyvis/mark.rb', line 138 def scene @scene end |
#target ⇒ Object
The mark anchor target, possibly undefined.
149 150 151 |
# File 'lib/rubyvis/mark.rb', line 149 def target @target end |
Class Method Details
.attr_accessor_dsl(*attr) ⇒ Object
Creates a dinamic property using property_method().
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/rubyvis/mark.rb', line 227 def self.attr_accessor_dsl(*attr) attr.each do |sym| if sym.is_a? Array name,func=sym else name=sym func=nil end @properties[name]=true self.property_method(name,false, func, Rubyvis::Mark) define_method(name.to_s+"=") {|v| self.send(name,v) } end end |
.defaults ⇒ Object
Default properties for all mark types. By default, the data array is the parent data as a single-element array; if the data property is not specified, this causes each mark to be instantiated as a singleton with the parents datum. The visible property is true by default, and the reverse property is false.
485 486 487 |
# File 'lib/rubyvis/mark.rb', line 485 def self.defaults Mark.new({:data=>lambda {|d| [d]}, :visible=>true, :antialias=>true, :events=>'painted'}) end |
.index ⇒ Object
Common index for all marks
415 416 417 |
# File 'lib/rubyvis/mark.rb', line 415 def Mark.index @index end |
.index=(v) ⇒ Object
Set common index for all marks
420 421 422 |
# File 'lib/rubyvis/mark.rb', line 420 def Mark.index=(v) @index=v end |
.mark_method(name, mark) ⇒ Object
Create a new Mark method shorcut.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 7 def self.mark_method(name, mark) #:nodoc: define_method(name) do |*args,&block| opts=args[0] opts||=Hash.new if opts[:anchor] base=anchor(opts[:anchor]) else base=self end a=base.add(mark) if block block.arity<1 ? a.instance_eval(&block) : block.call(a) end a end end |
.properties ⇒ Object
411 412 413 |
# File 'lib/rubyvis/mark.rb', line 411 def self.properties @properties end |
.property_method(name, _def, func = nil, klass = nil) ⇒ Object
Defines a setter-getter for the specified property.
If a cast function has been assigned to the specified property name, the property function is wrapped by the cast function, or, if a constant is specified, the constant is immediately cast. Note, however, that if the property value is nil, the cast function is not invoked.
Parameters:
-
@param [String] name the property name.
-
@param [Boolean]
def
whether is a property or a def. -
@param [Proc]
cast
the cast function for this property. -
@param [Class]
klass
the klass on which property will be added
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/rubyvis/mark.rb', line 184 def self.property_method(name, _def, func=nil, klass=nil) return if klass.method_defined? name klass.send(:define_method, name) do |*arguments,&block| v=arguments[0] #v,dummy = arguments if block v=block end if _def and self.scene if arguments.size>0 defs[name]=OpenStruct.new({:id=>(v.nil?) ? 0 : Rubyvis.id, :value=> v}) return self end return defs[name] end if arguments.size>0 or block v=v.to_proc if v.respond_to? :to_proc type=(!_def).to_i<<1 | (v.is_a? Proc).to_i property_value(name,(type & 1 !=0) ? lambda {|*args| x=v.js_apply(self, args) (func and x) ? func.call(x) : x } : (func and v) ? func.call(v) : v)._type=type #@_properties_types[name]=type return self end i=instance() if i.nil? raise "No instance for #{self} on #{name}" else # puts "index:#{self.index}, name:#{name}, val:#{i.send(name)}" i.send(name) end end camel=name.to_s.gsub(/(_.)/) {|v| v[1,1].upcase} if camel!=name klass.send(:alias_method, camel, name) end end |
.scene ⇒ Object
Get common scene for all marks
424 425 426 |
# File 'lib/rubyvis/mark.rb', line 424 def self.scene @scene end |
.scene=(v) ⇒ Object
Set common scene for all marks
428 429 430 |
# File 'lib/rubyvis/mark.rb', line 428 def self.scene=(v) @scene=v end |
Instance Method Details
#add(type) ⇒ Object
Adds a new mark of the specified type to the enclosing parent panel, whilst simultaneously setting the prototype of the new mark to be this mark.
-
@param function type the type of mark to add; a constructor, such as
Rubyvis::Bar
-
@returns Rubyvis::Mark the new mark.
-
@see #mark_extend
582 583 584 |
# File 'lib/rubyvis/mark.rb', line 582 def add(type) parent.add(type).mark_extend(self) end |
#anchor(name = 'center') ⇒ Anchor
Returns an anchor with the specified name. All marks support the five standard anchor names:
-
top
-
left
-
center
-
bottom
-
right
In addition to positioning properties (left, right, top bottom), the anchors support text rendering properties (text-align, text-baseline). Text is rendered to appear inside the mark by default.
To facilitate stacking, anchors are defined in terms of their opposite edge. For example, the top anchor defines the bottom property, such that the mark extends upwards; the bottom anchor instead defines the top property, such that the mark extends downwards. See also Layout::Stack
While anchor names are typically constants, the anchor name is a true property, which means you can specify a function to compute the anchor name dynamically. See the Anchor#name property for details.
608 609 610 |
# File 'lib/rubyvis/mark.rb', line 608 def anchor(name='center') mark_anchor(name) end |
#area ⇒ Object
:method: area(opts, &block)
Adds an Area mark to current mark. If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
35 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 35 mark_method :area, Rubyvis::Area |
#bar ⇒ Object
:method: bar(opts,&block)
Adds a Bar mark to current mark. If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
48 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 48 mark_method :bar, Rubyvis::Bar |
#bind ⇒ Object
do not need to be queried during build.
864 865 866 |
# File 'lib/rubyvis/mark.rb', line 864 def bind mark_bind end |
#build ⇒ Object
Evaluates properties and computes implied properties. Properties are stored in the Mark.scene array for each instance of this mark.
As marks are built recursively, the Mark.index property is updated to match the current index into the data array for each mark. Note that the index property is only set for the mark currently being built and its enclosing parent panels. The index property for other marks is unset, but is inherited from the global Mark
class prototype. This allows mark properties to refer to properties on other marks in the same panel conveniently; however, in general it is better to reference mark instances specifically through the scene graph rather than depending on the magical behavior of Mark#index.
The root scene array has a special property, data
, which stores the current data stack. The first element in this stack is the current datum, followed by the datum of the enclosing parent panel, and so on. The data stack should not be accessed directly; instead, property functions are passed the current data stack as arguments.
<p>The evaluation of the data
and visible
properties is special. The data
property is evaluated first; unlike the other properties, the data stack is from the parent panel, rather than the current mark, since the data is not defined until the data property is evaluated. The visible
property is subsequently evaluated for each instance; only if true will the #buildInstance method be called, evaluating other properties and recursively building the scene graph.
<p>If this mark is being re-built, any old instances of this mark that no longer exist (because the new data array contains fewer elements) will be cleared using #clearInstance.
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 |
# File 'lib/rubyvis/mark.rb', line 997 def build scene=self.scene stack=Mark.stack if(!scene) self.scene=SceneElement.new scene=self.scene scene.mark=self scene.type=self.type scene.child_index=self.child_index if(self.parent) scene.parent=self.parent.scene scene.parent_index=self.parent.index end end # Resolve anchor target #puts "Resolve target" if(self.target) scene.target=self.target.instances(scene) end #pp self.binds data=self.binds.data #puts "stack:#{stack}" #puts "data_value:#{data.value}" data=(data._type & 1)>0 ? data.value.js_apply(self, stack) : data.value #puts "data:#{data}" stack.unshift(nil) scene.size=data.size data.each_with_index {|d, i| Mark.index=i self.index=i s=scene[i] if !s scene[i]=s=SceneElement.new end stack[0]=data[i] s.data=data[i] build_instance(s) } Mark.index=-1 delete_index stack.shift() self end |
#build_implied(s) ⇒ Object
Computes the implied properties for this mark for the specified instance s
in the scene graph. Implied properties are those with dependencies on multiple other properties; for example, the width property may be implied if the left and right properties are set. This method can be overridden by concrete mark types to define new implied properties, if necessary.
686 687 688 |
# File 'lib/rubyvis/mark.rb', line 686 def build_implied(s) # :nodoc: mark_build_implied(s) end |
#build_instance(s) ⇒ Object
1043 1044 1045 |
# File 'lib/rubyvis/mark.rb', line 1043 def build_instance(s) # :nodoc: mark_build_instance(s) end |
#build_properties(ss, props) ⇒ Object
Evaluates the specified array of properties for the specified instance s
in the scene graph.
1061 1062 1063 |
# File 'lib/rubyvis/mark.rb', line 1061 def build_properties(ss,props) # :nodoc: mark_build_properties(ss,props) end |
#context(scene, index, f) ⇒ Object
:nodoc:
950 951 952 953 954 955 956 957 958 959 960 961 962 963 |
# File 'lib/rubyvis/mark.rb', line 950 def context(scene, index, f) # :nodoc: #proto=Mark stack=Mark.stack oscene=Mark.scene oindex=Mark.index context_clear(oscene,oindex) context_apply(scene,index) begin f.js_apply(self, stack) ensure context_clear(scene,index) context_apply(oscene,oindex) end end |
#context_apply(scene, index) ⇒ Object
:nodoc:
895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 |
# File 'lib/rubyvis/mark.rb', line 895 def context_apply(scene,index) # :nodoc: Mark.scene=scene Mark.index=index return if(!scene) that=scene.mark mark=that ancestors=[] begin ancestors.push(mark) Mark.stack.push(scene[index].data) mark.index=index mark.scene=scene index=scene.parent_index scene=scene.parent end while(mark=mark.parent) k=1 ancestors.size.times {|ic| i=ancestors.size-ic-1 mark=ancestors[i] mark.scale=k k=k*mark.scene[mark.index].transform.k } if (that.children) n=that.children.size n.times {|i| mark=that.children[i] mark.scene=that.scene[that.index].children[i] mark.scale=k } end end |
#context_clear(scene, index) ⇒ Object
:nodoc:
928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 |
# File 'lib/rubyvis/mark.rb', line 928 def context_clear(scene,index) # :nodoc: return if !scene that=scene.mark mark=nil if(that.children) that.children.size.times {|i| mark=that.children[i] mark.scene=nil mark.scale=nil } end mark=that begin Mark.stack.pop if(mark.parent) mark.scene=nil mark.scale=nil end mark.index=nil end while(mark=mark.parent) end |
#cousin ⇒ Object
Returns the current instance in the scene graph of this mark, in the previous instance of the enclosing parent panel. May return nil if this instance could not be found.
568 569 570 571 572 |
# File 'lib/rubyvis/mark.rb', line 568 def cousin par=self.parent s= par ? par.sibling : nil (s and s.children) ? s.children[self.child_index][self.index] : nil end |
#delete_index ⇒ Object
Delete index
246 247 248 249 |
# File 'lib/rubyvis/mark.rb', line 246 def delete_index @index=nil @index_defined=false end |
#dot ⇒ Object
:method: dot(opts,&block)
Adds a Dot mark to current mark. If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
61 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 61 mark_method :dot, Rubyvis::Dot |
#event(type, handler) ⇒ Object
1078 1079 1080 1081 |
# File 'lib/rubyvis/mark.rb', line 1078 def event(type,handler) # :nodoc: #@_handlers[type]=handler self end |
#execute(&block) ⇒ Object
Execute a block using this mark as a reference Example
bar.execute |b|
b.width 10
b.add(Rubyvis::Label)
end
469 470 471 |
# File 'lib/rubyvis/mark.rb', line 469 def execute(&block) block.arity<1 ? self.instance_eval(&block) : block.call(self) end |
#first ⇒ Object
Returns the first instance of this mark in the scene graph. This method can only be called when the mark is bound to the scene graph (for example, from an event handler, or within a property function).
-
@returns a node in the scene graph.
539 540 541 |
# File 'lib/rubyvis/mark.rb', line 539 def first scene[0] end |
#image ⇒ Object
:method: image(opts,&block)
Adds an Image mark to current mark. If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
74 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 74 mark_method :image, Rubyvis::Image |
#index ⇒ Integer
The mark index. The value of this field depends on which instance (i.e., which element of the data array) is currently being evaluated. During the build phase, the index is incremented over each datum; when handling events, the index is set to the instance that triggered the event.
256 257 258 259 260 261 262 |
# File 'lib/rubyvis/mark.rb', line 256 def index if @index.nil? Mark.index else @index end end |
#index=(v) ⇒ Object
Set index attribute.
268 269 270 271 272 |
# File 'lib/rubyvis/mark.rb', line 268 def index=(v) @index_defined=true @index=v v end |
#index_defined? ⇒ Boolean
Returns true if index attribute is set and not deleted
264 265 266 |
# File 'lib/rubyvis/mark.rb', line 264 def index_defined? @index_defined end |
#instance(default_index = nil) ⇒ Object
Returns the current instance of this mark in the scene graph. This is typically equivalent to self.scene[self.index]
, 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. 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.
300 301 302 303 304 305 306 307 308 |
# File 'lib/rubyvis/mark.rb', line 300 def instance(default_index=nil) scene=self.scene scene||=self.parent.instance(-1).children[self.child_index] index = !self.index.nil? ? self.index : default_index #puts "defined?: #{index_defined?} : type: #{type}, self.index: #{self.index}, default_index: #{default_index}, index:#{index}" scene[index < 0 ? scene.size-1: index] end |
#instances(source) ⇒ Object
Find the instances of this mark that match source.
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 |
# File 'lib/rubyvis/mark.rb', line 504 def instances(source) mark = self _index = [] scene=nil while (!(scene = mark.scene)) do source = source.parent; _index.push(OpenStruct.new({:index=>source.index, :child_index=>mark.child_index})) mark = mark.parent end while (_index.size>0) do i = _index.pop() scene = scene[i.index].children[i.child_index] end # # When the anchor target is also an ancestor, as in the case of adding # to a panel anchor, only generate one instance per panel. Also, set # the margins to zero, since they are offset by the enclosing panel. # / if (index_defined?) s = scene[self.index].dup s.right = s.top = s.left = s.bottom = 0; return [s]; end scene end |
#label ⇒ Object
:method: label(opts,&block)
Adds a Label mark to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
89 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 89 mark_method :label, Rubyvis::Label |
#last ⇒ Object
Returns the last instance of this mark in the scene graph. This method can only be called when the mark is bound to the scene graph (for example, from an event handler, or within a property function). In addition, note that mark instances are built sequentially, so the last instance of this mark may not yet be constructed.
-
@returns a node in the scene graph.
549 550 551 |
# File 'lib/rubyvis/mark.rb', line 549 def last scene[scene.size - 1] end |
#layout_arc ⇒ Object
:method: layout_arc(opts,&block)
Adds a Layout::Arc to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
298 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 298 mark_method :layout_arc, Rubyvis::Layout::Arc |
#layout_cluster ⇒ Object
:method: layout_cluster(opts,&block)
Adds a Layout::Cluster to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
214 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 214 mark_method :layout_cluster, Rubyvis::Layout::Cluster |
#layout_grid ⇒ Object
:method: layout_grid(opts,&block)
Adds a Layout::Grid to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
256 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 256 mark_method :layout_grid, Rubyvis::Layout::Grid |
#layout_horizon ⇒ Object
:method: layout_horizon(opts,&block)
Adds a Layout::Horizon to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
284 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 284 mark_method :layout_horizon, Rubyvis::Layout::Horizon |
#layout_indent ⇒ Object
:method: layout_indent(opts,&block)
Adds a Layout::Indent to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
228 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 228 mark_method :layout_indent, Rubyvis::Layout::Indent |
#layout_matrix ⇒ Object
:method: layout_matrix(opts,&block)
Adds a Layout::Matrix to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
312 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 312 mark_method :layout_matrix, Rubyvis::Layout::Matrix |
#layout_pack ⇒ Object
:method: layout_pack(opts,&block)
Adds a Layout::Pack to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
242 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 242 mark_method :layout_pack, Rubyvis::Layout::Pack |
#layout_partition ⇒ Object
:method: layout_partition(opts,&block)
Adds a Layout::Partition to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
172 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 172 mark_method :layout_partition, Rubyvis::Layout::Partition |
#layout_partition_fill ⇒ Object
:method: layout_partition_fill(opts,&block)
Adds a Layout::Partition::Fill to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
186 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 186 mark_method :layout_partition_fill, Rubyvis::Layout::Partition::Fill |
#layout_stack ⇒ Object
:method: layout_stack(opts,&block)
Adds a Layout::Stack to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
158 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 158 mark_method :layout_stack, Rubyvis::Layout::Stack |
#layout_tree ⇒ Object
:method: layout_tree(opts,&block)
Adds a Layout::Tree to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
270 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 270 mark_method :layout_tree, Rubyvis::Layout::Tree |
#layout_treemap ⇒ Object
:method: layout_treemap(opts,&block)
Adds a Layout::Treemap to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
200 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 200 mark_method :layout_treemap, Rubyvis::Layout::Treemap |
#line ⇒ Object
:method: line(opts,&block)
Adds a Line mark to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
103 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 103 mark_method :line, Rubyvis::Line |
#margin(n) ⇒ Mark
Alias for setting the left, right, top and bottom properties simultaneously.
290 291 292 |
# File 'lib/rubyvis/mark.rb', line 290 def margin(n) self.left(n).right(n).top(n).bottom(n) end |
#mark_anchor(name = "center") ⇒ Object
Implementation of mark anchor
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 |
# File 'lib/rubyvis/mark.rb', line 612 def mark_anchor(name="center") # :nodoc: anchor=Rubyvis::Anchor. new(self). name(name). data(lambda { pp self.scene.target if $DEBUG a=self.scene.target.map {|s| puts "s:#{s.data}" if $DEBUG; s.data} p a if $DEBUG a }).visible(lambda { self.scene.target[index].visible }).id(lambda { self.scene.target[index].id }). left(lambda { s = self.scene.target[index] w = s.width w||=0 if ['bottom','top','center'].include?(self.name) s.left + w / 2.0 elsif self.name=='left' nil else s.left + w end }). top(lambda { s = self.scene.target[self.index] h = s.height h||= 0 if ['left','right','center'].include? self.name s.top+h/2.0 elsif self.name=='top' nil else s.top + h end }).right(lambda { s = self.scene.target[self.index] self.name() == "left" ? s.right + (s.width ? s.width : 0) : nil; }).bottom(lambda { s = self.scene.target[self.index]; self.name() == "top" ? s.bottom + (s.height ? s.height : 0) : nil; }).text_align(lambda { if ['bottom','top','center'].include? self.name 'center' elsif self.name=='right' 'right' else 'left' end }).text_baseline(lambda { if ['right','left','center'].include? self.name 'middle' elsif self.name=='top' 'top' else 'bottom' end }) anchor end |
#mark_bind ⇒ Object
:nodoc:
868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 |
# File 'lib/rubyvis/mark.rb', line 868 def mark_bind() # :nodoc: @seen={} @types={1=>[],2=>[],3=>[]} @_data=nil @_required=[] #puts "Binding!" bind_bind(self) bind_bind((self.class).defaults) @types[1].reverse! @types[3].reverse! #puts "***" #pp @types[3] #puts "***" mark=self begin properties.each {|name,v| if !@seen[name] @seen[name]=Property.new(:name=>name, :_type=>2, :value=>nil) @types[2].push(@seen[name]) end } end while(mark = mark.proto) @binds=OpenStruct.new({:properties=>@seen, :data=>@_data, :required=>@_required, :optional=>@types[1]+@types[2]+@types[3] }) end |
#mark_build_implied(s) ⇒ Object
:nodoc:
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 |
# File 'lib/rubyvis/mark.rb', line 690 def mark_build_implied(s) # :nodoc: l=s.left r=s.right t=s.top b=s.bottom prop=self.properties #p self w = (prop[:width]) ? s.width : 0 h = (prop[:height]) ? s.height : 0 width=self.parent ? self.parent.width() : (w+(l.nil? ? 0 : l)+(r.nil? ? 0 : r)) #puts (self.parent)? "parent width: #{self.parent.width}" : "no parent" if $DEBUG #p prop.sort if $DEBUG height=self.parent ? self.parent.height(): (h+(t.nil? ? 0 : t )+(b.nil? ? 0 : b)) puts "build implied #{type}: l:#{l},r:#{r},t:#{t},b:#{b}, w:#{prop[:width]} #{w},h: #{prop[:height]} #{h}, width:#{width}, height:#{height}" if $DEBUG if w.nil? r||=0 l||=0 w=width-r-l elsif r.nil? if l.nil? r=(width-w) / (2.0) l=r else r=width-w-l end elsif l.nil? l=width-w-r end if h.nil? t||=0 b||=0 h=height-t-b elsif b.nil? if t.nil? t=(height-h) / 2.0 b=t else b=height-h-t end elsif t.nil? t=height-h-b end s.left=l s.right=r s.top=t s.bottom=b puts "Post->left: #{l},right:#{r},top:#{t},bottom:#{b}, width:#{w}, height:#{h}\n\n" if $DEBUG s.width = w if prop[:width] s.height = h if prop[:height] s.text_style=Rubyvis::Color.transparent if prop[:text_style] and !s.text_style s.fill_style=Rubyvis::Color.transparent if prop[:fill_style] and !s.fill_style s.stroke_style=Rubyvis::Color.transparent if prop[:stroke_style] and !s.stroke_style end |
#mark_build_instance(s1) ⇒ Object
1047 1048 1049 1050 1051 1052 1053 |
# File 'lib/rubyvis/mark.rb', line 1047 def mark_build_instance(s1) # :nodoc: build_properties(s1, self.binds.required) if s1.visible build_properties(s1, self.binds.optional) build_implied(s1) end end |
#mark_build_properties(ss, props) ⇒ Object
:nodoc:
1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 |
# File 'lib/rubyvis/mark.rb', line 1065 def mark_build_properties(ss, props) # :nodoc: #p "#{type}:"+props.map {|prop| prop.name}.join(",") props.each do |prop| v=prop.value # p "#{prop.name}=#{v}" if prop._type==3 v=v.js_apply(self, Mark.stack) end ss.send((prop.name.to_s+"=").to_sym, v) end end |
#mark_extend(proto) ⇒ Object
Sets the prototype of this mark to the specified mark. Any properties not defined on this mark may be inherited from the specified prototype mark, or its prototype, and so on. The prototype mark need not be the same type of mark as this mark. (Note that for inheritance to be useful, properties with the same name on different mark types should have equivalent meaning). On protovis, this method is called extend
, but it should be changed because clashed with native extend
method
497 498 499 500 501 |
# File 'lib/rubyvis/mark.rb', line 497 def mark_extend(proto) @proto=proto @target=proto.target self end |
#panel ⇒ Object
:method: panel(opts,&block)
Adds a Panel mark to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
117 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 117 mark_method :panel, Rubyvis::Panel |
#properties ⇒ Object
Return properties for current mark
434 435 436 |
# File 'lib/rubyvis/mark.rb', line 434 def properties (self.class).properties end |
#property_value(name, v) ⇒ Object
Sets the value of the property name to v
275 276 277 278 279 280 281 |
# File 'lib/rubyvis/mark.rb', line 275 def property_value(name,v) prop=Property.new({:name=>name, :id=>Rubyvis.id, :value=>v}) @_properties.delete_if{|v1| v1.name==name} @_properties.push(prop) #@_properties_values[name]=v prop end |
#render ⇒ Object
Renders this mark, including recursively rendering all child marks if this is a panel. This method finds all instances of this mark and renders them. This method descends recursively to the level of the mark to be rendered, finding all visible instances of the mark. After the marks are rendered, the scene and index attributes are removed from the mark to restore them to a clean state.
<p>If an enclosing panel has an index property set (as is the case inside in an event handler), then only instances of this mark inside the given instance of the panel will be rendered; otherwise, all visible instances of the mark will be rendered.
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 |
# File 'lib/rubyvis/mark.rb', line 767 def render parent=self.parent @stack=Mark.stack if parent and !self.root.scene root.render() return end @indexes=[] mark=self until mark.parent.nil? @indexes.unshift(mark.child_index) end bind while(parent and !parent.respond_to? :index) do parent=parent.parent end self.context( parent ? parent.scene : nil, parent ? parent.index : -1, lambda { render_render(root, 0,1) } ) end |
#rule ⇒ Object
:method: rule(opts,&block)
Adds a Rule mark to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
131 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 131 mark_method :rule, Rubyvis::Rule |
#sibling ⇒ Object
Returns the previous instance of this mark in the scene graph, or nil if this is the first instance.
558 559 560 |
# File 'lib/rubyvis/mark.rb', line 558 def sibling (self.index==0) ? nil: self.scene[self.index-1] end |
#type ⇒ Object
The mark type; a lower name. The type name controls rendering behavior, and unless the rendering engine is extended, must be one of the built-in concrete mark types: area, bar, dot, image, label, line, panel, rule, or wedge.
476 477 478 |
# File 'lib/rubyvis/mark.rb', line 476 def type "mark" end |
#wedge ⇒ Object
:method: wedge(opts,&block)
Adds a Wedge mark to current mark.
If a block is provided, the context will be defined differently if parameter is provided
-
Without parameter: block executed inside context of new mark
-
With paramenter: block executed inside context of current mark. Paramenter references new mark
See Mark for examples of use
145 |
# File 'lib/rubyvis/mark/shorcut_methods.rb', line 145 mark_method :wedge, Rubyvis::Wedge |