Class: Accessibility::Graph

Inherits:
Object
  • Object
show all
Defined in:
lib/accessibility/graph.rb

Overview

DOT graph generator for AXElements. It can generate the digraph code for a UI subtree. That code can then be given to GraphViz to generate an image for the graph.

You can learn more about generating graphs in the Debugging tutorial.

Learn more about GraphViz.

Defined Under Namespace

Classes: Edge, Node

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root) ⇒ Graph

Returns a new instance of Graph

Parameters:



163
164
165
166
167
168
169
170
171
172
# File 'lib/accessibility/graph.rb', line 163

def initialize root
  root_node   = Node.new(root)
  @nodes      = [root_node]
  @edges      = []

  # exploit the ordering of a breadth-first enumeration to simplify
  # the creation of edges for the graph. This only works because
  # the UI hiearchy is a simple tree.
  @edge_queue = Array.new(root.children.size, root_node)
end

Instance Attribute Details

#edgesArray<Accessibility::Graph::Edge> (readonly)

List of edges in the graph.



160
161
162
# File 'lib/accessibility/graph.rb', line 160

def edges
  @edges
end

#nodesArray<Accessibility::Graph::Node> (readonly)

List of nodes in the UI hierarchy.



154
155
156
# File 'lib/accessibility/graph.rb', line 154

def nodes
  @nodes
end

Instance Method Details

#build!Object

Construct the list of nodes and edges for the graph.

The secret sauce is that we create an edge queue to exploit the breadth first ordering of the enumerator, which makes building the edges very easy.



180
181
182
183
184
185
186
187
188
# File 'lib/accessibility/graph.rb', line 180

def build!
  Accessibility::Enumerators::BreadthFirst.new(nodes.last.element).each do |element|
    nodes << node = Node.new(element)
    edges << Edge.new(node, @edge_queue.shift)
    # should use #size_of(:children), but that doesn't in all cases
    @edge_queue.concat Array.new(element.children.size, node)
  end
  @built = true
end

#generate_png!String

Generate the PNG file for the graph and save it to a temporary file. The path to the temporary file will be returned.

Returns:

  • (String)

    path to the saved PNG file



208
209
210
211
212
213
214
# File 'lib/accessibility/graph.rb', line 208

def generate_png!
  build! unless @built
  file = Tempfile.new 'ax_elements_graph'
  file.write self.to_dot
  `dot -Tpng #{file.path} > #{file.path}.png`
  "#{file.path}.png"
end

#to_dotString

Generate the dot graph code. You should take this string and feed it to the dot program to have it generate the graph.

Returns:

  • (String)


195
196
197
198
199
200
201
# File 'lib/accessibility/graph.rb', line 195

def to_dot
  graph  = "digraph {\n"
  graph << nodes.map(&:to_dot).join(";\n")
  graph << "\n\n"
  graph << edges.map(&:to_dot).join(";\n")
  graph << "\n}\n"
end