ea 0.6.54 → 0.6.55
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/lib/ea/model/diagram_connector.rb +9 -0
- data/lib/ea/sources/qea/diagram_builder.rb +24 -0
- data/lib/ea/svg/ea_emitter/connector_redock.rb +49 -5
- data/lib/ea/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7d4c834fa91906a0866bf29561214b7c9d140cb4b2a7106eb332f4ec029e56f1
|
|
4
|
+
data.tar.gz: e99cb2ff135675ec69d47397c102bd67f07925d8e59565bbabf6b96fb70cb60d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 302544eb3d7bc17747114aac54f1aacb3b91c6f87340c699d4c35bb8eace2f76c9a4766fd675eb1d58d0c5faa039624124ee5d7dca75d36b7a2e6e109d9aef2c
|
|
7
|
+
data.tar.gz: e5a86d18db02e980a690a2653529f17cd87b431ba7d7aee03683abe6f1fc3de9d4881347817735365a53575e234a91e0cca36364552a39d24e9b725a06932017
|
|
@@ -44,6 +44,13 @@ module Ea
|
|
|
44
44
|
# when the geometry string carries no offsets (auto-routed).
|
|
45
45
|
attribute :source_port, Ea::Model::Point
|
|
46
46
|
attribute :target_port, Ea::Model::Point
|
|
47
|
+
# Ray origins for the drawn line: element center translated by
|
|
48
|
+
# the stored Geometry SX/SY / EX/EY offsets. EA clips the
|
|
49
|
+
# segment between the two anchors at the DRAWN outlines
|
|
50
|
+
# (F851A657: anchors center+(-29,0)/center+(-29,0) clip to EA's
|
|
51
|
+
# (297,788)/(433,514) within 1.5px).
|
|
52
|
+
attribute :source_anchor, Ea::Model::Point
|
|
53
|
+
attribute :target_anchor, Ea::Model::Point
|
|
47
54
|
|
|
48
55
|
json do
|
|
49
56
|
map "id", to: :id
|
|
@@ -57,6 +64,8 @@ module Ea
|
|
|
57
64
|
map "targetEdge", to: :target_edge
|
|
58
65
|
map "sourcePort", to: :source_port
|
|
59
66
|
map "targetPort", to: :target_port
|
|
67
|
+
map "sourceAnchor", to: :source_anchor
|
|
68
|
+
map "targetAnchor", to: :target_anchor
|
|
60
69
|
map "connectorType", to: :connector_type
|
|
61
70
|
map "direction", to: :direction
|
|
62
71
|
map "sourceStereotype", to: :source_stereotype
|
|
@@ -373,6 +373,10 @@ module Ea
|
|
|
373
373
|
target_stereotype: connector&.deststereotype,
|
|
374
374
|
waypoints: context ? context_waypoints_for(connector, diagram_row) :
|
|
375
375
|
waypoints_for_link(link_row, diagram_row),
|
|
376
|
+
source_anchor: port_anchor_for(connector, diagram_row,
|
|
377
|
+
geom, :source),
|
|
378
|
+
target_anchor: port_anchor_for(connector, diagram_row,
|
|
379
|
+
geom, :target),
|
|
376
380
|
source_port: connection_port(diagram_row, connector, :source, geom),
|
|
377
381
|
target_port: connection_port(diagram_row, connector, :target, geom),
|
|
378
382
|
label_boxes: context ? {} : (geom[:label_boxes] || {}),
|
|
@@ -384,6 +388,26 @@ module Ea
|
|
|
384
388
|
)
|
|
385
389
|
end
|
|
386
390
|
|
|
391
|
+
# Ray origin for one connector end: the element's center
|
|
392
|
+
# translated by the stored SX/SY (source) or EX/EY (target)
|
|
393
|
+
# offset. EA clips the anchor-to-anchor segment at the drawn
|
|
394
|
+
# outlines.
|
|
395
|
+
def port_anchor_for(connector, diagram_row, geom, end_kind)
|
|
396
|
+
return nil unless connector
|
|
397
|
+
|
|
398
|
+
object_id = end_kind == :source ? connector.start_object_id :
|
|
399
|
+
connector.end_object_id
|
|
400
|
+
placement = diagram_object_placement(diagram_row.diagram_id,
|
|
401
|
+
object_id)
|
|
402
|
+
return nil unless placement
|
|
403
|
+
|
|
404
|
+
bounds = bounds_from_rect(placement)
|
|
405
|
+
dx = (end_kind == :source ? geom[:sx] : geom[:ex]).to_i
|
|
406
|
+
dy = (end_kind == :source ? geom[:sy] : geom[:ey]).to_i
|
|
407
|
+
Ea::Model::Point.new(x: bounds.x + bounds.width / 2 + dx,
|
|
408
|
+
y: bounds.y + bounds.height / 2 + dy)
|
|
409
|
+
end
|
|
410
|
+
|
|
387
411
|
# Context diagrams re-route every drawn connector as a
|
|
388
412
|
# direct line at draw time: the center-to-center ray clipped
|
|
389
413
|
# at both box outlines. The stored SX/SY/EDGE geometry is
|
|
@@ -19,11 +19,12 @@ module Ea
|
|
|
19
19
|
# self-loop, or no drawn bounds for either end).
|
|
20
20
|
def pairs_for(connector, diagram, model_index, bounds_map)
|
|
21
21
|
return nil unless bounds_map
|
|
22
|
-
return nil unless direct?(connector)
|
|
22
|
+
return nil unless direct?(connector) || two_point?(connector)
|
|
23
23
|
|
|
24
24
|
points = waypoint_pairs(connector)
|
|
25
25
|
return nil unless points.size == 2
|
|
26
26
|
|
|
27
|
+
|
|
27
28
|
rel = relationship_for(connector, model_index)
|
|
28
29
|
return nil unless rel
|
|
29
30
|
|
|
@@ -35,8 +36,45 @@ module Ea
|
|
|
35
36
|
return nil unless source_bounds && target_bounds
|
|
36
37
|
return nil if source_ref == target_ref
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
sa = connector.source_anchor
|
|
40
|
+
ta = connector.target_anchor
|
|
41
|
+
if sa && ta
|
|
42
|
+
[anchor_exit(sa, source_bounds, ta),
|
|
43
|
+
anchor_exit(ta, target_bounds, sa)]
|
|
44
|
+
else
|
|
45
|
+
[edge_point(source_bounds, target_bounds),
|
|
46
|
+
edge_point(target_bounds, source_bounds)]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Exit point of the anchor-to-anchor segment through a box's
|
|
51
|
+
# outline: smallest positive t whose crossing lies on the
|
|
52
|
+
# rectangle perimeter.
|
|
53
|
+
def anchor_exit(anchor, bounds, other)
|
|
54
|
+
ax, ay = anchor.x.to_f, anchor.y.to_f
|
|
55
|
+
ox, oy = other.x.to_f, other.y.to_f
|
|
56
|
+
dx, dy = ox - ax, oy - ay
|
|
57
|
+
candidates = []
|
|
58
|
+
if dx != 0
|
|
59
|
+
[bounds.x, bounds.x + bounds.width].each do |x|
|
|
60
|
+
t = (x - ax) / dx
|
|
61
|
+
candidates << [t, x, ay + t * dy] if t.positive?
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
if dy != 0
|
|
65
|
+
[bounds.y, bounds.y + bounds.height].each do |y|
|
|
66
|
+
t = (y - ay) / dy
|
|
67
|
+
candidates << [t, ax + t * dx, y] if t.positive?
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
on_perimeter = candidates.select do |_t, x, y|
|
|
71
|
+
x >= bounds.x - 0.01 && x <= bounds.x + bounds.width + 0.01 &&
|
|
72
|
+
y >= bounds.y - 0.01 && y <= bounds.y + bounds.height + 0.01
|
|
73
|
+
end
|
|
74
|
+
best = on_perimeter.min_by(&:first)
|
|
75
|
+
# EA floors the dock coordinates (F851A657: 297.75 -> 297,
|
|
76
|
+
# 433.7 -> 433) - a rounded-up dock is a visible miss.
|
|
77
|
+
best ? [best[1].floor, best[2].floor] : [ax.floor, ay.floor]
|
|
40
78
|
end
|
|
41
79
|
|
|
42
80
|
# EA never docks a horizontal connector line at the header
|
|
@@ -85,6 +123,12 @@ module Ea
|
|
|
85
123
|
%w[direct regenerated].any? { |k| style.key?(k) }
|
|
86
124
|
end
|
|
87
125
|
|
|
126
|
+
# EXPERIMENT: every auto-laid 2-waypoint connector re-docks
|
|
127
|
+
# as the center-to-center ray clipped at the drawn outlines.
|
|
128
|
+
def two_point?(connector)
|
|
129
|
+
(connector.waypoints || []).size == 2
|
|
130
|
+
end
|
|
131
|
+
|
|
88
132
|
def waypoint_pairs(connector)
|
|
89
133
|
(connector.waypoints || []).filter_map do |wp|
|
|
90
134
|
next unless wp.position
|
|
@@ -126,11 +170,11 @@ module Ea
|
|
|
126
170
|
if dx.abs * bounds.height > dy.abs * bounds.width
|
|
127
171
|
x = dx.positive? ? bounds.x + bounds.width : bounds.x
|
|
128
172
|
y = safe_y(cx, cy, dx, dy, x)
|
|
129
|
-
[x, y]
|
|
173
|
+
[x, y.floor]
|
|
130
174
|
else
|
|
131
175
|
y = dy.positive? ? bounds.y + bounds.height : bounds.y
|
|
132
176
|
x = safe_x(cx, cy, dx, dy, y)
|
|
133
|
-
[x, y]
|
|
177
|
+
[x.floor, y]
|
|
134
178
|
end
|
|
135
179
|
end
|
|
136
180
|
|
data/lib/ea/version.rb
CHANGED