rubyvis 0.3.5 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ === 0.3.6 / 2010-12-28
2
+
3
+ * Matrix layout implemented. Example and spec available.
4
+ * Added spec for Layout::Arc
5
+
1
6
  === 0.3.5 / 2010-12-20
2
7
 
3
8
  * Horizon and Arc layouts implemented
data/Manifest.txt CHANGED
@@ -46,6 +46,7 @@ examples/5_pv_hierarchies/node_link_tree.rb
46
46
  examples/5_pv_hierarchies/sunburst.rb
47
47
  examples/5_pv_hierarchies/treemap.rb
48
48
  examples/6_pv_networks/arc.rb
49
+ examples/6_pv_networks/matrix.rb
49
50
  examples/6_pv_networks/miserables_data.rb
50
51
  lib/rubyvis.rb
51
52
  lib/rubyvis/color/color.rb
@@ -65,6 +66,7 @@ lib/rubyvis/layout/grid.rb
65
66
  lib/rubyvis/layout/hierarchy.rb
66
67
  lib/rubyvis/layout/horizon.rb
67
68
  lib/rubyvis/layout/indent.rb
69
+ lib/rubyvis/layout/matrix.rb
68
70
  lib/rubyvis/layout/network.rb
69
71
  lib/rubyvis/layout/pack.rb
70
72
  lib/rubyvis/layout/partition.rb
@@ -112,7 +114,9 @@ spec/histogram_spec.rb
112
114
  spec/internal_spec.rb
113
115
  spec/javascript_behaviour_spec.rb
114
116
  spec/label_spec.rb
117
+ spec/layout_arc_spec.rb
115
118
  spec/layout_horizon_spec.rb
119
+ spec/layout_matrix_spec.rb
116
120
  spec/layout_stack_spec.rb
117
121
  spec/line_spec.rb
118
122
  spec/mark_spec.rb
data/README.txt CHANGED
@@ -33,6 +33,8 @@ Using protovis examples[http://vis.stanford.edu/protovis/ex/] as reference
33
33
  * Node-Link Tree
34
34
  * Sunburst
35
35
  * Treemap
36
+ * Networks:
37
+ * Arc
36
38
 
37
39
 
38
40
  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.
@@ -54,6 +56,7 @@ User could use +pv+ freely, cause is defined as a global method which call Rubyv
54
56
  * data/QuantitativeScale.js
55
57
  * data/OrdinalScale.js
56
58
  * data/Scale.js
59
+ * layout/Arc.js
57
60
  * layout/Layout.js
58
61
  * layout/Cluster.js
59
62
  * layout/Grid.js
data/Rakefile CHANGED
@@ -11,13 +11,28 @@ require 'rspec/core/rake_task'
11
11
 
12
12
  Hoe.plugin :git
13
13
 
14
- Hoe.spec 'rubyvis' do
14
+ h=Hoe.spec 'rubyvis' do
15
15
  self.testlib=:rspec
16
- #self.test_globs="spec/*_spec.rb"
17
16
  self.rspec_options << "-c" << "-b"
18
17
  self.developer('Claudio Bustos', 'clbustos_at_gmail.com')
19
18
  self.version=Rubyvis::VERSION
20
19
  self.extra_dev_deps << ["coderay",">=0"] << ["haml",">=0"] << ["nokogiri", ">=0"] << ["rspec",">=2.0"]
21
20
  end
22
21
 
22
+ task :publicar_docs => [:clean, :docs] do
23
+ #ruby %{agregar_adsense_a_doc.rb}
24
+ path = File.expand_path("~/.rubyforge/user-config.yml")
25
+ config = YAML.load(File.read(path))
26
+ host = "#{config["username"]}@rubyforge.org"
27
+
28
+ remote_dir = "/var/www/gforge-projects/#{h.rubyforge_name}/#{h.remote_rdoc_dir
29
+ }"
30
+ local_dir = h.local_rdoc_dir
31
+ Dir.glob(local_dir+"/**/*") {|file|
32
+ sh %{chmod 755 #{file}}
33
+ }
34
+ sh %{rsync #{h.rsync_args} #{local_dir}/ #{host}:#{remote_dir}}
35
+ end
36
+
37
+
23
38
  # vim: syntax=ruby
@@ -0,0 +1,34 @@
1
+ # = Matrix Diagrams
2
+ # A graph can be represented by an adjacency matrix, where each value in row i and column j corresponds to the link from node i to node j. Given this representation, an obvious visualization then is: show the matrix! Using color or saturation instead of text allows patterns to be perceived rapidly. The seriation problem applies just as much to the matrix view as to the arc diagram, so the order of rows and columns is important: here we use a community-detection algorithm to order and color the display.
3
+ # While path following is harder in a matrix view than in a node-link diagram, matrices have a number of compensating advantages. As networks get large and highly connected, node-link diagrams often devolve into giant hairballs of line crossings. In matrix views, however, line crossings are impossible, and with an effective sorting one quickly can spot clusters and bridges. Allowing interactive grouping and reordering of the matrix facilitates deeper exploration of network structure.
4
+ # This network represents character co-occurrence in the chapters of Victor Hugo's classic novel, Les Misérables. Node colors depict cluster memberships computed by a community-detection algorithm. Source: Knuth, D. E. 1993. The Stanford GraphBase: A Platform for Combinatorial Computing, Addison-Wesley.
5
+
6
+ $:.unshift(File.dirname(__FILE__)+"/../../lib")
7
+ require 'rubyvis'
8
+ load(File.dirname(__FILE__)+"/miserables_data.rb")
9
+ color=Rubyvis::Colors.category19
10
+
11
+
12
+ vis = Rubyvis::Panel.new() do
13
+ width 693
14
+ height 693
15
+ top 90
16
+ left 90
17
+ layout_matrix do
18
+ nodes $miserables.nodes
19
+ links $miserables.links
20
+ sort {|a,b| b.group<=>a.group }
21
+ directed (false)
22
+ link.bar do
23
+ fill_style {|l| l.link_value!=0 ?
24
+ ((l.target_node.group == l.source_node.group) ? color[l.source_node.group] : "#555") : "#eee"}
25
+ antialias(false)
26
+ line_width(1)
27
+ end
28
+ node_label.label do
29
+ text_style {|l| color[l.group]}
30
+ end
31
+ end
32
+ end
33
+ vis.render()
34
+ puts vis.to_svg
@@ -5,7 +5,7 @@ module Rubyvis
5
5
  Rubyvis::Layout::Arc
6
6
  end
7
7
 
8
- # @class Implements a layout for arc diagrams. An arc diagram is a network
8
+ # Implements a layout for arc diagrams. An arc diagram is a network
9
9
  # visualization with a one-dimensional layout of nodes, using circular arcs to
10
10
  # render links between nodes. For undirected networks, arcs are rendering on a
11
11
  # single side; this makes arc diagrams useful as annotations to other
@@ -16,28 +16,27 @@ module Rubyvis
16
16
  # <p>Arc layouts are particularly sensitive to node ordering; for best results,
17
17
  # order the nodes such that related nodes are close to each other. A poor
18
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.
19
+ # visual processing. A future improvement to this layout may include automatic reordering using, e.g., spectral graph layout or simulated annealing.
21
20
  #
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.
21
+ # This visualization technique is related to that developed by M. Wattenberg, {Arc Diagrams: Visualizing Structure in Strings}[http://www.research.ibm.com/visual/papers/arc-diagrams.pdf] in IEEE InfoVis, 2002.
26
22
  # However, this implementation is limited to simple node-link networks, as
27
23
  # opposed to structures with hierarchical self-similarity (such as strings).
24
+ # As with other network layouts, three mark prototypes are provided:<ul>
28
25
  #
29
- # <p>As with other network layouts, three mark prototypes are provided:<ul>
26
+ # <li><tt>node</tt> - for rendering nodes; typically a Rubyvis::Dot
27
+ # <li><tt>link</tt> - for rendering links; typically a Rubyvis::Line
28
+ # <li><tt>node_label</tt> - for rendering node labels; typically a Rubyvis::Label
30
29
  #
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}.
30
+ # </ul>
31
+ # For more details on how this layout is structured and can be customized,
32
+ # see Rubyvis::Layout::Network
37
33
 
38
34
  class Arc < Network
39
- @properties=Network.properties.dup
40
- attr_accessor :_interpolate, :_directed, :_reverse
35
+ @properties=Network.properties.dup
36
+
37
+ attr_accessor :_interpolate # :nodoc:
38
+ attr_accessor :_directed # :nodoc:
39
+ attr_accessor :_reverse # :nodoc:
41
40
  def initialize
42
41
  super
43
42
  @_interpolate=nil # cached interpolate
@@ -51,7 +50,7 @@ module Rubyvis
51
50
  }).interpolate(lambda{ that._interpolate})
