Class: Rubyvis::Layout::Matrix
- Defined in:
- lib/rubyvis/layout/matrix.rb
Overview
Implements a network visualization using a matrix view. This is, in effect, a visualization of the graph’s adjacency matrix: the cell at row i, column j, corresponds to the link from node i to node j. The fill color of each cell is binary by default, and corresponds to whether a link exists between the two nodes. If the underlying graph has links with variable values, the fillStyle
property can be substited to use an appropriate color function, such as pv.ramp.
<p>For undirected networks, the matrix is symmetric around the diagonal. For directed networks, links in opposite directions can be rendered on opposite sides of the diagonal using directed(true)
. The graph is assumed to be undirected by default.
<p>The mark prototypes for this network layout are slightly different than other implementations:<ul>
<li>node
- unsupported; undefined. No mark is needed to visualize nodes directly, as the nodes are implicit in the location (rows and columns) of the links.
<p><li>link
- for rendering links; typically a pv.Bar. The link mark is added directly to the layout, with the data property defined as all possible pairs of nodes. Each pair is represented as a pv.Network.Layout.Link, though the linkValue
attribute may be 0 if no link exists in the graph.
<p><li>label
- for rendering node labels; typically a pv.Label. The label mark is added directly to the layout, with the data property defined via the layout’s nodes
property; note, however, that the nodes are duplicated so as to provide a label across the top and down the side. Properties such as strokeStyle
and fillStyle
can be overridden to compute properties from node data dynamically.
</ul>For more details on how to use this layout, see pv.Layout.Network.
Instance Attribute Summary collapse
-
#_dx ⇒ Object
Returns the value of attribute _dx.
-
#_dy ⇒ Object
Returns the value of attribute _dy.
-
#_labels ⇒ Object
Returns the value of attribute _labels.
-
#_n ⇒ Object
Returns the value of attribute _n.
-
#_pairs ⇒ Object
Returns the value of attribute _pairs.
Attributes inherited from Network
#_id, #link, #node, #node_label
Attributes inherited from Panel
Attributes inherited from Mark
#_properties, #binds, #child_index, #parent, #proto, #root, #scale, #scene, #target
Class Method Summary collapse
Instance Method Summary collapse
-
#_link ⇒ Object
Deletes special add from network.
-
#build_implied(s) ⇒ Object
:nodoc:.
- #build_implied_post(s) ⇒ Object
-
#directed ⇒ Object
:attr: directed.
-
#initialize ⇒ Matrix
constructor
A new instance of Matrix.
-
#sort(f = nil, &block) ⇒ Object
Specifies an optional sort function.
Methods inherited from Network
#_node, #_node_label, #build_properties, #network_build_implied, #nodes, #reset
Methods inherited from Rubyvis::Layout
Arc, Cluster, Grid, Hierarchy, Horizon, Indent, Matrix, Network, Pack, Partition, Stack, Tree, Treemap, attr_accessor_dsl, #build_properties, #layout_build_implied, #layout_build_properties
Methods inherited from Panel
#add, #anchor, #bind, #build_instance, #children_inspect, #panel_build_implied, #to_svg, #type
Methods inherited from Bar
Methods inherited from Mark
#add, #anchor, #area, attr_accessor_dsl, #bar, #bind, #build, #build_instance, #build_properties, #context, #context_apply, #context_clear, #cousin, #delete_index, #dot, #event, #execute, #first, #image, index, #index, index=, #index=, #index_defined?, #instance, #instances, #label, #last, #layout_arc, #layout_cluster, #layout_grid, #layout_horizon, #layout_indent, #layout_matrix, #layout_pack, #layout_partition, #layout_partition_fill, #layout_stack, #layout_tree, #layout_treemap, #line, #margin, #mark_anchor, #mark_bind, #mark_build_implied, #mark_build_instance, #mark_build_properties, #mark_extend, mark_method, #panel, #properties, properties, property_method, #property_value, #render, #rule, scene, scene=, #sibling, stack, stack=, #type, #wedge
Constructor Details
#initialize ⇒ Matrix
Returns a new instance of Matrix.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/rubyvis/layout/matrix.rb', line 66 def initialize super @_n=nil, # cached matrix size @_dx=nil, # cached cell width @_dy=nil, # cached cell height @_labels=nil, # cached labels (array of strings) @_pairs=nil, # cached pairs (array of links) that=self #/* Links are all pairs of nodes. */ @link.data(lambda {that._pairs}). left(lambda { that._dx * (self.index % that._n) }). top(lambda { that._dy * (self.index / that._n.to_f).floor }). width(lambda { that._dx }). height(lambda { that._dy }). line_width(1.5). stroke_style("#fff"). fill_style(lambda {|l| l.link_value!=0 ? "#555" : "#eee" }) @link.parent = self #/* No special add for links! */ # delete this.link.add; #/* Labels are duplicated for top & left. */ @node_label. data(lambda { that._labels }). left(lambda { (self.index & 1)!=0 ? that._dx * ((self.index >> 1) + 0.5) : 0 }). top(lambda { (self.index & 1)!=0 ? 0 : that._dy * ((self.index >> 1) + 0.5) }). text_margin(4).text_align(lambda { (self.index & 1)!=0 ? "left" : "right"; }). text_angle(lambda { (self.index & 1)!=0 ? -Math::PI / 2.0 : 0; }); @node=nil end |
Instance Attribute Details
#_dx ⇒ Object
Returns the value of attribute _dx.
46 47 48 |
# File 'lib/rubyvis/layout/matrix.rb', line 46 def _dx @_dx end |
#_dy ⇒ Object
Returns the value of attribute _dy.
46 47 48 |
# File 'lib/rubyvis/layout/matrix.rb', line 46 def _dy @_dy end |
#_labels ⇒ Object
Returns the value of attribute _labels.
46 47 48 |
# File 'lib/rubyvis/layout/matrix.rb', line 46 def _labels @_labels end |
#_n ⇒ Object
Returns the value of attribute _n.
46 47 48 |
# File 'lib/rubyvis/layout/matrix.rb', line 46 def _n @_n end |
#_pairs ⇒ Object
Returns the value of attribute _pairs.
46 47 48 |
# File 'lib/rubyvis/layout/matrix.rb', line 46 def _pairs @_pairs end |
Class Method Details
Instance Method Details
#_link ⇒ Object
Deletes special add from network
55 56 57 58 59 60 61 62 63 64 |
# File 'lib/rubyvis/layout/matrix.rb', line 55 def _link # :nodoc: #that=self l=Mark.new(). mark_extend(@node). data(lambda {|d| [d.source_node, d.target_node] }). fill_style(nil). line_width(lambda {|d,_p| _p.link_value * 1.5 }). stroke_style("rgba(0,0,0,.2)") l end |
#build_implied(s) ⇒ Object
:nodoc:
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/rubyvis/layout/matrix.rb', line 138 def build_implied(s) # :nodoc: return nil if network_build_implied(s) nodes = s.nodes links = s.links sort = @sort n = nodes.size index = Rubyvis.range(n) labels = [] pairs = [] map = {} s._matrix = OpenStruct.new({:labels=> labels, :pairs=> pairs}) #/* Sort the nodes. */ if sort index.sort! {|a,b| sort.call(nodes[a],nodes[b])} end #/* Create pairs. */ n.times {|i| n.times {|j| a = index[i] b = index[j] _p = OpenStruct.new({ :row=> i, :col=> j, :source_node=> nodes[a], :target_node=> nodes[b], :link_value=> 0}) map["#{a}.#{b}"] = _p pairs.push(map["#{a}.#{b}"]) } } #/* Create labels. */ n.times {|i| a = index[i] labels.push(nodes[a], nodes[a]) } #/* Accumulate link values. */ links.each_with_index {|l,i| source = l.source_node.index target = l.target_node.index value = l.link_value map["#{source}.#{target}"].link_value += value map["#{target}.#{source}"].link_value += value if (!s.directed) } build_implied_post(s) end |
#build_implied_post(s) ⇒ Object
47 48 49 50 51 52 53 |
# File 'lib/rubyvis/layout/matrix.rb', line 47 def build_implied_post(s) @_n = s.nodes.size @_dx = s.width.to_f / @_n @_dy = s.height.to_f / @_n @_labels = s._matrix.labels @_pairs = s._matrix.pairs end |
#directed ⇒ Object
:attr: directed
Whether this matrix visualization is directed (bidirectional). By default, the graph is assumed to be undirected, such that the visualization is symmetric across the matrix diagonal. If the network is directed, then forward links are drawn above the diagonal, while reverse links are drawn below.
/
115 |
# File 'lib/rubyvis/layout/matrix.rb', line 115 attr_accessor_dsl :directed |
#sort(f = nil, &block) ⇒ Object
Specifies an optional sort function. The sort function follows the same comparator contract required by pv.Dom.Node#sort. Specifying a sort function provides an alternative to sort the nodes as they are specified by the nodes
property; the main advantage of doing this is that the comparator function can access implicit fields populated by the network layout, such as the linkDegree
.
<p>Note that matrix visualizations are particularly sensitive to order. This is referred to as the seriation problem, and many different techniques exist to find good node orders that emphasize clusters, such as spectral layout and simulated annealing.
/
133 134 135 136 137 |
# File 'lib/rubyvis/layout/matrix.rb', line 133 def sort(f=nil,&block) f||=block @sort=f self end |