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/lib/rubyvis/color/colors.rb
CHANGED
@@ -1,14 +1,61 @@
|
|
1
1
|
module Rubyvis
|
2
|
+
#
|
3
|
+
# :section: colors/Ramp.js
|
4
|
+
|
5
|
+
|
6
|
+
# Returns a linear color ramp from the specified <tt>start</tt> color to the
|
7
|
+
# specified <tt>end</tt> color. The color arguments may be specified either as
|
8
|
+
# <tt>string</tt>s or as Rubyvis::Color. This is equivalent to:
|
9
|
+
#
|
10
|
+
# <pre> pv.Scale.linear().domain(0, 1).range(...)</pre>
|
11
|
+
def self.ramp(*arguments)
|
12
|
+
start, _end, dummy = arguments
|
13
|
+
scale = Rubyvis.Scale.linear
|
14
|
+
scale.range(*arguments)
|
15
|
+
scale
|
16
|
+
end
|
17
|
+
|
18
|
+
# :section: colors/Colors.js
|
19
|
+
|
2
20
|
# Alias for Rubyvis::Colors
|
3
21
|
def self.Colors
|
4
22
|
Rubyvis::Colors
|
5
23
|
end
|
24
|
+
|
25
|
+
# Returns a new categorical color encoding using the specified colors. The
|
26
|
+
# arguments to this method are an array of colors; see Rubyvis.color(). For
|
27
|
+
# example, to create a categorical color encoding using the <tt>species</tt>
|
28
|
+
# attribute:
|
29
|
+
#
|
30
|
+
# <pre>Rubyvis.colors("red", "green", "blue").by(lambda{|d| d.species})</pre>
|
31
|
+
#
|
32
|
+
# The result of this expression can be used as a fill- or stroke-style
|
33
|
+
# property. This assumes that the data's <tt>species</tt> attribute is a
|
34
|
+
# string.
|
35
|
+
#
|
6
36
|
def self.colors(*args)
|
7
37
|
scale=Rubyvis::Scale.ordinal
|
8
38
|
scale.range(*args)
|
9
39
|
scale
|
10
40
|
end
|
41
|
+
|
42
|
+
# A collection of standard color palettes for categorical encoding.
|
11
43
|
module Colors
|
44
|
+
|
45
|
+
# Returns a new 10-color scheme. The arguments to this constructor are
|
46
|
+
# optional, and equivalent to calling Rubyvis::Scale::Ordinal.domain. The
|
47
|
+
# following colors are used:
|
48
|
+
#
|
49
|
+
# <div style="background:#1f77b4;">#1f77b4</div>
|
50
|
+
# <div style="background:#ff7f0e;">#ff7f0e</div>
|
51
|
+
# <div style="background:#2ca02c;">#2ca02c</div>
|
52
|
+
# <div style="background:#d62728;">#d62728</div>
|
53
|
+
# <div style="background:#9467bd;">#9467bd</div>
|
54
|
+
# <div style="background:#8c564b;">#8c564b</div>
|
55
|
+
# <div style="background:#e377c2;">#e377c2</div>
|
56
|
+
# <div style="background:#7f7f7f;">#7f7f7f</div>
|
57
|
+
# <div style="background:#bcbd22;">#bcbd22</div>
|
58
|
+
# <div style="background:#17becf;">#17becf</div>
|
12
59
|
def self.category10(*arguments)
|
13
60
|
scale = Rubyvis.colors(
|
14
61
|
"#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
|
@@ -16,6 +63,30 @@ module Rubyvis
|
|
16
63
|
scale.domain(*arguments) if arguments.size>0
|
17
64
|
scale
|
18
65
|
end
|
66
|
+
|
67
|
+
# Returns a new alternative 19-color scheme. The arguments to this constructor
|
68
|
+
# are optional, and equivalent to calling
|
69
|
+
# Rubyvis::Scale::Ordinal.domain. The following colors are used:
|
70
|
+
#
|
71
|
+
# <div style="background:#9c9ede;">#9c9ede</div>
|
72
|
+
# <div style="background:#7375b5;">#7375b5</div>
|
73
|
+
# <div style="background:#4a5584;">#4a5584</div>
|
74
|
+
# <div style="background:#cedb9c;">#cedb9c</div>
|
75
|
+
# <div style="background:#b5cf6b;">#b5cf6b</div>
|
76
|
+
# <div style="background:#8ca252;">#8ca252</div>
|
77
|
+
# <div style="background:#637939;">#637939</div>
|
78
|
+
# <div style="background:#e7cb94;">#e7cb94</div>
|
79
|
+
# <div style="background:#e7ba52;">#e7ba52</div>
|
80
|
+
# <div style="background:#bd9e39;">#bd9e39</div>
|
81
|
+
# <div style="background:#8c6d31;">#8c6d31</div>
|
82
|
+
# <div style="background:#e7969c;">#e7969c</div>
|
83
|
+
# <div style="background:#d6616b;">#d6616b</div>
|
84
|
+
# <div style="background:#ad494a;">#ad494a</div>
|
85
|
+
# <div style="background:#843c39;">#843c39</div>
|
86
|
+
# <div style="background:#de9ed6;">#de9ed6</div>
|
87
|
+
# <div style="background:#ce6dbd;">#ce6dbd</div>
|
88
|
+
# <div style="background:#a55194;">#a55194</div>
|
89
|
+
# <div style="background:#7b4173;">#7b4173</div>
|
19
90
|
def self.category19(*arguments)
|
20
91
|
scale = Rubyvis.colors(
|
21
92
|
"#9c9ede", "#7375b5", "#4a5584", "#cedb9c", "#b5cf6b",
|
@@ -25,6 +96,33 @@ module Rubyvis
|
|
25
96
|
scale.domain(*arguments) if arguments.size>0
|
26
97
|
scale
|
27
98
|
end
|
99
|
+
|
100
|
+
|
101
|
+
# Returns a new 20-color scheme. The arguments to this constructor are
|
102
|
+
# optional, and equivalent to calling Rubyvis::Scale::Ordinal.domain. The
|
103
|
+
# following colors are used:
|
104
|
+
#
|
105
|
+
# <div style="background:#1f77b4;">#1f77b4</div>
|
106
|
+
# <div style="background:#aec7e8;">#aec7e8</div>
|
107
|
+
# <div style="background:#ff7f0e;">#ff7f0e</div>
|
108
|
+
# <div style="background:#ffbb78;">#ffbb78</div>
|
109
|
+
# <div style="background:#2ca02c;">#2ca02c</div>
|
110
|
+
# <div style="background:#98df8a;">#98df8a</div>
|
111
|
+
# <div style="background:#d62728;">#d62728</div>
|
112
|
+
# <div style="background:#ff9896;">#ff9896</div>
|
113
|
+
# <div style="background:#9467bd;">#9467bd</div>
|
114
|
+
# <div style="background:#c5b0d5;">#c5b0d5</div>
|
115
|
+
# <div style="background:#8c564b;">#8c564b</div>
|
116
|
+
# <div style="background:#c49c94;">#c49c94</div>
|
117
|
+
# <div style="background:#e377c2;">#e377c2</div>
|
118
|
+
# <div style="background:#f7b6d2;">#f7b6d2</div>
|
119
|
+
# <div style="background:#7f7f7f;">#7f7f7f</div>
|
120
|
+
# <div style="background:#c7c7c7;">#c7c7c7</div>
|
121
|
+
# <div style="background:#bcbd22;">#bcbd22</div>
|
122
|
+
# <div style="background:#dbdb8d;">#dbdb8d</div>
|
123
|
+
# <div style="background:#17becf;">#17becf</div>
|
124
|
+
# <div style="background:#9edae5;">#9edae5</div>
|
125
|
+
|
28
126
|
def self.category20(*arguments)
|
29
127
|
scale = Rubyvis.colors(
|
30
128
|
"#1f77b4", "#aec7e8", "#ff7f0e", "#ffbb78", "#2ca02c",
|
data/lib/rubyvis/layout/stack.rb
CHANGED
@@ -1,225 +1,300 @@
|
|
1
1
|
module Rubyvis
|
2
2
|
class Layout
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
class Stack < Rubyvis::Layout
|
7
|
-
@properties=Panel.properties.dup
|
8
|
-
|
9
|
-
attr_accessor :_x, :_y, :_values, :prop
|
10
|
-
attr_accessor_dsl :orient,:offset, :order, :layers
|
11
|
-
def self.defaults
|
12
|
-
Stack.new.extend(Layout.defaults).orient("bottom-left").offset("zero").layers([[]])
|
13
|
-
end
|
14
|
-
def initialize
|
15
|
-
super
|
16
|
-
@none=lambda {nil}
|
17
|
-
@prop = {"t"=> @none, "l"=> @none, "r"=> @none, "b"=> @none, "w"=> @none, "h"=> @none}
|
18
|
-
@values=nil
|
19
|
-
@_x=lambda {return 0}
|
20
|
-
@_y=lambda {return 0}
|
21
|
-
@_values=Rubyvis.identity
|
22
|
-
end
|
23
|
-
def x(f)
|
24
|
-
@_x=Rubyvis.functor(f)
|
25
|
-
return self
|
26
|
-
end
|
27
|
-
def y(f)
|
28
|
-
@_y=Rubyvis.functor(f)
|
29
|
-
return self
|
3
|
+
# Alias for Rubyvis::Layout::Stack
|
4
|
+
def self.Stack
|
5
|
+
Rubyvis::Layout::Stack
|
30
6
|
end
|
31
|
-
def values(f=nil)
|
32
|
-
if f.nil?
|
33
|
-
@values
|
34
|
-
else
|
35
|
-
@_values=Rubyvis.functor(f)
|
36
|
-
return self
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
7
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
8
|
+
# Implements a layout for stacked visualizations, ranging from simple
|
9
|
+
# stacked bar charts to more elaborate "streamgraphs" composed of stacked
|
10
|
+
# areas. Stack layouts uses length as a visual encoding, as opposed to
|
11
|
+
# position, as the layers do not share an aligned axis.
|
12
|
+
#
|
13
|
+
# <p>Marks can be stacked vertically or horizontally. For example,
|
14
|
+
#
|
15
|
+
# vis.add(Rubyvis::Layout::Stack)
|
16
|
+
# .layers([[1, 1.2, 1.7, 1.5, 1.7],
|
17
|
+
# [.5, 1, .8, 1.1, 1.3],
|
18
|
+
# [.2, .5, .8, .9, 1]])
|
19
|
+
# .x(lambda { index * 35})
|
20
|
+
# .y(lambda {|d| d * 40})
|
21
|
+
# .layer.add(Rubyvis::Area)
|
22
|
+
#
|
23
|
+
# specifies a vertically-stacked area chart, using the default "bottom-left"
|
24
|
+
# orientation with "zero" offset. This visualization can be easily changed into
|
25
|
+
# a streamgraph using the "wiggle" offset, which attempts to minimize change in
|
26
|
+
# slope weighted by layer thickness. See the offset property for more
|
27
|
+
# supported streamgraph algorithms.
|
28
|
+
#
|
29
|
+
# <p>In the simplest case, the layer data can be specified as a two-dimensional
|
30
|
+
# array of numbers. The <tt>x</tt> and <tt>y</tt> psuedo-properties are used to
|
31
|
+
# define the thickness of each layer at the given position, respectively; in
|
32
|
+
# the above example of the "bottom-left" orientation, the <tt>x</tt> and
|
33
|
+
# <tt>y</tt> psuedo-properties are equivalent to the <tt>left</tt> and
|
34
|
+
# <tt>height</tt> properties that you might use if you implemented a stacked
|
35
|
+
# area by hand.
|
36
|
+
#
|
37
|
+
# <p>The advantage of using the stack layout is that the baseline, i.e., the
|
38
|
+
# <tt>bottom</tt> property is computed automatically using the specified offset
|
39
|
+
# algorithm. In addition, the order of layers can be computed using a built-in
|
40
|
+
# algorithm via the <tt>order</tt> property.
|
41
|
+
#
|
42
|
+
# <p>With the exception of the "expand" <tt>offset</tt>, the stack layout does
|
43
|
+
# not perform any automatic scaling of data; the values returned from
|
44
|
+
# <tt>x</tt> and <tt>y</tt> specify pixel sizes. To simplify scaling math, use
|
45
|
+
# this layout in conjunction with Rubyvis::Scale.linea} or similar.
|
46
|
+
#
|
47
|
+
# <p>In other cases, the <tt>values</tt> psuedo-property can be used to define
|
48
|
+
# the data more flexibly. As with a typical panel & area, the
|
49
|
+
# <tt>layers</tt> property corresponds to the data in the enclosing panel,
|
50
|
+
# while the <tt>values</tt> psuedo-property corresponds to the data for the
|
51
|
+
# area within the panel. For example, given an array of data values:
|
52
|
+
#
|
53
|
+
# crimea = [
|
54
|
+
# { date: "4/1854", wounds: 0, other: 110, disease: 110 },
|
55
|
+
# { date: "5/1854", wounds: 0, other: 95, disease: 105 },
|
56
|
+
# { date: "6/1854", wounds: 0, other: 40, disease: 95 },
|
57
|
+
# ...
|
58
|
+
#
|
59
|
+
# and a corresponding array of series names:
|
60
|
+
#
|
61
|
+
# causes = [:wounds, :other, :disease]
|
62
|
+
#
|
63
|
+
# Separate layers can be defined for each cause like so:
|
64
|
+
#
|
65
|
+
# vis.add(pv.Layout.Stack)
|
66
|
+
# .layers(causes)
|
67
|
+
# .values(crimea)
|
68
|
+
# .x(lambda {|d| x.scale(d[:date]})
|
69
|
+
# .y(lambda {|d,dp| y.scale(d[dp])})
|
70
|
+
# .layer.add(pv.Area)
|
71
|
+
#
|
72
|
+
# As with the panel & area case, the datum that is passed to the
|
73
|
+
# psuedo-properties <tt>x</tt> and <tt>y</tt> are the values (an element in
|
74
|
+
# <tt>crimea</tt>); the second argument is the layer data (a string in
|
75
|
+
# <tt>causes</tt>). Additional arguments specify the data of enclosing panels, if any.
|
76
|
+
class Stack < Rubyvis::Layout
|
77
|
+
@properties=Panel.properties.dup
|
78
|
+
|
79
|
+
attr_accessor :_x, :_y, :_values, :prop
|
80
|
+
attr_accessor_dsl :orient,:offset, :order, :layers
|
81
|
+
def self.defaults
|
82
|
+
Stack.new.extend(Layout.defaults).orient("bottom-left").offset("zero").layers([[]])
|
61
83
|
end
|
62
|
-
h = self.parent.send(horizontal ? "height" : "width")
|
63
|
-
x = []
|
64
|
-
y = []
|
65
|
-
dy = []
|
66
84
|
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
|
71
|
-
|
72
|
-
|
85
|
+
# Constructs a new, empty stack layout. Layouts are not typically constructed
|
86
|
+
# directly; instead, they are added to an existing panel via
|
87
|
+
# Rubyvis::Mark.add
|
88
|
+
def initialize
|
89
|
+
super
|
90
|
+
@none=lambda {nil}
|
91
|
+
@prop = {"t"=> @none, "l"=> @none, "r"=> @none, "b"=> @none, "w"=> @none, "h"=> @none}
|
92
|
+
@values=nil
|
93
|
+
@_x=lambda {return 0}
|
94
|
+
@_y=lambda {return 0}
|
95
|
+
@_values=Rubyvis.identity
|
96
|
+
end
|
97
|
+
def x(f)
|
98
|
+
@_x=Rubyvis.functor(f)
|
99
|
+
return self
|
100
|
+
end
|
101
|
+
def y(f)
|
102
|
+
@_y=Rubyvis.functor(f)
|
103
|
+
return self
|
104
|
+
end
|
105
|
+
def values(f=nil)
|
106
|
+
if f.nil?
|
107
|
+
@values
|
108
|
+
else
|
109
|
+
@_values=Rubyvis.functor(f)
|
110
|
+
return self
|
111
|
+
end
|
112
|
+
end
|
73
113
|
|
74
|
-
o = OpenStruct.new({:parent=> OpenStruct.new({:parent=> self})})
|
75
|
-
stack.unshift(nil)
|
76
|
-
values = []
|
77
|
-
n.times {|i|
|
78
|
-
dy[i] = []
|
79
|
-
y[i] = []
|
80
|
-
o.parent.index = i
|
81
|
-
stack[0] = data[i]
|
82
|
-
values[i] = self._values.js_apply(o.parent, stack);
|
83
|
-
m = values[i].size if (i==0)
|
84
|
-
stack.unshift(nil)
|
85
|
-
m.times {|j|
|
86
|
-
stack[0] = values[i][j]
|
87
|
-
o.index = j
|
88
|
-
x[j] = self._x.js_apply(o, stack) if i==0
|
89
|
-
dy[i][j] = self._y.js_apply(o, stack)
|
90
|
-
}
|
91
|
-
stack.shift()
|
92
|
-
}
|
93
|
-
stack.shift()
|
94
114
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
sums = dy.map {|v| Rubyvis.sum(v)}
|
102
|
-
top = 0
|
103
|
-
bottom = 0
|
104
|
-
tops = []
|
105
|
-
bottoms = []
|
106
|
-
n.times {|i|
|
107
|
-
j = map[i]
|
108
|
-
if (top < bottom)
|
109
|
-
top += sums[j];
|
110
|
-
tops.push(j);
|
111
|
-
else
|
112
|
-
bottom += sums[j];
|
113
|
-
bottoms.push(j);
|
114
|
-
end
|
115
|
+
def proxy(name)
|
116
|
+
that=self
|
117
|
+
return lambda {
|
118
|
+
a=that.prop[name].js_call(self, self.parent.index, self.index);
|
119
|
+
puts "proxy(#{name}): #{a}" if $DEBUG
|
120
|
+
a
|
115
121
|
}
|
116
|
-
_index = bottoms.reverse+tops
|
117
|
-
|
118
|
-
when "reverse"
|
119
|
-
_index = Rubyvis.range(n - 1, -1, -1)
|
120
|
-
else
|
121
|
-
_index = Rubyvis.range(n)
|
122
122
|
end
|
123
123
|
|
124
|
-
|
125
|
-
|
126
|
-
|
124
|
+
def build_implied(s)
|
125
|
+
# puts "Build stack" if $DEBUG
|
126
|
+
panel_build_implied(s)
|
127
|
+
data = s.layers
|
128
|
+
n = data.size
|
129
|
+
m = nil
|
130
|
+
orient = s.orient
|
131
|
+
if orient =~/^(top|bottom)\b/
|
132
|
+
horizontal=true
|
133
|
+
else
|
134
|
+
horizontal=false
|
135
|
+
end
|
136
|
+
h = self.parent.send(horizontal ? "height" : "width")
|
137
|
+
x = []
|
138
|
+
y = []
|
139
|
+
dy = []
|
140
|
+
|
141
|
+
#
|
142
|
+
# Iterate over the data, evaluating the values, x and y functions. The
|
143
|
+
# context in which the x and y psuedo-properties are evaluated is a
|
144
|
+
# pseudo-mark that is a grandchild of this layout.
|
145
|
+
#
|
146
|
+
stack = Rubyvis::Mark.stack
|
147
|
+
|
148
|
+
o = OpenStruct.new({:parent=> OpenStruct.new({:parent=> self})})
|
149
|
+
stack.unshift(nil)
|
150
|
+
values = []
|
151
|
+
n.times {|i|
|
152
|
+
dy[i] = []
|
153
|
+
y[i] = []
|
154
|
+
o.parent.index = i
|
155
|
+
stack[0] = data[i]
|
156
|
+
values[i] = self._values.js_apply(o.parent, stack);
|
157
|
+
m = values[i].size if (i==0)
|
158
|
+
stack.unshift(nil)
|
127
159
|
m.times {|j|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
y[_index[0]][j] = (h - o) / 2.0;
|
160
|
+
stack[0] = values[i][j]
|
161
|
+
o.index = j
|
162
|
+
x[j] = self._x.js_apply(o, stack) if i==0
|
163
|
+
dy[i][j] = self._y.js_apply(o, stack)
|
133
164
|
}
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
n.times {|i| o += dy[i][0] }
|
138
|
-
|
139
|
-
y[_index[0]][0] = o = (h - o) / 2.0
|
165
|
+
stack.shift()
|
166
|
+
}
|
167
|
+
stack.shift()
|
140
168
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
169
|
+
# order
|
170
|
+
_index=nil
|
171
|
+
case (s.order)
|
172
|
+
when "inside-out"
|
173
|
+
max = dy.map {|v| Rubyvis.max.index(v) }
|
174
|
+
map = pv.range(n).sort {|a,b| return max[a] - max[b]}
|
175
|
+
sums = dy.map {|v| Rubyvis.sum(v)}
|
176
|
+
top = 0
|
177
|
+
bottom = 0
|
178
|
+
tops = []
|
179
|
+
bottoms = []
|
146
180
|
n.times {|i|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
181
|
+
j = map[i]
|
182
|
+
if (top < bottom)
|
183
|
+
top += sums[j];
|
184
|
+
tops.push(j);
|
185
|
+
else
|
186
|
+
bottom += sums[j];
|
187
|
+
bottoms.push(j);
|
188
|
+
end
|
189
|
+
}
|
190
|
+
_index = bottoms.reverse+tops
|
191
|
+
|
192
|
+
when "reverse"
|
193
|
+
_index = Rubyvis.range(n - 1, -1, -1)
|
194
|
+
else
|
195
|
+
_index = Rubyvis.range(n)
|
196
|
+
end
|
197
|
+
|
198
|
+
#/* offset */
|
199
|
+
case (s.offset)
|
200
|
+
when "silohouette"
|
201
|
+
m.times {|j|
|
202
|
+
o = 0;
|
203
|
+
n.times {|i|
|
204
|
+
o += dy[i][j]
|
151
205
|
}
|
152
|
-
|
206
|
+
y[_index[0]][j] = (h - o) / 2.0;
|
153
207
|
}
|
154
|
-
|
155
|
-
|
208
|
+
|
209
|
+
when "wiggle"
|
210
|
+
o = 0;
|
211
|
+
n.times {|i| o += dy[i][0] }
|
156
212
|
|
157
|
-
|
158
|
-
|
213
|
+
y[_index[0]][0] = o = (h - o) / 2.0
|
214
|
+
|
215
|
+
(1...m).each {|j|
|
216
|
+
s1 = 0
|
217
|
+
s2 = 0
|
218
|
+
dx = x[j] - x[j - 1]
|
219
|
+
n.times {|i| s1 += dy[i][j]}
|
220
|
+
n.times {|i|
|
221
|
+
|
222
|
+
s3 = (dy[_index[i]][j] - dy[_index[i]][j - 1]) / (2.0 * dx)
|
223
|
+
i.times {|k|
|
224
|
+
s3 += (dy[_index[k]][j] - dy[_index[k]][j - 1]) / dx.to_f
|
225
|
+
}
|
226
|
+
s2 += s3 * dy[_index[i]][j]
|
227
|
+
}
|
228
|
+
o -= (s1!=0) ? s2 / s1.to_f * dx : 0
|
229
|
+
y[_index[0]][j] = o
|
230
|
+
|
231
|
+
}
|
232
|
+
when "expand"
|
233
|
+
m.times {|j|
|
234
|
+
y[_index[0]][j] = 0
|
235
|
+
|
236
|
+
k = 0
|
237
|
+
n.times {|i|k += dy[i][j]}
|
238
|
+
if (k!=0)
|
239
|
+
k = h / k.to_f
|
240
|
+
n.times {|i| dy[i][j] *= k}
|
241
|
+
else
|
242
|
+
k = h / n.to_f
|
243
|
+
n.times { dy[i][j] = k}
|
244
|
+
end
|
245
|
+
}
|
246
|
+
else
|
247
|
+
m.times {|j| y[_index[0]][j] = 0}
|
248
|
+
end
|
249
|
+
|
250
|
+
# Propagate the offset to the other series. */
|
159
251
|
m.times {|j|
|
160
|
-
|
252
|
+
o = y[_index[0]][j]
|
253
|
+
(1...n).each {|i|
|
161
254
|
|
162
|
-
|
163
|
-
|
164
|
-
if (k!=0)
|
165
|
-
k = h / k.to_f
|
166
|
-
n.times {|i| dy[i][j] *= k}
|
167
|
-
else
|
168
|
-
k = h / n.to_f
|
169
|
-
n.times { dy[i][j] = k}
|
170
|
-
end
|
255
|
+
o += dy[_index[i - 1]][j]
|
256
|
+
y[_index[i]][j] = o
|
171
257
|
}
|
172
|
-
|
173
|
-
|
258
|
+
}
|
259
|
+
|
260
|
+
# /* Find the property definitions for dynamic substitution. */
|
261
|
+
|
262
|
+
i = orient.index("-")
|
263
|
+
pdy = horizontal ? "h" : "w"
|
264
|
+
px = i < 0 ? (horizontal ? "l" : "b") : orient[i + 1,1]
|
265
|
+
py = orient[0,1]
|
266
|
+
|
267
|
+
@values=values
|
268
|
+
|
269
|
+
@prop.each {|k,v|
|
270
|
+
@prop[k]=@none
|
271
|
+
}
|
272
|
+
# puts "stack: x:#{px}, y:#{py}, dy:#{pdy}" if $DEBUG
|
273
|
+
@prop[px] =lambda {|i1,j| x[j]}
|
274
|
+
@prop[py] =lambda {|i1,j| y[i1][j]}
|
275
|
+
@prop[pdy]=lambda {|i1,j| dy[i1][j]}
|
174
276
|
end
|
175
277
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
278
|
+
def layer
|
279
|
+
that=self
|
280
|
+
value = Rubyvis::Mark.new().data(lambda { that.values[self.parent.index] }).top(proxy("t")).left(proxy("l")).right(proxy("r")).
|
281
|
+
bottom(proxy("b")).
|
282
|
+
width(proxy("w")).
|
283
|
+
height(proxy("h"))
|
180
284
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
pdy = horizontal ? "h" : "w"
|
190
|
-
px = i < 0 ? (horizontal ? "l" : "b") : orient[i + 1,1]
|
191
|
-
py = orient[0,1]
|
192
|
-
|
193
|
-
@values=values
|
194
|
-
|
195
|
-
@prop.each {|k,v|
|
196
|
-
@prop[k]=@none
|
197
|
-
}
|
198
|
-
# puts "stack: x:#{px}, y:#{py}, dy:#{pdy}" if $DEBUG
|
199
|
-
@prop[px] =lambda {|i1,j| x[j]}
|
200
|
-
@prop[py] =lambda {|i1,j| y[i1][j]}
|
201
|
-
@prop[pdy]=lambda {|i1,j| dy[i1][j]}
|
202
|
-
end
|
203
|
-
|
204
|
-
def layer
|
205
|
-
that=self
|
206
|
-
value = Rubyvis::Mark.new().data(lambda { that.values[self.parent.index] }).top(proxy("t")).left(proxy("l")).right(proxy("r")).
|
207
|
-
bottom(proxy("b")).
|
208
|
-
width(proxy("w")).
|
209
|
-
height(proxy("h"))
|
210
|
-
|
211
|
-
class << value
|
212
|
-
def that=(v)
|
213
|
-
@that = v
|
214
|
-
end
|
215
|
-
def add(type)
|
216
|
-
that = @that
|
217
|
-
that.add( Rubyvis.Panel ).data(lambda { that.layers() }).add(type).extend( self )
|
285
|
+
class << value # :nodoc:
|
286
|
+
def that=(v)
|
287
|
+
@that = v
|
288
|
+
end
|
289
|
+
def add(type)
|
290
|
+
that = @that
|
291
|
+
that.add( Rubyvis.Panel ).data(lambda { that.layers() }).add(type).extend( self )
|
292
|
+
end
|
218
293
|
end
|
294
|
+
|
295
|
+
value.that=self
|
296
|
+
return value
|
219
297
|
end
|
220
|
-
value.that=self
|
221
|
-
return value
|
222
298
|
end
|
223
299
|
end
|
224
|
-
end
|
225
300
|
end
|