ea 0.6.120 → 0.6.122

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -125,7 +125,7 @@ module Ea
125
125
  # Unknown faces retain the stored-upward fallback.
126
126
  def source_heading(connector, points)
127
127
  heading = leg_heading(points)
128
- return heading unless points.size == 2 && heading.none?(&:zero?)
128
+ return heading unless heading.none?(&:zero?) && source_face_route?(connector, points)
129
129
 
130
130
  box = source_dock_bounds(connector)
131
131
  face = box && source_dock_heading(connector, points.first, box)
@@ -134,6 +134,15 @@ module Ea
134
134
  stored_upward_heading(connector, heading)
135
135
  end
136
136
 
137
+ # Explicit source boxes preserve the heading of a manual bend. An
138
+ # omitted source box uses the same dock seat as a straight route.
139
+ def source_face_route?(connector, points)
140
+ return true if points.size == 2
141
+
142
+ boxes = connector.label_boxes || {}
143
+ end_boxes(boxes, :llt, :llb).nil? && !end_boxes(boxes, :lrt, :lrb).nil?
144
+ end
145
+
137
146
  # A target dock that clips an axis-aligned stored leg into a slight
138
147
  # diagonal keeps the stored leg's direction.
139
148
  def target_heading(connector, points)
@@ -150,15 +159,24 @@ module Ea
150
159
  # A saved external ray enters the source through the face it first
151
160
  # meets, even when the clipped leg then runs back across the box.
152
161
  def face_leads_leg?(connector, face, heading, box)
153
- anchor = connector.source_anchor
154
- if face == [0, 1] && anchor && anchor.y > box.y + box.height &&
155
- connector.style.to_h[:stored_association_ray] == true
156
- return true
157
- end
162
+ return true if saved_ray_beyond_face?(connector, face, box)
158
163
 
159
164
  face.zip(heading).any? { |axis, delta| (axis * delta).positive? }
160
165
  end
161
166
 
167
+ # A saved ray from beyond the bottom or right face meets that face
168
+ # first. The top face is excluded: its clipped leg keeps the anchor seat.
169
+ def saved_ray_beyond_face?(connector, face, box)
170
+ anchor = connector.source_anchor
171
+ return false unless anchor && connector.style.to_h[:stored_association_ray] == true
172
+
173
+ case face
174
+ when [0, 1] then anchor.y > box.y + box.height
175
+ when [1, 0] then anchor.x > box.x + box.width
176
+ else false
177
+ end
178
+ end
179
+
162
180
  def stored_upward_heading(connector, heading)
163
181
  return heading unless heading[1].negative?
164
182
 
@@ -4,7 +4,9 @@ module Ea
4
4
  module Svg
5
5
  module EaEmitter
6
6
  module Marker
7
- # Navigability arrow at the target end of an association.
7
+ # Navigability arrow at the target end of an association, plus
8
+ # the diamond of an association whose end carries an aggregate
9
+ # flag (SourceIsAggregate/DestIsAggregate).
8
10
  # Rendered as a `<path>` (not polygon) sharing style with the
9
11
  # connector line. When both ends are navigable
10
12
  # (bidirectional association), EA renders a separate arrow at
@@ -16,6 +18,14 @@ module Ea
16
18
 
17
19
  def self.specs_for(connector, source, target, before_target,
18
20
  after_source, relationship: nil)
21
+ Diamond.flagged_end_specs(relationship, source, target,
22
+ before_target, after_source) +
23
+ arrow_specs(connector, source, target, before_target,
24
+ after_source)
25
+ end
26
+
27
+ def self.arrow_specs(connector, source, target, before_target,
28
+ after_source)
19
29
  # EA draws the navigability arrow on directed
20
30
  # associations AND aggregations (333EFCCF: 6 aggregations
21
31
  # render diamond + path arrow); Direction
@@ -33,6 +43,7 @@ module Ea
33
43
  base = whole_end_at_source ? before_target : after_source
