module Silicium::GraphVisualizer

Public Instance Methods

change_edge_width(w) click to toggle source

Changes width of edges

# File lib/graph_visualizer.rb, line 18
def change_edge_width(w)
  @@line_width = w
end
change_label_color(c) click to toggle source

Changes labels color

# File lib/graph_visualizer.rb, line 36
def change_label_color(c)
  @@label_color = Color.new(c)
end
change_label_size(s) click to toggle source

Changes labels size

# File lib/graph_visualizer.rb, line 30
def change_label_size(s)
  @@label_size = s
end
change_vertex_color(c) click to toggle source

Changes vertices color

# File lib/graph_visualizer.rb, line 42
def change_vertex_color(c)
  @@vertex_color = Color.new(c)
end
change_vertices_radius(r) click to toggle source

Changes radius of vertices

# File lib/graph_visualizer.rb, line 24
def change_vertices_radius(r)
  @@vert_radius = r
end
change_window_size(w, h) click to toggle source

Changes window size

# File lib/graph_visualizer.rb, line 12
def change_window_size(w, h)
  (Window.get :window).set width: w, height: h
end
clear_window() click to toggle source

clear screen

# File lib/graph_visualizer.rb, line 60
def clear_window
  Window.clear
end
close_window() click to toggle source

close screen

# File lib/graph_visualizer.rb, line 66
def close_window
  Window.close
end
set_graph(graph) click to toggle source

Set the graph for visualization

# File lib/graph_visualizer.rb, line 48
def set_graph(graph)
  if graph.class != OrientedGraph and graph.class != UnorientedGraph
    raise ArgumentError, "Invalid graph type!"
  end
  clear_window
  set_vertices(graph)
  set_edges(graph)
  set_labels(graph)
end
show_window() click to toggle source

show graph on the screen

# File lib/graph_visualizer.rb, line 72
def show_window
  Window.show
end

Private Instance Methods

draw_edge(v1,v2,col) click to toggle source

creates edge between vertices

# File lib/graph_visualizer.rb, line 238
def draw_edge(v1,v2,col)
  x1 = @vertices[v1].x
  y1 = @vertices[v1].y
  x2 = @vertices[v2].x
  y2 = @vertices[v2].y
  x_len = x1-x2
  y_len = y1-y2
  len = Math.sqrt(x_len*x_len+y_len*y_len)

  if len == 0
    return draw_loop(v1,col)
  end

  sin = y_len/len
  cos = x_len/len
  pos_x0 = x1 - @@vert_radius*cos
  pos_y0 = y1 - @@vert_radius*sin

  x_len = x2-x1
  y_len = y2-y1
  sin = y_len/len
  cos = x_len/len
  pos_x1 = x2 - @@vert_radius*cos
  pos_y1 = y2 - @@vert_radius*sin
  return Line.new(x1: pos_x0, y1: pos_y0, x2: pos_x1, y2: pos_y1, width: @@line_width, color: col)
end
draw_edge_label(pair,label) click to toggle source

draws label on edge

# File lib/graph_visualizer.rb, line 120
def draw_edge_label(pair,label)
  if (label.class != String and label.class != Integer)
    return
  end
  x1 = @vertices[pair[:first]].x
  y1 = @vertices[pair[:first]].y
  x2 = @vertices[pair[:second]].x
  y2 = @vertices[pair[:second]].y
  x = (x1+x2)/2
  y = (y1+y2)/2

  if x1 == x2 and y1 == y2
    x = @edges[pair][:line].x
    y = @edges[pair][:line].y
  end

  return Text.new(label,x: x, y: y, size: @@label_size, color: @@label_color)
end
draw_loop(v,col) click to toggle source

create loop edge

# File lib/graph_visualizer.rb, line 267
def draw_loop(v,col)
  x = @vertices[v].x
  y = @vertices[v].y
  center_x = (Window.get :width) / 2
  center_y = (Window.get :height) / 2
  x_len = center_x-x
  y_len = center_y-y
  len = Math.sqrt(x_len*x_len+y_len*y_len)
  sin = y_len/len
  cos = x_len/len
  pos_x1 = x - @@vert_radius*cos*2
  pos_y1 = y - @@vert_radius*sin*2
  circle = Circle.new(x: pos_x1, y: pos_y1, radius: @@vert_radius*2, color: col)
  Circle.new(x: pos_x1, y: pos_y1, radius: @@vert_radius*2-@@line_width, color: Window.get( :background))
  @vertices[v] = Circle.new(x: x, y: y, radius: @@vert_radius+1, color: @@vertex_color)
  return circle
end
draw_oriented_edge(v1,v2,col) click to toggle source

creates arrow of edge between vertices

