ea 0.6.120 → 0.6.121
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.
- checksums.yaml +4 -4
- data/config/themes/119.yml +2 -4
- data/lib/ea/fonts/carlito_metrics.json +1 -1
- data/lib/ea/fonts/metrics.rb +12 -2
- data/lib/ea/sources/qea/diagram_builder.rb +2 -2
- data/lib/ea/svg/ea_emitter/color_resolver.rb +1 -1
- data/lib/ea/svg/ea_emitter/compartment/note_body.rb +13 -12
- data/lib/ea/svg/ea_emitter/connector_redock.rb +3 -2
- data/lib/ea/svg/ea_emitter/connectors.rb +38 -9
- data/lib/ea/svg/ea_emitter/element/stereotype_icon_renderer.rb +4 -44
- data/lib/ea/svg/ea_emitter/elements.rb +7 -2
- data/lib/ea/svg/ea_emitter/font_resolver.rb +18 -3
- data/lib/ea/svg/ea_emitter/marker/arrow_path.rb +12 -1
- data/lib/ea/svg/ea_emitter/marker/diamond.rb +39 -3
- data/lib/ea/svg/ea_emitter/marker/open_triangle.rb +1 -1
- data/lib/ea/svg/ea_emitter/marker/package_import.rb +6 -19
- data/lib/ea/svg/ea_emitter/marker/plus.rb +9 -17
- data/lib/ea/svg/ea_emitter/markers.rb +53 -64
- data/lib/ea/version.rb +1 -1
- metadata +1 -1
|
@@ -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
|
#
|
|
@@ -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
|
|
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
|
-
|
|
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|
|
|
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
|
-
|
|
117
|
-
style_key: :
|
|
118
|
-
render: ->(m, 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
|
|
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:#{
|
|
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
|
-
#
|
|
283
|
-
#
|
|
284
|
-
#
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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
|
|
@@ -387,38 +408,6 @@ module Ea
|
|
|
387
408
|
%(<path d="#{d}" shape-rendering="auto"/>)
|
|
388
409
|
end
|
|
389
410
|
|
|
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"
|
|
419
|
-
%(<path d="#{d}" shape-rendering="auto"/>)
|
|
420
|
-
end
|
|
421
|
-
|
|
422
411
|
# Dependency arrowhead: same open-path form as arrow_path
|
|
423
412
|
# but EA's slimmer base-10 template. Coordinates are whole
|
|
424
413
|
# pixels in EA's output (e.g. "M 2732 183 L 2747 178
|
|
@@ -449,8 +438,8 @@ module Ea
|
|
|
449
438
|
|
|
450
439
|
[dx / len, dy / len]
|
|
451
440
|
end
|
|
452
|
-
public :diamond_polygon, :triangle_polygon, :
|
|
453
|
-
:arrow_path, :dependency_arrow_path
|
|
441
|
+
public :diamond_polygon, :triangle_polygon, :nesting_marker,
|
|
442
|
+
:arrow_path, :dependency_arrow_path
|
|
454
443
|
|
|
455
444
|
def translate_point(p)
|
|
456
445
|
return p unless @canvas
|
data/lib/ea/version.rb
CHANGED