34
44
  [Registry::Spec.new(shape: :arrow, anchor: anchor, base: base)]
35
45
  end
46
+ private_class_method :arrow_specs
36
47
 
37
48
  # EA marks truly bidirectional associations with
38
49
  # direction="Bi-Directional" on t_connector. These get a
@@ -4,8 +4,9 @@ module Ea
4
4
  module Svg
5
5
  module EaEmitter
6
6
  module Marker
7
- # EA endpoint fields select the diamond end; direction selects
8
- # the arrow end for target-owned aggregations.
7
+ # EA endpoint fields select the diamond end and its fill (shared
8
+ # is hollow, composite is solid); direction selects the arrow end
9
+ # for target-owned aggregations.
9
10
  class Diamond < Kind
10
11
  def self.handles?(effective_type)
11
12
  %w[Aggregation Composition].include?(effective_type)
@@ -15,15 +16,51 @@ module Ea
15
16
  whole_at_target = whole_at_target?(connector, relationship)
16
17
  whole_anchor = whole_at_target ? target : source
17
18
  whole_base = whole_at_target ? before_target : after_source
18
- specs = [Registry::Spec.new(shape: :diamond,
19
+ specs = [Registry::Spec.new(shape: diamond_shape(connector, relationship, whole_at_target),
19
20
  anchor: whole_anchor,
20
21
  base: whole_base)]
21
22
  return specs unless whole_at_target
23
+ return specs if arrow_on_target_diamond?(connector, relationship)
22
24
 
23
25
  specs.concat(direction_specs(connector, source, target,
24
26
  before_target, after_source))
25
27
  end
26
28
 
29
+ # Diamonds for the ends of a plain association that carry an
30
+ # aggregate flag.
31
+ def self.flagged_end_specs(relationship, source, target,
32
+ before_target, after_source)
33
+ return [] unless relationship
34
+
35
+ { target_aggregation: [target, before_target],
36
+ source_aggregation: [source, after_source] }.filter_map do |reader, (anchor, base)|
37
+ shape = flagged_shape(relationship.public_send(reader))
38
+ Registry::Spec.new(shape: shape, anchor: anchor, base: base) if shape
39
+ end
40
+ end
41
+
42
+ def self.flagged_shape(kind)
43
+ case kind.to_s
44
+ when "shared" then :diamond_hollow
45
+ when "composite" then :diamond
46
+ end
47
+ end
48
+ private_class_method :flagged_shape
49
+
50
+ def self.diamond_shape(connector, relationship, whole_at_target)
51
+ kind = if relationship
52
+ whole_at_target ? relationship.target_aggregation : relationship.source_aggregation
53
+ end
54
+ kind = type_default_kind(connector) if kind.to_s.empty? || kind.to_s == "none"
55
+ kind.to_s == "shared" ? :diamond_hollow : :diamond
56
+ end
57
+ private_class_method :diamond_shape
58
+
59
+ def self.type_default_kind(connector)
60
+ connector.connector_type == "Composition" ? "composite" : "shared"
61
+ end
62
+ private_class_method :type_default_kind
63
+
27
64
  def self.whole_at_target?(connector, relationship)
28
65
  return true if dest_flagged?(relationship)
29
66
  return false if source_flagged?(relationship)
@@ -31,6 +68,14 @@ module Ea
31
68
  !whole_end_at_source?(connector)
32
69
  end
33
70
 
71
+ # EA draws no arrow where a directed, dest-flagged aggregation
72
+ # would put it on its own target diamond.
73
+ def self.arrow_on_target_diamond?(connector, relationship)
74
+ connector.direction == "Source -> Destination" &&
75
+ dest_flagged?(relationship)
76
+ end
77
+ private_class_method :arrow_on_target_diamond?
78
+
34
79
  def self.dest_flagged?(relationship)
35
80
  relationship &&
36
81
  %w[shared composite].include?(relationship.target_aggregation.to_s)
@@ -15,7 +15,7 @@ module Ea
15
15
  class OpenTriangle < Kind
16
16
  def self.handles?(effective_type)
17
17
  %w[Generalization Realization Realisation Dependency
18
- InformationFlow NoteLink].include?(effective_type)
18
+ InformationFlow].include?(effective_type)
19
19
  end
20
20
 
21
21
  def self.specs_for(connector, source, target, before_target, after_source, relationship: nil)
@@ -5,30 +5,17 @@ module Ea
5
5
  module EaEmitter
6
6
  module Marker
7
7
  # PackageImport marker for «import» connectors between
8
- # packages. EA draws a closed trapezoid silhouette at the
9
- # source end (the importing package) and an open V-arrow at
10
- # the target end (the imported package) — but ONLY when the
11
- # connector's geometry string carries explicit SX/SY offset
12
- # fields. Auto-routed connectors (no SX/SY) render as a
13
- # plain solid line with no package_anchor marker.
14
- #
15
- # Verified against both QEAs (output by the same EA run):
16
- # - basic.qea Package Imports: SX=0;SY=0 present → marker
17
- # - plateau Urban Planning ADE2: SX/SY absent → no marker
8
+ # packages. EA draws the dependency-style open arrowhead at the
9
+ # target (imported) end, whether or not the diagram link
10
+ # carries explicit SX/SY offsets.
18
11
  class PackageImport < Kind
19
12
  def self.handles?(effective_type)
20
13
  effective_type == "Package"
21
14
  end
22
15
 
23
- def self.specs_for(connector, source, target, before_target, after_source, relationship: nil)
24
- return [] unless connector.has_geometry_offsets
25
-
26
- [
27
- Registry::Spec.new(shape: :package_anchor,
28
- anchor: source, base: after_source),
29
- Registry::Spec.new(shape: :arrow, anchor: target,
30
- base: before_target)
31
- ]
16
+ def self.specs_for(_connector, _source, target, before_target, _after_source, **)
17
+ [Registry::Spec.new(shape: :dependency_arrow,
18
+ anchor: target, base: before_target)]
32
19
  end
33
20
  end
34
21
  end
@@ -4,16 +4,12 @@ module Ea
4
4
  module Svg
5
5
  module EaEmitter
6
6
  module Marker
7
- # Plus-symbol marker at the contained end of a Nesting
8
- # connector. EA renders a "+" (16x16, two crossed lines)
9
- # at the end pointing INTO the container.
7
+ # Circled-plus marker at the container end of a Nesting
8
+ # connector. EA draws a white circle of radius ARM_LENGTH just
9
+ # outside the container edge with a plus (two crossed arms)
10
+ # through its centre; the connector starts at the nested
11
+ # element and ends at the container.
10
12
  #
11
- # Path encoding (two sub-paths in one <path>):
12
- #
13
- # M cx cy-8 L cx cy+8 (vertical arm, 16 tall)
14
- # M cx+8 cy L cx-8 cy (horizontal arm, 16 wide)
15
- #
16
- # cx, cy = plus center, anchored at the source-end waypoint.
17
13
  class Plus < Kind
18
14
  ARM_LENGTH = 8
19
15
 
@@ -22,14 +18,10 @@ module Ea
22
18
  end
23
19
 
24
20
  def self.specs_for(connector, source, target, before_target, after_source, relationship: nil)
25
- # Plus is at the contained (child) end. EA's convention:
26
- # source end is the child, target end is the parent.
27
- # Default to source unless the connector direction
28
- # reverses the ends.
29
- whole_end_at_source = whole_end_at_source?(connector)
30
- anchor = whole_end_at_source ? source : target
31
- base = whole_end_at_source ? after_source : before_target
32
- [Registry::Spec.new(shape: :plus, anchor: anchor, base: base)]
21
+ container_at_target = whole_end_at_source?(connector)
22
+ anchor = container_at_target ? target : source
23
+ base = container_at_target ? before_target : after_source
24
+ [Registry::Spec.new(shape: :nesting, anchor: anchor, base: base)]
33
25
  end
34
26
  end
35
27
  end
@@ -9,7 +9,9 @@ module Ea
9
9
  #
10
10
  # Layer style keys:
11
11
  # - :diamond_filled → 4-pt <polygon>, black fill
12
+ # - :diamond_hollow → 4-pt <polygon>, white fill
12
13
  # - :triangle_open → 3-pt <polygon>, white fill
14
+ # - :nesting_circle → <ellipse> + plus <path>, white fill
13
15
  # - :arrow → 3-pt <path>, no fill (shares style with
14
16
  # connector lines — same stroke, no fill)
15
17
  #
@@ -20,7 +22,7 @@ module Ea
20
22
  DIAMOND_HALF_W = 5
21
23
  DIAMOND_HALF_H = 10
22
24
  TRI_HALF_BASE = 6
23
- TRI_HEIGHT = 11
25
+ TRI_HEIGHT = 16
24
26
  # EA's path arrowheads are height 15 corpus-wide, with
25
27
  # distinct bases per connector kind: association
26
28
  # navigability arrows base 12, dependency arrows base 10
@@ -48,22 +50,19 @@ module Ea
48
50
 
49
51
  def layers
50
52
  entries = visible_connectors.flat_map { |c| entries_for(c) }
51
- return [] if entries.empty?
52
53
 
53
54
  if grouped
54
- entries.group_by(&:style_key).map do |key, grouped_entries|
55
+ entries.group_by { |e| [e.style_key, e.stroke_width] }.map do |(key, width), grouped_entries|
55
56
  # EA emits ONE marker per connector regardless of
56
57
  # anchor overlap. Verified against plateau Bridge
57
58
  # diagram: 9 generalizations fanning from the same
58
59
  # parent anchor produce 9 distinct triangle polygons
59
60
  # at the same coordinates. The earlier "dedup by
60
61
  # anchor" hypothesis is disproven by reference SVGs.
61
- Layer.new(style_key: key,
62
- style: style_for(key),
63
- body: grouped_entries.map(&:body).join("\n "))
62
+ marker_layer(key, width, grouped_entries.map(&:body).join("\n "))
64
63
  end
65
64
  else
66
- entries.map { |e| Layer.new(style_key: e.style_key, style: style_for(e.style_key), body: e.body) }
65
+ entries.map { |e| marker_layer(e.style_key, e.stroke_width, e.body) }
67
66
  end
68
67
  end
69
68
 
@@ -86,7 +85,7 @@ module Ea
86
85
  # for future use (e.g. overlap diagnostics) but no longer
87
86
  # drives dedup — EA emits one marker per connector.
88
87
  Entry = Struct.new(:style_key, :body, :anchor,
89
- :connector_waypoint_count,
88
+ :connector_waypoint_count, :stroke_width,
90
89
  keyword_init: true) do
91
90
  def hash
92
91
  anchor.hash
@@ -109,13 +108,17 @@ module Ea
109
108
  style_key: :diamond_filled,
110
109
  render: ->(m, anchor, base) { m.diamond_polygon(anchor, base) }
111
110
  },