# File lib/graph_visualizer.rb, line 207
def draw_oriented_edge(v1,v2,col)
  line = draw_edge(v1,v2,col)

  x1 = @vertices[v1].x
  y1 = @vertices[v1].y
  x2 = @vertices[v2].x
  y2 = @vertices[v2].y

  x_len = x2-x1
  y_len = y2-y1
  len = Math.sqrt(x_len*x_len+y_len*y_len)
  sin = y_len/len
  cos = x_len/len
  pos_x1 = x2 - @@vert_radius*cos
  pos_y1 = y2 - @@vert_radius*sin
  height_x= pos_x1 - @@line_width*4*cos
  height_y= pos_y1 - @@line_width*4*sin
  sin, cos = cos, sin
  pos_x2 = height_x + @@line_width*2*cos
  pos_y3 = height_y + @@line_width*2*sin
  pos_x3 = height_x - @@line_width*2*cos
  pos_y2 = height_y - @@line_width*2*sin
  #triangle = Circle.new(x: pos_x2, y: pos_y3,radius: 4, color: col)
  #Circle.new(x: pos_x3, y: pos_y2,radius: 4, color: col)
  triangle = Triangle.new(x1: pos_x1, y1: pos_y1, x2: pos_x2, y2: pos_y2, x3: pos_x3, y3: pos_y3, color: col)

  return {line: line, triangle: triangle}
end
draw_vertex(x, y) click to toggle source

creates circle for vertex

# File lib/graph_visualizer.rb, line 200
def draw_vertex(x, y)
  circle = Circle.new(x: x, y: y, radius: @@vert_radius, sectors: 128, color: @@vertex_color)
  return circle
end
draw_vertex_label(v,label) click to toggle source

draws label on vertex

# File lib/graph_visualizer.rb, line 109
def draw_vertex_label(v,label)
  if (label.class != String and label.class != Integer)
    return
  end
  x = @vertices[v].x - Math.sqrt(2)/2*@@vert_radius
  y = @vertices[v].y - Math.sqrt(2)/2*@@vert_radius
  return Text.new(label,x: x, y: y, size: @@label_size, color: @@label_color)
end
get_random_color() click to toggle source

returns random color

# File lib/graph_visualizer.rb, line 173
def get_random_color
  col = Color.new('random')
  while (col == @@label_color) or (col == @@vertex_color)
    col = Color.new('random')
  end
  return col
end
has_edge?(from_vert, to_vert) click to toggle source

return true if graph contains current edge

# File lib/graph_visualizer.rb, line 164
def has_edge?(from_vert, to_vert)
  if @is_oriented
    return @edges.has_key?(Pair.new(from_vert,to_vert))
  end
  return (@edges.has_key?(Pair.new(to_vert,from_vert)) or @edges.has_key?(Pair.new(from_vert,to_vert)))
end
push_edge(from_vert, to_vert) click to toggle source

creates edge and push it to the @edges

# File lib/graph_visualizer.rb, line 153
def push_edge(from_vert, to_vert)
  col = get_random_color
  if @is_oriented and has_edge?(to_vert,from_vert)
    col = @edges[Pair.new(to_vert,from_vert)][:line].color
  end
  arrow = @is_oriented ? draw_oriented_edge(from_vert,to_vert,col):draw_edge(from_vert,to_vert,col)
  @edges[Pair.new(from_vert,to_vert)] = arrow
end
set_edges(graph) click to toggle source

set all edges of the graph

# File lib/graph_visualizer.rb, line 141
def set_edges(graph)
  @edges = {}
  @is_oriented = graph.class == OrientedGraph
  graph.vertices.keys.each do |from_vert|
    graph.vertices[from_vert].each do |to_vert|
      push_edge(from_vert,to_vert)
    end
  end
end
set_labels(graph) click to toggle source

creates labels of edges and vertices

# File lib/graph_visualizer.rb, line 95
def set_labels(graph)
  @v_labels = {}
  graph.vertex_labels.keys.each do |v|
    @v_labels[v] = draw_vertex_label(v, graph.vertex_labels[v])
  end

  @e_labels = {}
  graph.edge_labels.keys.each do |pair|
    @e_labels[pair] = draw_edge_label(pair, graph.edge_labels[pair])
  end
end
set_vertices(graph) click to toggle source

draws all vertices of the graph

# File lib/graph_visualizer.rb, line 183
def set_vertices(graph)
  @vertices = {}
  w = Window.get :width
  h = Window.get :height
  radius= [w,h].min*1.0 / 2 - @@vert_radius*4
  vert_step = (360.0  / graph.vertex_number)*(Math::PI/180)
  position = 0
  graph.vertices.keys.each do |vert|
    x = w/2 + Math.cos(position)*radius
    y = h/2 + Math.sin(position)*radius
    @vertices[vert] = draw_vertex(x,y)
    position += vert_step
  end
end