rubyvis 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,228 @@
1
+ module Rubyvis
2
+ class Layout
3
+ def self.Stack
4
+ Rubyvis::Layout::Stack
5
+ end
6
+ class Stack < Rubyvis::Layout
7
+ @properties=Panel.properties.dup
8
+
9
+ attr_accessor :_x, :_y, :_values, :prop
10
+ attr_accessor_dsl :orient,:offset, :order, :layers
11
+ def self.defaults
12
+ Stack.new.extend(Layout.defaults).orient("bottom-left").offset("zero").layers([[]])
13
+ end
14
+ def initialize
15
+ super
16
+ @none=lambda {nil}
17
+ @prop = {"t"=> @none, "l"=> @none, "r"=> @none, "b"=> @none, "w"=> @none, "h"=> @none}
18
+ @values=nil
19
+ @_x=lambda {return 0}
20
+ @_y=lambda {return 0}
21
+ @_values=pv.identity
22
+ end
23
+ def x(f)
24
+ @_x=pv.functor(f)
25
+ return self
26
+ end
27
+ def y(f)
28
+ @_y=pv.functor(f)
29
+ return self
30
+ end
31
+ def values(f=nil)
32
+ if f.nil?
33
+ @values
34
+ else
35
+ @_values=pv.functor(f)
36
+ return self
37
+ end
38
+ end
39
+
40
+
41
+ def proxy(name)
42
+ that=self
43
+ return lambda {
44
+ a=that.prop[name].js_call(self, self.parent.index, self.index);
45
+ puts "proxy(#{name}): #{a}" if $DEBUG
46
+ a
47
+ }
48
+ end
49
+
50
+ def build_implied(s)
51
+ # puts "Build stack" if $DEBUG
52
+ panel_build_implied(s)
53
+ data = s.layers
54
+ n = data.size
55
+ m = nil
56
+ orient = s.orient
57
+ if orient =~/^(top|bottom)\b/
58
+ horizontal=true
59
+ else
60
+ horizontal=false
61
+ end
62
+ h = self.parent.send(horizontal ? "height" : "width")
63
+ x = []
64
+ y = []
65
+ dy = []
66
+
67
+ #
68
+ # Iterate over the data, evaluating the values, x and y functions. The
69
+ # context in which the x and y psuedo-properties are evaluated is a
70
+ # pseudo-mark that is a grandchild of this layout.
71
+ #
72
+ stack = Rubyvis::Mark.stack
73
+
74
+ o = OpenStruct.new({:parent=> OpenStruct.new({:parent=> self})})
75
+ stack.unshift(nil)
76
+ values = []
77
+ n.times {|i|
78
+ dy[i] = []
79
+ y[i] = []
80
+ o.parent.index = i
81
+ stack[0] = data[i]
82
+ values[i] = self._values.js_apply(o.parent, stack);
83
+ m = values[i].size if (i==0)
84
+ stack.unshift(nil)
85
+ m.times {|j|
86
+ stack[0] = values[i][j]
87
+ o.index = j
88
+ x[j] = self._x.js_apply(o, stack) if i==0
89
+ dy[i][j] = self._y.js_apply(o, stack)
90
+ }
91
+ stack.shift()
92
+ }
93
+ stack.shift()
94
+
95
+ # order
96
+ _index=nil
97
+ case (s.order)
98
+ when "inside-out"
99
+ max = dy.map {|v| pv.max.index(v) }
100
+ map = pv.range(n).sort {|a,b| return max[a] - max[b]}
101
+ sums = dy.map {|v| pv.sum(v)}
102
+ top = 0
103
+ bottom = 0
104
+ tops = []
105
+ bottoms = []
106
+ n.times {|i|
107
+ j = map[i]
108
+ if (top < bottom)
109
+ top += sums[j];
110
+ tops.push(j);
111
+ else
112
+ bottom += sums[j];
113
+ bottoms.push(j);
114
+ end
115
+ }
116
+ _index = bottoms.reverse+tops
117
+
118
+ when "reverse"
119
+ _index = pv.range(n - 1, -1, -1)
120
+ else
121
+ _index = pv.range(n)
122
+ end
123
+
124
+ #/* offset */
125
+ case (s.offset)
126
+ when "silohouette"
127
+ m.times {|j|
128
+ o = 0;
129
+ n.times {|i|
130
+ o += dy[i][j]
131
+ }
132
+ y[_index[0]][j] = (h - o) / 2.0;
133
+ }
134
+
135
+ when "wiggle"
136
+ o = 0;
137
+ n.times {|i| o += dy[i][0] }
138
+
139
+ y[_index[0]][0] = o = (h - o) / 2.0
140
+
141
+ (1...m).each {|j|
142
+ s1 = 0
143
+ s2 = 0
144
+ dx = x[j] - x[j - 1]
145
+ n.times {|i| s1 += dy[i][j]}
146
+ n.times {|i|
147
+
148
+ s3 = (dy[_index[i]][j] - dy[_index[i]][j - 1]) / (2.0 * dx)
149
+ i.times {|k|
150
+ s3 += (dy[_index[k]][j] - dy[_index[k]][j - 1]) / dx.to_f
151
+ }
152
+ s2 += s3 * dy[_index[i]][j]
153
+ }
154
+ o -= (s1!=0) ? s2 / s1.to_f * dx : 0
155
+ y[_index[0]][j] = o
156
+
157
+ }
158
+ when "expand"
159
+ m.times {|j|
160
+ y[_index[0]][j] = 0
161
+
162
+ k = 0
163
+ n.times {|i|k += dy[i][j]}
164
+ if (k!=0)
165
+ k = h / k.to_f
166
+ n.times {|i| dy[i][j] *= k}
167
+ else
168
+ k = h / n.to_f
169
+ n.times { dy[i][j] = k}
170
+ end
171
+ }
172
+ else
173
+ m.times {|j| y[_index[0]][j] = 0}
174
+ end
175
+
176
+ # Propagate the offset to the other series. */
177
+ m.times {|j|
178
+ o = y[_index[0]][j]
179
+ (1...n).each {|i|
180
+
181
+ o += dy[_index[i - 1]][j]
182
+ y[_index[i]][j] = o
183
+ }
184
+ }
185
+
186
+ # /* Find the property definitions for dynamic substitution. */
187
+
188
+ i = orient.index("-")
189
+ pdy = horizontal ? "h" : "w"
190
+ px = i < 0 ? (horizontal ? "l" : "b") : orient[i + 1,1]
191
+ py = orient[0,1]
192
+
193
+ @values=values
194
+
195
+ @prop.each {|k,v|
196
+ @prop[k]=@none
197
+ }
198
+ # puts "stack: x:#{px}, y:#{py}, dy:#{pdy}" if $DEBUG
199
+ @prop[px] =lambda {|i1,j| x[j]}
200
+ @prop[py] =lambda {|i1,j| y[i1][j]}
201
+ @prop[pdy]=lambda {|i1,j| dy[i1][j]}
202
+ end
203
+
204
+ def layer
205
+ that=self
206
+ value = Rubyvis::Mark.new().data(lambda { that.values[self.parent.index] })
207
+ .top(proxy("t"))
208
+ .left(proxy("l"))
209
+ .right(proxy("r"))
210
+ .bottom(proxy("b"))
211
+ .width(proxy("w"))
212
+ .height(proxy("h"))
213
+
214
+ class << value
215
+ def that=(v)
216
+ @that = v
217
+ end
218
+ def add(type)
219
+ that = @that
220
+ that.add( pv.Panel ).data(lambda { that.layers() }).add(type).extend( self )
221
+ end
222
+ end
223
+ value.that=self
224
+ return value
225
+ end
226
+ end
227
+ end
228
+ end
@@ -6,10 +6,9 @@ module Rubyvis
6
6
  class Mark
