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 +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
|