rubyvis 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.txt +13 -1
  3. data/Manifest.txt +19 -0
  4. data/examples/antibiotics/antibiotics.rb +96 -0
  5. data/examples/antibiotics/antibiotics_data.rb +20 -0
  6. data/examples/area.rb +103 -0
  7. data/examples/bar_column_chart.rb +55 -0
  8. data/examples/barley/barley.rb +29 -19
  9. data/examples/barley/barley_data.rb +122 -0
  10. data/examples/crimea/crimea_grouped_bar.rb +59 -0
  11. data/examples/dot.rb +19 -0
  12. data/examples/first.rb +1 -6
  13. data/examples/line.rb +84 -0
  14. data/examples/pie_and_donut.rb +38 -0
  15. data/examples/scatterplot.rb +55 -0
  16. data/examples/second.rb +3 -4
  17. data/examples/third.rb +1 -1
  18. data/lib/rubyvis.rb +3 -1
  19. data/lib/rubyvis/color/color.rb +31 -3
  20. data/lib/rubyvis/color/colors.rb +3 -3
  21. data/lib/rubyvis/format/number.rb +80 -10
  22. data/lib/rubyvis/internals.rb +11 -5
  23. data/lib/rubyvis/javascript_behaviour.rb +1 -0
  24. data/lib/rubyvis/mark.rb +43 -20
  25. data/lib/rubyvis/mark/anchor.rb +1 -1
  26. data/lib/rubyvis/mark/area.rb +15 -13
  27. data/lib/rubyvis/mark/bar.rb +2 -2
  28. data/lib/rubyvis/mark/dot.rb +85 -0
  29. data/lib/rubyvis/mark/label.rb +1 -1
  30. data/lib/rubyvis/mark/line.rb +7 -6
  31. data/lib/rubyvis/mark/panel.rb +0 -1
  32. data/lib/rubyvis/mark/rule.rb +5 -4
  33. data/lib/rubyvis/mark/wedge.rb +124 -0
  34. data/lib/rubyvis/nest.rb +158 -0
  35. data/lib/rubyvis/scale.rb +4 -0
  36. data/lib/rubyvis/scale/log.rb +55 -0
  37. data/lib/rubyvis/scale/ordinal.rb +34 -11
  38. data/lib/rubyvis/scale/quantitative.rb +17 -3
  39. data/lib/rubyvis/scene/svg_area.rb +197 -0
  40. data/lib/rubyvis/scene/svg_dot.rb +67 -0
  41. data/lib/rubyvis/scene/svg_label.rb +17 -15
  42. data/lib/rubyvis/scene/svg_line.rb +0 -2
  43. data/lib/rubyvis/scene/svg_rule.rb +2 -2
  44. data/lib/rubyvis/scene/svg_scene.rb +8 -1
  45. data/lib/rubyvis/scene/svg_wedge.rb +56 -0
  46. data/lib/rubyvis/sceneelement.rb +2 -1
  47. data/spec/bar_spec.rb +27 -3
  48. data/spec/label_spec.rb +1 -1
  49. data/spec/nest_spec.rb +41 -0
  50. data/spec/panel_spec.rb +1 -1
  51. data/spec/scale_linear_spec.rb +2 -2
  52. data/spec/scale_ordinal_spec.rb +81 -0
  53. data/spec/spec.opts +0 -1
  54. metadata +24 -3
  55. metadata.gz.sig +0 -0
@@ -27,7 +27,7 @@ module Rubyvis
27
27
  return Rubyvis.rgb(r,g,b,a)
28
28
  end
29
29
  end
30
-
30
+
31
31
  named = Rubyvis::Color.names[format.to_sym]
32
32
 
33
33
 
@@ -60,7 +60,9 @@ module Rubyvis
60
60
  @color=color
61
61
  @opacity=opacity
62
62
  end
63
-
63
+ def darker(*args)
64
+ self.rgb.darker(*args)
65
+ end
64
66
 
65
67
  def self.names