52
51
  end
53
52
 
54
- def build_implied(s)
53
+ def build_implied(s) # :nodoc:
55
54
  return true if network_build_implied(s)
56
55
  # Cached
57
56
 
@@ -87,17 +86,17 @@ module Rubyvis
87
86
 
88
87
  # /** @private Returns the x-position, given the breadth. */
89
88
  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))
89
+ case orient
90
+ when "top"
91
+ b * w
92
+ when "bottom"
93
+ b * w
94
+ when "left"
95
+ 0;
96
+ when "right"
97
+ w;
98
+ when "radial"
99
+ w / 2.0 + r * Math.cos(mid_angle.call(b))
101
100
  end
102
101
  end
103
102
 
@@ -135,8 +134,7 @@ module Rubyvis
135
134
 
136
135
  ##
137
136
  # :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
137
+ # The orientation. The default orientation is "bottom", which means that nodes will be positioned from bottom-to-top in the order they are specified in the
140
138
  # <tt>nodes</tt> property. The following orientations are supported:<ul>
141
139
  #
142
140
  # <li>left - left-to-right.
@@ -155,26 +153,23 @@ module Rubyvis
155
153
  # respectively), while reverse links are drawn on the opposite side.
156
154
 
157
155
  attr_accessor_dsl :orient, :directed
158
-
156
+ # Default properties for arc layouts. By default, the orientation is "bottom".
159
157
  def self.defaults
160
158
  Arc.new.mark_extend(Network.defaults).
161
159
  orient("bottom")
162
160
  end
163
161
 
164
162
  # Specifies an optional sort function. The sort function follows the same
165
- # comparator contract required by {@link pv.Dom.Node#sort}. Specifying a sort
163
+ # comparator contract required by Rubyvis::Dom::Node.sort(). Specifying a sort
166
164
  # function provides an alternative to sort the nodes as they are specified by
167
165
  # the <tt>nodes</tt> property; the main advantage of doing this is that the
168
166
  # comparator function can access implicit fields populated by the network
169
- # layout, such as the <tt>linkDegree</tt>.
167
+ # layout, such as the <tt>link_degree</tt>.
170
168
  #
171
169
  # <p>Note that arc diagrams are particularly sensitive to order. This is
172
170
  # referred to as the seriation problem, and many different techniques exist to
173
171
  # find good node orders that emphasize clusters, such as spectral layout and
174
172
  # simulated annealing.
175
- #
176
- # @param {function} f comparator function for nodes.
177
- # @returns {pv.Layout.Arc} this.
178
173
  def sort(f=nil,&block)
179
174
  f||=block
180
175
  @_sort=f
@@ -18,7 +18,7 @@ module Rubyvis
18
18
  # sizing for leaf nodes; all leaf nodes are the same size.
19
19
  #
20
20
  # <p>For more details on how to use this layout, see
21
- # {@link pv.Layout.Hierarchy}.
21
+ # Rubyvis::Layout::Hierarchy.
22
22
  #
23
23
  # @see pv.Layout.Cluster.Fill
24
24
  # @extends pv.Layout.Hierarchy
@@ -141,9 +141,9 @@ module Rubyvis
141
141
  if (n.first_child)
142
142
  n.breadth = Rubyvis.mean(n.child_nodes, lambda {|nn| nn.breadth })
143
143
  else
144
- if (group!=0 and (par != n.parent_node))
145
- par = n.parent_node
146
- leaf_index += group
144
+ if (group!=0 and (par != n.parent_node))
145
+ par = n.parent_node
146
+ leaf_index += group
147
147
  end
148
148
  n.breadth = breadth * leaf_index
149
149
  leaf_index+=1
@@ -179,7 +179,7 @@ module Rubyvis
179
179
  # in the arrangement of the space-filling nodes.
180
180
  #
181
181
  # <p><li><tt>label</tt> - for rendering node labels; typically a
182
- # {@link pv.Label}.
182
+ # Rubyvis::Label.
183
183
  #
184
184
  # </ul>For more details on how to use this layout, see
185
185
  # {@link pv.Layout.Cluster}.
@@ -9,9 +9,9 @@ module Rubyvis
9
9
  # area chart where the area is folded into multiple bands. Color is used to
10
10
  # encode band, allowing the size of the chart to be reduced significantly
11
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
12
+ # J. Heer, N. Kong and M. Agrawala in {Sizing
13
13
  # the Horizon: The Effects of Chart Size and Layering on the Graphical