111
+ diamond_hollow: {
112
+ style_key: :diamond_hollow,
113
+ render: ->(m, anchor, base) { m.diamond_polygon(anchor, base) }
114
+ },
112
115
  triangle: {
113
116
  style_key: :triangle_open,
114
117
  render: ->(m, anchor, base) { m.triangle_polygon(anchor, base) }
115
118
  },
116
- plus: {
117
- style_key: :connector_line,
118
- render: ->(m, anchor, _base) { m.plus_path(anchor) }
119
+ nesting: {
120
+ style_key: :nesting_circle,
121
+ render: ->(m, anchor, base) { m.nesting_marker(anchor, base) }
119
122
  },
120
123
  arrow: {
121
124
  style_key: :connector_line,
@@ -124,10 +127,6 @@ module Ea
124
127
  dependency_arrow: {
125
128
  style_key: :connector_line,
126
129
  render: ->(m, anchor, base) { m.dependency_arrow_path(anchor, base) }
127
- },
128
- package_anchor: {
129
- style_key: :connector_line,
130
- render: ->(m, anchor, base) { m.package_anchor_path(anchor, base) }
131
130
  }
132
131
  }.freeze
133
132
 
@@ -135,15 +134,22 @@ module Ea
135
134
  # is shared, so only the fill and opacity vary.
136
135
  STYLE_MAP = {
137
136
  diamond_filled: { fill: "#000000", opacity: "1.00" },
137
+ diamond_hollow: { fill: "#FFFFFF", opacity: "1.00" },
138
138
  triangle_open: { fill: "#FFFFFF", opacity: "1.00" },
139
+ nesting_circle: { fill: "#FFFFFF", opacity: "1.00" },
139
140
  connector_line: { fill: "#000000", opacity: "0.00" }
140
141
  }.freeze
141
142
 
142
- def style_for(key)
143
+ def marker_layer(key, width, body)
144
+ Layer.new(style_key: Connectors.layer_key(key, width, stroke_width),
145
+ style: style_for(key, width), body: body)
146
+ end
147
+
148
+ def style_for(key, width = stroke_width)
143
149
  spec = STYLE_MAP[key]
144
150
  return nil unless spec
145
151
 
146
- "stroke-width:#{stroke_width};stroke-linecap:round;stroke-linejoin:bevel; " \
152
+ "stroke-width:#{width};stroke-linecap:round;stroke-linejoin:bevel; " \
147
153
  "fill:#{spec[:fill]};fill-opacity:#{spec[:opacity]}; " \
148
154
  "stroke:#000000; stroke-opacity:1.00"
149
155
  end
@@ -164,7 +170,8 @@ module Ea
164
170
  Entry.new(style_key: style_key_for(spec),
165
171
  body: body,
166
172
  anchor: anchor_for(spec),
167
- connector_waypoint_count: waypoint_count)
173
+ connector_waypoint_count: waypoint_count,
174
+ stroke_width: Connectors.stroke_width_for(connector, stroke_width))
168
175
  end