66
68
  {
@@ -219,6 +221,7 @@ module Rubyvis
219
221
 
220
222
 
221
223
  class Rgb < Color
224
+ attr_reader :r, :b, :g, :a
222
225
  def initialize(r,g,b,a)
223
226
  @r=r
224
227
  @b=b
@@ -226,14 +229,39 @@ module Rubyvis
226
229
  @a=a
227
230
  @opacity=a
228
231
  if @a>0
229
- @color="rgb(#{r},#{g},#{b})"
232
+ @color="rgb(#{r.to_i},#{g.to_i},#{b.to_i})"
230
233
  else
231
234
  @color="none"
232
235
  end
233
236
  end
237
+ def ==(v)
238
+ self.class==v.class and @r==v.r and @b==v.b and @g=v.g and @a=v.a
239
+ end
240
+ def red(r1)
241
+ pv.rgb(r1,g,b,a)
242
+ end
243
+ def green(g1)
244
+ pv.rgb(r,g1,b,a)
245
+ end
246
+ def blue(b1)
247
+ pv.rgb(r,g,b1,a)
248
+ end
249
+ def alpha(a1)
250
+ pv.rgb(r,g,b,a1)
251
+ end
252
+
234
253
  def rgb
235
254
  self
236
255
  end
256
+ def darker(*arguments)
257
+ k,dummy=arguments
258
+ k = 0.7 ** ( arguments.size>0 ? k : 1)
259
+ return pv.rgb(
260
+ [0, (k * self.r).floor].max,
261
+ [0, (k * self.g).floor].max,
262
+ [0, (k * self.b).floor].max,
263
+ self.a)
264
+ end
237
265
  def to_s
238
266
  @color
239
267
  end
@@ -15,7 +15,7 @@ module Rubyvis
15
15
  scale = pv.colors(
16
16
  "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
17
17
  "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf")
18
- scale.domain(*arguments);
18
+ scale.domain(*arguments) if arguments.size>0
19
19
  scale
20
20
  end
21
21
  def self.category19(*arguments)
@@ -24,7 +24,7 @@ module Rubyvis
24
24
  "#8ca252", "#637939", "#e7cb94", "#e7ba52", "#bd9e39",
25
25
  "#8c6d31", "#e7969c", "#d6616b", "#ad494a", "#843c39",
26
26
  "#de9ed6", "#ce6dbd", "#a55194", "#7b4173")
27
- scale.domain(*arguments);
27
+ scale.domain(*arguments) if arguments.size>0
28
28
  scale
29
29
  end
30
30
  def self.category20(*arguments)
@@ -33,7 +33,7 @@ module Rubyvis
33
33
  "#98df8a", "#d62728", "#ff9896", "#9467bd", "#c5b0d5",
34
34
  "#8c564b", "#c49c94", "#e377c2", "#f7b6d2", "#7f7f7f",
35
35
  "#c7c7c7", "#bcbd22", "#dbdb8d", "#17becf", "#9edae5")
36
- scale.domain(*arguments);
36
+ scale.domain(*arguments) if arguments.size>0
37
37
  scale
38
38
  end
39
39
  end
@@ -2,10 +2,11 @@ module Rubyvis
2
2
  module Format
3
3
  class Number
4
4
  def initialize
5
+ @mini = 0
5
6
  @maxi = Infinity # default maximum integer digits
6
- @mins = 0 # mini, including group separators
7
- @minf = 0 # default minimum fraction digits
8
- @maxf = 0 # default maximum fraction digits
7
+ @mins = 0.0 # mini, including group separators
8
+ @minf = 0.0 # default minimum fraction digits
9
+ @maxf = 0.0 # default maximum fraction digits
9
10
  @maxk = 1 # 10^maxf
10
11
  @padi = "0" # default integer pad
11
12
  @padf = "0" # default fraction pad
@@ -15,16 +16,85 @@ module Rubyvis
15
16
  @np = "\u2212" # default negative prefix
16
17
  @ns = "" # default negative suffix
17
18
  end
