Class: Rubyvis::Mark
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:
- 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.
- 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.
- 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.
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.
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.
- .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
-
#anchor(name = 'center') ⇒ Anchor
Returns an anchor with the specified name.
-
#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
- #context_apply(scene, index) ⇒ Object
- #context_clear(scene, index) ⇒ Object
-
#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.
- #event(type, handler) ⇒ Object
-
#extend(proto) ⇒ Object
Sets the prototype of this mark to the specified mark.
-
#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) ⇒ Mark
constructor
Create a new Mark.
-
#instance(default_index = nil) ⇒ Object
This is typically equivalent to this.scene, however if the scene or index is unset, the default instance of the mark is returned.
-
#instances(source) ⇒ Object
Find the instances of this mark that match source.
-
#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
-
#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.
-
#sibling ⇒ Object
Returns the previous instance of this mark in the scene graph, or null if this is the first instance.
-
#type ⇒ Object
The mark type; a lower name.
Constructor Details
#initialize(opts = Hash.new) ⇒ Mark
Create a new Mark
382 383 384 385 386 387 388 389 390 391 392 393 |
# File 'lib/rubyvis/mark.rb', line 382 def initialize(opts=Hash.new) @_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 end |
Instance Attribute Details
#_properties ⇒ Object (readonly)
Array with stores properties values
110 111 112 |
# File 'lib/rubyvis/mark.rb', line 110 def _properties @_properties end |
#binds ⇒ Object
OpenStruct which store values for scenes
113 114 115 |
# File 'lib/rubyvis/mark.rb', line 113 def binds @binds end |
#child_index ⇒ Object
The child index. -1 if the enclosing parent panel is null; otherwise, the zero-based index of this mark into the parent panel's children array.
76 77 78 |
# File 'lib/rubyvis/mark.rb', line 76 def child_index @child_index end |
#parent ⇒ Object
64 65 66 |
# File 'lib/rubyvis/mark.rb', line 64 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.
90 91 92 |
# File 'lib/rubyvis/mark.rb', line 90 def proto @proto end |
#root ⇒ Object
The root parent panel. This may be undefined for "offscreen" marks that are created for inheritance purposes only.
70 71 72 |
# File 'lib/rubyvis/mark.rb', line 70 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:
dot.shape_radius(lambda { 10 / self.scale})
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.
107 108 109 |
# File 'lib/rubyvis/mark.rb', line 107 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.
83 84 85 |
# File 'lib/rubyvis/mark.rb', line 83 def scene @scene end |
#target ⇒ Object
The mark anchor target, possibly undefined.
94 95 96 |
# File 'lib/rubyvis/mark.rb', line 94 def target @target end |
Class Method Details
.attr_accessor_dsl(*attr) ⇒ Object
Creates a dinamic property using property_method().
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/rubyvis/mark.rb', line 167 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.
409 410 411 |
# File 'lib/rubyvis/mark.rb', line 409 def self.defaults Mark.new({:data=>lambda {|d| [d]}, :visible=>true, :antialias=>true, :events=>'painted'}) end |
.index ⇒ Object
Common index for all marks
350 351 352 |
# File 'lib/rubyvis/mark.rb', line 350 def Mark.index @index end |
.index=(v) ⇒ Object
Set common index for all marks
355 356 357 |
# File 'lib/rubyvis/mark.rb', line 355 def Mark.index=(v) @index=v end |
.properties ⇒ Object
346 347 348 |
# File 'lib/rubyvis/mark.rb', line 346 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 null, the cast function is not invoked.
Parameters:
- @param [String] name the property name.
- @param [Boolean]
defwhether is a property or a def. - @param [Proc]
castthe cast function for this property. - @param [Class]
klassthe klass on which property will be added
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/rubyvis/mark.rb', line 129 def self.property_method(name, _def, func=nil, klass=nil) return if klass.method_defined? name klass.send(:define_method, name) do |*arguments| v,dummy = arguments 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 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
359 360 361 |
# File 'lib/rubyvis/mark.rb', line 359 def self.scene @scene end |
.scene=(v) ⇒ Object
Set common scene for all marks
363 364 365 |
# File 'lib/rubyvis/mark.rb', line 363 def self.scene=(v) @scene=v end |
Instance Method Details
#add(type) ⇒ Object
475 476 477 |
# File 'lib/rubyvis/mark.rb', line 475 def add(type) parent.add(type).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.
501 502 503 |
# File 'lib/rubyvis/mark.rb', line 501 def anchor(name='center') mark_anchor(name) end |
#bind ⇒ Object
do not need to be queried during build.
747 748 749 |
# File 'lib/rubyvis/mark.rb', line 747 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.
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.
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.
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 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 |
# File 'lib/rubyvis/mark.rb', line 876 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.
577 578 579 |
# File 'lib/rubyvis/mark.rb', line 577 def build_implied(s) # :nodoc: mark_build_implied(s) end |
#build_instance(s) ⇒ Object
923 924 925 |
# File 'lib/rubyvis/mark.rb', line 923 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.
942 943 944 945 946 947 948 949 950 951 952 953 |
# File 'lib/rubyvis/mark.rb', line 942 def build_properties(ss, props) #p props 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 |
#context(scene, index, f) ⇒ Object
829 830 831 832 833 834 835 836 837 838 839 840 841 842 |
# File 'lib/rubyvis/mark.rb', line 829 def context(scene,index,f) 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
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 |
# File 'lib/rubyvis/mark.rb', line 774 def context_apply(scene,index) 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
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 |
# File 'lib/rubyvis/mark.rb', line 807 def context_clear(scene,index) 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 null if this instance could not be found.
470 471 472 473 474 |
# File 'lib/rubyvis/mark.rb', line 470 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
186 187 188 189 |
# File 'lib/rubyvis/mark.rb', line 186 def delete_index @index=nil @index_defined=false end |
#event(type, handler) ⇒ Object
implement
955 956 957 958 |
# File 'lib/rubyvis/mark.rb', line 955 def event(type,handler) #@_handlers[type]=handler self end |
#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.)
419 420 421 422 423 |
# File 'lib/rubyvis/mark.rb', line 419 def extend(proto) @proto=proto @target=proto.target self end |
#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.
196 197 198 |
# File 'lib/rubyvis/mark.rb', line 196 def index @index end |
#index=(v) ⇒ Object
Set index attribute.
204 205 206 207 208 |
# File 'lib/rubyvis/mark.rb', line 204 def index=(v) @index_defined=true @index=v v end |
#index_defined? ⇒ Boolean
Returns true if index attribute is set and not deleted
200 201 202 |
# File 'lib/rubyvis/mark.rb', line 200 def index_defined? @index_defined end |
#instance(default_index = nil) ⇒ Object
This is typically equivalent to this.scene, 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.
236 237 238 239 240 241 242 243 |
# File 'lib/rubyvis/mark.rb', line 236 def instance(default_index=nil) scene=self.scene scene||=self.parent.instance(-1).children[self.child_index] index = index_defined? ? self.index : default_index # "defined?: #{index_defined?} : type: #{type}, self.index: #{self.index}, index:#{index}" scene[index<0 ? scene.size-1: index] end |
#instances(source) ⇒ Object
Find the instances of this mark that match source.
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 |
# File 'lib/rubyvis/mark.rb', line 426 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 |
#margin(n) ⇒ Mark
Alias for setting the left, right, top and bottom properties simultaneously.
226 227 228 |
# File 'lib/rubyvis/mark.rb', line 226 def margin(n) self.left(n).right(n).top(n).bottom(n) end |
#mark_anchor(name = "center") ⇒ Object
Implementation of mark anchor
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 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
# File 'lib/rubyvis/mark.rb', line 505 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[self.index].visible }). id(lambda {self.scene.target[self.index].id}). left(lambda { s = self.scene.target[self.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 }) return anchor end |
#mark_bind ⇒ Object
:nodoc:
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 |
# File 'lib/rubyvis/mark.rb', line 751 def mark_bind() # :nodoc: @seen={} @types={1=>[],2=>[],3=>[]} @_data=nil @_required=[] bind_bind(self) bind_bind((self.class).defaults) @types[1].reverse! @types[3].reverse! 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:
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 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 |
# File 'lib/rubyvis/mark.rb', line 581 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 puts "build implied #{type}: l:#{l},r:#{r},t:#{t},b:#{b}, w:#{prop[:width]} #{w},h: #{prop[:height]} #{h}, width:#{width}" 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 height=self.parent ? self.parent.height(): (h+(t.nil? ? 0 : t )+(b.nil? ? 0 : b)) 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}" if $DEBUG s.width=w if prop[:width] #puts "width:#{s.width}" if $DEBUG 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
927 928 929 930 931 932 933 |
# File 'lib/rubyvis/mark.rb', line 927 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 |
#properties ⇒ Object
Return properties for current mark
369 370 371 |
# File 'lib/rubyvis/mark.rb', line 369 def properties (self.class).properties end |
#property_value(name, v) ⇒ Object
Sets the value of the property name to v
211 212 213 214 215 216 217 |
# File 'lib/rubyvis/mark.rb', line 211 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.
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.
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 656 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(self.root, 0,1)}) end |
#sibling ⇒ Object
Returns the previous instance of this mark in the scene graph, or null if this is the first instance.
460 461 462 |
# File 'lib/rubyvis/mark.rb', line 460 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.
400 401 402 |
# File 'lib/rubyvis/mark.rb', line 400 def type "mark" end |