rubyvis 0.1.7 → 0.2.0

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.
data.tar.gz.sig CHANGED
Binary file
data/History.txt CHANGED
@@ -1,3 +1,15 @@
1
+ === 0.2.0 / 2010-11-02
2
+
3
+ * IMPORTANT: Added 'ruby best practices' API. See README and examples/first_rbp_api.rb to learn how to use
4
+ * Added width and height explicitly on examples pages.
5
+ * Added examples for interpolation on lines and areas
6
+ * Fixed interpolate for lines and areas.
7
+ * New spec for Line and Area spec.
8
+ * Added spec for numeric tick_format
9
+ * Added documentation for Rubyvis::Colors, Rubyvis::Color and Rubyvis::Line
10
+ * Bug fix: interpolate "step-after", "step-before" and "basis" on Area marks doesn't work Spec for Area marks
11
+ * Changed API_VERSION for PROTOVIS_API_VERSION
12
+
1
13
  === 0.1.7 / 2010-10-31
2
14
 
3
15
  * Added image support
data/Manifest.txt CHANGED
@@ -5,6 +5,7 @@ Rakefile
5
5
  examples/antibiotics/antibiotics.rb
6
6
  examples/antibiotics/antibiotics_data.rb
7
7
  examples/area.rb
8
+ examples/area_interpolation.rb
8
9
  examples/bar_column_chart.rb
9
10
  examples/barley/barley.rb
10
11
  examples/barley/barley_data.rb
@@ -12,13 +13,15 @@ examples/crimea/crimea_data.rb
12
13
  examples/crimea/crimea_grouped_bar.rb
13
14
  examples/crimea/crimea_line.rb
14
15
  examples/dot.rb
15
- examples/first.rb
16
+ examples/first_protovis_api.rb
17
+ examples/first_rbp_api.rb
16
18
  examples/fixtures/tipsy.gif
17
19
  examples/grouped_charts.rb
18
20
  examples/image.rb
19
21
  examples/image.svg
20
22
  examples/line.rb
21
23
  examples/line_and_step.rb
24
+ examples/line_interpolation.rb
22
25
  examples/nested_grid.rb
23
26
  examples/pie_and_donut.rb
24
27
  examples/scatterplot.rb
@@ -28,7 +31,6 @@ examples/third.rb
28
31
  lib/rubyvis.rb
29
32
  lib/rubyvis/color/color.rb
30
33
  lib/rubyvis/color/colors.rb
31
- lib/rubyvis/color/ramp.rb
32
34
  lib/rubyvis/format.rb
33
35
  lib/rubyvis/format/date.rb
34
36
  lib/rubyvis/format/number.rb
@@ -46,6 +48,7 @@ lib/rubyvis/mark/label.rb
46
48
  lib/rubyvis/mark/line.rb
47
49
  lib/rubyvis/mark/panel.rb
48
50
  lib/rubyvis/mark/rule.rb
51
+ lib/rubyvis/mark/shorcut_methods.rb
49
52
  lib/rubyvis/mark/wedge.rb
50
53
  lib/rubyvis/nest.rb
51
54
  lib/rubyvis/property.rb
@@ -56,6 +59,7 @@ lib/rubyvis/scale/ordinal.rb
56
59
  lib/rubyvis/scale/quantitative.rb
57
60
  lib/rubyvis/scene/svg_area.rb
58
61
  lib/rubyvis/scene/svg_bar.rb
62
+ lib/rubyvis/scene/svg_curve.rb
59
63
  lib/rubyvis/scene/svg_dot.rb
60
64
  lib/rubyvis/scene/svg_image.rb
61
65
  lib/rubyvis/scene/svg_label.rb
@@ -67,13 +71,16 @@ lib/rubyvis/scene/svg_wedge.rb
67
71
  lib/rubyvis/sceneelement.rb
68
72
  lib/rubyvis/transform.rb
69
73
  spec/anchor_spec.rb
74
+ spec/area_spec.rb
70
75
  spec/bar_spec.rb
71
76
  spec/internal_spec.rb
72
77
  spec/javascript_behaviour_spec.rb
73
78
  spec/label_spec.rb
79
+ spec/line_spec.rb
74
80
  spec/mark_spec.rb
75
81
  spec/nest_spec.rb
76
82
  spec/panel_spec.rb
83
+ spec/ruby_api_spec.rb
77
84
  spec/scale_linear_datetime_spec.rb