14
- # Perception of Time Series Visualizations"</a>, CHI 2009.
14
+ # Perception of Time Series Visualizations}[http://hci.stanford.edu/publications/2009/heer-horizon-chi09.pdf], CHI 2009.
15
15
  #
16
16
  # <p>This layout exports a single <tt>band</tt> mark prototype, which is
17
17
  # intended to be used with an area mark. The band mark is contained in a panel
@@ -0,0 +1,188 @@
1
+ module Rubyvis
2
+ class Layout
3
+ # Alias for Rubyvis::Layout::Matrix
4
+ def self.Matrix
5
+ Rubyvis::Layout::Matrix
6
+ end
7
+
8
+ # Implements a network visualization using a matrix view. This is, in
9
+ # effect, a visualization of the graph's <i>adjacency matrix</i>: the cell at
10
+ # row <i>i</i>, column <i>j</i>, corresponds to the link from node <i>i</i> to
11
+ # node <i>j</i>. The fill color of each cell is binary by default, and
12
+ # corresponds to whether a link exists between the two nodes. If the underlying
13
+ # graph has links with variable values, the <tt>fillStyle</tt> property can be
14
+ # substited to use an appropriate color function, such as {@link pv.ramp}.
15
+ #
16
+ # <p>For undirected networks, the matrix is symmetric around the diagonal. For
17
+ # directed networks, links in opposite directions can be rendered on opposite
18
+ # sides of the diagonal using <tt>directed(true)</tt>. The graph is assumed to
19
+ # be undirected by default.
20
+ #
21
+ # <p>The mark prototypes for this network layout are slightly different than
22
+ # other implementations:<ul>
23
+ #
24
+ # <li><tt>node</tt> - unsupported; undefined. No mark is needed to visualize
25
+ # nodes directly, as the nodes are implicit in the location (rows and columns)
26
+ # of the links.
27
+ #
28
+ # <p><li><tt>link</tt> - for rendering links; typically a {@link pv.Bar}. The
29
+ # link mark is added directly to the layout, with the data property defined as
30
+ # all possible pairs of nodes. Each pair is represented as a
31
+ # {@link pv.Network.Layout.Link}, though the <tt>linkValue</tt> attribute may
32
+ # be 0 if no link exists in the graph.
33
+ #
34
+ # <p><li><tt>label</tt> - for rendering node labels; typically a
35
+ # {@link pv.Label}. The label mark is added directly to the layout, with the
36
+ # data property defined via the layout's <tt>nodes</tt> property; note,
37
+ # however, that the nodes are duplicated so as to provide a label across the
38
+ # top and down the side. Properties such as <tt>strokeStyle</tt> and
39
+ # <tt>fillStyle</tt> can be overridden to compute properties from node data
40
+ # dynamically.
41
+ #
42
+ # </ul>For more details on how to use this layout, see
43
+ # {@link pv.Layout.Network}.
44
+ class Matrix < Network
45
+ @properties=Network.properties.dup
46
+ attr_accessor :_n, :_dx, :_dy, :_labels, :_pairs
47
+ def build_implied_post(s)
48
+ @_n = s.nodes.size
49
+ @_dx = s.width.to_f / @_n
50
+ @_dy = s.height.to_f / @_n
51
+ @_labels = s._matrix.labels
52
+ @_pairs = s._matrix.pairs
53
+ end
54
+ # Deletes special add from network
55
+ def _link # :nodoc:
56
+ that=self
57
+ l=Mark.new().
58
+ mark_extend(@node).
59
+ data(lambda {|d| [d.source_node, d.target_node] }).
60
+ fill_style(nil).
61
+ line_width(lambda {|d,_p| _p.link_value * 1.5 }).
62
+ stroke_style("rgba(0,0,0,.2)")
63
+ l
64
+ end
65
+
66
+ def initialize
67
+ super
68
+ @_n=nil, # cached matrix size
69
+ @_dx=nil, # cached cell width
70
+ @_dy=nil, # cached cell height
71
+ @_labels=nil, # cached labels (array of strings)
72
+ @_pairs=nil, # cached pairs (array of links)
73
+ that=self
74
+ #/* Links are all pairs of nodes. */
75
+ @link.data(lambda {that._pairs})
76
+ .left(lambda { that._dx * (self.index % that._n) })
77
+ .top(lambda { that._dy * (self.index / that._n.to_f).floor })
78
+ .width(lambda { that._dx })
79
+ .height(lambda { that._dy })
80
+ .line_width(1.5)
81
+ .stroke_style("#fff")
82
+ .fill_style(lambda {|l| l.link_value!=0 ? "#555" : "#eee" })
83
+
84
+ @link.parent = self
85
+ #/* No special add for links! */
86
+
87
+ # delete this.link.add;
88
+
89
+ #/* Labels are duplicated for top & left. */
90
+ @node_label.
91
+ data(lambda { that._labels }).
92
+ left(lambda { (self.index & 1)!=0 ? that._dx * ((self.index >> 1) + 0.5) : 0 }).
93
+ top(lambda { (self.index & 1)!=0 ? 0 : that._dy * ((self.index >> 1) + 0.5) }).
94
+ text_margin(4).text_align(lambda { (self.index & 1)!=0 ? "left" : "right"; }).
95
+ text_angle(lambda { (self.index & 1)!=0 ? -Math::PI / 2.0 : 0; });
96
+ @node=nil
97
+ end
98
+ def self.defaults
99
+ Matrix.new.mark_extend(Network.defaults).
100
+ directed(true)
101
+ end
102
+ ##
103
+ # :attr: directed
104
+ #
105
+ # Whether this matrix visualization is directed (bidirectional). By default,
106
+ # the graph is assumed to be undirected, such that the visualization is
107
+ # symmetric across the matrix diagonal. If the network is directed, then
108
+ # forward links are drawn above the diagonal, while reverse links are drawn
109
+ # below.
110
+ #
111
+ # @type boolean
112
+ # @name pv.Layout.Matrix.prototype.directed
113
+ #/
114
+
115
+ attr_accessor_dsl :directed
116
+
117
+
118
+ # Specifies an optional sort function. The sort function follows the same
119
+ # comparator contract required by {@link pv.Dom.Node#sort}. Specifying a sort
120
+ # function provides an alternative to sort the nodes as they are specified by
121
+ # the <tt>nodes</tt> property; the main advantage of doing this is that the
122
+ # comparator function can access implicit fields populated by the network
123
+ # layout, such as the <tt>linkDegree</tt>.
124
+ #
125
+ # <p>Note that matrix visualizations are particularly sensitive to order. This
126
+ # is referred to as the seriation problem, and many different techniques exist
127
+ # to find good node orders that emphasize clusters, such as spectral layout and
128
+ # simulated annealing.
129
+ #
130
+ # @param {function} f comparator function for nodes.
131
+ # @returns {pv.Layout.Matrix} this.
132
+ #/
133
+ def sort(f=nil,&block)
134
+ f||=block
135
+ @sort=f
136
+ self
137
+ end
138
+ def build_implied(s) # :nodoc:
139
+ return nil if network_build_implied(s)
140
+ nodes = s.nodes
141
+ links = s.links
142
+ sort = @sort
143
+
144
+ n = nodes.size
145
+ index = Rubyvis.range(n)
146
+ labels = []
147
+ pairs = []
148
+ map = {}
149
+
150
+ s._matrix = OpenStruct.new({:labels=> labels, :pairs=> pairs})
151
+
152
+ #/* Sort the nodes. */
153
+ if sort
154
+ index.sort! {|a,b| sort.call(nodes[a],nodes[b])}
155
+ end
156
+ #/* Create pairs. */
157
+ n.times {|i|
158
+ n.times {|j|
159
+ a = index[i]
160
+ b = index[j]
161
+ _p = OpenStruct.new({
162
+ :row=> i,
163
+ :col=> j,
164
+ :source_node=> nodes[a],
165
+ :target_node=> nodes[b],
166
+ :link_value=> 0})
167
+ map["#{a}.#{b}"] = _p
168
+ pairs.push(map["#{a}.#{b}"])
169
+ }
170
+ }
171
+ #/* Create labels. */
172
+ n.times {|i|
173
+ a = index[i]
174
+ labels.push(nodes[a], nodes[a])
175
+ }
176
+ #/* Accumulate link values. */
177
+ links.each_with_index {|l,i|
178
+ source = l.source_node.index
179
+ target = l.target_node.index
180
+ value = l.link_value
181
+ map["#{source}.#{target}"].link_value += value
182
+ map["#{target}.#{source}"].link_value += value if (!s.directed)
183
+ }
184
+ build_implied_post(s)
185
+ end
186
+ end
187
+ end
188
+ end
@@ -15,7 +15,7 @@ module Rubyvis
15
15
  # Network layouts require the graph data structure to be defined using two
