Class: Rubyvis::Layout::Network

Inherits:
Rubyvis::Layout show all
Defined in:
lib/rubyvis/layout/network.rb

Overview

Represents an abstract layout for network diagrams. This class provides the basic structure for both node-link diagrams (such as force-directed graph layout) and space-filling network diagrams (such as sunbursts and treemaps). Note that “network” here is a general term that includes hierarchical structures; a tree is represented using links from child to parent.

Network layouts require the graph data structure to be defined using two properties:<ul>

<li>nodes - an array of objects representing nodes. Objects in this array must conform to the Rubyvis::Layout::Network::Node interface; which is to say, be careful to avoid naming collisions with automatic attributes such as index and link_degree. If the nodes property is defined as an array of primitives, such as numbers or strings, these primitives are automatically wrapped in an object; the resulting object’s node_value attribute points to the original primitive value.

<p><li>links - an array of objects representing links. Objects in this array must conform to the Rubyvis::Layout::Network::Link interface; at a minimum, either source and target indexes or source_node and target_node references must be set. Note that if the links property is defined after the nodes property, the links can be defined in terms of this.nodes().

</ul>

<p>Three standard mark prototypes are provided:<ul>

<li>node - 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 nodes property. Properties such as stroke_style and fillStyle can be overridden to compute properties from node data dynamically.

<p><li>link - for rendering links; typically a Rubyvis::Line. The link mark is added to a child panel, whose data property is defined as layout’s links property. The link’s data property is then a two-element array of the source node and target node. Thus, poperties such as stroke_style and fill_style can be overridden to compute properties from either the node data (the first argument) or the link data (the second argument; the parent panel data) dynamically.

<p><li>node_label - for rendering node labels; typically a Rubyvis::Label. The label mark is added directly to the layout, with the data property defined via the layout’s nodes property. Properties such as strokeStyle and fillStyle can be overridden to compute properties from node data dynamically.

</ul>Note that some network implementations may not support all three standard mark prototypes; for example, space-filling hierarchical layouts typically do not use a link prototype, as the parent-child links are implied by the structure of the space-filling node marks. Check the specific network layout for implementation details.

<p>Network layout properties, including nodes and links, are typically cached rather than re-evaluated with every call to render. This is a performance optimization, as network layout algorithms can be expensive. If the network structure changes, call #reset to clear the cache before rendering. Note that although the network layout properties are cached, child mark properties, such as the marks used to render the nodes and links, are not. Therefore, non-structural changes to the network layout, such as changing the color of a mark on mouseover, do not need to reset the layout.

See Also:

Direct Known Subclasses

Arc, Hierarchy, Matrix

Defined Under Namespace

Modules: LinkAdd Classes: Link, Node

Instance Attribute Summary collapse

Attributes inherited from Panel

#_canvas, #children, #root

Attributes inherited from Mark

#_properties, #binds, #child_index, #parent, #proto, #root, #scale, #scene, #target

Instance Method Summary collapse

Methods inherited from Rubyvis::Layout

Arc, Cluster, Grid, Hierarchy, Horizon, Indent, Matrix, Network, Pack, Partition, Stack, Tree, Treemap, attr_accessor_dsl, #layout_build_implied, #layout_build_properties

Methods inherited from Panel

#add, #anchor, #bind, #build_instance, #children_inspect, defaults, #panel_build_implied, #to_svg, #type

Methods inherited from Bar

defaults, #type, #width

Methods inherited from Mark

#add, #anchor, #area, attr_accessor_dsl, #bar, #bind, #build, #build_instance, #context, #context_apply, #context_clear, #cousin, defaults, #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

#initializeNetwork

Returns a new instance of Network.



91
92
93
94
95
96
97
# File 'lib/rubyvis/layout/network.rb', line 91

def initialize
  super
  @_id=Rubyvis.id()
  @node=_node
  @link=_link
  @node_label=_node_label
end

Instance Attribute Details

#_idObject

Returns the value of attribute _id.



90
91
92
# File 'lib/rubyvis/layout/network.rb', line 90

def _id
  @_id
end

The link prototype, which renders edges between source nodes and target nodes. This prototype is intended to be used with a Line mark in conjunction with the node prototype.



80
81
82
# File 'lib/rubyvis/layout/network.rb', line 80

def link
  @link
end