169
176
  end
170
177
 
@@ -279,22 +286,36 @@ module Ea
279
286
  entry[:render].call(self, spec.anchor, spec.base)
280
287
  end
281
288
 
282
- # Plus marker: two crossed line segments at the anchor.
283
- # EA encodes as one <path> with two sub-paths:
284
- # M cx cy-8 L cx cy+8 (vertical arm)
285
- # M cx+8 cy L cx-8 cy (horizontal arm)
286
- def plus_path(anchor)
287
- cx, cy = translate_point(anchor)
288
- cx_str = Canvas.coord(cx)
289
- cy_str = Canvas.coord(cy)
290
- up = Canvas.coord(cy - Marker::Plus::ARM_LENGTH)
291
- down = Canvas.coord(cy + Marker::Plus::ARM_LENGTH)
292
- left = Canvas.coord(cx - Marker::Plus::ARM_LENGTH)
293
- right = Canvas.coord(cx + Marker::Plus::ARM_LENGTH)
294
- d = "M #{cx_str} #{up} L #{cx_str} #{down} M #{right} #{cy_str} L #{left} #{cy_str}"
289
+ # Nesting marker: a white circle tangent to the container edge
290
+ # at the anchor, with a plus through its centre. The plus is an
291
+ # unfilled path, so it stays visible on the circle's fill.
292
+ def nesting_marker(tip, base)
293
+ tx, ty = translate_point(tip)
294
+ bx, by = translate_point(base)
295
+ ux, uy = unit_vector(tx, ty, bx, by)
296
+ return nil unless ux
297
+
298
+ radius = Marker::Plus::ARM_LENGTH
299
+ cx_val = tx - ux * radius
300
+ cy_val = ty - uy * radius
301
+ circle = %(<ellipse cx="#{fixed(cx_val)}" cy="#{fixed(cy_val)}" ) +
302
+ %(rx="#{radius}.00" ry="#{radius}.00" shape-rendering="auto" />)
303
+ [circle, plus_path(cx_val, cy_val)].join("\n ")
304
+ end
305
+
306
+ def plus_path(center_x, center_y)
307
+ arm = Marker::Plus::ARM_LENGTH
308
+ d = "M #{Canvas.coord(center_x)} #{Canvas.coord(center_y - arm)} " \
309
+ "L #{Canvas.coord(center_x)} #{Canvas.coord(center_y + arm)} " \
310
+ "M #{Canvas.coord(center_x + arm)} #{Canvas.coord(center_y)} " \
311
+ "L #{Canvas.coord(center_x - arm)} #{Canvas.coord(center_y)}"
295
312
  %(<path d="#{d}" shape-rendering="auto"/>)