16
16
  # properties:<ul>
17
17
  #
18
- # <li><tt>nodes</tt> - an array of objects representing nodes. Objects in this array must conform to the {@link pv.Layout.Network.Node} interface; which is
18
+ # <li><tt>nodes</tt> - an array of objects representing nodes. Objects in this array must conform to the Rubyvis::Layout::Network::Node interface; which is
19
19
  # to say, be careful to avoid naming collisions with automatic attributes such
20
20
  # as <tt>index</tt> and <tt>link_degree</tt>.
21
21
  # If the nodes property is defined
@@ -24,7 +24,7 @@ module Rubyvis
24
24
  # attribute points to the original primitive value.
25
25
  #
26
26
  # <p><li><tt>links</tt> - an array of objects representing links. Objects in
27
- # this array must conform to the {@link pv.Layout.Network.Link} interface; at a minimum, either <tt>source</tt> and <tt>target</tt> indexes or
27
+ # this array must conform to the Rubyvis::Layout::Network::Link interface; at a minimum, either <tt>source</tt> and <tt>target</tt> indexes or
28
28
  # <tt>source_node</tt> and <tt>target_node</tt> references must be set. Note that
29
29
  # if the links property is defined after the nodes property, the links can be defined in terms of <tt>this.nodes()</tt>.
30
30
  #
@@ -32,22 +32,18 @@ module Rubyvis
32
32
  #
33
33
  # <p>Three standard mark prototypes are provided:<ul>
34
34
  #
35
- # <li><tt>node</tt> - for rendering nodes; typically a {@link pv.Dot}. The node
36
- # mark is added directly to the layout, with the data property defined via the
37
- # layout's <tt>nodes</tt> property. Properties such as <tt>strokeStyle</tt> and
38
- # <tt>fillStyle</tt> can be overridden to compute properties from node data
39
- # dynamically.
35
+ # <li><tt>node</tt> - for rendering nodes; typically a Rubyvis::Dot. The node mark is added directly to the layout, with the data property defined via the layout's <tt>nodes</tt> property. Properties such as <tt>stroke_style</tt> and <tt>fillStyle</tt> can be overridden to compute properties from node data dynamically.
40
36
  #
41
- # <p><li><tt>link</tt> - for rendering links; typically a {@link pv.Line}. The
37
+ # <p><li><tt>link</tt> - for rendering links; typically a Rubyvis::Line. The
42
38
  # link mark is added to a child panel, whose data property is defined as
43
39
  # layout's <tt>links</tt> property. The link's data property is then a
44
40
  # two-element array of the source node and target node. Thus, poperties such as
45
- # <tt>strokeStyle</tt> and <tt>fillStyle</tt> can be overridden to compute
41
+ # <tt>stroke_style</tt> and <tt>fill_style</tt> can be overridden to compute
46
42
  # properties from either the node data (the first argument) or the link data
47
43
  # (the second argument; the parent panel data) dynamically.
48
44
  #
49
- # <p><li><tt>label</tt> - for rendering node labels; typically a
50
- # {@link pv.Label}. The label mark is added directly to the layout, with the
45
+ # <p><li><tt>node_label</tt> - for rendering node labels; typically a
46
+ # Rubyvis::Label. The label mark is added directly to the layout, with the
51
47
  # data property defined via the layout's <tt>nodes</tt> property. Properties
52
48
  # such as <tt>strokeStyle</tt> and <tt>fillStyle</tt> can be overridden to
53
49
  # compute properties from node data dynamically.
@@ -223,6 +219,7 @@ module Rubyvis
223
219
  def build_implied(s) # :nodoc:
224
220
  network_build_implied(s)
225
221
  end
222
+
226
223
  def network_build_implied(s) # :nodoc:
227
224
  layout_build_implied(s)
228
225
  return true if (!s._id.nil? and s._id >= self._id)
@@ -9,13 +9,13 @@ module Rubyvis
9
9
  # the exported mark prototypes changes slightly in the space-filling
10
10
  # implementation:<ul>
11
11
  #
12
- # <li><tt>node</tt> - for rendering nodes; typically a {@link pv.Dot}.
12
+ # <li><tt>node</tt> - for rendering nodes; typically a Rubyvis::Dot.
13
13
  #
14
14
  # <p><li><tt>link</tt> - unsupported; undefined. Links are encoded implicitly
15
15
  # in the arrangement of the space-filling nodes.
16
16
  #
17
17
  # <p><li><tt>label</tt> - for rendering node labels; typically a