7
7
  @properties={}
8
8
 
9
- def self.property_method(name, _def, func=nil)
10
-
11
- return if Mark.method_defined? name
12
- Mark.send(:define_method, name) do |*arguments|
9
+ def self.property_method(name, _def, func=nil, klass=nil)
10
+ return if klass.method_defined? name
11
+ klass.send(:define_method, name) do |*arguments|
13
12
  v,dummy = arguments
14
13
  if _def and self.scene
15
14
  if arguments.size>0
@@ -33,16 +32,35 @@ module Rubyvis
33
32
  if i.nil?
34
33
  raise "No instance for #{self} on #{name}"
35
34
  else
36
- # puts "index:#{self.index}, name:#{name}, val:#{i.send(name)}"
35
+ # puts "index:#{self.index}, name:#{name}, val:#{i.send(name)}"
37
36
  i.send(name)
38
37
  end
39
38
  end
40
39
 
41
40
  camel=name.to_s.gsub(/(_.)/) {|v| v[1,1].upcase}
42
41
  if camel!=name
43
- Mark.send(:alias_method, camel, name)
42
+ klass.send(:alias_method, camel, name)
43
+ end
44
+ end
45
+
46
+ def self.attr_accessor_dsl(*attr)
47
+ attr.each do |sym|
48
+ if sym.is_a? Array
49
+ name,func=sym
50
+ else
51
+ name=sym
52
+ func=nil
53
+ end
54
+
55
+ @properties[name]=true
56
+ self.property_method(name,false, func, Rubyvis::Mark)
57
+ define_method(name.to_s+"=") {|v|
58
+ self.send(name,v)
59
+ }
44
60
  end
