class Lutaml::Formatter::Graphviz
Constants
- ACCESS_SYMBOLS
- DEFAULT_CLASS_FONT
- VALID_TYPES
Attributes
edge[R]
graph[R]
node[R]
Public Class Methods
new(attributes = {})
click to toggle source
Calls superclass method
Lutaml::Formatter::Base::new
# File lib/lutaml/formatter/graphviz.rb, line 43 def initialize(attributes = {}) super @graph = Attributes.new # Associations lines style, `true` gives curved lines # https://graphviz.org/doc/info/attrs.html#d:splines @graph["splines"] = "ortho" # Padding between outside of picture and nodes @graph["pad"] = 0.5 # Padding between levels @graph["ranksep"] = "1.2.equally" # Padding between nodes @graph["nodesep"] = "1.2.equally" # TODO: set rankdir # @graph['rankdir'] = 'BT' @edge = Attributes.new @edge["color"] = "gray50" @node = Attributes.new @node["shape"] = "box" @type = :dot end
Public Instance Methods
escape_html_chars(text)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 84 def escape_html_chars(text) text .gsub(/</, "<") .gsub(/>/, ">") .gsub(/\[/, "[") .gsub(/\]/, "]") end
format(node)
click to toggle source
Calls superclass method
Lutaml::Formatter::Base::format
# File lib/lutaml/formatter/graphviz.rb, line 78 def format(node) dot = super.lines.map(&:rstrip).join("\n") generate_from_dot(dot) end
format_class(node, hide_members)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 222 def format_class(node, hide_members) name = ["<B>#{node.name}</B>"] name.unshift("«#{node.keyword}»") if node.keyword name_html = <<~HEREDOC <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"> #{name.map { |n| %(<TR><TD ALIGN="CENTER">#{n}</TD></TR>) }.join('\n')} </TABLE> HEREDOC field_table = format_member_rows(node.attributes, hide_members) method_table = format_member_rows(node.methods, hide_members) table_body = [name_html, field_table, method_table].map do |type| next if type.nil? <<~TEXT <TR> <TD>#{type}</TD> </TR> TEXT end <<~HEREDOC.chomp <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="10"> #{table_body.compact.join("\n")} </TABLE> HEREDOC end
format_document(node)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 250 def format_document(node) @fontname = node.fontname || DEFAULT_CLASS_FONT @node["fontname"] = "#{@fontname}-bold" if node.fidelity hide_members = node.fidelity["hideMembers"] hide_other_classes = node.fidelity["hideOtherClasses"] end classes = (node.classes + node.enums + node.data_types + node.primitives).map do |class_node| graph_node_name = generate_graph_name(class_node.name) <<~HEREDOC #{graph_node_name} [ shape="plain" fontname="#{@fontname || DEFAULT_CLASS_FONT}" label=<#{format_class(class_node, hide_members)}>] HEREDOC end.join("\n") associations = node.classes.map(&:associations).compact.flatten + node.associations if node.groups associations = sort_by_document_groupping(node.groups, associations) end classes_names = node.classes.map(&:name) associations = associations.map do |assoc_node| if hide_other_classes && !classes_names.include?(assoc_node.member_end) next end format_relationship(assoc_node) end.join("\n") classes = classes.lines.map { |line| " #{line}" }.join.chomp associations = associations .lines.map { |line| " #{line}" }.join.chomp <<~HEREDOC digraph G { graph [#{@graph}] edge [#{@edge}] node [#{@node}] #{classes} #{associations} } HEREDOC end
format_field(node)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 92 def format_field(node) symbol = ACCESS_SYMBOLS[node.visibility] result = "#{symbol}#{node.name}" if node.type keyword = node.keyword ? "«#{node.keyword}»" : "" result += " : #{keyword}#{node.type}" end if node.cardinality result += "[#{node.cardinality['min']}..#{node.cardinality['max']}]" end result = escape_html_chars(result) result = "<U>#{result}</U>" if node.static result end
format_label(name, cardinality = {})
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 191 def format_label(name, cardinality = {}) res = "+#{name}" if cardinality.nil? || (cardinality["min"].nil? || cardinality["max"].nil?) return res end "#{res} #{cardinality['min']}..#{cardinality['max']}" end
format_member_rows(members, hide_members)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 201 def format_member_rows(members, hide_members) unless !hide_members && members && members.length.positive? return <<~HEREDOC.chomp <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"> <TR><TD ALIGN="LEFT"></TD></TR> </TABLE> HEREDOC end field_rows = members.map do |field| %{<TR><TD ALIGN="LEFT">#{format_field(field)}</TD></TR>} end field_table = <<~HEREDOC.chomp <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"> #{field_rows.map { |row| ' ' * 10 + row }.join("\n")} </TABLE> HEREDOC field_table << "\n" << " " * 6 field_table end
format_method(node)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 108 def format_method(node) symbol = ACCESS_SYMBOLS[node.access] result = "#{symbol} #{node.name}" if node.arguments arguments = node.arguments.map do |argument| "#{argument.name}#{" : #{argument.type}" if argument.type}" end.join(", ") end result << "(#{arguments})" result << " : #{node.type}" if node.type result = "<U>#{result}</U>" if node.static result = "<I>#{result}</I>" if node.abstract result end
format_relationship(node)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 125 def format_relationship(node) graph_parent_name = generate_graph_name(node.owner_end) graph_node_name = generate_graph_name(node.member_end) attributes = generate_graph_relationship_attributes(node) graph_attributes = " [#{attributes}]" unless attributes.empty? %{#{graph_parent_name} -> #{graph_node_name}#{graph_attributes}} end
generate_graph_relationship_attributes(node)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 134 def generate_graph_relationship_attributes(node) attributes = Attributes.new if %w[dependency realizes].include?(node.member_end_type) attributes["style"] = "dashed" end attributes["dir"] = if node.owner_end_type && node.member_end_type "both" elsif node.owner_end_type "back" else "direct" end attributes["label"] = node.action if node.action if node.owner_end_attribute_name attributes["headlabel"] = format_label( node.owner_end_attribute_name, node.owner_end_cardinality ) end if node.member_end_attribute_name attributes["taillabel"] = format_label( node.member_end_attribute_name, node.member_end_cardinality ) end attributes["arrowtail"] = case node.owner_end_type when "composition" "diamond" when "aggregation" "odiamond" when "direct" "vee" else "onormal" end attributes["arrowhead"] = case node.member_end_type when "composition" "diamond" when "aggregation" "odiamond" when "direct" "vee" else "onormal" end # swap labels and arrows if `dir` eq to `back` if attributes["dir"] == "back" && attributes["arrowtail"] != "vee" attributes["arrowhead"], attributes["arrowtail"] = [attributes["arrowtail"], attributes["arrowhead"]] attributes["headlabel"], attributes["taillabel"] = [attributes["taillabel"], attributes["headlabel"]] end attributes end
type=(value)
click to toggle source
Calls superclass method
Lutaml::Formatter::Base#type=
# File lib/lutaml/formatter/graphviz.rb, line 72 def type=(value) super @type = :dot unless VALID_TYPES.include?(@type) end
Protected Instance Methods
generate_from_dot(input)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 323 def generate_from_dot(input) Lutaml::Layout::GraphVizEngine.new(input: input).render(@type) end
generate_graph_name(name)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 327 def generate_graph_name(name) name.gsub(/[^0-9a-zA-Z]/i, "") end
sort_by_document_groupping(groups, associations)
click to toggle source
# File lib/lutaml/formatter/graphviz.rb, line 306 def sort_by_document_groupping(groups, associations) result = [] groups.each do |batch| batch.each do |group_name| associations .select { |assc| assc.owner_end == group_name } .each do |association| result.push(association) unless result.include?(association) end end end associations.each do |association| result.push(association) unless result.include?(association) end result end