78
85
  spec/scale_linear_spec.rb
79
86
  spec/scale_log_spec.rb
data/README.txt CHANGED
@@ -8,7 +8,7 @@ Ruby port of Protovis[http://vis.stanford.edu/protovis/], a great visualization
8
8
 
9
9
  == FEATURES/PROBLEMS:
10
10
 
11
- Implemented: All marks, except transient, image and transition.
11
+ Implemented: All marks, except transient and transitions.
12
12
 
13
13
  Basic protovis examples[http://vis.stanford.edu/protovis/ex/] works exactly like ruby ones with minor sintactic modifications:
14
14
  * Area Charts: Ok
@@ -28,10 +28,6 @@ Complex examples requires more works:
28
28
 
29
29
  I try to maintain, when posible, complete compatibility with Javascript API, including camel case naming of functions. Johnson [http://github.com/jbarnette/johnson] - the lovely Javascript wrapper inside Ruby embrace - is our friend to test implementation of basic object.
30
30
 
31
- Until version 0.1.0, lambdas should always should created explicitly for method you may be temted to call it with a block.
32
-
33
- On a second stage, traditional block calling could be using maintaining backwards compatibily with Javascript API. See TODO section for proposal of new API.
34
-
35
31
  User could use +pv+ freely, cause is defined as a global method which call Rubyvis.
36
32
 
37
33
  == CURRENT PROGRESS
@@ -69,70 +65,45 @@ User could use +pv+ freely, cause is defined as a global method which call Rubyv
69
65
 
70
66
  == SYNOPSIS:
71
67
 
68
+ The primary API, based on Gregory Brown's Ruby Best Practices, uses blocks and name of marks as methods
69
+
72
70
  require 'rubyvis'
73
71
 
74
- vis = Rubyvis::Panel.new.width(150).height(150);
75
- vis.add(pv.Bar).data([1, 1.2, 1.7, 1.5, 0.7, 0.3]).
76
- width(20).
77
- height(lambda {|d| d * 80}).
78
- bottom(0).
79
- left(lambda {self.index * 25});
72
+ vis = Rubyvis::Panel.new do
73
+ width 150
74
+ height 150
75
+ bar do
76
+ data [1, 1.2, 1.7, 1.5, 0.7, 0.3]
77
+ width 20
78
+ height {|d| d * 80}
79
+ bottom(0)
80
+ left {index * 25}
81
+ end
82
+ end
83
+
80
84
  vis.render
81
85
  puts vis.to_svg
82
-
83
- See examples directory for original protovis examples adaptations.
84
-
85
- == TODO
86
86
 
87
- Implement a ruby-like API, like ReportBuilder[http://ruby-statsample.rubyforge.org/reportbuilder/] or Prawn [http://prawn.majesticseacreature.com/docs/]
88
87
 
89
- The examples/area.rb script should like somethink like that
88
+ The library allows you to use chain methods API, like original protovis
90
89
 
91
90
  require 'rubyvis'
92
- vis = Rubyvis::Panel.new {
93
- width w
94
- height h
95
- bottom 20
96
- left 20
97
- right 10
98
- top 5
99
- # Y-axis
100
- rule {
101
- data y.ticks(5)
102
- bottom y
103
- stroke_style {|d| d!=0 ? "#eee" : "#000"}
104
- anchor("left") {
105
- label {
106
- text y.tick_format
107
- }
108
- }
109
- }
110
- # X-axis
111
- rule {
112
- data x.ticks
113
- visible {|d| d!=0}
114
- left x
115
- bottom -5
116
- height -5
117
- label(:anchor=>'bottom') { # shortcut to create a mark inside an anchor
118
- text x.tick_format
119
- }
120
- }
121
-
122
- # The area with top line.
123
- area {
124
- data(data)
125
- bottom 1
126
- left {|d| x.scale(d.x)}
127
- height {|d| y.scale(d.y)}
128
- fill_style "rgb(121,173,210)"
129
- line(:anchor=>"top") {
130
- line_width 3
131
- }
132
- }
133
- }
134
91
 
92
+ vis = Rubyvis::Panel.new.width(150).height(150);
93
+
94
+ vis.add(pv.Bar).
95
+ data([1, 1.2, 1.7, 1.5, 0.7, 0.3]).
96
+ width(20).
97
+ height(lambda {|d| d * 80}).
98
+ bottom(0).
99
+ left(lambda {self.index * 25});
100
+
101
+ vis.render
135
102
  puts vis.to_svg
103
+
104
+
105
+ See examples directory for original protovis examples adaptations and others graphics
106
+
136
107
 
137
108
 
138
109
  == REQUIREMENTS:
@@ -0,0 +1,56 @@
1
+ # = Area Interpolation
2
+ # This example show the 5 types of interpolation available for areas.
3
+ $:.unshift(File.dirname(__FILE__)+"/../lib")
4
+ require 'rubyvis'
5
+
6
+ data = pv.range(0, 10, 0.5).map {|x|
7
+ OpenStruct.new({:x=> x, :y=> Math.sin(x) + 2+rand()*0.3})
8
+ }
9
+
10
+ p_w=200
11
+ p_h=150
12
+ #p data
13
+ w = 20+p_w*2
14
+ h = 20+p_h*3
15
+
16
+ x = pv.Scale.linear(data, lambda {|d| d.x}).range(0, p_w-30)
17
+ y = pv.Scale.linear(data, lambda {|d| d.y}).range(0, p_h-20);
18
+ interpolations=["linear","step-before","step-after", "basis", "cardinal"]
19
+
20
+ vis = Rubyvis::Panel.new do |pan|
21
+ pan.width w
22
+ pan.height h
23
+ pan.bottom 20
24
+ pan.left 20
25
+ pan.right 10
26
+ pan.top 5
27
+
28
+ interpolations.each_with_index do |inter,i|
29
+ n=i%2
30
+ m=(i/2).floor
31
+ pan.panel do
32
+ left(n*(p_w+10))
33
+ top(m*(p_h+10))
34
+ width p_w
35
+ height p_h
36
+ label(:anchor=>'top') do
37
+ text(inter)
38
+ end
39
+ # uses 'a' as reference inside block
40
+ # to use data method with data variable
41
+ area do |a|
42
+ a.data data
43
+ a.left {|d| x.scale(d.x)}
44
+ a.height {|d| y.scale(d.y)}
45
+ a.bottom 1
46
+ a.interpolate inter
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+
53
+ vis.render();
54
+
55
+
56
+ puts vis.to_svg
@@ -1,5 +1,5 @@
1
1
  # = First example
2
- # This is the ruby version of "Getting Started" example of Protovis introduction.
2
+ # This is the protovis API version of "Getting Started" example of Protovis introduction.
3
3
  # On this example we show you how can you build a bar chart using panel and bar marks.
4
4
  # A mark represents a set of graphical elements that share data and visual encodings. Although marks are simple by themselves, you can combine them in interesting ways to make rich, interactive visualizations
5
5
  $:.unshift(File.dirname(__FILE__)+"/../lib")
@@ -0,0 +1,21 @@
1
+ # = First example
2
+ # This is the RBP API version of "Getting Started" example of Protovis introduction.
3
+ # On this example we show you how can you build a bar chart using panel and bar marks.
4
+ # A mark represents a set of graphical elements that share data and visual encodings. Although marks are simple by themselves, you can combine them in interesting ways to make rich, interactive visualizations
5
+ $:.unshift(File.dirname(__FILE__)+"/../lib")
6
+ require 'rubyvis'
7
+
8
+ vis = Rubyvis::Panel.new do
9
+ width 150
10
+ height 150
11
+ bar do
12
+ data [1, 1.2, 1.7, 1.5, 0.7, 0.3]
13
+ width 20
14
+ height {|d| d * 80}
15
+ bottom(0)
16
+ left {index * 25}
17
+ end
18
+ end
19
+
20
+ vis.render
21
+ puts vis.to_svg
data/examples/image.rb CHANGED
@@ -16,5 +16,4 @@ dot=vis.add(pv.Image)
16
16
  .url(img_url)
17
17
 
18
18
  vis.render()
19
- #puts vis.children_inspect
20
19
  puts vis.to_svg
data/examples/line.rb CHANGED
@@ -25,7 +25,6 @@ vis = pv.Panel.new()
25
25
  .right(10)
26
26
  .top(5)
27
27
 
28
- #/* The area with top line. */
29
28
  vis.add(pv.Line).
30
29
  data(data).
31
30
  line_width(5).
@@ -0,0 +1,55 @@
1
+ # = Line Interpolation
2
+ # This example show the 7 types of interpolation available for lines.
3
+ $:.unshift(File.dirname(__FILE__)+"/../lib")
4
+ require 'rubyvis'
5
+
6
+ data = pv.range(0, 10, 1).map {|x|
7
+ OpenStruct.new({:x=> x, :y=> Math.sin(x) + 2+rand()*0.2})
8
+ }
9
+
10
+ p_w=200
11
+ p_h=150
12
+ #p data
13
+ w = 20+p_w*2
14
+ h = 20+p_h*4
15
+
16
+ x = pv.Scale.linear(data, lambda {|d| d.x}).range(0, p_w-30)
17
+
18
+
19
+ y = pv.Scale.linear(data, lambda {|d| d.y}).range(0, p_h-20);
20
+
21
+ interpolations=["linear","step-before","step-after","polar","polar-reverse", "basis", "cardinal"]
22
+
23
+ #/* The root panel. */
24
+ vis = pv.Panel.new()
25
+ .width(w)
26
+ .height(h)
27
+ .bottom(20)
28
+ .left(20)
29
+ .right(10)
30
+ .top(5)
31
+
32
+ interpolations.each_with_index do |inter,i|
33
+ n=i%2
34
+ m=(i/2).floor
35
+ panel=vis.add(Rubyvis::Panel).
36
+ left(n*(p_w+10)).
37
+ top(m*(p_h+10)).
38
+ width(p_w).
39
+ height(p_h)
40
+ panel.anchor('top').add(Rubyvis::Label).text(inter)
41
+ panel.add(Rubyvis::Line).data(data).
42
+ line_width(2).
43
+ left(lambda {|d| x.scale(d.x)}).
44
+ bottom(lambda {|d| y.scale(d.y)}).
45
+ interpolate(inter)
46
+
47
+ end
48
+
49
+
50
+
51
+
52
+ vis.render();
53
+
54
+
55
+ puts vis.to_svg
data/lib/rubyvis.rb CHANGED
@@ -22,12 +22,13 @@ require 'rubyvis/scene/svg_scene'
22
22
  require 'rubyvis/transform'
23
23
 
24
24
 
25
+
25
26
  module Rubyvis
26
27
  @document=nil
27
28
  # Rubyvis version
28
- VERSION = '0.1.7'
29
+ VERSION = '0.2.0'
29
30
  # Protovis API on which current Rubyvis is based
30
- API_VERSION='3.3'
31
+ PROTOVIS_API_VERSION='3.3'
31
32
  # You actually can do it! http://snipplr.com/view/2137/uses-for-infinity-in-ruby/
32
33
  Infinity=1.0 / 0
33
34
  #
@@ -89,4 +90,3 @@ end
89
90
  def pv
90
91
  Rubyvis
91
92
  end
92
-
@@ -1,5 +1,29 @@
1
1
  module Rubyvis
2
-
2
+ # Returns the Rubyvis::Color for the specified color format string. Colors
3
+ # may have an associated opacity, or alpha channel.
4
+ # Color formats are specified by CSS Color Modular Level 3,
5
+ # using either in RGB or HSL color space. For example:<ul>
6
+ #
7
+ # <li>#f00 // #rgb
8
+ # <li>#ff0000 // #rrggbb
9
+ # <li>rgb(255, 0, 0)
10
+ # <li>rgb(100%, 0%, 0%)
11
+ # <li>hsl(0, 100%, 50%)
12
+ # <li>rgba(0, 0, 255, 0.5)
13
+ # <li>hsla(120, 100%, 50%, 1)
14
+ # </ul>
15
+ #
16
+ # The SVG 1.0 color keywords names are also supported, such as "aliceblue"
17
+ # and "yellowgreen". The "transparent" keyword is supported for fully-
18
+ # transparent black.
19
+ #
20
+ # <p>If the <tt>format</tt> argument is already an instance of <tt>Color</tt>,
21
+ # the argument is returned with no further processing.
22
+ #
23
+ # * see <a href="http://www.w3.org/TR/SVG/types.html#ColorKeywords">SVG color
24
+ # keywords</a>
25
+ # * see <a href="http://www.w3.org/TR/css3-color/">CSS3 color module</a>
26
+ #/
3
27
  def self.color(format)
4
28
  return format.rgb if format.respond_to? :rgb
5
29
  if (format =~/([a-z]+)\((.*)\)/)
@@ -51,22 +75,53 @@ module Rubyvis
51
75
  # Otherwise, pass-through unsupported colors. */
52
76
  return Rubyvis::Color.new(format, 1);
53
77
  end
54
-
78
+ # Constructs a new RGB color with the specified channel values.
55
79
  def self.rgb(r,g,b,a=1)
56
80
  Rubyvis::Color::Rgb.new(r,g,b,a)
57
81
  end
58
-
82
+ def self.hsl(h,s,l,a=1)
83
+ Rubyvis::Color::Hsl.new(h,s,l,a)
84
+ end
85
+ # Represents an abstract (possibly translucent) color. The color is
86
+ # divided into two parts: the <tt>color</tt> attribute, an opaque color format
87
+ # string, and the <tt>opacity</tt> attribute, a float in [0, 1]. The color
88
+ # space is dependent on the implementing class; all colors support the
89
+ # Color.rgb() method to convert to RGB color space for interpolation.
59
90
  class Color
60
- attr_reader :color, :opacity
91
+ # An opaque color format string, such as "#f00".
92
+ attr_reader :color
93
+ # The opacity, a float in [0, 1].
94
+ attr_reader :opacity
95
+
96
+ # Constructs a color with the specified color format string and opacity. This
97
+ # constructor should not be invoked directly; use Rubyvis.color instead.
61
98
  def initialize(color,opacity)
62
99
  @color=color
63
100
  @opacity=opacity
64
101
  end
65
- def darker(*args)
66
- self.rgb.darker(*args)
102
+ # Returns a new color that is a brighter version of this color. The behavior of
103
+ # this method may vary slightly depending on the underlying color space.
104
+ # Although brighter and darker are inverse operations, the results of a series
105
+ # of invocations of these two methods might be inconsistent because of rounding
106
+ # errors.
107
+ # * @param [k] {number} an optional scale factor; defaults to 1.
108
+ def brighter(k)
109
+ self.rgb.lighter(k)
67
110
  end
68
-
69
- def self.names
111
+
112
+ # Returns a new color that is a brighter version of this color. The behavior of
113
+ # this method may vary slightly depending on the underlying color space.
114
+ # Although brighter and darker are inverse operations, the results of a series
115
+ # of invocations of these two methods might be inconsistent because of rounding
116
+ # errors.
117
+ #
118
+ # * @param [k] {number} an optional scale factor; defaults to 1.
119
+ def darker(k)
120
+ self.rgb.darker(k)
121
+ end
122
+
123
+ # Association between names and colors
124
+ def self.names # :nodoc:
70
125
  {
71
126
  :aliceblue=>"#f0f8ff",
72
127
  :antiquewhite=>"#faebd7",
@@ -220,10 +275,17 @@ module Rubyvis
220
275
  def self.transparent
221
276
  Rubyvis.rgb(0,0,0,0)
222
277
  end
223
-
224
-
278
+ # Represents a color in RGB space.
225
279
  class Rgb < Color
226
- attr_reader :r, :b, :g, :a
280
+ # The red channel, an integer in [0, 255].
281
+ attr_reader :r
282
+ # The blue channel, an integer in [0, 255].
283
+ attr_reader :b
284
+ # The green channel, an integer in [0, 255].
285
+ attr_reader :g
286
+ # The alpha channel, a float in [0, 1].
287
+ attr_reader :a
288
+ # Constructs a new RGB color with the specified channel values.
227
289
  def initialize(r,g,b,a)
228
290
  @r=r
229
291
  @b=b
@@ -239,34 +301,129 @@ module Rubyvis
239
301
  def ==(v)
240
302
  self.class==v.class and @r==v.r and @b==v.b and @g=v.g and @a=v.a
241
303
  end
304
+
305
+ # Constructs a new RGB color with the same green, blue and alpha channels
306
+ # as this color, with the specified red channel.
242
307
  def red(r1)
243
308
  Rubyvis.rgb(r1,g,b,a)
244
309
  end
310
+ # Constructs a new RGB color with the same red, blue and alpha channels
311
+ # as this color, with the specified green channel.
245
312
  def green(g1)
246
313
  Rubyvis.rgb(r,g1,b,a)
247
314
  end
315
+ # Constructs a new RGB color with the same red, green and alpha channels
316
+ # as this color, with the specified blue channel.
248
317
  def blue(b1)
249
318
  Rubyvis.rgb(r,g,b1,a)
250
319
  end
320
+ # Constructs a new RGB color with the same red, green and blue channels as this
321
+ # color, with the specified alpha channel.
322
+
251
323
  def alpha(a1)
252
324
  Rubyvis.rgb(r,g,b,a1)
253
325
  end
254
-
326
+ # Returns the RGB color equivalent to this color. This method is abstract and must be implemented by subclasses.
255
327
  def rgb
256
328
  self
257
329
  end
258
- def darker(*arguments)
259
- k,dummy=arguments
260
- k = 0.7 ** ( arguments.size>0 ? k : 1)
261
- return Rubyvis.rgb(
262
- [0, (k * self.r).floor].max,
263
- [0, (k * self.g).floor].max,
264
- [0, (k * self.b).floor].max,
265
- self.a)
330
+ # Returns a new color that is a brighter version of this color. This method
331
+ # applies an arbitrary scale factor to each of the three RGB components of this
332
+ # color to create a brighter version of this color. Although brighter and
333
+ # darker are inverse operations, the results of a series of invocations of
334
+ # these two methods might be inconsistent because of rounding errors.
335
+ def lighter(k=1)
336
+ k = 0.7**k
337
+ i = 30
338
+ r=self.r
339
+ g=self.g
340
+ b=self.b
341
+ return Rubyvis.rgb(i, i, i, a) if (!r and !g and !b)
342
+ r = i if (r and (r < i))
343
+ g = i if (g and (g < i))
344
+ b = i if (b and (b < i))
345
+ Rubyvis.rgb(
346
+ [255, (r/k).floor].min,
347
+ [255, (g/k).floor].min,
348
+ [255, (b/k).floor].min,
349
+ a)
350
+ end
351
+ # Returns a new color that is a darker version of this color. This method
352
+ # applies an arbitrary scale factor to each of the three RGB components of this
353
+ # color to create a darker version of this color. Although brighter and darker
354
+ # are inverse operations, the results of a series of invocations of these two
355
+ # methods might be inconsistent because of rounding errors.
356
+ def darker(k=1)
357
+ k = 0.7 ** k
358
+ Rubyvis.rgb(
359
+ [0, (k * r).floor].max,
360
+ [0, (k * g).floor].max,
361
+ [0, (k * b).floor].max,
362
+ a)
266
363
  end
364
+
267
365
  def to_s
268
366
  @color
269
367
  end
270
368
  end
369
+ # Represents a color in HSL space.
370
+ class Hsl < Color
371
+
372
+ # The hue, an integer in [0, 360].
373
+ attr_accessor :h
374
+ # The saturation, a float in [0, 1].
375
+ attr_accessor :s
376
+ # The lightness, a float in [0, 1].
377
+ attr_accessor :l
378
+ # The opacity, a float in [0, 1].
379
+ attr_accessor :a
380
+
381
+ def initialize(h,s,l,a)
382
+ c="hsl(#{h},#{s * 100}%,#{l * 100}%)"
383
+ super(c,a)
384
+ @h=h
385
+ @s=s
386
+ @l=l
387
+ @a=a
388
+ end
389
+
390
+ # Returns the RGB color equivalent to this HSL color.
391
+ def rgb
392
+ h = self.h
393
+ s = self.s
394
+ l = self.l
395
+
396
+ # Some simple corrections for h, s and l. */
397
+ h = h % 360
398
+ h += 360 if (h < 0)
399
+ s = [0, [s, 1].min].max
400
+ l = [0, [l, 1].min].max
401
+
402
+ # From FvD 13.37, CSS Color Module Level 3
403
+ m2 = (l <= 0.5) ? (l * (1 + s)) : (l + s - l * s)
404
+ m1 = 2 * l - m2
405
+ v=lambda {|h1|
406
+ if (h1 > 360)
407
+ h1 -= 360;
408
+ elsif (h1 < 0)
409
+ h1 += 360
410
+ end
411
+
412
+
413
+ return m1 + (m2 - m1) * h1 / 60 if (h1 < 60)
414
+ return m2 if (h1 < 180)
415
+ return m1 + (m2 - m1) * (240 - h1) / 60 if (h1 < 240)
416
+ return m1
417
+ }
418
+ vv=lambda {|h1|
419
+ (v(h1) * 255).round
420
+ }
421
+
422
+ Rubyvis.rgb(vv.call(h + 120), vv.call(h), vv.call(h - 120), a)
423
+ end
424
+ end
425
+
426
+
427
+
271
428
  end
272
429
  end