45
61
  end
62
+
63
+
46
64
  def property_value(name,v)
47
65
  prop=Property.new({:name=>name, :id=>Rubyvis.id, :value=>v})
48
66
  @_properties.delete_if{|v1| v1.name==name}
@@ -63,23 +81,6 @@ module Rubyvis
63
81
  end
64
82
 
65
83
 
66
- def self.attr_accessor_dsl(*attr)
67
- attr.each do |sym|
68
-
69
- if sym.is_a? Array
70
- name,func=sym
71
- else
72
- name=sym
73
- func=nil
74
- end
75
-
76
- @properties[name]=true
77
- self.property_method(name,false, func)
78
- define_method(name.to_s+"=") {|v|
79
- self.send(name,v)
80
- }
81
- end
82
- end
83
84
 
84
85
  attr_accessor :parent, :root, :index, :child_index, :scene, :proto, :target, :scale
85
86
  attr_reader :_properties
@@ -119,11 +120,7 @@ module Rubyvis
119
120
  end
120
121
 
121
122
  def initialize(opts=Hash.new)
122
- #@_properties_values={}
123
- #@_properties_types={}
124
123
  @_properties=[]
125
- #@options=opts
126
- # @stack=[]
127
124
  opts.each {|k,v|
128
125
  self.send("#{k}=",v) if self.respond_to? k
129
126
  }
@@ -253,19 +250,22 @@ module Rubyvis
253
250
  t=s.top
254
251
  b=s.bottom
255
252
  prop=self.properties
253
+
256
254
  #p self
255
+
257
256
  w = (prop[:width]) ? s.width : 0
258
257
  h = (prop[:height]) ? s.height : 0
259
- #puts "l:#{l},r:#{r},t:#{t},b:#{b}"
260
- #puts "w:#{w},h:#{h}"
261
- width=self.parent ? self.parent.width(): (w+(l.nil? ? 0 : l)+(r.nil? ? 0 :r))
258
+
259
+ width=self.parent ? self.parent.width() : (w+(l.nil? ? 0 : l)+(r.nil? ? 0 : r))
260
+ #puts (self.parent)? "parent width: #{self.parent.width}" : "no parent" if $DEBUG
261
+ #p prop.sort if $DEBUG
262
+ puts "build implied #{type}: l:#{l},r:#{r},t:#{t},b:#{b}, w:#{prop[:width]} #{w},h: #{prop[:height]} #{h}, width:#{width}" if $DEBUG
262
263
  if w.nil?
263
264
  r||=0
264
265
  l||=0
265
266
  w=width-r-l
266
267
  elsif r.nil?
267
268
  if l.nil?
268
-
269
269
  r=(width-w) / (2.0)
270
270
  l=r
271
271
  else
@@ -299,9 +299,10 @@ module Rubyvis
299
299
  s.top=t
300
300
  s.bottom=b
301
301
 
302
- # puts "#{l},#{r},#{t},#{b}"
302
+ puts "Post->left: #{l},right:#{r},top:#{t},bottom:#{b}, width:#{w}, height:#{h}" if $DEBUG
303
303
 
304
304
  s.width=w if prop[:width]
305
+ #puts "width:#{s.width}" if $DEBUG
305
306
  s.height=h if prop[:height]
306
307
  s.text_style=Rubyvis::Color.transparent if prop[:text_style] and !s.text_style
307
308
  s.fill_style=Rubyvis::Color.transparent if prop[:fill_style] and !s.fill_style
@@ -543,7 +544,7 @@ module Rubyvis
543
544
  def mark_build_instance(s1)
544
545
  build_properties(s1, self.binds.required)
545
546
  if s1.visible
546
- build_properties(s1,self.binds.optional)
547
+ build_properties(s1, self.binds.optional)
547
548
  build_implied(s1)
548
549
  end
549
550
  end
@@ -112,7 +112,8 @@ module Rubyvis
112
112
  area_build_instance(s)
113
113
  end
114
114
  def self.defaults
