rubyvis 0.3.4 → 0.3.5
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 +8 -0
- data/Manifest.txt +7 -0
- data/README.txt +23 -6
- data/examples/2_medium/horizon.rb +58 -0
- data/examples/5_pv_hierarchies/dendogram.rb +2 -2
- data/examples/6_pv_networks/arc.rb +32 -0
- data/examples/6_pv_networks/miserables_data.rb +348 -0
- data/lib/rubyvis.rb +1 -1
- data/lib/rubyvis/color/color.rb +32 -34
- data/lib/rubyvis/format/number.rb +1 -1
- data/lib/rubyvis/layout.rb +3 -2
- data/lib/rubyvis/layout/arc.rb +188 -0
- data/lib/rubyvis/layout/horizon.rb +153 -0
- data/lib/rubyvis/mark/shorcut_methods.rb +29 -1
- data/lib/rubyvis/scene/svg_panel.rb +6 -4
- data/lib/rubyvis/sceneelement.rb +1 -1
- data/spec/color_spec.rb +79 -0
- data/spec/layout_horizon_spec.rb +78 -0
- data/spec/layout_stack_spec.rb +3 -5
- data/web/index.haml +20 -12
- metadata +11 -4
- metadata.gz.sig +0 -0
data/lib/rubyvis.rb
CHANGED
@@ -30,7 +30,7 @@ require 'rubyvis/mark/shorcut_methods'
|
|
30
30
|
module Rubyvis
|
31
31
|
@document=nil
|
32
32
|
# Rubyvis version
|
33
|
-
VERSION = '0.3.
|
33
|
+
VERSION = '0.3.5'
|
34
34
|
# Protovis API on which current Rubyvis is based
|
35
35
|
PROTOVIS_API_VERSION='3.3'
|
36
36
|
# You actually can do it! http://snipplr.com/view/2137/uses-for-infinity-in-ruby/
|
data/lib/rubyvis/color/color.rb
CHANGED
@@ -27,24 +27,24 @@ module Rubyvis
|
|
27
27
|
def self.color(format)
|
28
28
|
return format.rgb if format.respond_to? :rgb
|
29
29
|
if (format =~/([a-z]+)\((.*)\)/)
|
30
|
-
|
30
|
+
color_type,color_data=$1,$2
|
31
|
+
m2 = color_data.split(",")
|
31
32
|
a = 1
|
32
|
-
if ['hsla','rgba'].include?
|
33
|
+
if ['hsla','rgba'].include? color_type
|
33
34
|
a = m2[3].to_f
|
34
35
|
return Color.transparent if (a==0)
|
35
36
|
end
|
36
37
|
|
37
|
-
if ['hsla','hsl'].include?
|
38
|
-
h=m2[0].
|
39
|
-
s=m2[
|
40
|
-
l=m2[
|
41
|
-
return Color::Hsl.new(h,s,l,a).rgb
|
38
|
+
if ['hsla','hsl'].include? color_type
|
39
|
+
h=m2[0].to_i
|
40
|
+
s=m2[1].to_f / 100
|
41
|
+
l=m2[2].to_f / 100
|
42
|
+
return Color::Hsl.new(h,s,l,a).rgb
|
42
43
|
end
|
43
|
-
|
44
|
-
if ['rgba','rgb'].include?
|
44
|
+
|
45
|
+
if ['rgba','rgb'].include? color_type
|
45
46
|
parse=lambda {|c|
|
46
|
-
|
47
|
-
return (c[c.size-1]=='%') ? (f*2.55).round : f
|
47
|
+
(c[c.size-1,1]=='%') ? (c.to_f*2.55).round : c.to_i
|
48
48
|
}
|
49
49
|
r=parse.call(m2[0])
|
50
50
|
g=parse.call(m2[1])
|
@@ -69,7 +69,7 @@ module Rubyvis
|
|
69
69
|
g = format[3,2]
|
70
70
|
b = format[5,2]
|
71
71
|
end
|
72
|
-
return Rubyvis.rgb(r.to_i(16), g.to_i(16), b.to_i(16), 1)
|
72
|
+
return Rubyvis.rgb(r.to_i(16), g.to_i(16), b.to_i(16), 1)
|
73
73
|
end
|
74
74
|
|
75
75
|
# Otherwise, pass-through unsupported colors. */
|
@@ -292,14 +292,10 @@ module Rubyvis
|
|
292
292
|
@g=g
|
293
293
|
@a=a
|
294
294
|
@opacity=a
|
295
|
-
|
296
|
-
@color="rgb(#{r.to_i},#{g.to_i},#{b.to_i})"
|
297
|
-
else
|
298
|
-
@color="none"
|
299
|
-
end
|
295
|
+
@color= @a > 0 ? "rgb(#{r.to_i},#{g.to_i},#{b.to_i})" : "none"
|
300
296
|
end
|
301
297
|
def ==(v)
|
302
|
-
self.class==v.class and @r==v.r and @b==v.b and @g
|
298
|
+
self.class==v.class and @r==v.r and @b==v.b and @g==v.g and @a==v.a
|
303
299
|
end
|
304
300
|
|
305
301
|
# Constructs a new RGB color with the same green, blue and alpha channels
|
@@ -333,20 +329,20 @@ module Rubyvis
|
|
333
329
|
# darker are inverse operations, the results of a series of invocations of
|
334
330
|
# these two methods might be inconsistent because of rounding errors.
|
335
331
|
def lighter(k=1)
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
332
|
+
k = 0.7**k
|
333
|
+
i = 30
|
334
|
+
r=self.r
|
335
|
+
g=self.g
|
336
|
+
b=self.b
|
337
|
+
return Rubyvis.rgb(i, i, i, a) if (!r and !g and !b)
|
338
|
+
r = i if (r and (r < i))
|
339
|
+
g = i if (g and (g < i))
|
340
|
+
b = i if (b and (b < i))
|
341
|
+
Rubyvis.rgb(
|
342
|
+
[255, (r/k).floor].min,
|
343
|
+
[255, (g/k).floor].min,
|
344
|
+
[255, (b/k).floor].min,
|
345
|
+
a)
|
350
346
|
end
|
351
347
|
# Returns a new color that is a darker version of this color. This method
|
352
348
|
# applies an arbitrary scale factor to each of the three RGB components of this
|
@@ -368,7 +364,6 @@ module Rubyvis
|
|
368
364
|
end
|
369
365
|
# Represents a color in HSL space.
|
370
366
|
class Hsl < Color
|
371
|
-
|
372
367
|
# The hue, an integer in [0, 360].
|
373
368
|
attr_accessor :h
|
374
369
|
# The saturation, a float in [0, 1].
|
@@ -386,6 +381,9 @@ module Rubyvis
|
|
386
381
|
@l=l
|
387
382
|
@a=a
|
388
383
|
end
|
384
|
+
def ==(v)
|
385
|
+
self.class==v.class and @h==v.h and @s==v.s and @l==v.l and @a==v.a
|
386
|
+
end
|
389
387
|
|
390
388
|
# Returns the RGB color equivalent to this HSL color.
|
391
389
|
def rgb
|
@@ -416,7 +414,7 @@ module Rubyvis
|
|
416
414
|
return m1
|
417
415
|
}
|
418
416
|
vv=lambda {|h1|
|
419
|
-
(v(h1) * 255).round
|
417
|
+
(v.call(h1) * 255).round
|
420
418
|
}
|
421
419
|
|
422
420
|
Rubyvis.rgb(vv.call(h + 120), vv.call(h), vv.call(h - 120), a)
|
data/lib/rubyvis/layout.rb
CHANGED
@@ -23,7 +23,7 @@ module Rubyvis
|
|
23
23
|
end
|
24
24
|
@properties[name]=true
|
25
25
|
self.property_method(name,false, func, self)
|
26
|
-
define_method(name.to_s+"=") {|v|
|
26
|
+
define_method(name.to_s + "=") {|v|
|
27
27
|
self.send(name,v)
|
28
28
|
}
|
29
29
|
end
|
@@ -32,6 +32,7 @@ module Rubyvis
|
|
32
32
|
end
|
33
33
|
|
34
34
|
require 'rubyvis/layout/stack'
|
35
|
+
require 'rubyvis/layout/horizon'
|
35
36
|
require 'rubyvis/layout/grid'
|
36
37
|
require 'rubyvis/layout/network'
|
37
38
|
require 'rubyvis/layout/hierarchy'
|
@@ -41,5 +42,5 @@ require 'rubyvis/layout/partition'
|
|
41
42
|
require 'rubyvis/layout/cluster'
|
42
43
|
require 'rubyvis/layout/indent'
|
43
44
|
require 'rubyvis/layout/pack'
|
44
|
-
|
45
|
+
require 'rubyvis/layout/arc'
|
45
46
|
|
@@ -0,0 +1,188 @@
|
|
1
|
+
module Rubyvis
|
2
|
+
class Layout
|
3
|
+
# Alias for Rubyvis::Layout::Arc
|
4
|
+
def self.Arc
|
5
|
+
Rubyvis::Layout::Arc
|
6
|
+
end
|
7
|
+
|
8
|
+
# @class Implements a layout for arc diagrams. An arc diagram is a network
|
9
|
+
# visualization with a one-dimensional layout of nodes, using circular arcs to
|
10
|
+
# render links between nodes. For undirected networks, arcs are rendering on a
|
11
|
+
# single side; this makes arc diagrams useful as annotations to other
|
12
|
+
# two-dimensional network layouts, such as rollup, matrix or table layouts. For
|
13
|
+
# directed networks, links in opposite directions can be rendered on opposite
|
14
|
+
# sides using <tt>directed(true)</tt>.
|
15
|
+
#
|
16
|
+
# <p>Arc layouts are particularly sensitive to node ordering; for best results,
|
17
|
+
# order the nodes such that related nodes are close to each other. A poor
|
18
|
+
# (e.g., random) order may result in large arcs with crossovers that impede
|
19
|
+
# visual processing. A future improvement to this layout may include automatic
|
20
|
+
# reordering using, e.g., spectral graph layout or simulated annealing.
|
21
|
+
#
|
22
|
+
# <p>This visualization technique is related to that developed by
|
23
|
+
# M. Wattenberg, <a
|
24
|
+
# href="http://www.research.ibm.com/visual/papers/arc-diagrams.pdf">"Arc
|
25
|
+
# Diagrams: Visualizing Structure in Strings"</a> in <i>IEEE InfoVis</i>, 2002.
|
26
|
+
# However, this implementation is limited to simple node-link networks, as
|
27
|
+
# opposed to structures with hierarchical self-similarity (such as strings).
|
28
|
+
#
|
29
|
+
# <p>As with other network layouts, three mark prototypes are provided:<ul>
|
30
|
+
#
|
31
|
+
# <li><tt>node</tt> - for rendering nodes; typically a {@link pv.Dot}.
|
32
|
+
# <li><tt>link</tt> - for rendering links; typically a {@link pv.Line}.
|
33
|
+
# <li><tt>label</tt> - for rendering node labels; typically a {@link pv.Label}.
|
34
|
+
#
|
35
|
+
# </ul>For more details on how this layout is structured and can be customized,
|
36
|
+
# see {@link pv.Layout.Network}.
|
37
|
+
|
38
|
+
class Arc < Network
|
39
|
+
@properties=Network.properties.dup
|
40
|
+
attr_accessor :_interpolate, :_directed, :_reverse
|
41
|
+
def initialize
|
42
|
+
super
|
43
|
+
@_interpolate=nil # cached interpolate
|
44
|
+
@_directed=nil # cached directed
|
45
|
+
@_reverse=nil # cached reverse
|
46
|
+
@_sort=nil
|
47
|
+
that=self
|
48
|
+
@link.data(lambda {|_p|
|
49
|
+
s=_p.source_node;t=_p.target_node
|
50
|
+
that._reverse != (that._directed or (s.breadth < t.breadth)) ? [s, t] : [t, s]
|
51
|
+
}).interpolate(lambda{ that._interpolate})
|
52
|
+
end
|
53
|
+
|
54
|
+
def build_implied(s)
|
55
|
+
return true if network_build_implied(s)
|
56
|
+
# Cached
|
57
|
+
|
58
|
+
nodes = s.nodes
|
59
|
+
orient = s.orient
|
60
|
+
sort = @_sort
|
61
|
+
index = Rubyvis.range(nodes.size)
|
62
|
+
w = s.width
|
63
|
+
h = s.height
|
64
|
+
r = [w,h].min / 2.0
|
65
|
+
# /* Sort the nodes. */
|
66
|
+
if (sort)
|
67
|
+
index.sort! {|a,b| sort.call(nodes[a],nodes[b])}
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
#/** @private Returns the mid-angle, given the breadth. */
|
73
|
+
mid_angle=lambda do |b|
|
74
|
+
case orient
|
75
|
+
when "top"
|
76
|
+
-Math::PI / 2.0
|
77
|
+
when "bottom"
|
78
|
+
Math::PI / 2.0
|
79
|
+
when "left"
|
80
|
+
Math::PI
|
81
|
+
when "right"
|
82
|
+
0
|
83
|
+
when "radial"
|
84
|
+
(b - 0.25) * 2.0 * Math::PI
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# /** @private Returns the x-position, given the breadth. */
|
89
|
+
x= lambda do |b|
|
90
|
+
case orient
|
91
|
+
when "top"
|
92
|
+
b * w
|
93
|
+
when "bottom"
|
94
|
+
b * w
|
95
|
+
when "left"
|
96
|
+
0;
|
97
|
+
when "right"
|
98
|
+
w;
|
99
|
+
when "radial"
|
100
|
+
w / 2.0 + r * Math.cos(mid_angle.call(b))
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# /** @private Returns the y-position, given the breadth. */
|
105
|
+
y=lambda do |b|
|
106
|
+
case orient
|
107
|
+
when "top"
|
108
|
+
0;
|
109
|
+
when "bottom"
|
110
|
+
h;
|
111
|
+
when "left"
|
112
|
+
b* h
|
113
|
+
when "right"
|
114
|
+
b * h
|
115
|
+
when "radial"
|
116
|
+
h / 2.0 + r * Math.sin(mid_angle.call(b))
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
#/* Populate the x, y and mid-angle attributes. */
|
121
|
+
nodes.each_with_index do |nod, i|
|
122
|
+
n=nodes[index[i]]
|
123
|
+
n.breadth=(i+0.5) / nodes.size
|
124
|
+
b=n.breadth
|
125
|
+
n.x=x[b]
|
126
|
+
n.y=y[b]
|
127
|
+
n.mid_angle=mid_angle[b]
|
128
|
+
end
|
129
|
+
|
130
|
+
@_directed = s.directed
|
131
|
+
@_interpolate = s.orient == "radial" ? "linear" : "polar"
|
132
|
+
@_reverse = s.orient == "right" or s.orient == "top"
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# :attr: orient
|
138
|
+
# The orientation. The default orientation is "left", which means that nodes
|
139
|
+
# will be positioned from left-to-right in the order they are specified in the
|
140
|
+
# <tt>nodes</tt> property. The following orientations are supported:<ul>
|
141
|
+
#
|
142
|
+
# <li>left - left-to-right.
|
143
|
+
# <li>right - right-to-left.
|
144
|
+
# <li>top - top-to-bottom.
|
145
|
+
# <li>bottom - bottom-to-top.
|
146
|
+
# <li>radial - radially, starting at 12 o'clock and proceeding clockwise.</ul>
|
147
|
+
|
148
|
+
##
|
149
|
+
# :attr: directed
|
150
|
+
# Whether this arc digram is directed (bidirectional); only applies to
|
151
|
+
# non-radial orientations. By default, arc digrams are undirected, such that
|
152
|
+
# all arcs appear on one side. If the arc digram is directed, then forward
|
153
|
+
# links are drawn on the conventional side (the same as as undirected
|
154
|
+
# links--right, left, bottom and top for left, right, top and bottom,
|
155
|
+
# respectively), while reverse links are drawn on the opposite side.
|
156
|
+
|
157
|
+
attr_accessor_dsl :orient, :directed
|
158
|
+
|
159
|
+
def self.defaults
|
160
|
+
Arc.new.mark_extend(Network.defaults).
|
161
|
+
orient("bottom")
|
162
|
+
end
|
163
|
+
|
164
|
+
# Specifies an optional sort function. The sort function follows the same
|
165
|
+
# comparator contract required by {@link pv.Dom.Node#sort}. Specifying a sort
|
166
|
+
# function provides an alternative to sort the nodes as they are specified by
|
167
|
+
# the <tt>nodes</tt> property; the main advantage of doing this is that the
|
168
|
+
# comparator function can access implicit fields populated by the network
|
169
|
+
# layout, such as the <tt>linkDegree</tt>.
|
170
|
+
#
|
171
|
+
# <p>Note that arc diagrams are particularly sensitive to order. This is
|
172
|
+
# referred to as the seriation problem, and many different techniques exist to
|
173
|
+
# find good node orders that emphasize clusters, such as spectral layout and
|
174
|
+
# simulated annealing.
|
175
|
+
#
|
176
|
+
# @param {function} f comparator function for nodes.
|
177
|
+
# @returns {pv.Layout.Arc} this.
|
178
|
+
def sort(f=nil,&block)
|
179
|
+
f||=block
|
180
|
+
@_sort=f
|
181
|
+
self
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module Rubyvis
|
2
|
+
class Layout
|
3
|
+
# Alias for Rubyvis::Layout::Horizon
|
4
|
+
def self.Horizon
|
5
|
+
Rubyvis::Layout::Horizon
|
6
|
+
end
|
7
|
+
|
8
|
+
# Implements a horizon layout, which is a variation of a single-series
|
9
|
+
# area chart where the area is folded into multiple bands. Color is used to
|
10
|
+
# encode band, allowing the size of the chart to be reduced significantly
|
11
|
+
# without impeding readability. This layout algorithm is based on the work of
|
12
|
+
# J. Heer, N. Kong and M. Agrawala in <a href="http://hci.stanford.edu/publications/2009/heer-horizon-chi09.pdf">"Sizing
|
13
|
+
# the Horizon: The Effects of Chart Size and Layering on the Graphical
|
14
|
+
# Perception of Time Series Visualizations"</a>, CHI 2009.
|
15
|
+
#
|
16
|
+
# <p>This layout exports a single <tt>band</tt> mark prototype, which is
|
17
|
+
# intended to be used with an area mark. The band mark is contained in a panel
|
18
|
+
# which is replicated per band (and for negative/positive bands). For example,
|
19
|
+
# to create a simple horizon graph given an array of numbers:
|
20
|
+
#
|
21
|
+
# vis.add(Rubyvis::Layout::Horizon)
|
22
|
+
# .bands(n)
|
23
|
+
# .band.add(Rubyvis::Area)
|
24
|
+
# .data(data)
|
25
|
+
# .left(lambda { index * 35})
|
26
|
+
# .height(lambda {|d| d * 40})
|
27
|
+
#
|
28
|
+
# The layout can be further customized by changing the number of bands, and
|
29
|
+
# toggling whether the negative bands are mirrored or offset. (See the
|
30
|
+
# above-referenced paper for guidance.)
|
31
|
+
#
|
32
|
+
# <p>The <tt>fill_style</tt> of the area can be overridden, though typically it
|
33
|
+
# is easier to customize the layout's behavior through the custom
|
34
|
+
# <tt>background_style</tt>, <tt>positive_style</tt> and <tt>negative_style</tt>
|
35
|
+
# properties. By default, the background is white, positive bands are blue, and
|
36
|
+
# negative bands are red. For the most accurate presentation, use fully-opaque
|
37
|
+
# colors of equal intensity for the negative and positive bands.
|
38
|
+
class Horizon < Layout
|
39
|
+
@properties=Layout.properties.dup
|
40
|
+
# The band prototype. This prototype is intended to be used with an Area
|
41
|
+
# mark to render the horizon bands.
|
42
|
+
attr_accessor :band
|
43
|
+
attr_accessor :_bands, :_mode, :_size, :_fill, :_red, :_blue
|
44
|
+
def initialize
|
45
|
+
super
|
46
|
+
@_bands=nil
|
47
|
+
@_mode=nil # cached mode
|
48
|
+
@_size=nil # cached height
|
49
|
+
@_fill=nil # cached background style
|
50
|
+
@_red=nil # cached negative color (ramp)
|
51
|
+
@_blue=nil # cached positive color (ramp)
|
52
|
+
@_bands_panel=_bands_panel
|
53
|
+
@band=_band
|
54
|
+
end
|
55
|
+
def build_implied(s)
|
56
|
+
layout_build_implied(s)
|
57
|
+
@_bands=s.bands
|
58
|
+
@_mode=s.mode
|
59
|
+
@_size=((@_mode == "color" ? 0.5 : 1) * s.height).round
|
60
|
+
@_fill=s.background_style
|
61
|
+
@_red=Rubyvis.ramp(@_fill, s.negative_style).domain(0,@_bands)
|
62
|
+
@_blue=Rubyvis.ramp(@_fill, s.positive_style).domain(0,@_bands)
|
63
|
+
|
64
|
+
end
|
65
|
+
def _bands_panel
|
66
|
+
that=self
|
67
|
+
Rubyvis::Panel.new().
|
68
|
+
data(lambda {Rubyvis.range(that._bands.to_f * 2)}).
|
69
|
+
overflow("hidden").
|
70
|
+
height(lambda {that._size}).
|
71
|
+
top(lambda {|i| that._mode=='color' ? (i & 1) * that._size : 0 }).
|
72
|
+
fill_style(lambda {|i| i!=0 ? nil : that._fill})
|
73
|
+
end
|
74
|
+
|
75
|
+
def _band
|
76
|
+
that=self
|
77
|
+
m=Rubyvis::Mark.new().
|
78
|
+
top(lambda {|d,i|
|
79
|
+
(that._mode == "mirror" and (i & 1)!=0) ? (i + 1 >> 1) * that._size : nil
|
80
|
+
}).
|
81
|
+
bottom(lambda {|d,i|
|
82
|
+
crit= (i & 1)!= 0 ? i & 1 : -1
|
83
|
+
(that._mode == "mirror") ? ((i & 1)!=0 ? nil : (i + 1 >> 1) * -that._size) : (crit * (i + 1 >> 1) * that._size)
|
84
|
+
}).
|
85
|
+
fill_style(lambda {|d,i|
|
86
|
+
((i & 1)!=0 ? that._red : that._blue).scale((i >> 1) + 1)
|
87
|
+
})
|
88
|
+
|
89
|
+
class << m # :nodoc:
|
90
|
+
def that_and_bands(that,bands)
|
91
|
+
@that = that
|
92
|
+
@bands=bands
|
93
|
+
end
|
94
|
+
def add(type)
|
95
|
+
bands=@bands
|
96
|
+
that = @that
|
97
|
+
that.add( Rubyvis.Panel ).mark_extend(bands). add(type). mark_extend(self)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
m.that_and_bands(self, @_bands_panel)
|
102
|
+
m
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# :attr: mode
|
107
|
+
# The horizon mode: offset, mirror, or color. The default is "offset".
|
108
|
+
|
109
|
+
##
|
110
|
+
# :attr: bands
|
111
|
+
# The number of bands. Must be at least one. The default value is two.
|
112
|
+
#
|
113
|
+
|
114
|
+
##
|
115
|
+
# :attr: positive_style
|
116
|
+
# The positive band color; if non-null, the interior of positive bands are
|
117
|
+
# filled with the specified color. The default value of this property is blue.
|
118
|
+
# For accurate blending, this color should be fully opaque.
|
119
|
+
#
|
120
|
+
|
121
|
+
##
|
122
|
+
# :attr: negative_style
|
123
|
+
# The negative band color; if non-null, the interior of negative bands are
|
124
|
+
# filled with the specified color. The default value of this property is red.
|
125
|
+
# For accurate blending, this color should be fully opaque.
|
126
|
+
#
|
127
|
+
|
128
|
+
##
|
129
|
+
# :attr: background_style
|
130
|
+
# The background color. The panel background is filled with the specified
|
131
|
+
# color, and the negative and positive bands are filled with an interpolated
|
132
|
+
# color between this color and the respective band color. The default value of
|
133
|
+
# this property is white. For accurate blending, this color should be fully
|
134
|
+
# opaque.
|
135
|
+
#
|
136
|
+
|
137
|
+
attr_accessor_dsl :bands, :mode, :background_style, [:background_style, lambda {|d| Rubyvis.color(d)}], [:positive_style, lambda {|d| Rubyvis.color(d)}], [:negative_style, lambda {|d| Rubyvis.color(d)}]
|
138
|
+
|
139
|
+
# Default properties for horizon layouts. By default, there are two bands, the
|
140
|
+
# mode is "offset", the background style is "white", the positive style is
|
141
|
+
# blue, negative style is red.
|
142
|
+
def self.defaults
|
143
|
+
Horizon.new.mark_extend(Layout.defaults).
|
144
|
+
bands(2).
|
145
|
+
mode('offset').
|
146
|
+
background_style('white').
|
147
|
+
positive_style('#1f77b4').
|
148
|
+
negative_style('#d62728')
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|