18
- def fraction_digits(*arguments)
19
- if (arguments.size>0)
20
- min=arguments[0]
21
- max=arguments[1]
22
- @minf = min.to_f
23
- @maxf = (arguments.size > 1) ? max.to_f : @minf
19
+
20
+
21
+ def to_proc
22
+ that=self
23
+ lambda {|*args| args[0] ? that.format(args[0]) : nil }
24
+ end
25
+ #/** @private */
26
+ def format(x)
27
+
28
+ # /* Round the fractional part, and split on decimal separator. */
29
+ x = (x * @maxk).round.quo(@maxk) if (Infinity > @maxf)
30
+ x = (x.to_f-x.to_i==0) ? x.to_i : x.to_f
31
+ s = x.abs.to_s.split(".")
32
+
33
+ #/* Pad, truncate and group the integral part. */
34
+ i = s[0]
35
+
36
+ i = i[i.size-@maxi, i.size] if (i.size > @maxi)
37
+ if (@padg and (i.size < @mini))
38
+ i = Array.new(@mini - i.size + 1).join(@padi) + i.to_s
39
+ end
40
+
41
+ if (i.size > 3)
42
+ i = i.gsub(/\B(?=(?:\d{3})+(?!\d))/, @group)
43
+ end
44
+
45
+ if (@padg=="" and (i.size < @mins))
46
+ i = Array.new(mins - i.size + 1).join(@padi) + i.to_s
47
+ end
48
+
49
+ s[0] = x < 0 ? np + i + ns : i
50
+
51
+ #/* Pad the fractional part. */
52
+ f = s[1].nil? ? "" : s[1]
53
+ if (f.size < @minf)
54
+ s[1] = f + Array.new(@minf - f.size + 1).join(@padf)
55
+ end
56
+ s.join(@decimal)
57
+ end
58
+
59
+ # Sets or gets the minimum and maximum number of fraction digits. The
60
+ # controls the number of decimal digits to display after the decimal
61
+ # separator for the fractional part of the number.
62
+ # If the number of digits is smaller than the minimum, the digits
63
+ # are padded; if the number of digits is
64
+ # larger, the fractional part is rounded, showing only the higher-order
65
+ # digits. The default range is [0, 0].
66
+ #
67
+ # If only one argument is specified to this method, this value is used as
68
+ # both the minimum and maximum number. If no arguments are specified, a
69
+ # two-element array is returned containing the minimum and the maximum.
70
+ #
71
+ # @function
72
+ # @name pv.Format.number.prototype.fractionDigits
73
+ # @param {number} [min] the minimum fraction digits.
74
+ # @param {number} [max] the maximum fraction digits.
75
+ # @returns {pv.Format.number} <tt>this</tt>, or the current fraction digits.
76
+
77
+ def fraction_digits(min=nil,max=nil)
78
+ if (!min.nil?)
79
+ max||=min
80
+ @minf = min
81
+ @maxf = max
24
82
  @maxk = 10**@maxf
25
83
  return self
26
84
  end
27
- [minf, maxf]
85
+ [@minf, @maxf]
86
+ end
87
+
88
+
89
+ def integer_digits(min=nil,max=nil)
90
+ if (!min.nil?)
91
+ max||=min
92
+ @mini=min
93
+ @maxi=max
94
+ @mins=@mini+(@mini/3.0).floor*@group.size
95
+ return self
96
+ end
97
+ [@mini, @maxi]
28
98
  end
29
99
  end
30
100
  end
@@ -69,11 +69,11 @@ module Rubyvis
69
69
  def self.uniq(array, f=nil )
70
70
  self.map(array,f).uniq
71
71
  end
72
- def self.natural_order(a,b)
73
- a<=>b
72
+ def self.natural_order()
73
+ lambda {|a,b| a<=>b}
74
74
  end
75
- def self.reverse_order(a,b)
76
- -(a<=>b)
75
+ def self.reverse_order()
76
+ lambda {|a,b| -(a<=>b)}
77
77
  end
78
78
 
79
79
  def self.search(array, value, f=nil)
@@ -173,7 +173,7 @@ module Rubyvis
173
173
  end
174
174
  def self.median(array,f=nil)
175
175
  return (array.length - 1).quo(2) if (f == pv.index)
176
- array = Rubyvis.map(array, f).sort{|a,b| Rubyvis.natural_order(a,b)}
176
+ array = Rubyvis.map(array, f).sort
177
177
  return array[array.size.quo(2).floor] if (array.length % 2>0)
178
178
  i = array.size.quo(2);
179
179
  return (array[i - 1] + array[i]).quo(2);
@@ -212,4 +212,10 @@ module Rubyvis
212
212
  def self.degrees(radians)
213
213
  ((180.0) / Math::PI)*radians
214
214
  end
215
+ # :section: /data/Objects.js
216
+
217
+ def self.keys(map)
218
+ map.keys
219
+ end
220
+
215
221
  end