296
313
  end
297
314
 
315
+ def fixed(value)
316
+ format("%<value>.2f", value: value)
317
+ end
318
+
298
319
  def specs_for(connector)
299
320
  points = waypoint_pairs(connector)
300
321
  return [] if points.size < 2
@@ -343,10 +364,10 @@ module Ea
343
364
  left_x = tx - ux * DIAMOND_HALF_H - (-uy) * DIAMOND_HALF_W
344
365
  left_y = ty - uy * DIAMOND_HALF_H - ux * DIAMOND_HALF_W
345
366
  pts = [
346
- Canvas.coord(tx), Canvas.coord(ty),
347
- Canvas.coord(right_x), Canvas.coord(right_y),
348
- Canvas.coord(back_x), Canvas.coord(back_y),
349
- Canvas.coord(left_x), Canvas.coord(left_y)
367
+ Canvas.coord(tx.round), Canvas.coord(ty.round),
368
+ Canvas.coord(right_x.round), Canvas.coord(right_y.round),
369
+ Canvas.coord(back_x.round), Canvas.coord(back_y.round),
370
+ Canvas.coord(left_x.round), Canvas.coord(left_y.round)
350
371
  ].join(" ")
351
372
  %(<polygon points="#{pts}" shape-rendering="auto" style="fill-rule:evenodd;"/>)
