class Graphdown::Graph
Constants
- PADDING
Attributes
nodes[R]
Public Class Methods
new()
click to toggle source
# File lib/graphdown/graph.rb, line 9 def initialize @nodes = [] @width = 0 @height = 0 end
Public Instance Methods
<<(node)
click to toggle source
# File lib/graphdown/graph.rb, line 15 def <<(node) labels = @nodes.map(&:label) @nodes << node unless labels.include?(node.label) end
find_node_by_label(label)
click to toggle source
# File lib/graphdown/graph.rb, line 20 def find_node_by_label(label) (@nodes || []).select { |node| node.label == label }.first end
layer_nodes()
click to toggle source
# File lib/graphdown/graph.rb, line 28 def layer_nodes nodes_with_level = @nodes.select { |node| node.level >= 1 } begin diff_total = 0 nodes_with_level.each do |node| node.children.each do |child| if node.level >= child.level child.level += node.level + 1 diff_total += node.level + 1 end end end end while diff_total != 0 end
layered_nodes()
click to toggle source
# File lib/graphdown/graph.rb, line 24 def layered_nodes @layered_nodes ||= @nodes.sort_by(&:level).group_by(&:level).values end
layout_edges()
click to toggle source
# File lib/graphdown/graph.rb, line 60 def layout_edges @nodes.each do |node| node.child_edges.each_with_index do |edge, index| edge.origin.x = node.x + (node.width.to_f * (index + 1) / (node.child_edges.count + 1)) edge.origin.y = node.y + node.height end node.parent_edges.each_with_index do |edge, index| edge.target.x = node.x + (node.width.to_f * (index + 1) / (node.parent_edges.count + 1)) edge.target.y = node.y end end end
layout_nodes()
click to toggle source
# File lib/graphdown/graph.rb, line 43 def layout_nodes layer_widths = [] layer_offset = PADDING layered_nodes.each do |nodes| node_offset = PADDING nodes.each do |node| node.x = node_offset node.y = layer_offset node_offset += node.width + Node::MARGIN_RIGHT end layer_widths << node_offset + PADDING layer_offset += nodes.map(&:height).max + Node::MARGIN_BOTTOM end @width = layer_widths.max @height = layer_offset + PADDING end
to_svg()
click to toggle source
# File lib/graphdown/graph.rb, line 74 def to_svg svg = SVGen::SVG.new(width: @width, height: @height) do |svg| # nodes svg.g(fill: "none", stroke: "black") do |g| @nodes.each do |node| g.rect(x: node.x, y: node.y, width: node.width, height: node.height) end end # texts svg.g("font-size" => Node::FONT_SIZE, "font-family" => Node::FONT_FAMILY, "text-anchor" => "middle") do |g| @nodes.each do |node| g.text(node.label, x: node.x + node.width / 2, y: node.y + Node::WORD_HEIGHT + Node::PADDING_TOP / 2) end end # edges svg.g(stroke: "black", "stroke-width" => 2) do |g| @nodes.each do |node| node.child_edges.each do |edge| g.path(d: edge.line_d, fill: "none") g.path(d: edge.arrow_d, fill: "black") if edge.forward? g.path(d: edge.reverse_arrow_d, fill: "black") if edge.backward? end end end end svg.generate end