115
- Area.new.extend(Mark.defaults).line_width(1.5).fill_style(lambda {pv.Colors.category20.scale(self.parent.index)}).interpolate('linear').tension(0.7)
115
+ a= Rubyvis::Colors.category20
116
+ Area.new.extend(Mark.defaults).line_width(1.5).fill_style(lambda {a.scale(self.parent.index)}).interpolate('linear').tension(0.7)
116
117
  end
117
118
  def anchor(name)
118
119
  area_anchor(name)
@@ -120,7 +121,7 @@ module Rubyvis
120
121
  def build_implied(s)
121
122
  s.heigth=0 if s.height.nil?
122
123
  s.width=0 if s.width.nil?
123
- super(s)
124
+ mark_build_implied(s)
124
125
  end
125
126
  end
126
127
  end
@@ -10,7 +10,10 @@ module Rubyvis
10
10
  @properties=Mark.properties.dup
11
11
  attr_accessor_dsl :width, :height, :line_width, [:stroke_style, lambda {|d| pv.color(d)}], [:fill_style, lambda {|d| pv.color(d)}]
12
12
  def self.defaults
13
- Bar.new.extend(Mark.defaults).line_width(1.5).fill_style( lambda {Rubyvis.Colors.category20().scale(self.parent.index)})
13
+ a=Rubyvis.Colors.category20()
14
+ Bar.new.extend(Mark.defaults).line_width(1.5).fill_style( lambda {
15
+ a.scale(self.parent.index)
16
+ })
14
17
  end
15
18
  end
16
19
  end
@@ -12,57 +12,57 @@ module Rubyvis
12
12
  attr_accessor_dsl :shape, :shape_angle, :shape_radius, :shape_size, :line_width, [:stroke_style, lambda {|d| pv.color(d)}], [:fill_style, lambda {|d| pv.color(d)}]
13
13
 
14
14
  def self.defaults()
15
- Dot.new().extend(Mark.defaults).shape("circle"). line_width(1.5). stroke_style(lambda {pv.Colors.category10().scale(self.parent.index)})
15
+ a=Rubyvis::Colors.category10
16
+ Dot.new().extend(Mark.defaults).shape("circle"). line_width(1.5). stroke_style(lambda {a.scale(self.parent.index)})
16
17
  end
17
18
 
18
19
  def anchor(name)
19
20
 
20
21
 
21
22
  mark_anchor(name).left(lambda {
22
- s=scene.target[self.index]
23
- case self.name
23
+ s=scene.target[self.index]
24
+ case self.name
24
25
  when 'bottom' then s.left;
25
26
  when 'top' then s.left;
26
27
  when 'center' then s.left;
27
28
  when 'left' then nil;
28
29
  else
29
30
  s.left+s.shape_radius
30
- end
31
+ end
31
32
  }).right(lambda {
32
- s=scene.target[self.index]
33
- self.name()=='left' ? s.right+s.shape_radius : nil
34
-
33
+ s=scene.target[self.index]
34
+ self.name()=='left' ? s.right+s.shape_radius : nil
35
35
  }).top(lambda {
36
36
  s=scene.target[self.index]
37
- case self.name
37
+ case self.name
38
38
  when 'left' then s.top;
39
39
  when 'right' then s.top;
40
40
  when 'center' then s.top;
41
41
  when 'top' then nil;
42
42
  else
43
43
  s.top+s.shape_radius
44
- end
44
+ end
45
45
  }).bottom(lambda {
46
- s=scene.target[self.index]
47
- self.name()=='top' ? s.bottom+s.shape_radius : nil
46
+ s=scene.target[self.index]
47
+ self.name()=='top' ? s.bottom+s.shape_radius : nil
48
48
  }).text_align(lambda {
49
- case self.name
49
+ case self.name
50
50
  when 'left' then 'right';
51
51
  when 'bottom' then 'center';
52
52
  when 'top' then 'center';
53
53
  when 'center' then 'center';
54
54
  else
55
55
  'left'
56
- end
56
+ end
57
57
  }).text_baseline( lambda {
58
- case self.name
59
- when 'right' then 'middle';
60
- when 'left' then 'middle';
61
- when 'center' then 'middle';
58
+ case self.name
59
+ when 'right' then 'middle';
60
+ when 'left' then 'middle';
61
+ when 'center' then 'middle';
62
62
  when 'bottom' then 'top';
63
63
  else
64
64
  'bottom'
65
- end
65
+ end
66
66
 
67
67
  })
68
68
  end