Class: Archimate::Svg::Connection
- Inherits:
-
Object
- Object
- Archimate::Svg::Connection
- Defined in:
- lib/archimate/svg/connection.rb
Instance Attribute Summary collapse
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
-
#css_style ⇒ Object
readonly
Returns the value of attribute css_style.
Instance Method Summary collapse
-
#calc_points(a, b) ⇒ Object
a: Bounds b: Bounds.
-
#css_classify(str) ⇒ Object
TODO: StringRefinements refinement isn’t working in this class, so added this method here.
- #id ⇒ Object
-
#initialize(connection) ⇒ Connection
constructor
A new instance of Connection.
- #line_style ⇒ Object
- #line_to(point) ⇒ Object
- #move_to(point) ⇒ Object
- #path_attrs ⇒ Object
-
#path_class ⇒ Object
Look at the type (if any of the path and set the class appropriately).
-
#path_d ⇒ Object
builds the line coordinates for the path rough drawing is the point at center of first element, point of each bendpoint, and center of end element First naive implementation if left/right range of both overlap, use centerpoint of overlap range as x val if top/bottom range of both overlap, use centerpoint of overlap range as y val.
- #ranges_overlap(r1, r2) ⇒ Object
- #render(svg) ⇒ Object
- #text_position ⇒ Object
- #to_svg(xml) ⇒ Object
Constructor Details
#initialize(connection) ⇒ Connection
Returns a new instance of Connection.
9 10 11 12 |
# File 'lib/archimate/svg/connection.rb', line 9 def initialize(connection) @connection = connection @css_style = CssStyle.new(connection.style) end |
Instance Attribute Details
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
6 7 8 |
# File 'lib/archimate/svg/connection.rb', line 6 def connection @connection end |
#css_style ⇒ Object (readonly)
Returns the value of attribute css_style.
7 8 9 |
# File 'lib/archimate/svg/connection.rb', line 7 def css_style @css_style end |
Instance Method Details
#calc_points(a, b) ⇒ Object
a: Bounds b: Bounds
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/archimate/svg/connection.rb', line 141 def calc_points(a, b) ax_range = a.x_range bx_range = b.x_range overlap_x_center = ranges_overlap(ax_range, bx_range) if overlap_x_center ax = bx = overlap_x_center elsif b.is_right_of?(a) ax = a.right bx = b.left else ax = a.left bx = b.right end ay_range = a.y_range by_range = b.y_range overlap_y_center = ranges_overlap(ay_range, by_range) if overlap_y_center ay = by = overlap_y_center elsif b.is_above?(a) ay = a.top by = b.bottom else ay = a.bottom by = b.top end [Point.new(ax, ay), Point.new(bx, by)] end |
#css_classify(str) ⇒ Object
TODO: StringRefinements refinement isn’t working in this class, so added this method here. Investigate.
85 86 87 88 89 90 |
# File 'lib/archimate/svg/connection.rb', line 85 def css_classify(str) str.gsub(/::/, '/') .gsub(/([A-Z]+)([A-Z][a-z])/, '\1-\2') .gsub(/([a-z\d])([A-Z])/, '\1-\2') .downcase end |
#id ⇒ Object
72 73 74 |
# File 'lib/archimate/svg/connection.rb', line 72 def id connection.relationship_element&.id || connection.id end |
#line_style ⇒ Object
41 42 43 44 45 46 47 48 49 50 |
# File 'lib/archimate/svg/connection.rb', line 41 def line_style style = connection.style return "" if style.nil? { "stroke": style.line_color&.to_rgba, "stroke-width": style.line_width }.delete_if { |_key, value| value.nil? } .map { |key, value| "#{key}:#{value};" } .join("") end |
#line_to(point) ⇒ Object
179 180 181 |
# File 'lib/archimate/svg/connection.rb', line 179 def line_to(point) "L #{point.x} #{point.y}" end |
#move_to(point) ⇒ Object
175 176 177 |
# File 'lib/archimate/svg/connection.rb', line 175 def move_to(point) "M #{point.x} #{point.y}" end |
#path_attrs ⇒ Object
63 64 65 66 67 68 69 70 |
# File 'lib/archimate/svg/connection.rb', line 63 def path_attrs { id: id, class: path_class, d: path_d, style: line_style } end |
#path_class ⇒ Object
Look at the type (if any of the path and set the class appropriately)
77 78 79 80 81 82 |
# File 'lib/archimate/svg/connection.rb', line 77 def path_class [ "archimate", css_classify(connection&.relationship_element&.type || "default") ].join("-") + " archimate-relationship" end |
#path_d ⇒ Object
builds the line coordinates for the path rough drawing is the point at center of first element, point of each bendpoint, and center of end element First naive implementation if left/right range of both overlap, use centerpoint of overlap range as x val if top/bottom range of both overlap, use centerpoint of overlap range as y val
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/archimate/svg/connection.rb', line 104 def path_d source_bounds = connection.source_element&.absolute_position || DataModel::Bounds.zero target_bounds = connection.target_element&.absolute_position || DataModel::Bounds.zero start_point = DataModel::Bounds.new( x: source_bounds.left + source_bounds.width / 2.0, y: source_bounds.top + source_bounds.height / 2.0, width: 0, height: 0 ) bp_bounds = connection.bendpoints.map do |bp| DataModel::Bounds.new( x: start_point.x + (bp.x || 0), y: start_point.y + (bp.y || 0), width: 0, height: 0 ) end bp_bounds = bp_bounds.reject do |bounds| bounds.inside?(source_bounds) || bounds.inside?(target_bounds) end bounds = [source_bounds].concat(bp_bounds) << target_bounds points = [] a = bounds.shift until bounds.empty? b = bounds.shift points.concat(calc_points(a, b)) a = b end points.uniq! [move_to(points.shift)].concat(points.map { |pt| line_to(pt) }).join(" ") end |
#ranges_overlap(r1, r2) ⇒ Object
92 93 94 95 96 97 |
# File 'lib/archimate/svg/connection.rb', line 92 def ranges_overlap(r1, r2) begin_max = [r1, r2].map(&:begin).max end_min = [r1, r2].map(&:end).min return nil if begin_max > end_min (begin_max + end_min) / 2.0 end |
#render(svg) ⇒ Object
14 15 16 17 18 19 |
# File 'lib/archimate/svg/connection.rb', line 14 def render(svg) Nokogiri::XML::Builder.with(svg) do |xml| to_svg(xml) end svg end |
#text_position ⇒ Object
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/archimate/svg/connection.rb', line 52 def text_position case connection.style when 0 "10%" when 1 "90%" else "50%" end end |
#to_svg(xml) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/archimate/svg/connection.rb', line 21 def to_svg(xml) return if connection.source_element.nodes.include?(connection.target_element) xml.path(path_attrs) do xml.title @connection.description end name = connection&.relationship_element&.name&.strip return if name.nil? || name.empty? xml.text_( class: "archimate-relationship-name", dy: -2, "text-anchor" => "middle", style: css_style.text ) do xml.textPath(startOffset: text_position, "xlink:href" => "##{id}") do xml.text name end end end |