18
- # {@link pv.Label}.
18
+ # Rubyvis::Label.
19
19
  #
20
20
  # </ul>The pack layout support dynamic sizing for leaf nodes, if a
21
21
  # {@link #size} psuedo-property is specified. The default size function returns
@@ -29,7 +29,7 @@ module Rubyvis
29
29
  # operator.
30
30
  #
31
31
  # <p>For more details on how to use this layout, see
32
- # {@link pv.Layout.Hierarchy}.
32
+ # Rubyvis::Layout::Hierarchy.
33
33
  #
34
34
  # @extends pv.Layout.Hierarchy
35
35
  # @see <a href="http://portal.acm.org/citation.cfm?id=1124772.1124851"
@@ -22,7 +22,7 @@ module Rubyvis
22
22
  # operator.
23
23
  #
24
24
  # <p>For more details on how to use this layout, see
25
- # {@link pv.Layout.Hierarchy}.
25
+ # Rubyvis::Layout::Hierarchy.
26
26
  #
27
27
  # @see pv.Layout.Partition.Fill
28
28
  # @extends pv.Layout.Hierarchy
@@ -193,7 +193,7 @@ module Rubyvis
193
193
  # in the arrangement of the space-filling nodes.
194
194
  #
195
195
  # <p><li><tt>label</tt> - for rendering node labels; typically a
196
- # {@link pv.Label}.
196
+ # Rubyvis::Label.
197
197
  #
198
198
  # </ul>For more details on how to use this layout, see
199
199
  # {@link pv.Layout.Partition}.
@@ -18,7 +18,7 @@ module Rubyvis
18
18
  # dimensions, similar to the indent layout.
19
19
  #
20
20
  # <p>For more details on how to use this layout, see
21
- # {@link pv.Layout.Hierarchy}
21
+ # Rubyvis::Layout::Hierarchy
22
22
  class Tree < Hierarchy
23
23
  @properties=Hierarchy.properties.dup
24
24
  def initialize
@@ -1,5 +1,6 @@
1
1
  module Rubyvis
2
2
  class Layout
3
+ # Alias for Rubyvis::Layout::Treemap
3
4
  def self.Treemap
4
5
  Rubyvis::Layout::Treemap
5
6
  end
@@ -21,16 +22,16 @@ module Rubyvis
21
22
  # the standard <tt>x</tt> and <tt>y</tt> position attributes.
22
23
  #
23
24
  # <p><li><tt>leaf</tt> - for rendering leaf nodes only, with no fill or stroke
24
- # style by default; typically a {@link pv.Panel} or another layout!
25
+ # style by default; typically a Rubyvis::Panel or another layout!
25
26
  #
26
27
  # <p><li><tt>link</tt> - unsupported; undefined. Links are encoded implicitly
27
28
  # in the arrangement of the space-filling nodes.
28
29
  #
29
30
  # <p><li><tt>label</tt> - for rendering node labels; typically a
30
- # {@link pv.Label}.
31
+ # Rubyvis::Label.
31
32
  #
32
33
  # </ul>For more details on how to use this layout, see
33
- # {@link pv.Layout.Hierarchy}.
34
+ # Rubyvis::Layout::Hierarchy.
34
35
  #
35
36
  class Treemap < Hierarchy
36
37
  @properties=Hierarchy.properties.dup
@@ -265,14 +266,14 @@ module Rubyvis
265
266
 
266
267
  if (n.size > 0)
267
268
  #/* Scale the sizes to fill the current subregion. */
268
- n.visit_before {|n,i| n.size *= k }
269
+ n.visit_before {|n1,i1| n1.size *= k }
269
270
 
270
271
  #/** @private Position the specified nodes along one dimension. */
