class NetworkDrawer::Diagram
Replesent of source file
Constants
- DEFAULT_OPTIONS
- ELELMENT_KEYS
- TOP_LAYER
Public Class Methods
draw(source, dest_file, options = {})
click to toggle source
# File lib/network_drawer/diagram.rb, line 10 def self.draw(source, dest_file, options = {}) diagram = new(source, dest_file, options) diagram.draw end
new(source, dest_file, options = {})
click to toggle source
# File lib/network_drawer/diagram.rb, line 15 def initialize(source, dest_file, options = {}) @source = source ? source : {} @dest_file = dest_file @options = DEFAULT_OPTIONS.merge(options) @title = @options[:title] ? @options[:title] : File.basename(@dest_file, '.*') @nodes = {} @layers = {} @connections = [] @rankings = {} @style = options[:style] ? options[:style] : {} @gv = Gviz.new(@title) end
Public Instance Methods
draw()
click to toggle source
# File lib/network_drawer/diagram.rb, line 29 def draw @layers = create_layers @connections = create_connections draw_elements @gv.global(layout: @options[:layout] ? @options[:layout] : :dot) @gv.global(newrank: true) if @rankings.size > 0 @gv.global(@source.dup.delete_if { |k, _| ELELMENT_KEYS.include?(k) }) @gv.save @dest_file, @options[:format] end
Private Instance Methods
create_connections()
click to toggle source
# File lib/network_drawer/diagram.rb, line 96 def create_connections return unless @source[:connections] connections = [] @source[:connections].each do |c| from_name, from_port = c[:from].split(':') to_name, to_port = c[:to].split(':') from_name = from_name.to_sym to_name = to_name.to_sym return unless node_exist?(from_name) && node_exist?(to_name) connection = Element::Connection.new({}, @style[:types]) c.each_pair { |k, v| connection[k.to_sym] = v } from_name = @nodes[from_name][:id] if @nodes[from_name] to_name = @nodes[to_name][:id] if @nodes[to_name] from = from_port ? "#{from_name}:p#{from_port}" : from_name to = to_port ? "#{to_name}:p#{to_port}" : to_name connection.from = from connection.to = to connections << connection end connections end
create_layers(name = TOP_LAYER, source = @source)
click to toggle source
# File lib/network_drawer/diagram.rb, line 53 def create_layers(name = TOP_LAYER, source = @source) return nil unless source && source.is_a?(Hash) layer = Element::Layer.new(source, @style[:types]) layer.name = name layer.layers = create_sub_layers(source) layer.nodes = create_nodes(source) layer end
create_nodes(source)
click to toggle source
# File lib/network_drawer/diagram.rb, line 75 def create_nodes(source) return nil unless source && source[:nodes] nodes = [] source[:nodes].each do |n| return nil unless n.is_a?(Hash) node = Element::Node.new(n.values.first, @style[:types]) node.name = n.keys.first @nodes[node.name] = { id: node.id } ranking = node.ranking.to_i unless node.ranking.nil? if @rankings[ranking] @rankings[ranking] += [node.id] else @rankings[ranking] = [node.id] end end nodes << node end nodes end
create_sub_layers(source)
click to toggle source
# File lib/network_drawer/diagram.rb, line 62 def create_sub_layers(source) return nil unless source && source[:layers] sub_layers = [] source[:layers].each do |l| return nil unless l.is_a?(Hash) name = l.keys.first src = l[name] sub_layer = create_layers(name, src) if src sub_layers << sub_layer if sub_layer end sub_layers end
draw_elements()
click to toggle source
# File lib/network_drawer/diagram.rb, line 42 def draw_elements code = @layers.to_code if @layers @connections.each do |c| code << c.to_code end if @connections rank_nodes @gv.graph(&eval("proc {#{code}}")) end
node_exist?(name)
click to toggle source
# File lib/network_drawer/diagram.rb, line 139 def node_exist?(name) return false unless name if @nodes[name] && @nodes[name][:id] true else puts "No #{name} exists" false end end
node_id(name)
click to toggle source
# File lib/network_drawer/diagram.rb, line 149 def node_id(name) return nil unless node_exist?(name) @nodes[name.to_sym][:id] end
rank_nodes()
click to toggle source
# File lib/network_drawer/diagram.rb, line 123 def rank_nodes return if @rankings.size == 0 sorted_rankings = @rankings.sort rank_ids = [] sorted_rankings.each_with_index do |r, i| rank_id = (@nodes.size + i) rank_ids << rank_id @gv.rank(:same, *([rank_id] + r[1])) end rank_ids.each_with_index do |r, i| @gv.node(r.to_s.to_sym, style: :invis) edge_id = "#{rank_ids[i]}_#{rank_ids[i + 1]}".to_sym @gv.edge(edge_id, style: :invis) if i < rank_ids.size - 1 end end