#nodeObject

The node prototype. This prototype is intended to be used with a Dot mark in conjunction with the link prototype.



76
77
78
# File 'lib/rubyvis/layout/network.rb', line 76

def node
  @node
end

#node_labelObject

The node label prototype, which renders the node name adjacent to the node. This prototype is provided as an alternative to using the anchor on the node mark; it is primarily intended to be used with radial node-link layouts, since it provides a convenient mechanism to set the text angle.

NOTE FOR PROTOVIS USERS: The original name of method was label but it was replaced to not conflict with rubyvis shortcut method Mark.label()



89
90
91
# File 'lib/rubyvis/layout/network.rb', line 89

def node_label
  @node_label
end

Instance Method Details

:nodoc:



123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/rubyvis/layout/network.rb', line 123

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.extend LinkAdd
  l.that=self
  l
end

#_nodeObject

:nodoc:



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/rubyvis/layout/network.rb', line 99

def _node #:nodoc:
  that=self        
  m=Mark.new().
    data(lambda {that.nodes}).
    stroke_style("#1f77b4").
    fill_style("#fff").
    left(lambda {|n| n.x }).
    top(lambda {|n| n.y })
  m.parent = self
  m 
end

#_node_labelObject

:nodoc:



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/rubyvis/layout/network.rb', line 137

def _node_label #:nodoc:
  #that=self
  nl=Mark.new().
    mark_extend(@node).
    text_margin(7).
    text_baseline("middle").
    text(lambda {|n| n.node_name ? n.node_name : n.node_value }).
    text_angle(lambda {|n| 
      a = n.mid_angle
      Rubyvis::Wedge.upright(a) ? a : (a + Math::PI)
    }).
    text_align(lambda {|n| 
      Rubyvis::Wedge.upright(n.mid_angle) ? "left" : "right"
    })
  nl.parent = self
  nl
end

#build_implied(s) ⇒ Object

:nodoc:



219
220
221
# File 'lib/rubyvis/layout/network.rb', line 219

def build_implied(s) # :nodoc:
  network_build_implied(s)
end

#build_properties(s, properties) ⇒ Object



211
212
213
214
215
216
217
# File 'lib/rubyvis/layout/network.rb', line 211

def build_properties(s, properties) # :nodoc:
  s_id=s._id
  s_id||=0
  if (s_id < self._id)
    layout_build_properties(s,properties)
  end
end

#network_build_implied(s) ⇒ Object

:nodoc:



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/rubyvis/layout/network.rb', line 223

def network_build_implied(s) # :nodoc:
  layout_build_implied(s)
  return true if (!s._id.nil? and s._id >= self._id)
  s._id= self._id
  
  s.nodes.each do |d|
    d.link_degree=0
  end
  
  s.links.each do |d|
    v=d.link_value
    if !d.source_node
      d.source_node=s.nodes[d.source]
    end
    d.source_node.link_degree+=v
    if !d.target_node
      d.target_node=s.nodes[d.target]
    end
    d.target_node.link_degree+=v
    
  end
  false
end

#nodesObject

:attr: nodes

an array of objects representing nodes. Objects in this array must conform to the Rubyvis::Layout::Network::Node interface; which is to say, be careful to avoid naming collisions with automatic attributes such as index and link_degree. If the nodes property is defined as an array of ‘primitives’ (objects which doesn’t respond to node_value) these primitives are automatically wrapped in an OpenStruct object; the resulting object’s node_value attribute points to the original primitive value.



166
167
168
169
170
171
172
173
174
# File 'lib/rubyvis/layout/network.rb', line 166

attr_accessor_dsl [:nodes, lambda {|v|
  out=[]
  v.each_with_index {|d,i|
    d=OpenStruct.new({:node_value=>d}) unless d.respond_to? :node_value
    d.index=i
    out.push(d)
  }
  out
}]

#resetObject

Resets the cache, such that changes to layout property definitions will be visible on subsequent render. Unlike normal marks (and normal layouts), properties associated with network layouts are not automatically re-evaluated on render; the properties are cached, and any expensive layout algorithms are only run after the layout is explicitly reset.

(@returns Rubyvis::Layout::Network) self



204
205
206
207
# File 'lib/rubyvis/layout/network.rb', line 204

def reset
  self._id=Rubyvis.id()
  self
end