@meltemi/diagrams-layout 0.0.0-stage → 1.9.0
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.
- package/LICENSE +21 -0
- package/README.md +52 -2
- package/dist/audit.d.ts +58 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +239 -0
- package/dist/audit.js.map +1 -0
- package/dist/checks.d.ts +38 -0
- package/dist/checks.d.ts.map +1 -0
- package/dist/checks.js +331 -0
- package/dist/checks.js.map +1 -0
- package/dist/constraints.d.ts +20 -0
- package/dist/constraints.d.ts.map +1 -0
- package/dist/constraints.js +149 -0
- package/dist/constraints.js.map +1 -0
- package/dist/engine.d.ts +96 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +3 -0
- package/dist/engine.js.map +1 -0
- package/dist/frame.d.ts +17 -0
- package/dist/frame.d.ts.map +1 -0
- package/dist/frame.js +51 -0
- package/dist/frame.js.map +1 -0
- package/dist/free.d.ts +75 -0
- package/dist/free.d.ts.map +1 -0
- package/dist/free.js +122 -0
- package/dist/free.js.map +1 -0
- package/dist/geometry.d.ts +58 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +223 -0
- package/dist/geometry.js.map +1 -0
- package/dist/icons.d.ts +16 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/icons.js +94 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.d.ts +206 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +3527 -0
- package/dist/layout.js.map +1 -0
- package/dist/mark.d.ts +24 -0
- package/dist/mark.d.ts.map +1 -0
- package/dist/mark.js +60 -0
- package/dist/mark.js.map +1 -0
- package/dist/markers.d.ts +62 -0
- package/dist/markers.d.ts.map +1 -0
- package/dist/markers.js +255 -0
- package/dist/markers.js.map +1 -0
- package/dist/measure.d.ts +38 -0
- package/dist/measure.d.ts.map +1 -0
- package/dist/measure.js +44 -0
- package/dist/measure.js.map +1 -0
- package/dist/messages/en.d.ts +160 -0
- package/dist/messages/en.d.ts.map +1 -0
- package/dist/messages/en.js +163 -0
- package/dist/messages/en.js.map +1 -0
- package/dist/messages/es.d.ts +4 -0
- package/dist/messages/es.d.ts.map +1 -0
- package/dist/messages/es.js +104 -0
- package/dist/messages/es.js.map +1 -0
- package/dist/messages/index.d.ts +86 -0
- package/dist/messages/index.d.ts.map +1 -0
- package/dist/messages/index.js +17 -0
- package/dist/messages/index.js.map +1 -0
- package/dist/routing.d.ts +94 -0
- package/dist/routing.d.ts.map +1 -0
- package/dist/routing.js +549 -0
- package/dist/routing.js.map +1 -0
- package/dist/scene.d.ts +220 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +5 -0
- package/dist/scene.js.map +1 -0
- package/dist/sequence.d.ts +17 -0
- package/dist/sequence.d.ts.map +1 -0
- package/dist/sequence.js +875 -0
- package/dist/sequence.js.map +1 -0
- package/dist/shapes.d.ts +140 -0
- package/dist/shapes.d.ts.map +1 -0
- package/dist/shapes.js +1030 -0
- package/dist/shapes.js.map +1 -0
- package/dist/styles.d.ts +58 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +106 -0
- package/dist/styles.js.map +1 -0
- package/dist/text.d.ts +8 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +28 -0
- package/dist/text.js.map +1 -0
- package/dist/theme.d.ts +100 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +246 -0
- package/dist/theme.js.map +1 -0
- package/dist/viewport.d.ts +98 -0
- package/dist/viewport.d.ts.map +1 -0
- package/dist/viewport.js +177 -0
- package/dist/viewport.js.map +1 -0
- package/package.json +49 -3
package/dist/checks.js
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { messages } from "./messages/index.js";
|
|
2
|
+
import { crossedBoxes } from "./routing.js";
|
|
3
|
+
import { segmentCrossesPolygon } from "./shapes.js";
|
|
4
|
+
/** The kinds drawn as boxes that may not overlap: flow kinds, free boxes and C4 entities. */
|
|
5
|
+
const BOX_KINDS = new Set([
|
|
6
|
+
"node",
|
|
7
|
+
"decision",
|
|
8
|
+
"data",
|
|
9
|
+
"box",
|
|
10
|
+
"person",
|
|
11
|
+
"system",
|
|
12
|
+
"container",
|
|
13
|
+
"datastore",
|
|
14
|
+
"component",
|
|
15
|
+
]);
|
|
16
|
+
const EPSILON = 0.5;
|
|
17
|
+
/** Shortest shared stretch of two collinear connectors that is reported. */
|
|
18
|
+
export const CONNECTOR_OVERLAP = 24;
|
|
19
|
+
function intersects(a, b) {
|
|
20
|
+
return (a.x < b.x + b.width - EPSILON &&
|
|
21
|
+
b.x < a.x + a.width - EPSILON &&
|
|
22
|
+
a.y < b.y + b.height - EPSILON &&
|
|
23
|
+
b.y < a.y + a.height - EPSILON);
|
|
24
|
+
}
|
|
25
|
+
function union(a, b) {
|
|
26
|
+
const x = Math.min(a.x, b.x);
|
|
27
|
+
const y = Math.min(a.y, b.y);
|
|
28
|
+
return {
|
|
29
|
+
x,
|
|
30
|
+
y,
|
|
31
|
+
width: Math.max(a.x + a.width, b.x + b.width) - x,
|
|
32
|
+
height: Math.max(a.y + a.height, b.y + b.height) - y,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function contains(outer, inner) {
|
|
36
|
+
return (inner.x >= outer.x - EPSILON &&
|
|
37
|
+
inner.y >= outer.y - EPSILON &&
|
|
38
|
+
inner.x + inner.width <= outer.x + outer.width + EPSILON &&
|
|
39
|
+
inner.y + inner.height <= outer.y + outer.height + EPSILON);
|
|
40
|
+
}
|
|
41
|
+
/** How far in from a side of the outer box a stacked box lies, at least, on one of its sides. */
|
|
42
|
+
const STACK_INSET = 1;
|
|
43
|
+
/**
|
|
44
|
+
* Whether `inner` is stacked on `outer`: inside it, and at least `STACK_INSET` in from one of its
|
|
45
|
+
* sides. Two boxes that coincide hold each other, but one hides the other: they are no stack.
|
|
46
|
+
* Hosts use the same rule to find the boxes a box holds (a stack is the later box of a layer).
|
|
47
|
+
*/
|
|
48
|
+
export function stacked(outer, inner) {
|
|
49
|
+
return (contains(outer, inner) &&
|
|
50
|
+
Math.max(inner.x - outer.x, inner.y - outer.y, outer.x + outer.width - (inner.x + inner.width), outer.y + outer.height - (inner.y + inner.height)) >=
|
|
51
|
+
STACK_INSET - 1e-9);
|
|
52
|
+
}
|
|
53
|
+
/** Whether a segment crosses the inside of a box. */
|
|
54
|
+
function segmentHitsBox(a, b, box) {
|
|
55
|
+
// Liang-Barsky clipping against the box shrunk by a pixel.
|
|
56
|
+
const inner = { x: box.x + 1, y: box.y + 1, width: box.width - 2, height: box.height - 2 };
|
|
57
|
+
if (inner.width <= 0 || inner.height <= 0)
|
|
58
|
+
return false;
|
|
59
|
+
let t0 = 0;
|
|
60
|
+
let t1 = 1;
|
|
61
|
+
const dx = b.x - a.x;
|
|
62
|
+
const dy = b.y - a.y;
|
|
63
|
+
const checks = [
|
|
64
|
+
[-dx, a.x - inner.x],
|
|
65
|
+
[dx, inner.x + inner.width - a.x],
|
|
66
|
+
[-dy, a.y - inner.y],
|
|
67
|
+
[dy, inner.y + inner.height - a.y],
|
|
68
|
+
];
|
|
69
|
+
for (const [p, q] of checks) {
|
|
70
|
+
if (p === 0) {
|
|
71
|
+
if (q < 0)
|
|
72
|
+
return false;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const r = q / p;
|
|
76
|
+
if (p < 0) {
|
|
77
|
+
if (r > t1)
|
|
78
|
+
return false;
|
|
79
|
+
if (r > t0)
|
|
80
|
+
t0 = r;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
if (r < t0)
|
|
84
|
+
return false;
|
|
85
|
+
if (r < t1)
|
|
86
|
+
t1 = r;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return t0 < t1;
|
|
90
|
+
}
|
|
91
|
+
function horizontal(p, q) {
|
|
92
|
+
return Math.abs(p.y - q.y) < EPSILON;
|
|
93
|
+
}
|
|
94
|
+
function verticalSeg(p, q) {
|
|
95
|
+
return Math.abs(p.x - q.x) < EPSILON;
|
|
96
|
+
}
|
|
97
|
+
/** The length two axis-aligned segments share when they lie on the same line. */
|
|
98
|
+
function sharedLength(a1, a2, b1, b2) {
|
|
99
|
+
if (horizontal(a1, a2) && horizontal(b1, b2) && Math.abs(a1.y - b1.y) < EPSILON) {
|
|
100
|
+
const lo = Math.max(Math.min(a1.x, a2.x), Math.min(b1.x, b2.x));
|
|
101
|
+
const hi = Math.min(Math.max(a1.x, a2.x), Math.max(b1.x, b2.x));
|
|
102
|
+
return Math.max(0, hi - lo);
|
|
103
|
+
}
|
|
104
|
+
if (verticalSeg(a1, a2) && verticalSeg(b1, b2) && Math.abs(a1.x - b1.x) < EPSILON) {
|
|
105
|
+
const lo = Math.max(Math.min(a1.y, a2.y), Math.min(b1.y, b2.y));
|
|
106
|
+
const hi = Math.min(Math.max(a1.y, a2.y), Math.max(b1.y, b2.y));
|
|
107
|
+
return Math.max(0, hi - lo);
|
|
108
|
+
}
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
/** The bounding box of a polyline. */
|
|
112
|
+
function pointsBox(points) {
|
|
113
|
+
let minX = Infinity;
|
|
114
|
+
let minY = Infinity;
|
|
115
|
+
let maxX = -Infinity;
|
|
116
|
+
let maxY = -Infinity;
|
|
117
|
+
for (const p of points) {
|
|
118
|
+
minX = Math.min(minX, p.x);
|
|
119
|
+
minY = Math.min(minY, p.y);
|
|
120
|
+
maxX = Math.max(maxX, p.x);
|
|
121
|
+
maxY = Math.max(maxY, p.y);
|
|
122
|
+
}
|
|
123
|
+
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Index pairs `[i, j]` (i < j) of boxes that touch or come within `slack` of each other, in
|
|
127
|
+
* ascending order. Sweeping along x keeps large diagrams fast: only boxes whose x ranges meet are
|
|
128
|
+
* compared.
|
|
129
|
+
*/
|
|
130
|
+
function nearPairs(boxes, slack) {
|
|
131
|
+
const sorted = boxes.map((_, i) => i).sort((a, b) => boxes[a].x - boxes[b].x || a - b);
|
|
132
|
+
const pairs = [];
|
|
133
|
+
for (let s = 0; s < sorted.length; s++) {
|
|
134
|
+
const i = sorted[s];
|
|
135
|
+
const a = boxes[i];
|
|
136
|
+
const right = a.x + a.width + slack;
|
|
137
|
+
for (let t = s + 1; t < sorted.length; t++) {
|
|
138
|
+
const j = sorted[t];
|
|
139
|
+
const b = boxes[j];
|
|
140
|
+
if (b.x > right)
|
|
141
|
+
break;
|
|
142
|
+
if (b.y <= a.y + a.height + slack && a.y <= b.y + b.height + slack) {
|
|
143
|
+
pairs.push(i < j ? [i, j] : [j, i]);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return pairs.sort((p, q) => p[0] - q[0] || p[1] - q[1]);
|
|
148
|
+
}
|
|
149
|
+
/** The layer an element or relation is drawn on. */
|
|
150
|
+
const layerOf = (item) => item.layer ?? "main";
|
|
151
|
+
/**
|
|
152
|
+
* Composition checks (decision D7 of the layout-engine change): overlapping boxes, boxes crossing
|
|
153
|
+
* group edges, labels lying on other connectors, boxes too close to the edge or title band of a
|
|
154
|
+
* placed group, and connectors running along each other. Tags and notes are not checked, nor are
|
|
155
|
+
* the text, icons and images of free diagrams; boxes and groups on different layers overlap on
|
|
156
|
+
* purpose, and a box declared after a box that holds it whole (`stacked`) is a stack, not an
|
|
157
|
+
* overlap; written the other way round, the overlap's hint says to declare the outer box first.
|
|
158
|
+
* `untitled` tells the groups without a title band (see `isUntitledGroup`). `outlines` holds the
|
|
159
|
+
* outline polygon of the boxes drawn with a shape other than a box (see `shapeOutline`): a
|
|
160
|
+
* connector crosses such a box only through its outline, not through its box's empty corners.
|
|
161
|
+
* `labels` holds the labels boxes draw outside them (an icon shape's): a box and its label are two
|
|
162
|
+
* rectangles that overlap other boxes and groups, with nothing between them; a box over another's
|
|
163
|
+
* label is an overlap, never a stack; boxes keep their groups' margins with their labels;
|
|
164
|
+
* connectors cross the boxes.
|
|
165
|
+
*/
|
|
166
|
+
export function checkComposition(diagram, boxes, connectors, explicitGroups, theme, untitled, outlines = new Map(), labels = new Map()) {
|
|
167
|
+
const diagnostics = [];
|
|
168
|
+
// Messages are written in the interface language of the moment the checks run.
|
|
169
|
+
const { diagnostics: words, hints } = messages();
|
|
170
|
+
// `ids` are the elements and relations the message names, for tools that must not read it.
|
|
171
|
+
const warn = (code, message, range, ids, hint) => diagnostics.push({
|
|
172
|
+
code,
|
|
173
|
+
severity: "warning",
|
|
174
|
+
message,
|
|
175
|
+
range,
|
|
176
|
+
...(hint === undefined ? {} : { hints: [hint] }),
|
|
177
|
+
data: { ids },
|
|
178
|
+
});
|
|
179
|
+
const order = new Map(diagram.elements.map((e, i) => [e.id, i]));
|
|
180
|
+
const later = (a, b) => (order.get(a.id) ?? 0) > (order.get(b.id) ?? 0) ? a : b;
|
|
181
|
+
const shapes = diagram.elements.filter((e) => BOX_KINDS.has(e.kind) && boxes.has(e.id));
|
|
182
|
+
const groups = diagram.elements.filter((e) => e.kind === "group" && boxes.has(e.id));
|
|
183
|
+
/** What a shape draws: its box, and the label outside it if it has one. */
|
|
184
|
+
const partsOf = (id) => {
|
|
185
|
+
const label = labels.get(id);
|
|
186
|
+
return label ? [boxes.get(id), label] : [boxes.get(id)];
|
|
187
|
+
};
|
|
188
|
+
/** The extent of what a shape draws. */
|
|
189
|
+
const extentOf = (id) => {
|
|
190
|
+
const label = labels.get(id);
|
|
191
|
+
return label ? union(boxes.get(id), label) : boxes.get(id);
|
|
192
|
+
};
|
|
193
|
+
const meets = (a, b) => a.some((p) => b.some((q) => intersects(p, q)));
|
|
194
|
+
const shapeParts = shapes.map((s) => partsOf(s.id));
|
|
195
|
+
const shapeBoxes = shapes.map((s) => extentOf(s.id));
|
|
196
|
+
for (const [i, j] of nearPairs(shapeBoxes, 0)) {
|
|
197
|
+
// `shapes` keeps the declaration order, so `a` is declared before `b`.
|
|
198
|
+
const a = shapes[i];
|
|
199
|
+
const b = shapes[j];
|
|
200
|
+
if (layerOf(a) !== layerOf(b))
|
|
201
|
+
continue;
|
|
202
|
+
if (!meets(shapeParts[i], shapeParts[j]))
|
|
203
|
+
continue;
|
|
204
|
+
// A later box drawn whole inside an earlier one is a stack; a box over a label is not.
|
|
205
|
+
if (stacked(boxes.get(a.id), shapeBoxes[j]))
|
|
206
|
+
continue;
|
|
207
|
+
// An earlier box inside a later one is a stack written inner first, and hidden by it.
|
|
208
|
+
const reversed = stacked(boxes.get(b.id), shapeBoxes[i]);
|
|
209
|
+
warn("layout.overlap", words.overlap(a.id, b.id), later(a, b).range, [a.id, b.id], reversed ? hints.stackOrder(b.id, a.id) : undefined);
|
|
210
|
+
}
|
|
211
|
+
for (const [index, shape] of shapes.entries()) {
|
|
212
|
+
const box = shapeBoxes[index];
|
|
213
|
+
for (const group of groups) {
|
|
214
|
+
if (layerOf(shape) !== layerOf(group))
|
|
215
|
+
continue;
|
|
216
|
+
const area = boxes.get(group.id);
|
|
217
|
+
if (!meets(shapeParts[index], [area]))
|
|
218
|
+
continue;
|
|
219
|
+
const declared = shape.groupPath.includes(group.id);
|
|
220
|
+
if (declared && contains(area, box))
|
|
221
|
+
continue;
|
|
222
|
+
warn("layout.overlap", declared ? words.crossesGroup(shape.id, group.id) : words.overlapsGroup(shape.id, group.id), shape.range, [shape.id, group.id]);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
for (const group of groups) {
|
|
226
|
+
if (!explicitGroups.has(group.id))
|
|
227
|
+
continue;
|
|
228
|
+
const area = boxes.get(group.id);
|
|
229
|
+
const margin = theme.groupPadding / 2;
|
|
230
|
+
// A titled group keeps its title band clear; an untitled one has no band.
|
|
231
|
+
const top = untitled(group) ? margin : theme.groupHeader;
|
|
232
|
+
for (const shape of shapes) {
|
|
233
|
+
if (!shape.groupPath.includes(group.id))
|
|
234
|
+
continue;
|
|
235
|
+
// A group on another layer is a backdrop, as for the overlaps above.
|
|
236
|
+
if (layerOf(shape) !== layerOf(group))
|
|
237
|
+
continue;
|
|
238
|
+
const box = extentOf(shape.id);
|
|
239
|
+
if (!contains(area, box))
|
|
240
|
+
continue; // already reported as crossing the edge
|
|
241
|
+
const tooClose = box.x - area.x < margin - EPSILON ||
|
|
242
|
+
area.x + area.width - (box.x + box.width) < margin - EPSILON ||
|
|
243
|
+
area.y + area.height - (box.y + box.height) < margin - EPSILON ||
|
|
244
|
+
box.y - area.y < top - EPSILON;
|
|
245
|
+
if (tooClose) {
|
|
246
|
+
warn("layout.container-margin", words.containerMargin(shape.id, group.id), shape.range, [
|
|
247
|
+
shape.id,
|
|
248
|
+
group.id,
|
|
249
|
+
]);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Labels and connectors in one sweep: connectors first, then the labels.
|
|
254
|
+
const extents = connectors.map((c) => pointsBox(c.points));
|
|
255
|
+
const labelled = connectors.flatMap((c, i) => (c.label ? [i] : []));
|
|
256
|
+
const sweep = [...extents, ...labelled.map((i) => connectors[i].label)];
|
|
257
|
+
const hits = [];
|
|
258
|
+
for (const [p, q] of nearPairs(sweep, 0)) {
|
|
259
|
+
if (p >= connectors.length || q < connectors.length)
|
|
260
|
+
continue; // not a connector and a label
|
|
261
|
+
const owner = labelled[q - connectors.length];
|
|
262
|
+
if (owner !== p)
|
|
263
|
+
hits.push([owner, p]);
|
|
264
|
+
}
|
|
265
|
+
hits.sort((x, y) => x[0] - y[0] || x[1] - y[1]);
|
|
266
|
+
for (const [owner, index] of hits) {
|
|
267
|
+
const connector = connectors[owner];
|
|
268
|
+
const other = connectors[index];
|
|
269
|
+
const pts = other.points;
|
|
270
|
+
let hit = false;
|
|
271
|
+
for (let k = 1; k < pts.length && !hit; k++)
|
|
272
|
+
hit = segmentHitsBox(pts[k - 1], pts[k], connector.label);
|
|
273
|
+
if (hit) {
|
|
274
|
+
warn("layout.label-under-connector", words.labelUnderConnector(connector.relation.key, other.relation.key), connector.relation.range, [connector.relation.key, other.relation.key]);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
for (const [i, j] of nearPairs(extents, EPSILON)) {
|
|
278
|
+
const a = connectors[i];
|
|
279
|
+
const b = connectors[j];
|
|
280
|
+
if (a.curved || b.curved)
|
|
281
|
+
continue;
|
|
282
|
+
let shared = 0;
|
|
283
|
+
for (let p = 1; p < a.points.length; p++) {
|
|
284
|
+
for (let q = 1; q < b.points.length; q++) {
|
|
285
|
+
shared = Math.max(shared, sharedLength(a.points[p - 1], a.points[p], b.points[q - 1], b.points[q]));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (shared > CONNECTOR_OVERLAP) {
|
|
289
|
+
warn("layout.connector-overlap", words.connectorOverlap(a.relation.key, b.relation.key, Math.round(shared)), b.relation.range, [a.relation.key, b.relation.key]);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// Connectors through the shapes of their layer that they do not join, nor hold their ends.
|
|
293
|
+
for (const connector of connectors) {
|
|
294
|
+
const relation = connector.relation;
|
|
295
|
+
const holders = new Set([relation.from, relation.to].flatMap((id) => [
|
|
296
|
+
id,
|
|
297
|
+
...(diagram.elementsById.get(id)?.groupPath ?? []),
|
|
298
|
+
]));
|
|
299
|
+
const ends = [relation.from, relation.to].flatMap((id) => boxes.get(id) ?? []);
|
|
300
|
+
const extent = pointsBox(connector.points);
|
|
301
|
+
const others = shapes.filter((s) => {
|
|
302
|
+
if (holders.has(s.id) || layerOf(s) !== layerOf(relation))
|
|
303
|
+
return false;
|
|
304
|
+
const box = boxes.get(s.id);
|
|
305
|
+
// A box an end is stacked inside holds that end.
|
|
306
|
+
if (ends.some((end) => contains(box, end)))
|
|
307
|
+
return false;
|
|
308
|
+
return (box.x <= extent.x + extent.width &&
|
|
309
|
+
extent.x <= box.x + box.width &&
|
|
310
|
+
box.y <= extent.y + extent.height &&
|
|
311
|
+
extent.y <= box.y + box.height);
|
|
312
|
+
});
|
|
313
|
+
const crossed = crossedBoxes(connector.points, others.map((s) => ({ ...boxes.get(s.id), id: s.id }))).filter((box) => {
|
|
314
|
+
// A shaped box is crossed through its outline.
|
|
315
|
+
const outline = outlines.get(box.id);
|
|
316
|
+
if (!outline)
|
|
317
|
+
return true;
|
|
318
|
+
for (let k = 1; k < connector.points.length; k++) {
|
|
319
|
+
if (segmentCrossesPolygon(connector.points[k - 1], connector.points[k], outline)) {
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return false;
|
|
324
|
+
});
|
|
325
|
+
for (const box of crossed) {
|
|
326
|
+
warn("layout.connector-crossing", words.connectorCrossing(relation.key, box.id), relation.range, [relation.key, box.id]);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return diagnostics;
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ConstraintEntry, Point } from "@meltemi/diagrams-model";
|
|
2
|
+
/** A box the solver may move, given by its centre and size. */
|
|
3
|
+
export interface SolverBox {
|
|
4
|
+
center: Point;
|
|
5
|
+
readonly width: number;
|
|
6
|
+
readonly height: number;
|
|
7
|
+
/** Fixed boxes never move: placed ones in `assisted`, every one in `manual`. */
|
|
8
|
+
readonly fixed: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface ConstraintConflict {
|
|
11
|
+
readonly entry: ConstraintEntry;
|
|
12
|
+
/** Why it does not hold, in the interface language of the moment it was found. */
|
|
13
|
+
readonly message: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Moves free boxes until every constraint holds, for a bounded number of rounds, and returns the
|
|
17
|
+
* constraints that still do not hold. Fixed boxes never move.
|
|
18
|
+
*/
|
|
19
|
+
export declare function solveConstraints(constraints: readonly ConstraintEntry[], boxes: ReadonlyMap<string, SolverBox>, defaultAxis: "horizontal" | "vertical", spacing: number): ConstraintConflict[];
|
|
20
|
+
//# sourceMappingURL=constraints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraints.d.ts","sourceRoot":"","sources":["../src/constraints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,eAAe,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAGjF,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,kFAAkF;IAClF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AA6CD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,SAAS,eAAe,EAAE,EACvC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,EACrC,WAAW,EAAE,YAAY,GAAG,UAAU,EACtC,OAAO,EAAE,MAAM,GACd,kBAAkB,EAAE,CAgDtB"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { messages } from "./messages/index.js";
|
|
2
|
+
const ROUNDS = 20;
|
|
3
|
+
const TOLERANCE = 0.5;
|
|
4
|
+
function edgeValue(box, edge) {
|
|
5
|
+
switch (edge) {
|
|
6
|
+
case "top":
|
|
7
|
+
return box.center.y - box.height / 2;
|
|
8
|
+
case "middle":
|
|
9
|
+
return box.center.y;
|
|
10
|
+
case "bottom":
|
|
11
|
+
return box.center.y + box.height / 2;
|
|
12
|
+
case "left":
|
|
13
|
+
return box.center.x - box.width / 2;
|
|
14
|
+
case "center":
|
|
15
|
+
return box.center.x;
|
|
16
|
+
case "right":
|
|
17
|
+
return box.center.x + box.width / 2;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const horizontalEdge = (edge) => edge === "left" || edge === "center" || edge === "right";
|
|
21
|
+
function setEdge(box, edge, value) {
|
|
22
|
+
const delta = value - edgeValue(box, edge);
|
|
23
|
+
box.center = horizontalEdge(edge)
|
|
24
|
+
? { x: box.center.x + delta, y: box.center.y }
|
|
25
|
+
: { x: box.center.x, y: box.center.y + delta };
|
|
26
|
+
}
|
|
27
|
+
/** The gap between two boxes, edge to edge, along the axis on which they are furthest apart. */
|
|
28
|
+
function gap(a, b) {
|
|
29
|
+
const dx = Math.abs(a.center.x - b.center.x) - (a.width + b.width) / 2;
|
|
30
|
+
const dy = Math.abs(a.center.y - b.center.y) - (a.height + b.height) / 2;
|
|
31
|
+
return dx >= dy ? { value: dx, axis: "x" } : { value: dy, axis: "y" };
|
|
32
|
+
}
|
|
33
|
+
const along = (box, axis) => (axis === "x" ? box.center.x : box.center.y);
|
|
34
|
+
const extent = (box, axis) => (axis === "x" ? box.width : box.height);
|
|
35
|
+
const moveTo = (box, axis, value) => {
|
|
36
|
+
box.center = axis === "x" ? { x: value, y: box.center.y } : { x: box.center.x, y: value };
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Moves free boxes until every constraint holds, for a bounded number of rounds, and returns the
|
|
40
|
+
* constraints that still do not hold. Fixed boxes never move.
|
|
41
|
+
*/
|
|
42
|
+
export function solveConstraints(constraints, boxes, defaultAxis, spacing) {
|
|
43
|
+
const members = (entry) => entry.targets.map((id) => boxes.get(id)).filter((b) => b !== undefined);
|
|
44
|
+
for (let round = 0; round < ROUNDS; round++) {
|
|
45
|
+
let moved = false;
|
|
46
|
+
for (const entry of constraints) {
|
|
47
|
+
const list = members(entry);
|
|
48
|
+
if (list.length < 2)
|
|
49
|
+
continue;
|
|
50
|
+
if (entry.edge) {
|
|
51
|
+
const edge = entry.edge;
|
|
52
|
+
const fixed = list.find((b) => b.fixed);
|
|
53
|
+
const reference = fixed
|
|
54
|
+
? edgeValue(fixed, edge)
|
|
55
|
+
: list.reduce((sum, b) => sum + edgeValue(b, edge), 0) / list.length;
|
|
56
|
+
for (const box of list) {
|
|
57
|
+
if (!box.fixed && Math.abs(edgeValue(box, edge) - reference) > TOLERANCE) {
|
|
58
|
+
setEdge(box, edge, reference);
|
|
59
|
+
moved = true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if (entry.kind === "order") {
|
|
64
|
+
const axis = (entry.axis ?? defaultAxis) === "horizontal" ? "x" : "y";
|
|
65
|
+
for (let i = 1; i < list.length; i++) {
|
|
66
|
+
const previous = list[i - 1];
|
|
67
|
+
const current = list[i];
|
|
68
|
+
const needed = (extent(previous, axis) + extent(current, axis)) / 2 + spacing;
|
|
69
|
+
if (along(current, axis) - along(previous, axis) >= needed - TOLERANCE)
|
|
70
|
+
continue;
|
|
71
|
+
if (!current.fixed)
|
|
72
|
+
moveTo(current, axis, along(previous, axis) + needed);
|
|
73
|
+
else if (!previous.fixed)
|
|
74
|
+
moveTo(previous, axis, along(current, axis) - needed);
|
|
75
|
+
else
|
|
76
|
+
continue;
|
|
77
|
+
moved = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else if (entry.kind === "distance" && entry.distance !== null) {
|
|
81
|
+
const [a, b] = list;
|
|
82
|
+
const current = gap(a, b);
|
|
83
|
+
if (current.value >= entry.distance - TOLERANCE)
|
|
84
|
+
continue;
|
|
85
|
+
const push = entry.distance - current.value;
|
|
86
|
+
const mover = !b.fixed ? b : !a.fixed ? a : undefined;
|
|
87
|
+
if (!mover)
|
|
88
|
+
continue;
|
|
89
|
+
const other = mover === b ? a : b;
|
|
90
|
+
const direction = along(mover, current.axis) >= along(other, current.axis) ? 1 : -1;
|
|
91
|
+
moveTo(mover, current.axis, along(mover, current.axis) + direction * push);
|
|
92
|
+
moved = true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (!moved)
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
return conflicts(constraints, boxes, defaultAxis);
|
|
99
|
+
}
|
|
100
|
+
const round = (value) => Math.round(value * 10) / 10;
|
|
101
|
+
/** Constraints that do not hold for the current boxes. */
|
|
102
|
+
function conflicts(constraints, boxes, defaultAxis) {
|
|
103
|
+
const found = [];
|
|
104
|
+
const words = messages().diagnostics;
|
|
105
|
+
for (const entry of constraints) {
|
|
106
|
+
const list = entry.targets.map((id) => [id, boxes.get(id)]).filter(([, b]) => b);
|
|
107
|
+
if (list.length < 2)
|
|
108
|
+
continue;
|
|
109
|
+
if (entry.edge) {
|
|
110
|
+
const edge = entry.edge;
|
|
111
|
+
const values = list.map(([id, b]) => [id, edgeValue(b, edge)]);
|
|
112
|
+
const [firstId, first] = values[0];
|
|
113
|
+
const worst = values.reduce((w, v) => Math.abs(v[1] - first) > Math.abs(w[1] - first) ? v : w);
|
|
114
|
+
const difference = Math.abs(worst[1] - first);
|
|
115
|
+
if (difference > TOLERANCE) {
|
|
116
|
+
found.push({
|
|
117
|
+
entry,
|
|
118
|
+
message: words.alignConflict(entry.kind, entry.targets, edge, worst[0], round(difference), firstId),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if (entry.kind === "order") {
|
|
123
|
+
const axis = (entry.axis ?? defaultAxis) === "horizontal" ? "x" : "y";
|
|
124
|
+
for (let i = 1; i < list.length; i++) {
|
|
125
|
+
const [previousId, previous] = list[i - 1];
|
|
126
|
+
const [currentId, current] = list[i];
|
|
127
|
+
if (along(current, axis) <= along(previous, axis)) {
|
|
128
|
+
found.push({
|
|
129
|
+
entry,
|
|
130
|
+
message: words.orderConflict(entry.targets, currentId, axis, previousId),
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else if (entry.kind === "distance" && entry.distance !== null) {
|
|
137
|
+
const [[aId, a], [bId, b]] = list;
|
|
138
|
+
const current = gap(a, b).value;
|
|
139
|
+
if (current < entry.distance - TOLERANCE) {
|
|
140
|
+
found.push({
|
|
141
|
+
entry,
|
|
142
|
+
message: words.distanceConflict(aId, bId, round(Math.max(0, current)), entry.distance),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return found;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=constraints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraints.js","sourceRoot":"","sources":["../src/constraints.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAiB/C,MAAM,MAAM,GAAG,EAAE,CAAC;AAClB,MAAM,SAAS,GAAG,GAAG,CAAC;AAEtB,SAAS,SAAS,CAAC,GAAc,EAAE,IAAe;IAChD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK;YACR,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;QACvC,KAAK,QAAQ;YACX,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACtB,KAAK,QAAQ;YACX,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;QACvC,KAAK,MAAM;YACT,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;QACtC,KAAK,QAAQ;YACX,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACtB,KAAK,OAAO;YACV,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,IAAe,EAAE,EAAE,CACzC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO,CAAC;AAE3D,SAAS,OAAO,CAAC,GAAc,EAAE,IAAe,EAAE,KAAa;IAC7D,MAAM,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC3C,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC;QAC/B,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE;QAC9C,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;AACnD,CAAC;AAED,gGAAgG;AAChG,SAAS,GAAG,CAAC,CAAY,EAAE,CAAY;IACrC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACxE,CAAC;AAED,MAAM,KAAK,GAAG,CAAC,GAAc,EAAE,IAAe,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChG,MAAM,MAAM,GAAG,CAAC,GAAc,EAAE,IAAe,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC5F,MAAM,MAAM,GAAG,CAAC,GAAc,EAAE,IAAe,EAAE,KAAa,EAAE,EAAE;IAChE,GAAG,CAAC,MAAM,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;AAC5F,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,WAAuC,EACvC,KAAqC,EACrC,WAAsC,EACtC,OAAe;IAEf,MAAM,OAAO,GAAG,CAAC,KAAsB,EAAE,EAAE,CACzC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAkB,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IAC1F,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5C,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC5B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAC9B,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;gBACxB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACxC,MAAM,SAAS,GAAG,KAAK;oBACrB,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC;oBACxB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;gBACvE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,EAAE,CAAC;wBACzE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;wBAC9B,KAAK,GAAG,IAAI,CAAC;oBACf,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAClC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,WAAW,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;gBACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;oBAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;oBACzB,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;oBAC9E,IAAI,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,GAAG,SAAS;wBAAE,SAAS;oBACjF,IAAI,CAAC,OAAO,CAAC,KAAK;wBAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;yBACrE,IAAI,CAAC,QAAQ,CAAC,KAAK;wBAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;;wBAC3E,SAAS;oBACd,KAAK,GAAG,IAAI,CAAC;gBACf,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAChE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAA8B,CAAC;gBAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC1B,IAAI,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,GAAG,SAAS;oBAAE,SAAS;gBAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC;gBAC5C,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACtD,IAAI,CAAC,KAAK;oBAAE,SAAS;gBACrB,MAAM,KAAK,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpF,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;gBAC3E,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;QACH,CAAC;QACD,IAAI,CAAC,KAAK;YAAE,MAAM;IACpB,CAAC;IACD,OAAO,SAAS,CAAC,WAAW,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AAE7D,0DAA0D;AAC1D,SAAS,SAAS,CAChB,WAAuC,EACvC,KAAqC,EACrC,WAAsC;IAEtC,MAAM,KAAK,GAAyB,EAAE,CAAC;IACvC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC,WAAW,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1F,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC9B,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;YACxB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,CAAE,EAAE,IAAI,CAAC,CAAU,CAAC,CAAC;YACzE,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;YACpC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACnC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACxD,CAAC;YACF,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;YAC9C,IAAI,UAAU,GAAG,SAAS,EAAE,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC;oBACT,KAAK;oBACL,OAAO,EAAE,KAAK,CAAC,aAAa,CAC1B,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,OAAO,EACb,IAAI,EACJ,KAAK,CAAC,CAAC,CAAC,EACR,KAAK,CAAC,UAAU,CAAC,EACjB,OAAO,CACR;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,WAAW,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;gBAC5C,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;gBACtC,IAAI,KAAK,CAAC,OAAQ,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,QAAS,EAAE,IAAI,CAAC,EAAE,CAAC;oBACpD,KAAK,CAAC,IAAI,CAAC;wBACT,KAAK;wBACL,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC;qBACzE,CAAC,CAAC;oBACH,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAChE,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,IAAkD,CAAC;YAChF,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;YAChC,IAAI,OAAO,GAAG,KAAK,CAAC,QAAQ,GAAG,SAAS,EAAE,CAAC;gBACzC,KAAK,CAAC,IAAI,CAAC;oBACT,KAAK;oBACL,OAAO,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC;iBACvF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/engine.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Point } from "@meltemi/diagrams-model";
|
|
2
|
+
import type { Box, Side } from "./geometry.js";
|
|
3
|
+
/** A port of a node: a side and a position along it, from 0 to 1. */
|
|
4
|
+
export interface ArrangePort {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly side: Side;
|
|
7
|
+
readonly position: number;
|
|
8
|
+
}
|
|
9
|
+
/** A box to arrange: a node, decision, data store, note or tag. */
|
|
10
|
+
export interface ArrangeNode {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly width: number;
|
|
13
|
+
readonly height: number;
|
|
14
|
+
readonly kind: string;
|
|
15
|
+
/** The innermost group declaring the node, or null. */
|
|
16
|
+
readonly parent: string | null;
|
|
17
|
+
/** The centre of a placed node in `assisted` mode; the engine may use it as a hint. */
|
|
18
|
+
readonly fixed: Point | null;
|
|
19
|
+
readonly ports: readonly ArrangePort[];
|
|
20
|
+
}
|
|
21
|
+
export interface ArrangeGroup {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly parent: string | null;
|
|
24
|
+
readonly padding: {
|
|
25
|
+
readonly top: number;
|
|
26
|
+
readonly right: number;
|
|
27
|
+
readonly bottom: number;
|
|
28
|
+
readonly left: number;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The written `size` of a placed group with children: the engine lays the group out at least
|
|
32
|
+
* this large, its children centred inside.
|
|
33
|
+
*/
|
|
34
|
+
readonly minimum?: {
|
|
35
|
+
readonly width: number;
|
|
36
|
+
readonly height: number;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface ArrangeEdge {
|
|
40
|
+
readonly id: string;
|
|
41
|
+
/** A node or group id. */
|
|
42
|
+
readonly source: string;
|
|
43
|
+
readonly target: string;
|
|
44
|
+
/** A port id of the source or target node, or null for any side. */
|
|
45
|
+
readonly sourcePort: string | null;
|
|
46
|
+
readonly targetPort: string | null;
|
|
47
|
+
/** True for `->` relations, false for `-->` ones, which the engine may route less directly. */
|
|
48
|
+
readonly primary: boolean;
|
|
49
|
+
/** The label pill drawn at the middle of the relation, which the engine leaves room for. */
|
|
50
|
+
readonly label?: {
|
|
51
|
+
readonly width: number;
|
|
52
|
+
readonly height: number;
|
|
53
|
+
} | null;
|
|
54
|
+
}
|
|
55
|
+
export interface ArrangeRequest {
|
|
56
|
+
readonly direction: "LR" | "RL" | "TB" | "BT";
|
|
57
|
+
/**
|
|
58
|
+
* `tree` keeps parents centred over their children (declared types may ask for it); layered
|
|
59
|
+
* graphs by default.
|
|
60
|
+
*/
|
|
61
|
+
readonly algorithm?: "layered" | "tree";
|
|
62
|
+
readonly nodes: readonly ArrangeNode[];
|
|
63
|
+
readonly groups: readonly ArrangeGroup[];
|
|
64
|
+
readonly edges: readonly ArrangeEdge[];
|
|
65
|
+
readonly spacing: {
|
|
66
|
+
readonly node: number;
|
|
67
|
+
readonly layer: number;
|
|
68
|
+
readonly edge: number;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export interface Arrangement {
|
|
72
|
+
/** Centres of every node, in diagram coordinates. */
|
|
73
|
+
readonly centers: ReadonlyMap<string, Point>;
|
|
74
|
+
/** Points of every edge from the source border to the target border. */
|
|
75
|
+
readonly routes: ReadonlyMap<string, readonly Point[]>;
|
|
76
|
+
/**
|
|
77
|
+
* The box of every group, in diagram coordinates. Engines that leave it out let the layout
|
|
78
|
+
* draw groups around their children.
|
|
79
|
+
*/
|
|
80
|
+
readonly groups?: ReadonlyMap<string, Box>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Arranges unplaced boxes for `auto` and `assisted` diagrams. Engines are synchronous so layout
|
|
84
|
+
* stays synchronous for every host; `@meltemi/diagrams-layout-elk` provides one backed by ELK.
|
|
85
|
+
*/
|
|
86
|
+
export interface LayoutEngine {
|
|
87
|
+
readonly name: string;
|
|
88
|
+
arrange(request: ArrangeRequest): Arrangement;
|
|
89
|
+
}
|
|
90
|
+
/** Spacing passed to engines: between boxes in a layer, between layers, and between edges. */
|
|
91
|
+
export declare const ENGINE_SPACING: {
|
|
92
|
+
readonly node: 40;
|
|
93
|
+
readonly layer: 70;
|
|
94
|
+
readonly edge: 16;
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|