Class: Rubyvis::Layout::Cluster

Inherits:
Hierarchy show all
Includes:
NodeLink
Defined in:
lib/rubyvis/layout/cluster.rb

Overview

Implements a hierarchical layout using the cluster (or dendrogram) algorithm. This layout provides both node-link and space-filling implementations of cluster diagrams. In many ways it is similar to pv.Layout.Partition, except that leaf nodes are positioned at maximum depth, and the depth of internal nodes is based on their distance from their deepest descendant, rather than their distance from the root.

<p>The cluster layout supports a “group” property, which if true causes siblings to be positioned closer together than unrelated nodes at the same depth. Unlike the partition layout, this layout does not support dynamic sizing for leaf nodes; all leaf nodes are the same size.

<p>For more details on how to use this layout, see Rubyvis::Layout::Hierarchy.

See Also:

  • pvpv.Layoutpv.Layout.Clusterpv.Layout.Cluster.Fill

Direct Known Subclasses

Fill

Defined Under Namespace

Classes: Fill

Instance Attribute Summary collapse

Attributes included from NodeLink

#_h, #_ir, #_or, #_orient, #_w

Attributes inherited from Network

#_id, #link, #node, #node_label

Attributes inherited from Panel

#_canvas, #children, #root

Attributes inherited from Mark

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

Class Method Summary collapse

Instance Method Summary collapse

Methods included from NodeLink

#node_link_build_implied

Methods inherited from Hierarchy

#hierarchy_build_implied, #links

Methods inherited from Network

#_link, #_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

#type, #width

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

#initializeCluster

Returns a new instance of Cluster.



34
35
36
37
38
39
40
# File 'lib/rubyvis/layout/cluster.rb', line 34

def initialize
  super
  @interpolate=nil
  that=self
  ## @private Cache layout state to optimize properties. #/
  @link.interpolate {that.interpolate}
end

Instance Attribute Details

#interpolateObject

Constructs a new, empty cluster layout. Layouts are not typically constructed directly; instead, they are added to an existing panel via pv.Mark#add.



32
33
34
# File 'lib/rubyvis/layout/cluster.rb', line 32

def interpolate
  @interpolate
end

Class Method Details

.defaultsObject

Defaults for cluster layouts. The default group parameter is 0 and the default orientation is “top”.



95
96
97
98
99
# File 'lib/rubyvis/layout/cluster.rb', line 95

def self.defaults
  Cluster.new.mark_extend(Hierarchy.defaults).
    group(0).
    orient("top")
end

Instance Method Details

#build_implied(s) ⇒ Object



100
101
102
# File 'lib/rubyvis/layout/cluster.rb', line 100

def build_implied(s)
  cluster_build_implied(s)
end

#cluster_build_implied(s) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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
# File 'lib/rubyvis/layout/cluster.rb', line 103

def cluster_build_implied(s)
  @interpolate=case s.orient
    when /^(top|bottom)$/
      'step-before'
    when /^(left|right)$/
      'step-after'
    else
      'linear'
  end
  return nil if hierarchy_build_implied(s)
  root = s.nodes[0]
  group = s.group
  breadth =nil
  depth = nil 
  leaf_count = 0
  leaf_index = 0.5 - group / 2.0

  # Count the leaf nodes and compute the depth of descendants. #/
  par = nil
  root.visit_after {|n,i|
    #puts "#{n.node_value} #{i}"
    if (n.first_child) 
      n.depth = 1 + Rubyvis.max(n.child_nodes, lambda {|nn| nn.depth })
    else
      if (group!=0 and (par != n.parent_node)) 
        par = n.parent_node
        leaf_count += group
      end
      leaf_count+=1
      n.depth = 0
    end
  }
  breadth = 1.0 / leaf_count
  depth = 1.0 / root.depth

  # Compute the unit breadth and depth of each node. #/
  par = nil
  root.visit_after  {|n,i|
    if (n.first_child) 
        n.breadth = Rubyvis.mean(n.child_nodes, lambda {|nn| nn.breadth })
     else 
      if (group!=0 and (par != n.parent_node)) 
      par = n.parent_node
      leaf_index += group
      end
      n.breadth = breadth * leaf_index
      leaf_index+=1
    end
    n.depth = 1 - n.depth * depth
  }

  # Compute breadth and depth ranges for space-filling layouts. #/
  root.visit_after {|n,i|
    n.min_breadth = n.first_child ? n.first_child.min_breadth : (n.breadth - breadth / 2.0)
    n.max_breadth = n.first_child ? n.last_child.max_breadth : (n.breadth + breadth / 2.0)
  }
  root.visit_before {|n,i|
    n.min_depth = n.parent_node ? n.parent_node.max_depth : 0
    n.max_depth = n.parent_node ? (n.depth + root.depth) : (n.min_depth + 2 * root.depth)
  }
  root.min_depth = -depth
  node_link_build_implied(s)
  false
end

#groupObject

:attr: outer_radius The outer radius; defaults to fill the containing panel, based on the height and width of the layout. If the layout has no height and width specified, it will extend to fill the enclosing panel.



87
# File 'lib/rubyvis/layout/cluster.rb', line 87

attr_accessor_dsl :group, :orient, :inner_radius, :outer_radius