@@ -37,6 +37,7 @@ end
37
37
  # called +js_apply+ and +js_call+, respectivly.
38
38
 
39
39
  class Proc
40
+ attr_accessor :order
40
41
  # Apply on javascript is very flexible. Can accept more or less
41
42
  # variables than explicitly defined parameters on lambda, so the method
42
43
  # adds or remove elements according to lambda arity
data/lib/rubyvis/mark.rb CHANGED
@@ -6,7 +6,8 @@ module Rubyvis
6
6
  class Mark
7
7
  @properties={}
8
8
 
9
- def self.property_method(name,_def)
9
+ def self.property_method(name, _def, func=nil)
10
+
10
11
  return if Mark.method_defined? name
11
12
  Mark.send(:define_method, name) do |*arguments|
12
13
  v,dummy = arguments
@@ -18,8 +19,13 @@ module Rubyvis
18
19
  return defs[name]
19
20
  end
20
21
  if arguments.size>0
21
- type=(!_def).to_i<<1 | (v.is_a? Proc).to_i
22
- property_value(name,(type & 1 !=0) ? lambda {|*args| v.js_apply(self, args)} : v)._type=type
22
+ v=v.to_proc if v.respond_to? :to_proc
23
+ type=(!_def).to_i<<1 | (v.is_a? Proc).to_i
24
+
25
+ property_value(name,(type & 1 !=0) ? lambda {|*args|
26
+ x=v.js_apply(self, args)
27
+ (func and x) ? func.call(x) : x
28
+ } : (func and v) ? func.call(v) : v)._type=type
23
29
  #@_properties_types[name]=type
24
30
  return self
25
31
  end
@@ -27,11 +33,15 @@ module Rubyvis
27
33
  if i.nil?
28
34
  raise "No instance for #{self} on #{name}"
29
35
  else
30
- #puts "Instancia para #{name}"
31
- #puts "index:#{self.index}, name:#{name}, val:#{i.send(name)}"
36
+ # puts "index:#{self.index}, name:#{name}, val:#{i.send(name)}"
32
37
  i.send(name)
33
38
  end
34
39
  end
40
+
41
+ camel=name.to_s.gsub(/(_.)/) {|v| v[1,1].upcase}
42
+ if camel!=name
43
+ Mark.send(:alias_method, camel, name)
44
+ end
35
45
  end
36
46
  def property_value(name,v)
37
47
  prop=Property.new({:name=>name, :id=>Rubyvis.id, :value=>v})
@@ -55,17 +65,26 @@ module Rubyvis
55
65
 
56
66
  def self.attr_accessor_dsl(*attr)
57
67
  attr.each do |sym|
58
- @properties[sym]=true
59
- sym_w_sm=sym.to_s.gsub(":","")
60
- self.property_method(sym,false)
61
- define_method(sym.to_s+"=") {|v|
62
- self.send(sym,v)
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)
63
80
  }
64
81
  end
65
82
  end
66
83
 
67
84
  attr_accessor :parent, :root, :index, :child_index, :scene, :proto, :target, :scale
68
85
  attr_reader :_properties
86
+
87
+
69
88
  attr_accessor_dsl :data,:visible, :left, :right, :top, :bottom, :cursor, :title, :reverse, :antialias, :events, :id
70
89
 
71
90
  @scene=nil
@@ -155,13 +174,14 @@ module Rubyvis
155
174
  end
156
175
  return scene;
157
176
  end
158
-
159
-
160
-
161
-
162
-
163
-
164
-
177
+ def sibling
178
+ (self.index==0) ? nil: self.scene[self.index-1]
179
+ end
180
+ def cousin
181
+ par=self.parent
182
+ s= par ? par.sibling : nil
183
+ (s and s.children) ? s.children[self.child_index][self.index] : nil
184
+ end
165
185
  def add(type)
166
186
  parent.add(type).extend(self)
167
187
  end
@@ -218,8 +238,6 @@ module Rubyvis
218
238
  'bottom'
219
239
  end
220
240
  })
221
-
222
-
223
241
  return anchor
224
242
  end
225
243
 
@@ -542,6 +560,10 @@ module Rubyvis
542
560
  end
543
561
  # p ss
544
562
  end
563
+ def event(type,handler)
564
+ #@_handlers[type]=handler
565
+ return self
566
+ end
545
567
  end