352
373
  end
@@ -364,9 +385,9 @@ module Ea
364
385
  w2_x = back_x - (-uy) * TRI_HALF_BASE
365
386
  w2_y = back_y - ux * TRI_HALF_BASE
366
387
  pts = [
367
- Canvas.coord(tx), Canvas.coord(ty),
368
- Canvas.coord(w1_x), Canvas.coord(w1_y),
369
- Canvas.coord(w2_x), Canvas.coord(w2_y)
388
+ Canvas.coord(tx.round), Canvas.coord(ty.round),
389
+ Canvas.coord(w1_x.round), Canvas.coord(w1_y.round),
390
+ Canvas.coord(w2_x.round), Canvas.coord(w2_y.round)
370
391
  ].join(" ")
371
392
  %(<polygon points="#{pts}" shape-rendering="auto" style="fill-rule:evenodd;"/>)
372
393
  end
@@ -383,39 +404,9 @@ module Ea
383
404
  w1_y = back_y + ux * ARROW_HALF_BASE
384
405
  w2_x = back_x - (-uy) * ARROW_HALF_BASE
385
406
  w2_y = back_y - ux * ARROW_HALF_BASE
386
- d = "M #{Canvas.coord(w1_x)} #{Canvas.coord(w1_y)} L #{Canvas.coord(tx)} #{Canvas.coord(ty)} L #{Canvas.coord(w2_x)} #{Canvas.coord(w2_y)}"
387
- %(<path d="#{d}" shape-rendering="auto"/>)
388
- end
389
-
390
- # «import» source-end marker: a small closed trapezoid that
391
- # visually represents the imported package. Shape is a 4-point
392
- # polygon: top edge shorter than bottom edge, centered on the
393
- # anchor point.
394
- PACKAGE_ANCHOR_W = 5
395
- PACKAGE_ANCHOR_H_TOP = 3
396
- PACKAGE_ANCHOR_H_BOTTOM = 4
397
-
398
- def package_anchor_path(tip, base)
399
- tx, ty = translate_point(tip)
400
- bx, by = translate_point(base)
401
- ux, uy = unit_vector(tx, ty, bx, by)
402
- return nil unless ux
403
-
404
- back_x = tx - ux * PACKAGE_ANCHOR_H_BOTTOM
405
- back_y = ty - uy * PACKAGE_ANCHOR_H_BOTTOM
406
- tl_x = tx - ux * PACKAGE_ANCHOR_H_TOP + (-uy) * PACKAGE_ANCHOR_W
407
- tl_y = ty - uy * PACKAGE_ANCHOR_H_TOP + ux * PACKAGE_ANCHOR_W
408
- tr_x = tx - ux * PACKAGE_ANCHOR_H_TOP - (-uy) * PACKAGE_ANCHOR_W
409
- tr_y = ty - uy * PACKAGE_ANCHOR_H_TOP - ux * PACKAGE_ANCHOR_W
410
- bl_x = back_x + (-uy) * (PACKAGE_ANCHOR_W + 1)
411
- bl_y = back_y + ux * (PACKAGE_ANCHOR_W + 1)
412
- br_x = back_x - (-uy) * (PACKAGE_ANCHOR_W + 1)
413
- br_y = back_y - ux * (PACKAGE_ANCHOR_W + 1)
414
- d = "M #{Canvas.coord(tl_x)} #{Canvas.coord(tl_y)} " \
415
- "L #{Canvas.coord(tr_x)} #{Canvas.coord(tr_y)} " \
416
- "L #{Canvas.coord(br_x)} #{Canvas.coord(br_y)} " \
417
- "L #{Canvas.coord(bl_x)} #{Canvas.coord(bl_y)} " \
418
- "L #{Canvas.coord(tl_x)} #{Canvas.coord(tl_y)} Z"
407
+ d = "M #{Canvas.coord(w1_x.round)} #{Canvas.coord(w1_y.round)} " \
408
+ "L #{Canvas.coord(tx.round)} #{Canvas.coord(ty.round)} " \
409
+ "L #{Canvas.coord(w2_x.round)} #{Canvas.coord(w2_y.round)}"
419
410
  %(<path d="#{d}" shape-rendering="auto"/>)
420
411
  end
421
412
 
@@ -449,8 +440,8 @@ module Ea
449
440
 
450
441
  [dx / len, dy / len]
451
442
  end
452
- public :diamond_polygon, :triangle_polygon, :plus_path,
453
- :arrow_path, :dependency_arrow_path, :package_anchor_path
443
+ public :diamond_polygon, :triangle_polygon, :nesting_marker,
444
+ :arrow_path, :dependency_arrow_path
454
445
 
455
446
  def translate_point(p)
456
447
  return p unless @canvas
data/lib/ea/version.rb CHANGED
@@ -4,5 +4,5 @@ module Ea
4
4
  # Gem release version. Extracted to its own file so the
5
5
  # `gem-release` tool's `gem bump` can find and update it via the
6
6
  # standard `lib/<gem>/version.rb` convention.
7
- VERSION = "0.6.120"
7
+ VERSION = "0.6.122"
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ea
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.120
4
+ version: 0.6.122
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.