271
- position=lambda {|row|
272
+ position=lambda {|row1|
272
273
  horizontal = w == l
273
- sum = Rubyvis.sum(row, size)
274
+ sum = Rubyvis.sum(row1, size)
274
275
  r = l>0 ? round.call(sum / l.to_f) : 0
275
- slice.call(row, sum, horizontal, x, y, horizontal ? w : r, horizontal ? r : h)
276
+ slice.call(row1, sum, horizontal, x, y, horizontal ? w : r, horizontal ? r : h)
276
277
  if horizontal
277
278
  y += r
278
279
  h -= r
@@ -43,4 +43,5 @@ require 'rubyvis/layout/cluster'
43
43
  require 'rubyvis/layout/indent'
44
44
  require 'rubyvis/layout/pack'
45
45
  require 'rubyvis/layout/arc'
46
+ require 'rubyvis/layout/matrix'
46
47
 
@@ -295,5 +295,19 @@ class Rubyvis::Mark
295
295
  #
296
296
  # See Mark for examples of use
297
297
  mark_method :layout_arc, Rubyvis::Layout::Arc
298
+
299
+ ##
300
+ # :method: layout_matrix(opts,&block)
301
+ #
302
+ # Adds a Layout::Matrix to current mark.
303
+ #
304
+ # If a block is provided, the context will be defined differently if
305
+ # parameter is provided
306
+ # * Without parameter: block executed inside context of new mark
307
+ # * With paramenter: block executed inside context of current mark.
308
+ # Paramenter references new mark
309
+ #
310
+ # See Mark for examples of use
311
+ mark_method :layout_matrix, Rubyvis::Layout::Matrix
298
312
 
299
313
  end
@@ -8,7 +8,7 @@ module Rubyvis
8
8
  end
9
9
  include Enumerable
10
10
  attr_accessor :visible
11
- attr_accessor :mark, :type, :child_index, :parent, :parent_index, :target, :defs, :data, :antialias, :line_width, :fill_style, :overflow, :width, :height, :top, :bottom, :left, :right, :title, :reverse, :stroke_style, :transform, :canvas, :_g, :events, :cursor, :children, :id, :segmented, :interpolate, :tension, :name, :text_baseline, :text_align, :text, :font, :text_angle, :text_style, :text_margin, :text_decoration, :text_shadow, :line_join, :eccentricity, :shape_size, :shape, :shape_angle, :shape_radius, :start_angle, :end_angle, :angle, :inner_radius, :outer_radius, :layers, :orient, :offset, :order,:url, :image_width, :image_height, :image, :_id, :nodes, :round, :links, :padding_left, :padding_right, :padding_top, :padding_bottom, :mode, :group, :depth, :breadth, :spacing, :rows, :cols, :_grid,:bands, :background_style, :positive_style, :negative_style,:directed
11
+ attr_accessor :mark, :type, :child_index, :parent, :parent_index, :target, :defs, :data, :antialias, :line_width, :fill_style, :overflow, :width, :height, :top, :bottom, :left, :right, :title, :reverse, :stroke_style, :transform, :canvas, :_g, :events, :cursor, :children, :id, :segmented, :interpolate, :tension, :name, :text_baseline, :text_align, :text, :font, :text_angle, :text_style, :text_margin, :text_decoration, :text_shadow, :line_join, :eccentricity, :shape_size, :shape, :shape_angle, :shape_radius, :start_angle, :end_angle, :angle, :inner_radius, :outer_radius, :layers, :orient, :offset, :order,:url, :image_width, :image_height, :image, :_id, :nodes, :round, :links, :padding_left, :padding_right, :padding_top, :padding_bottom, :mode, :group, :depth, :breadth, :spacing, :rows, :cols, :_grid,:bands, :background_style, :positive_style, :negative_style,:directed, :_matrix
12
12
 
13
13
  def []=(v,i)
14
14
  if v.is_a? Numeric
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.5'
33
+ VERSION = '0.3.6'
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/
@@ -0,0 +1,87 @@
1
+ require File.expand_path(File.dirname(__FILE__)+"/spec_helper.rb")
2
+ describe Rubyvis::Layout::Arc do
3
+ it "should have correct properties" do
4
+ props=[:antialias, :bottom, :canvas, :cursor, :data, :directed, :events, :fill_style, :height, :id, :left, :line_width, :links, :nodes, :orient, :overflow, :reverse, :right, :stroke_style, :title, :top, :transform, :visible, :width].inject({}) {|ac, v| ac[v]=true; ac}
5
+ Rubyvis::Layout::Arc.properties.should==props
6
+ end
7
+ describe "rendered" do
8
+ before do
9
+
10
+
11
+ nodes=[
12
+ OpenStruct.new({:node_value=>'A', :group=>1}),
13
+ OpenStruct.new({:node_value=>'B', :group=>1}),
14
+ OpenStruct.new({:node_value=>'C', :group=>2}),
15
+ OpenStruct.new({:node_value=>'D',:group=>2}),
16
+ OpenStruct.new({:node_value=>'E',:group=>3}),
17
+ OpenStruct.new({:node_value=>'F',:group=>3})
18
+
19
+ ]
20
+ links=[
21
+ OpenStruct.new({:source=>0,:target=>1, :value=>1}),
22
+ OpenStruct.new({:source=>1,:target=>2, :value=>1}),
23
+ OpenStruct.new({:source=>2,:target=>3, :value=>1}),
24
+ OpenStruct.new({:source=>3,:target=>4, :value=>1}),
25
+ OpenStruct.new({:source=>4,:target=>5, :value=>1}),
26
+ OpenStruct.new({:source=>1,:target=>0, :value=>1}),
27
+ OpenStruct.new({:source=>2,:target=>1, :value=>1}),
28
+ OpenStruct.new({:source=>3,:target=>2, :value=>1}),
29
+ OpenStruct.new({:source=>4,:target=>3, :value=>1}),
30
+ OpenStruct.new({:source=>5,:target=>4, :value=>1}),
31
+ ]
32
+
33
+
34
+ w = 300
35
+ h = 100
36
+
37
+ color=Rubyvis::Colors.category19
38
+
39
+ @vis = Rubyvis::Panel.new()
40
+ .width(w)
41
+ .height(h)
42
+ .bottom(50)
43
+ .left(0)
44
+
45
+ mat=@vis.add(Rubyvis::Layout::Arc)
46
+ .nodes(nodes).links(links)
47
+ .sort(lambda {|a,b| a.group<=>b.group})
48
+
49
+ mat.link.add(Rubyvis::Line).
50
+ antialias(false).
51
+ line_width(1)
52
+
53
+ mat.node.add(Rubyvis::Dot).
54
+ shape_size(10).
55
+ fill_style(lambda {|l| color[l.group]})
56
+
57
+ mat.node_label.add(Rubyvis::Label).
58
+ text_style(lambda {|l| color[l.group]})
59
+
60
+ @vis.render
61
+
62
+ html_out=<<EOF
63
+ <svg font-size="10px" font-family="sans-serif" fill="none" stroke="none" stroke-width="1.5" width="300" height="150"><g><g><g><path shape-rendering="crispEdges" d="M25,100A25,25 0 0,1 75,100" stroke="rgb(0,0,0)" stroke-opacity="0.2" stroke-width="1"/></g><g><path shape-rendering="crispEdges" d="M75,100A25,25 0 0,1 125,100" stroke="rgb(0,0,0)" stroke-opacity="0.2" stroke-width="1"/></g><g><path shape-rendering="crispEdges" d="M125,100A25,25 0 0,1 175,100" stroke="rgb(0,0,0)" stroke-opacity="0.2" stroke-width="1"/></g><g><path shape-rendering="crispEdges" d="M175,100A25,25 0 0,1 225,100" stroke="rgb(0,0,0)" stroke-opacity="0.2" stroke-width="1"/></g><g><path shape-rendering="crispEdges" d="M225,100A25,25 0 0,1 275,100" stroke="rgb(0,0,0)" stroke-opacity="0.2" stroke-width="1"/></g><g><path shape-rendering="crispEdges" d="M25,100A25,25 0 0,1 75,100" stroke="rgb(0,0,0)" stroke-opacity="0.2" stroke-width="1"/></g><g><path shape-rendering="crispEdges" d="M75,100A25,25 0 0,1 125,100" stroke="rgb(0,0,0)" stroke-opacity="0.2" stroke-width="1"/></g><g><path shape-rendering="crispEdges" d="M125,100A25,25 0 0,1 175,100" stroke="rgb(0,0,0)" stroke-opacity="0.2" stroke-width="1"/></g><g><path shape-rendering="crispEdges" d="M175,100A25,25 0 0,1 225,100" stroke="rgb(0,0,0)" stroke-opacity="0.2" stroke-width="1"/></g><g><path shape-rendering="crispEdges" d="M225,100A25,25 0 0,1 275,100" stroke="rgb(0,0,0)" stroke-opacity="0.2" stroke-width="1"/></g></g><g><circle fill="rgb(156,158,222)" stroke="rgb(31,119,180)" cx="25" cy="100" r="3.1622776601683795"/><circle fill="rgb(156,158,222)" stroke="rgb(31,119,180)" cx="75" cy="100" r="3.1622776601683795"/><circle fill="rgb(115,117,181)" stroke="rgb(31,119,180)" cx="125" cy="100" r="3.1622776601683795"/><circle fill="rgb(115,117,181)" stroke="rgb(31,119,180)" cx="175" cy="100" r="3.1622776601683795"/><circle fill="rgb(74,85,132)" stroke="rgb(31,119,180)" cx="225" cy="100" r="3.1622776601683795"/><circle fill="rgb(74,85,132)" stroke="rgb(31,119,180)" cx="275" cy="100" r="3.1622776601683795"/></g><g><text pointer-events="none" x="-7" dy="0.35em" transform="translate(25, 100) rotate(270)" fill="rgb(156,158,222)" text-anchor="end">A</text><text pointer-events="none" x="-7" dy="0.35em" transform="translate(75, 100) rotate(270)" fill="rgb(156,158,222)" text-anchor="end">B</text><text pointer-events="none" x="-7" dy="0.35em" transform="translate(125, 100) rotate(270)" fill="rgb(115,117,181)" text-anchor="end">C</text><text pointer-events="none" x="-7" dy="0.35em" transform="translate(175, 100) rotate(270)" fill="rgb(115,117,181)" text-anchor="end">D</text><text pointer-events="none" x="-7" dy="0.35em" transform="translate(225, 100) rotate(270)" fill="rgb(74,85,132)" text-anchor="end">E</text><text pointer-events="none" x="-7" dy="0.35em" transform="translate(275, 100) rotate(270)" fill="rgb(74,85,132)" text-anchor="end">F</text></g></g></svg>
64
+ EOF
65
+ @rv_svg=Nokogiri::XML(@vis.to_svg)
66
+ @pv_svg=Nokogiri::XML(html_out)
67
+ end
68
+
69
+ it "should render correct number of clipaths" do
70
+
71
+ @rv_svg.xpath("//xmlns:path").size.should eq @pv_svg.xpath("//path").size
72
+ end
73
+ it "should render equal paths (links)" do
74
+ pv_paths=@pv_svg.xpath("//path")
75
+ @rv_svg.xpath("//xmlns:path").each_with_index {|rv_path,i|
76
+ rv_path.should have_path_data_close_to pv_paths[i]['d']
77
+ }
78
+ end
79
+ it "should render equal dots (nodes)" do
80
+ pv_circles=@pv_svg.xpath("//circle")
81
+ @rv_svg.xpath("//xmlns:circle").each_with_index {|rv_circle,i|
82
+ rv_circle.should have_same_position pv_circles[i]
83
+ }
84
+
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,80 @@
1
+ require File.expand_path(File.dirname(__FILE__)+"/spec_helper.rb")
2
+ describe Rubyvis::Layout::Matrix do
3
+ it "should have correct properties" do
4
+ props=[:antialias, :bottom, :canvas, :cursor, :data, :directed, :events, :fill_style, :height, :id, :left, :line_width, :links, :nodes, :overflow, :reverse, :right, :stroke_style, :title, :top, :transform, :visible, :width].inject({}) {|ac, v| ac[v]=true; ac}
5
+ Rubyvis::Layout::Matrix.properties.should==props
6
+ end
7
+ describe "rendered" do
8
+ before do
9
+
10
+ nodes=[
11
+ OpenStruct.new({:node_value=>'A', :group=>1}),
12
+ OpenStruct.new({:node_value=>'B', :group=>1}),
13
+ OpenStruct.new({:node_value=>'C', :group=>2}),
14
+ OpenStruct.new({:node_value=>'D',:group=>2}),
15
+ OpenStruct.new({:node_value=>'E',:group=>3}),
16
+ OpenStruct.new({:node_value=>'F',:group=>3})
17
+
18
+ ]
19
+ links=[
20
+ OpenStruct.new({:source=>0,:target=>1, :value=>1}),
21
+ OpenStruct.new({:source=>1,:target=>2, :value=>1}),
22
+ OpenStruct.new({:source=>2,:target=>3, :value=>1}),
23
+ OpenStruct.new({:source=>3,:target=>4, :value=>1}),
24
+ OpenStruct.new({:source=>4,:target=>5, :value=>1}),
25
+ OpenStruct.new({:source=>1,:target=>0, :value=>1}),
26
+ OpenStruct.new({:source=>2,:target=>1, :value=>1}),
27
+ OpenStruct.new({:source=>3,:target=>2, :value=>1}),
28
+ OpenStruct.new({:source=>4,:target=>3, :value=>1}),
29
+ OpenStruct.new({:source=>5,:target=>4, :value=>1}),
30
+ ]
31
+
32
+
33
+ w = 700
34
+ h = 700
35
+
36
+ color=Rubyvis::Colors.category19()
37
+ @vis = Rubyvis::Panel.new()
38
+ .width(w)
39
+ .height(h)
40
+ .top(50)
41
+ .left(50)
42
+
43
+ mat=@vis.add(Rubyvis::Layout.Matrix)
44
+ .directed(true)
45
+ .nodes(nodes).links(links)
46
+ .sort(lambda {|a,b| a.group<=>b.group})
47
+
48
+ mat.link.add(pv.Bar).
49
+ fill_style(lambda {|l| l.link_value!=0 ?
50
+ ((l.target_node.group==l.source_node.group) ? color[l.sourceNode] : "#555") : "#eee"}).
51
+ antialias(false).
52
+ line_width(1)
53
+ mat.node_label.add(Rubyvis::Label).
54
+ text_style(color)
55
+
56
+
57
+
58
+ @vis.render
59
+
60
+ html_out=<<EOF
61
+ <svg font-size="10px" font-family="sans-serif" fill="none" stroke="none" stroke-width="1.5" width="750" height="750"><g transform="translate(50, 50)"><g><rect shape-rendering="crispEdges" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="116.66666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(156,158,222)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="233.33333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="350" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="466.6666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="583.3333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" y="116.66666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(156,158,222)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="116.66666666666667" y="116.66666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="233.33333333333334" y="116.66666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(85,85,85)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="350" y="116.66666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="466.6666666666667" y="116.66666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="583.3333333333334" y="116.66666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" y="233.33333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="116.66666666666667" y="233.33333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(85,85,85)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="233.33333333333334" y="233.33333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="350" y="233.33333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(156,158,222)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="466.6666666666667" y="233.33333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="583.3333333333334" y="233.33333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" y="350" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="116.66666666666667" y="350" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="233.33333333333334" y="350" width="116.66666666666667" height="116.66666666666667" fill="rgb(156,158,222)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="350" y="350" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="466.6666666666667" y="350" width="116.66666666666667" height="116.66666666666667" fill="rgb(85,85,85)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="583.3333333333334" y="350" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" y="466.6666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="116.66666666666667" y="466.6666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="233.33333333333334" y="466.6666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="350" y="466.6666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(85,85,85)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="466.6666666666667" y="466.6666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="583.3333333333334" y="466.6666666666667" width="116.66666666666667" height="116.66666666666667" fill="rgb(156,158,222)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" y="583.3333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="116.66666666666667" y="583.3333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="233.33333333333334" y="583.3333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="350" y="583.3333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="466.6666666666667" y="583.3333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(156,158,222)" stroke="rgb(255,255,255)" stroke-width="1"/><rect shape-rendering="crispEdges" x="583.3333333333334" y="583.3333333333334" width="116.66666666666667" height="116.66666666666667" fill="rgb(238,238,238)" stroke="rgb(255,255,255)" stroke-width="1"/></g><g><text pointer-events="none" x="-4" dy="0.35em" transform="translate(0, 58.3333)" fill="rgb(156,158,222)" text-anchor="end">A</text><text pointer-events="none" x="4" dy="0.35em" transform="translate(58.3333) rotate(-90)" fill="rgb(156,158,222)">A</text><text pointer-events="none" x="-4" dy="0.35em" transform="translate(0, 175)" fill="rgb(156,158,222)" text-anchor="end">B</text><text pointer-events="none" x="4" dy="0.35em" transform="translate(175) rotate(-90)" fill="rgb(156,158,222)">B</text><text pointer-events="none" x="-4" dy="0.35em" transform="translate(0, 291.667)" fill="rgb(156,158,222)" text-anchor="end">C</text><text pointer-events="none" x="4" dy="0.35em" transform="translate(291.667) rotate(-90)" fill="rgb(156,158,222)">C</text><text pointer-events="none" x="-4" dy="0.35em" transform="translate(0, 408.333)" fill="rgb(156,158,222)" text-anchor="end">D</text><text pointer-events="none" x="4" dy="0.35em" transform="translate(408.333) rotate(-90)" fill="rgb(156,158,222)">D</text><text pointer-events="none" x="-4" dy="0.35em" transform="translate(0, 525)" fill="rgb(156,158,222)" text-anchor="end">E</text><text pointer-events="none" x="4" dy="0.35em" transform="translate(525) rotate(-90)" fill="rgb(156,158,222)">E</text><text pointer-events="none" x="-4" dy="0.35em" transform="translate(0, 641.667)" fill="rgb(156,158,222)" text-anchor="end">F</text><text pointer-events="none" x="4" dy="0.35em" transform="translate(641.667) rotate(-90)" fill="rgb(156,158,222)">F</text></g></g></svg>
62
+ EOF
63
+ @rv_svg=Nokogiri::XML(@vis.to_svg)
64
+ @pv_svg=Nokogiri::XML(html_out)
65
+ end
66
+
67
+ it "should render correct number of rects(links)" do
68
+ @rv_svg.xpath("//xmlns:rect").size.should eq @pv_svg.xpath("//rect").size
69
+ end
70
+ it "should render equal intersections (links)" do
71
+ pv_rects=@pv_svg.xpath("//rect")
72
+ @rv_svg.xpath("//xmlns:rect").each_with_index {|rv_rect,i|
73
+ rv_rect.should have_same_position pv_rects[i]
74
+ }
75
+
76
+ end
77
+
78
+
79
+ end
80
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,19 @@
1
1
  $:.unshift(File.dirname(__FILE__)+"/../lib")
2
+ begin
3
+ require 'simplecov'
4
+ SimpleCov.start do
5
+ add_filter "/spec/"
6
+ add_group "Libraries", "lib"
7
+ end
8
+ rescue LoadError
9
+ end
2
10
  require 'rspec'
3
11
  #require 'spec/autorun'
4
12
  require 'rubyvis'
5
13
  require 'pp'
6
14
  require 'nokogiri'
15
+
16
+
7
17
  $PROTOVIS_DIR=File.dirname(__FILE__)+"/../vendor/protovis/src"
8
18
  module Rubyvis
9
19
  class JohnsonLoader
@@ -34,6 +44,22 @@ RSpec::Matchers.define :have_svg_attributes do |exp|
34
44
  }
35
45
  end
36
46
  end
47
+ Rspec::Matchers.define :have_same_position do |exp|
48
+ match do |obs|
49
+ correct=true
50
+ attrs={
51
+ "circle"=>['cx','cy','r'],
52
+ "rect"=>["x","y","width","height"]
53
+ }
54
+ attrs[exp.name].each do |attr|
55
+ if (obs[attr].to_f - exp[attr].to_f)>0.0001
56
+ correct=false
57
+ break
58
+ end
59
+ end
60
+ correct
61
+ end
62
+ end
37
63
  RSpec::Matchers.define :have_path_data_close_to do |exp|
38
64
  def path_scan(path)
39
65
  path.scan(/([MmCcZzLlHhVvSsQqTtAa, ])(\d+(?:\.\d+)?)/).map {|v|
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyvis
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 5
10
- version: 0.3.5
9
+ - 6
10
+ version: 0.3.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Claudio Bustos
@@ -36,7 +36,7 @@ cert_chain:
36
36
  rpP0jjs0
37
37
  -----END CERTIFICATE-----
38
38
 
39
- date: 2010-12-20 00:00:00 -03:00
39
+ date: 2010-12-28 00:00:00 -03:00
40
40
  default_executable:
41
41
  dependencies:
42
42
  - !ruby/object:Gem::Dependency
@@ -172,6 +172,7 @@ files:
172
172
  - examples/5_pv_hierarchies/sunburst.rb
173
173
  - examples/5_pv_hierarchies/treemap.rb
174
174
  - examples/6_pv_networks/arc.rb
175
+ - examples/6_pv_networks/matrix.rb
175
176
  - examples/6_pv_networks/miserables_data.rb
176
177
  - lib/rubyvis.rb
177
178
  - lib/rubyvis/color/color.rb
@@ -191,6 +192,7 @@ files:
191
192
  - lib/rubyvis/layout/hierarchy.rb
192
193
  - lib/rubyvis/layout/horizon.rb
193
194
  - lib/rubyvis/layout/indent.rb
195
+ - lib/rubyvis/layout/matrix.rb
194
196
  - lib/rubyvis/layout/network.rb
195
197
  - lib/rubyvis/layout/pack.rb
196
198
  - lib/rubyvis/layout/partition.rb
@@ -238,7 +240,9 @@ files:
238
240
  - spec/internal_spec.rb
239
241
  - spec/javascript_behaviour_spec.rb
240
242
  - spec/label_spec.rb
243
+ - spec/layout_arc_spec.rb
241
244
  - spec/layout_horizon_spec.rb
245
+ - spec/layout_matrix_spec.rb
242
246
  - spec/layout_stack_spec.rb
243
247
  - spec/line_spec.rb
244
248
  - spec/mark_spec.rb
metadata.gz.sig CHANGED
Binary file