rubyvis 0.1.7 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/History.txt +12 -0
- data/Manifest.txt +9 -2
- data/README.txt +30 -59
- data/examples/area_interpolation.rb +56 -0
- data/examples/{first.rb → first_protovis_api.rb} +1 -1
- data/examples/first_rbp_api.rb +21 -0
- data/examples/image.rb +0 -1
- data/examples/line.rb +0 -1
- data/examples/line_interpolation.rb +55 -0
- data/lib/rubyvis.rb +3 -3
- data/lib/rubyvis/color/color.rb +177 -20
- data/lib/rubyvis/color/colors.rb +98 -0
- data/lib/rubyvis/layout/stack.rb +271 -196
- data/lib/rubyvis/mark.rb +26 -9
- data/lib/rubyvis/mark/anchor.rb +2 -1
- data/lib/rubyvis/mark/area.rb +99 -1
- data/lib/rubyvis/mark/bar.rb +2 -2
- data/lib/rubyvis/mark/dot.rb +2 -2
- data/lib/rubyvis/mark/line.rb +116 -4
- data/lib/rubyvis/mark/panel.rb +2 -1
- data/lib/rubyvis/mark/shorcut_methods.rb +58 -0
- data/lib/rubyvis/scale/quantitative.rb +5 -3
- data/lib/rubyvis/scene/svg_area.rb +127 -121
- data/lib/rubyvis/scene/svg_curve.rb +328 -0
- data/lib/rubyvis/scene/svg_line.rb +20 -18
- data/lib/rubyvis/scene/svg_scene.rb +5 -4
- data/lib/rubyvis/sceneelement.rb +4 -1
- data/spec/area_spec.rb +48 -0
- data/spec/bar_spec.rb +1 -1
- data/spec/line_spec.rb +63 -0
- data/spec/panel_spec.rb +2 -4
- data/spec/ruby_api_spec.rb +47 -0
- data/spec/scale_linear_spec.rb +14 -1
- data/spec/spec_helper.rb +35 -0
- data/web/Rakefile +1 -1
- data/web/build_site.rb +17 -1
- data/web/examples.haml +2 -2
- data/web/index.haml +13 -7
- metadata +16 -6
- metadata.gz.sig +0 -0
- data/lib/rubyvis/color/ramp.rb +0 -1
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/
|
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
|
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
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
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
|
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
data/examples/line.rb
CHANGED
@@ -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.
|
29
|
+
VERSION = '0.2.0'
|
29
30
|
# Protovis API on which current Rubyvis is based
|
30
|
-
|
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
|
-
|
data/lib/rubyvis/color/color.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
66
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
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
|