rubyvis 0.3.3 → 0.3.4
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 +45 -36
- data/examples/{first_rbp_api.rb → 1_basic/1a_bar_rbp_api.rb} +1 -1
- data/examples/{first_protovis_api.rb → 1_basic/1b_bar_pv_api.rb} +1 -1
- data/examples/{second.rb → 1_basic/2_bar_and_rule.rb} +2 -2
- data/examples/{third.rb → 1_basic/3_grouped_bars.rb} +1 -1
- data/examples/{area_interpolation.rb → 1_basic/area_interpolation.rb} +1 -1
- data/examples/{dot.rb → 1_basic/dot.rb} +1 -1
- data/examples/{fixtures → 1_basic/fixtures}/tipsy.gif +0 -0
- data/examples/1_basic/grid.rb +29 -0
- data/examples/{image.rb → 1_basic/image.rb} +1 -1
- data/examples/{line.rb → 1_basic/line.rb} +1 -1
- data/examples/{line_interpolation.rb → 1_basic/line_interpolation.rb} +1 -1
- data/examples/2_medium/censo_agropecuario/censo_agropecuario_chile_data.rb +53 -0
- data/examples/2_medium/censo_agropecuario/census_treemap.rb +63 -0
- data/examples/2_medium/censo_agropecuario/create_data.rb +10 -0
- data/examples/2_medium/censo_agropecuario/resultset.csv +51 -0
- data/examples/{nested_grid.rb → 2_medium/nested_grid.rb} +3 -4
- data/examples/{area.rb → 3_pv_conventional/area.rb} +1 -1
- data/examples/{bar_column_chart.rb → 3_pv_conventional/bar_column_chart.rb} +1 -1
- data/examples/{grouped_charts.rb → 3_pv_conventional/grouped_charts.rb} +1 -1
- data/examples/{line_and_step.rb → 3_pv_conventional/line_and_step.rb} +1 -1
- data/examples/{pie_and_donut.rb → 3_pv_conventional/pie_and_donut.rb} +1 -1
- data/examples/{scatterplot.rb → 3_pv_conventional/scatterplot.rb} +1 -1
- data/examples/{stacked_charts.rb → 3_pv_conventional/stacked_charts.rb} +1 -3
- data/examples/{antibiotics → 4_pv_custom/antibiotics}/antibiotics_data.rb +0 -0
- data/examples/{antibiotics → 4_pv_custom/antibiotics}/antibiotics_scatter.rb +1 -1
- data/examples/{antibiotics → 4_pv_custom/antibiotics}/antibiotics_wedge.rb +1 -1
- data/examples/{barley → 4_pv_custom/barley}/barley.rb +5 -1
- data/examples/{barley → 4_pv_custom/barley}/barley_data.rb +0 -0
- data/examples/{cars → 4_pv_custom/cars}/cars.rb +1 -1
- data/examples/{cars → 4_pv_custom/cars}/cars_data.rb +0 -0
- data/examples/{crimea → 4_pv_custom/crimea}/crimea_data.rb +0 -0
- data/examples/{crimea → 4_pv_custom/crimea}/crimea_grouped_bar.rb +1 -1
- data/examples/{crimea → 4_pv_custom/crimea}/crimea_line.rb +1 -1
- data/examples/{bubble_charts.rb → 5_pv_hierarchies/bubble_charts.rb} +3 -2
- data/examples/5_pv_hierarchies/bubble_charts_matrix.rb +64 -0
- data/examples/{circle_packing.rb → 5_pv_hierarchies/circle_packing.rb} +4 -4
- data/examples/{dendogram.rb → 5_pv_hierarchies/dendogram.rb} +2 -2
- data/examples/{icicle.rb → 5_pv_hierarchies/icicle.rb} +2 -2
- data/examples/{indent.rb → 5_pv_hierarchies/indent.rb} +2 -2
- data/examples/5_pv_hierarchies/node_link_tree.rb +52 -0
- data/examples/{sunburst.rb → 5_pv_hierarchies/sunburst.rb} +2 -2
- data/examples/5_pv_hierarchies/treemap.rb +48 -0
- data/lib/rubyvis.rb +1 -1
- data/lib/rubyvis/dom.rb +16 -1
- data/lib/rubyvis/internals.rb +2 -2
- data/lib/rubyvis/layout.rb +2 -0
- data/lib/rubyvis/layout/grid.rb +105 -0
- data/lib/rubyvis/layout/pack.rb +53 -54
- data/lib/rubyvis/layout/stack.rb +26 -24
- data/lib/rubyvis/layout/tree.rb +267 -0
- data/lib/rubyvis/layout/treemap.rb +1 -0
- data/lib/rubyvis/mark.rb +10 -8
- data/lib/rubyvis/mark/area.rb +6 -6
- data/lib/rubyvis/mark/dot.rb +1 -1
- data/lib/rubyvis/mark/shorcut_methods.rb +29 -2
- data/lib/rubyvis/nest.rb +48 -2
- data/lib/rubyvis/scale/ordinal.rb +6 -6
- data/lib/rubyvis/scale/quantitative.rb +13 -7
- data/lib/rubyvis/scene/svg_area.rb +20 -14
- data/lib/rubyvis/scene/svg_bar.rb +1 -1
- data/lib/rubyvis/scene/svg_scene.rb +0 -1
- data/lib/rubyvis/sceneelement.rb +1 -1
- data/spec/area_spec.rb +12 -0
- data/spec/dom_spec.rb +15 -8
- data/spec/layout_stack_spec.rb +70 -0
- data/spec/nest_spec.rb +8 -2
- data/spec/scale_linear_spec.rb +7 -1
- data/spec/scale_ordinal_spec.rb +4 -0
- data/spec/spec_helper.rb +1 -1
- data/web/build_site.rb +6 -2
- data/web/index.haml +2 -2
- metadata +61 -68
- metadata.gz.sig +0 -0
- data/examples/treemap/treemap.rb +0 -29
- data/examples/treemap/treemap_data.rb +0 -285
@@ -0,0 +1,267 @@
|
|
1
|
+
module Rubyvis
|
2
|
+
class Layout
|
3
|
+
# Alias for Rubyvis::Layout::Tree
|
4
|
+
def self.Tree
|
5
|
+
Rubyvis::Layout::Tree
|
6
|
+
end
|
7
|
+
# Implements a node-link tree diagram using the Reingold-Tilford "tidy"
|
8
|
+
# tree layout algorithm. The specific algorithm used by this layout is based on
|
9
|
+
# <a href="http://citeseer.ist.psu.edu/buchheim02improving.html">"Improving
|
10
|
+
# Walker's Algorithm to Run in Linear Time"</A> by C. Buchheim, M. Jünger
|
11
|
+
# & S. Leipert, Graph Drawing 2002. This layout supports both cartesian and
|
12
|
+
# radial orientations orientations for node-link diagrams.
|
13
|
+
#
|
14
|
+
# <p>The tree layout supports a "group" property, which if true causes siblings
|
15
|
+
# to be positioned closer together than unrelated nodes at the same depth. The
|
16
|
+
# layout can be configured using the <tt>depth</tt> and <tt>breadth</tt>
|
17
|
+
# properties, which control the increments in pixel space between nodes in both
|
18
|
+
# dimensions, similar to the indent layout.
|
19
|
+
#
|
20
|
+
# <p>For more details on how to use this layout, see
|
21
|
+
# {@link pv.Layout.Hierarchy}
|
22
|
+
class Tree < Hierarchy
|
23
|
+
@properties=Hierarchy.properties.dup
|
24
|
+
def initialize
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# :attr: breadth
|
30
|
+
# The offset between siblings nodes; defaults to 15.
|
31
|
+
|
32
|
+
##
|
33
|
+
# :attr: depth
|
34
|
+
# The offset between parent and child nodes; defaults to 60.
|
35
|
+
#
|
36
|
+
|
37
|
+
##
|
38
|
+
# :attr: orient
|
39
|
+
# The orientation. The default orientation is "top", which means that the root
|
40
|
+
# node is placed on the top edge, leaf nodes appear at the bottom, and internal
|
41
|
+
# nodes are in-between. The following orientations are supported:<ul>
|
42
|
+
#
|
43
|
+
# <li>left - left-to-right.
|
44
|
+
# <li>right - right-to-left.
|
45
|
+
# <li>top - top-to-bottom.
|
46
|
+
# <li>bottom - bottom-to-top.
|
47
|
+
# <li>radial - radially, with the root at the center.</ul>
|
48
|
+
#
|
49
|
+
|
50
|
+
##
|
51
|
+
# :group:
|
52
|
+
# The sibling grouping, i.e., whether differentiating space is placed between
|
53
|
+
# sibling groups. The default is 1 (or true), causing sibling leaves to be
|
54
|
+
# separated by one breadth offset. Setting this to false (or 0) causes
|
55
|
+
# non-siblings to be adjacent.
|
56
|
+
|
57
|
+
attr_accessor_dsl :group, :breadth, :depth, :orient
|
58
|
+
|
59
|
+
# Default properties for tree layouts. The default orientation is "top",
|
60
|
+
# the default group parameter is 1, and the default breadth and depth
|
61
|
+
# offsets are 15 and 60 respectively.
|
62
|
+
def self.defaults
|
63
|
+
Rubyvis::Layout::Tree.new.mark_extend(Rubyvis::Layout::Hierarchy.defaults).
|
64
|
+
group(1).
|
65
|
+
breadth(15).
|
66
|
+
depth(60).
|
67
|
+
orient("top")
|
68
|
+
end
|
69
|
+
|
70
|
+
def first_walk(v)
|
71
|
+
l,r,a=nil,nil,nil
|
72
|
+
if (!v.first_child)
|
73
|
+
l= v.previous_sibling
|
74
|
+
v.prelim = l.prelim + distance(v.depth, true) if l
|
75
|
+
else
|
76
|
+
l = v.first_child
|
77
|
+
r = v.last_child
|
78
|
+
a = l # default ancestor
|
79
|
+
v.each_child {|c|
|
80
|
+
first_walk(c)
|
81
|
+
a = apportion(c, a)
|
82
|
+
}
|
83
|
+
execute_shifts(v)
|
84
|
+
midpoint = 0.5 * (l.prelim + r.prelim)
|
85
|
+
l = v.previous_sibling
|
86
|
+
if l
|
87
|
+
v.prelim = l.prelim + distance(v.depth, true)
|
88
|
+
v.mod = v.prelim - midpoint
|
89
|
+
else
|
90
|
+
v.prelim = midpoint
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
def second_walk(v,m,depth)
|
95
|
+
v.breadth = v.prelim + m
|
96
|
+
m += v.mod
|
97
|
+
v.each_child {|c|
|
98
|
+
second_walk(c, m, depth)
|
99
|
+
}
|
100
|
+
end
|
101
|
+
def apportion(v,a)
|
102
|
+
w = v.previous_sibling
|
103
|
+
if w
|
104
|
+
vip = v
|
105
|
+
vop = v
|
106
|
+
vim = w
|
107
|
+
vom = v.parent_node.first_child
|
108
|
+
sip = vip.mod
|
109
|
+
sop = vop.mod
|
110
|
+
sim = vim.mod
|
111
|
+
som = vom.mod
|
112
|
+
nr = next_right(vim)
|
113
|
+
nl = next_left(vip)
|
114
|
+
while (nr and nl) do
|
115
|
+
vim = nr
|
116
|
+
vip = nl
|
117
|
+
vom = next_left(vom)
|
118
|
+
vop = next_right(vop)
|
119
|
+
vop.ancestor = v
|
120
|
+
shift = (vim.prelim + sim) - (vip.prelim + sip) + distance(vim.depth, false)
|
121
|
+
if (shift > 0)
|
122
|
+
move_subtree(ancestor(vim, v, a), v, shift)
|
123
|
+
sip += shift
|
124
|
+
sop += shift
|
125
|
+
end
|
126
|
+
sim += vim.mod
|
127
|
+
sip += vip.mod
|
128
|
+
som += vom.mod
|
129
|
+
sop += vop.mod
|
130
|
+
nr = next_right(vim)
|
131
|
+
nl = next_left(vip)
|
132
|
+
end
|
133
|
+
|
134
|
+
if (nr and !next_right(vop))
|
135
|
+
vop.thread = nr
|
136
|
+
vop.mod += sim - sop
|
137
|
+
end
|
138
|
+
if (nl and !next_left(vom))
|
139
|
+
vom.thread = nl
|
140
|
+
vom.mod += sip - som
|
141
|
+
a = v
|
142
|
+
end
|
143
|
+
end
|
144
|
+
a
|
145
|
+
end
|
146
|
+
|
147
|
+
def next_left(v)
|
148
|
+
v.first_child ? v.first_child : v.thread
|
149
|
+
end
|
150
|
+
def next_right(v)
|
151
|
+
v.last_child ? v.last_child : v.thread
|
152
|
+
end
|
153
|
+
|
154
|
+
def move_subtree(wm, wp, shift)
|
155
|
+
subtrees = wp.number - wm.number
|
156
|
+
wp.change -= shift / subtrees.to_f
|
157
|
+
wp.shift += shift
|
158
|
+
wm.change += shift / subtrees.to_f
|
159
|
+
wp.prelim += shift
|
160
|
+
wp.mod += shift
|
161
|
+
end
|
162
|
+
|
163
|
+
def execute_shifts(v)
|
164
|
+
shift = 0
|
165
|
+
change = 0
|
166
|
+
c=v.last_child
|
167
|
+
while c
|
168
|
+
c.prelim += shift
|
169
|
+
c.mod += shift
|
170
|
+
change += c.change
|
171
|
+
shift += c.shift + change
|
172
|
+
c = c.previous_sibling
|
173
|
+
end
|
174
|
+
end
|
175
|
+
def ancestor(vim, v, a)
|
176
|
+
(vim.ancestor.parent_node == v.parent_node) ? vim.ancestor : a
|
177
|
+
end
|
178
|
+
|
179
|
+
def distance(depth, siblings)
|
180
|
+
(siblings ? 1 : (@_group + 1)).to_f / ((@_orient == "radial") ? depth : 1)
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
def mid_angle(n)
|
185
|
+
(@_orient == "radial") ? n.breadth.to_f / depth : 0;
|
186
|
+
end
|
187
|
+
|
188
|
+
#/** @private */
|
189
|
+
def x(n)
|
190
|
+
case @_orient
|
191
|
+
when "left"
|
192
|
+
n.depth;
|
193
|
+
when "right"
|
194
|
+
@_w - n.depth;
|
195
|
+
when "top"
|
196
|
+
n.breadth + @_w / 2.0
|
197
|
+
when "bottom"
|
198
|
+
n.breadth + @_w / 2.0
|
199
|
+
when "radial"
|
200
|
+
@_w / 2.0 + n.depth * Math.cos(mid_angle(n))
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
#/** @private */
|
205
|
+
def y(n)
|
206
|
+
case @_orient
|
207
|
+
when "left"
|
208
|
+
n.breadth + @_h / 2.0
|
209
|
+
when "right"
|
210
|
+
n.breadth + @_h / 2.0
|
211
|
+
when "top"
|
212
|
+
n.depth;
|
213
|
+
when "bottom"
|
214
|
+
@_h - n.depth
|
215
|
+
when "radial"
|
216
|
+
@_h / 2.0 + n.depth * Math.sin(mid_angle(n))
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
def build_implied(s)
|
223
|
+
return nil if hierarchy_build_implied(s)
|
224
|
+
@_nodes = s.nodes
|
225
|
+
@_orient = s.orient
|
226
|
+
@_depth = s.depth
|
227
|
+
@_breadth = s.breadth
|
228
|
+
@_group = s.group
|
229
|
+
@_w = s.width
|
230
|
+
@_h = s.height
|
231
|
+
root=@_nodes[0]
|
232
|
+
root.visit_after {|v,i|
|
233
|
+
v.ancestor = v
|
234
|
+
v.prelim = 0
|
235
|
+
v.mod = 0
|
236
|
+
v.change = 0
|
237
|
+
v.shift = 0
|
238
|
+
v.number = v.previous_sibling ? (v.previous_sibling.number + 1) : 0
|
239
|
+
v.depth = i
|
240
|
+
}
|
241
|
+
#/* Compute the layout using Buchheim et al.'s algorithm. */
|
242
|
+
first_walk(root)
|
243
|
+
second_walk(root, -root.prelim, 0)
|
244
|
+
|
245
|
+
root.visit_after {|v,i|
|
246
|
+
v.breadth *= breadth
|
247
|
+
v.depth *= depth
|
248
|
+
v.mid_angle = mid_angle(v)
|
249
|
+
v.x = x(v)
|
250
|
+
v.y = y(v)
|
251
|
+
v.mid_angle += Math::PI if (v.first_child)
|
252
|
+
v.breadth=nil
|
253
|
+
v.depth=nil
|
254
|
+
v.ancestor=nil
|
255
|
+
v.prelim=nil
|
256
|
+
v.mod=nil
|
257
|
+
v.change=nil
|
258
|
+
v.shift=nil
|
259
|
+
v.number=nil
|
260
|
+
v.thread=nil
|
261
|
+
}
|
262
|
+
|
263
|
+
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
data/lib/rubyvis/mark.rb
CHANGED
@@ -699,7 +699,11 @@ module Rubyvis
|
|
699
699
|
width=self.parent ? self.parent.width() : (w+(l.nil? ? 0 : l)+(r.nil? ? 0 : r))
|
700
700
|
#puts (self.parent)? "parent width: #{self.parent.width}" : "no parent" if $DEBUG
|
701
701
|
#p prop.sort if $DEBUG
|
702
|
-
|
702
|
+
|
703
|
+
height=self.parent ? self.parent.height(): (h+(t.nil? ? 0 : t )+(b.nil? ? 0 : b))
|
704
|
+
|
705
|
+
puts "build implied #{type}: l:#{l},r:#{r},t:#{t},b:#{b}, w:#{prop[:width]} #{w},h: #{prop[:height]} #{h}, width:#{width}, height:#{height}" if $DEBUG
|
706
|
+
|
703
707
|
if w.nil?
|
704
708
|
r||=0
|
705
709
|
l||=0
|
@@ -715,7 +719,7 @@ module Rubyvis
|
|
715
719
|
l=width-w-r
|
716
720
|
end
|
717
721
|
|
718
|
-
|
722
|
+
|
719
723
|
|
720
724
|
if h.nil?
|
721
725
|
t||=0
|
@@ -739,11 +743,9 @@ module Rubyvis
|
|
739
743
|
s.top=t
|
740
744
|
s.bottom=b
|
741
745
|
|
742
|
-
puts "Post->left: #{l},right:#{r},top:#{t},bottom:#{b}, width:#{w}, height:#{h}" if $DEBUG
|
743
|
-
|
744
|
-
s.
|
745
|
-
#puts "width:#{s.width}" if $DEBUG
|
746
|
-
s.height=h if prop[:height]
|
746
|
+
puts "Post->left: #{l},right:#{r},top:#{t},bottom:#{b}, width:#{w}, height:#{h}\n\n" if $DEBUG
|
747
|
+
s.width = w if prop[:width]
|
748
|
+
s.height = h if prop[:height]
|
747
749
|
s.text_style=Rubyvis::Color.transparent if prop[:text_style] and !s.text_style
|
748
750
|
s.fill_style=Rubyvis::Color.transparent if prop[:fill_style] and !s.fill_style
|
749
751
|
s.stroke_style=Rubyvis::Color.transparent if prop[:stroke_style] and !s.stroke_style
|
@@ -874,7 +876,7 @@ module Rubyvis
|
|
874
876
|
@types[2].push(@seen[name])
|
875
877
|
end
|
876
878
|
}
|
877
|
-
end while(mark=mark.proto)
|
879
|
+
end while(mark = mark.proto)
|
878
880
|
@binds=OpenStruct.new({:properties=>@seen, :data=>@_data, :required=>@_required, :optional=>@types[1]+@types[2]+@types[3]
|
879
881
|
})
|
880
882
|
end
|
data/lib/rubyvis/mark/area.rb
CHANGED
@@ -55,9 +55,9 @@ module Rubyvis
|
|
55
55
|
# p binds.fixed
|
56
56
|
#/* Evaluate all properties on the first instance. */
|
57
57
|
else
|
58
|
-
binds.required = binds._required
|
59
|
-
binds.optional = binds._optional
|
60
|
-
binds.fixed = nil
|
58
|
+
binds.required = binds._required
|
59
|
+
binds.optional = binds._optional
|
60
|
+
binds.fixed = nil
|
61
61
|
end
|
62
62
|
# pp binds
|
63
63
|
mark_build_instance(s)
|
@@ -66,7 +66,7 @@ module Rubyvis
|
|
66
66
|
|
67
67
|
|
68
68
|
def area_bind
|
69
|
-
mark_bind
|
69
|
+
mark_bind
|
70
70
|
binds = self.binds
|
71
71
|
|
72
72
|
required = binds.required
|
@@ -80,8 +80,8 @@ module Rubyvis
|
|
80
80
|
}
|
81
81
|
optional.delete_if {|v| v.name=='segmented'}
|
82
82
|
# Cache the original arrays so they can be restored on build. */
|
83
|
-
@binds._required = required
|
84
|
-
@binds._optional = optional
|
83
|
+
@binds._required = required
|
84
|
+
@binds._optional = optional
|
85
85
|
end
|
86
86
|
|
87
87
|
|
data/lib/rubyvis/mark/dot.rb
CHANGED
@@ -21,7 +21,7 @@ module Rubyvis
|
|
21
21
|
# :attr: shape_size
|
22
22
|
# The size of the shape, in square pixels. Square pixels are used such that the
|
23
23
|
# area of the shape is linearly proportional to the value of the
|
24
|
-
# <tt>
|
24
|
+
# <tt>shape_size</tt> property, facilitating representative encodings. This is
|
25
25
|
# an alternative to using shape_radius
|
26
26
|
#
|
27
27
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class Rubyvis::Mark
|
2
2
|
##
|
3
|
-
# :section:
|
3
|
+
# :section: RBP Api
|
4
4
|
##
|
5
5
|
|
6
|
-
# Create
|
6
|
+
# Create a new Mark method shorcut.
|
7
7
|
def self.mark_method(name, mark) #:nodoc:
|
8
8
|
define_method(name) do |*args,&block|
|
9
9
|
opts=args[0]
|
@@ -240,5 +240,32 @@ class Rubyvis::Mark
|
|
240
240
|
# See Mark for examples of use
|
241
241
|
mark_method :layout_pack, Rubyvis::Layout::Pack
|
242
242
|
|
243
|
+
##
|
244
|
+
# :method: layout_grid(opts,&block)
|
245
|
+
#
|
246
|
+
# Adds a Layout::Grid to current mark.
|
247
|
+
#
|
248
|
+
# If a block is provided, the context will be defined differently if
|
249
|
+
# parameter is provided
|
250
|
+
# * Without parameter: block executed inside context of new mark
|
251
|
+
# * With paramenter: block executed inside context of current mark.
|
252
|
+
# Paramenter references new mark
|
253
|
+
#
|
254
|
+
# See Mark for examples of use
|
255
|
+
mark_method :layout_grid, Rubyvis::Layout::Grid
|
256
|
+
|
257
|
+
##
|
258
|
+
# :method: tree_grid(opts,&block)
|
259
|
+
#
|
260
|
+
# Adds a Layout::Tree to current mark.
|
261
|
+
#
|
262
|
+
# If a block is provided, the context will be defined differently if
|
263
|
+
# parameter is provided
|
264
|
+
# * Without parameter: block executed inside context of new mark
|
265
|
+
# * With paramenter: block executed inside context of current mark.
|
266
|
+
# Paramenter references new mark
|
267
|
+
#
|
268
|
+
# See Mark for examples of use
|
269
|
+
mark_method :layout_tree, Rubyvis::Layout::Tree
|
243
270
|
|
244
271
|
end
|
data/lib/rubyvis/nest.rb
CHANGED
@@ -90,6 +90,22 @@ module Rubyvis
|
|
90
90
|
@order = order.nil? ? Rubyvis.natural_order : order
|
91
91
|
return self
|
92
92
|
end
|
93
|
+
|
94
|
+
# Returns a hierarchical map of values. Each key adds one level to the
|
95
|
+
# hierarchy. With only a single key, the returned map will have a key for each
|
96
|
+
# distinct value of the key function; the correspond value with be an array of
|
97
|
+
# elements with that key value. If a second key is added, this will be a nested
|
98
|
+
# map. For example:
|
99
|
+
#
|
100
|
+
# <pre>Rubyvis.nest(yields)
|
101
|
+
# .key(function(d) d.variety)
|
102
|
+
# .key(function(d) d.site)
|
103
|
+
# .map()</pre>
|
104
|
+
#
|
105
|
+
# returns a map <tt>m</tt> such that <tt>m[variety][site]</tt> is an array, a subset of
|
106
|
+
# <tt>yields</tt>, with each element having the given variety and site.
|
107
|
+
#
|
108
|
+
# @returns a hierarchical map of values
|
93
109
|
def map
|
94
110
|
#i=0
|
95
111
|
map={}
|
@@ -116,6 +132,19 @@ module Rubyvis
|
|
116
132
|
end
|
117
133
|
map
|
118
134
|
end
|
135
|
+
|
136
|
+
# Returns a hierarchical nested array. This method is similar to
|
137
|
+
# {@link pv.entries}, but works recursively on the entire hierarchy. Rather
|
138
|
+
# than returning a map like {@link #map}, this method returns a nested
|
139
|
+
# array. Each element of the array has a <tt>key</tt> and <tt>values</tt>
|
140
|
+
# field. For leaf nodes, the <tt>values</tt> array will be a subset of the
|
141
|
+
# underlying elements array; for non-leaf nodes, the <tt>values</tt> array will
|
142
|
+
# contain more key-values pairs.
|
143
|
+
#
|
144
|
+
# <p>For an example usage, see the {@link Nest} constructor.
|
145
|
+
#
|
146
|
+
# @returns a hierarchical nested array.
|
147
|
+
|
119
148
|
def entries()
|
120
149
|
entries_sort(entries_entries(map),0)
|
121
150
|
end
|
@@ -145,13 +174,30 @@ module Rubyvis
|
|
145
174
|
if value.is_a? Array
|
146
175
|
map[key]=f.call(value)
|
147
176
|
else
|
148
|
-
rollup_rollup(value)
|
177
|
+
rollup_rollup(value,f)
|
149
178
|
end
|
150
179
|
}
|
151
180
|
return map;
|
152
181
|
end
|
182
|
+
|
183
|
+
# Returns a rollup map. The behavior of this method is the same as
|
184
|
+
# {@link #map}, except that the leaf values are replaced with the return value
|
185
|
+
# of the specified rollup function <tt>f</tt>. For example,
|
186
|
+
#
|
187
|
+
# <pre>pv.nest(yields)
|
188
|
+
# .key(function(d) d.site)
|
189
|
+
# .rollup(function(v) pv.median(v, function(d) d.yield))</pre>
|
190
|
+
#
|
191
|
+
# first groups yield data by site, and then returns a map from site to median
|
192
|
+
# yield for the given site.
|
193
|
+
#
|
194
|
+
# @see #map
|
195
|
+
# @param {function} f a rollup function.
|
196
|
+
# @returns a hierarchical map, with the leaf values computed by <tt>f</tt>.
|
197
|
+
|
198
|
+
|
153
199
|
def rollup(f)
|
154
|
-
rollup_rollup(self.map,f)
|
200
|
+
rollup_rollup(self.map, f)
|
155
201
|
end
|
156
202
|
end
|
157
203
|
end
|