546
568
  end
547
569
 
@@ -552,4 +574,5 @@ require 'rubyvis/mark/area'
552
574
  require 'rubyvis/mark/line'
553
575
  require 'rubyvis/mark/rule'
554
576
  require 'rubyvis/mark/label'
555
-
577
+ require 'rubyvis/mark/dot'
578
+ require 'rubyvis/mark/wedge'
@@ -5,7 +5,7 @@ module Rubyvis
5
5
 
6
6
  class Anchor < Mark
7
7
  @properties=Mark.properties.dup
8
- attr_accessor_dsl :name
8
+ attr_accessor_dsl [:name, lambda {|d| d.to_s}]
9
9
 
10
10
  def initialize(target)
11
11
  super()
@@ -5,26 +5,26 @@ module Rubyvis
5
5
  module AreaPrototype
6
6
  def fixed
7
7
  {
8
- # :line_width=> true,
8
+ :line_width=> true,
9
9
  :line_join=> true,
10
- # :stroke_style=> true,
11
- # :fill_style=> true,
10
+ :stroke_style=> true,
11
+ :fill_style=> true,
12
12
  :segmented=> true,
13
13
  :interpolate=> true,
14
14
  :tension=> true
15
15
  }
16
16
  end
17
17
  def area_build_instance(s)
18
-
18
+
19
19
  binds = self.binds
20
-
21
20
  # Handle fixed properties on secondary instances. */
22
- if (self.index)
23
- fixed = @binds.fixed;
21
+ if (self.index!=0)
22
+ fixed = @binds.fixed
24
23
  #/* Determine which properties are fixed. */
25
24
  if (!fixed)
26
25
  binds.fixed=[]
27
26
  fixed = binds.fixed
27
+
28
28
  filter=lambda {|prop|
29
29
  if prop.fixed
30
30
  fixed.push(prop)
@@ -39,8 +39,9 @@ module Rubyvis
39
39
  if (!self.scene[0].segmented)
40
40
  binds.optional = binds.optional.find_all(&filter)
41
41
  end
42
+
42
43
  end
43
-
44
+
44
45
  # p binds.required
45
46
 
46
47
 
@@ -49,13 +50,14 @@ module Rubyvis
49
50
  name=prop.name
50
51
  s[name]=self.scene[0][name]
51
52
  }
53
+
54
+
52
55
  # p binds.fixed
53
56
  #/* Evaluate all properties on the first instance. */
54
57
  else
55
58
  binds.required = binds._required;
56
59
  binds.optional = binds._optional;
57
60
  binds.fixed = nil;
58
-
59
61
  end
60
62
  # pp binds
61
63
  mark_build_instance(s)
@@ -66,12 +68,11 @@ module Rubyvis
66
68
  def area_bind
67
69
  mark_bind()
68
70
  binds = self.binds
69
-
71
+
70
72
  required = binds.required
71
73
  optional = binds.optional
72
74
  optional.size.times {|i|
73
75
  prop = optional[i]
74
-
75
76
  prop.fixed = fixed.include? prop.name
76
77
  if (prop.name == "segmented")
77
78
  required.push(prop)
@@ -94,12 +95,13 @@ module Rubyvis
94
95
  }).tension(lambda {
95
96
  self.scene.target[self.index].tension
96
97
  })
98
+ return anchor
97
99
  end
98
100
  end
99
101
  class Area < Mark
100
102
  include AreaPrototype
101
103
  @properties=Mark.properties.dup
102
- attr_accessor_dsl :width, :height, :line_width, :stroke_style, :fill_style, :segmented, :interpolate, :tension
104
+ attr_accessor_dsl :width, :height, :line_width, [:stroke_style, lambda {|d| pv.color(d)}], [:fill_style, lambda {|d| pv.color(d)}], :segmented, :interpolate, :tension
103
105
  def type
104
106
  'area'
105
107
  end
@@ -110,7 +112,7 @@ module Rubyvis
110
112
  area_build_instance(s)
111
113
  end
112
114
  def self.defaults
113
- Area.new.extend(Mark.defaults).line_width(1.5).fill_style(pv.Colors.category20.by(pv.parent)).interpolate('linear').tension(0.7)
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)
114
116
  end
115
117
  def anchor(name)
116
118
  area_anchor(name)