@diagrammo/dgmo 0.86.0 → 0.88.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/dist/advanced.d.ts +6 -18
- package/dist/advanced.js +40 -37
- package/dist/block.js +6 -17
- package/dist/{chunk-FAV4RDVT.js → chunk-2A4DQAXG.js} +1 -1
- package/dist/{chunk-JIPUBFAM.js → chunk-5KGM44TG.js} +2 -2
- package/dist/{chunk-VEE777MD.js → chunk-5LD7SHXO.js} +3 -3
- package/dist/{chunk-QJ2JOLFN.js → chunk-6I5UN4FD.js} +2 -2
- package/dist/{chunk-ETBXIKK6.js → chunk-ABP5BUD6.js} +9 -430
- package/dist/{chunk-PKXKWHDW.js → chunk-AUS7V54P.js} +1 -1
- package/dist/{chunk-BF7JAFJI.js → chunk-B7CU2HW5.js} +2 -2
- package/dist/{chunk-X2VEJ5NT.js → chunk-BMUWF77V.js} +2 -2
- package/dist/{chunk-BP4BT5TH.js → chunk-CLQIXD2C.js} +1 -1
- package/dist/{chunk-QJFT5MAH.js → chunk-DSG6GBUQ.js} +2 -2
- package/dist/{chunk-EWSESGC2.js → chunk-EJS3K44P.js} +117 -78
- package/dist/{chunk-5JO443MB.js → chunk-HAH5X345.js} +1 -1
- package/dist/{chunk-HBCAY3KR.js → chunk-HTNLLT34.js} +1 -1
- package/dist/{chunk-HUMQIRJK.js → chunk-HTPZDZKQ.js} +2 -2
- package/dist/{chunk-VPVWG2GH.js → chunk-J7Q4VPBJ.js} +1 -1
- package/dist/{chunk-QPE646M2.js → chunk-JLETTWUJ.js} +30 -10
- package/dist/{chunk-3CQS3CIO.js → chunk-LL6D3MES.js} +1 -1
- package/dist/{chunk-ERYHC4KJ.js → chunk-LSQGJN5H.js} +1 -1
- package/dist/{chunk-AGO3PFGS.js → chunk-MVCPO6LI.js} +15 -10
- package/dist/{chunk-E6S2K6O2.js → chunk-N7XRBWXA.js} +2 -2
- package/dist/{chunk-WMIKC5XO.js → chunk-NPWVOFB3.js} +1 -1
- package/dist/{chunk-MYHPRQHR.js → chunk-O6MMQQLF.js} +3 -3
- package/dist/{chunk-GYORDNOM.js → chunk-P5V63L35.js} +1 -1
- package/dist/{chunk-BHZE36F7.js → chunk-PUVTFUNH.js} +1 -1
- package/dist/{chunk-TW6WMZFW.js → chunk-QT3KDDXK.js} +156 -7
- package/dist/{chunk-ZGHV4QLK.js → chunk-RJNZHFNG.js} +1 -1
- package/dist/{chunk-FWNJDD4U.js → chunk-S7W75MIM.js} +3 -20
- package/dist/{chunk-4YA5XW43.js → chunk-VW52W5F6.js} +981 -107
- package/dist/chunk-WXPBP4IT.js +438 -0
- package/dist/{chunk-C6FZZFYD.js → chunk-WZ23JJ7U.js} +1 -1
- package/dist/{chunk-LIYWJ6DV.js → chunk-XIFK423U.js} +108 -13
- package/dist/{chunk-4ELXLATB.js → chunk-XUDGZJTJ.js} +2 -2
- package/dist/{chunk-H6AFNCN3.js → chunk-XVSJYAK7.js} +1 -1
- package/dist/{chunk-LHBMQJC3.js → chunk-XWYR5T52.js} +2 -2
- package/dist/{chunk-QNKHJ5CK.js → chunk-YK4N6TBN.js} +4 -2
- package/dist/{chunk-XFMQSFS4.js → chunk-YMG7JDEY.js} +16 -6
- package/dist/chunk-Z6DXWULM.js +23 -0
- package/dist/{chunk-PBEH52A2.js → chunk-ZNNVI5SR.js} +1 -1
- package/dist/{flowchart-renderer-H72L7BEC.js → flowchart-renderer-THC6Y7EH.js} +7 -6
- package/dist/index.d.ts +68 -1
- package/dist/index.js +76 -7
- package/dist/{layout-QIPCNUSB.js → layout-BOVTLAOT.js} +7 -6
- package/dist/{layout-6JARW64V.js → layout-EHTYSMV4.js} +6 -5
- package/dist/{layout-YELNBVPC.js → layout-P6DTD4RT.js} +6 -5
- package/dist/{layout-T6TAB5OI.js → layout-RANVNAKI.js} +3 -3
- package/dist/{layout-FMKSENGL.js → layout-XUW444O5.js} +5 -4
- package/dist/{layout-search-AW5VBDCV.js → layout-search-VKSBUCDM.js} +57 -28
- package/dist/{renderer-AI2MD52D.js → renderer-222OTVQV.js} +3 -2
- package/dist/{renderer-UUWR7NGF.js → renderer-2KVQGGTT.js} +4 -3
- package/dist/{renderer-E5EKGIX2.js → renderer-2OOPQ4CH.js} +4 -3
- package/dist/{renderer-CZJ4AMYV.js → renderer-3FF4QVGW.js} +3 -2
- package/dist/{renderer-R6VJDZFO.js → renderer-4BHOELCE.js} +4 -3
- package/dist/{renderer-425QUIYO.js → renderer-4BIMRO4X.js} +4 -3
- package/dist/{renderer-5JVVJBAS.js → renderer-A4LMOBZL.js} +8 -7
- package/dist/{renderer-3AOOLHJU.js → renderer-A6ACVK4X.js} +3 -2
- package/dist/{renderer-ML2CLU25.js → renderer-DCFQDBGJ.js} +4 -3
- package/dist/{renderer-RH4U3UVM.js → renderer-LODEVN3V.js} +3 -2
- package/dist/{renderer-E7WF75GY.js → renderer-NHPKNNBD.js} +5 -4
- package/dist/{renderer-JEEGPLMM.js → renderer-R34GJL7U.js} +8 -7
- package/dist/{renderer-2BWRW23Z.js → renderer-RENDISO5.js} +1 -1
- package/dist/{renderer-NX4YKWCJ.js → renderer-RNCYODNF.js} +1 -1
- package/dist/{renderer-VKAJ52UO.js → renderer-SDUSBCJI.js} +3 -2
- package/dist/{renderer-RLSR7N6I.js → renderer-TPOZOAXR.js} +5 -4
- package/dist/{renderer-RUGMKHX5.js → renderer-WH2HWE5Z.js} +3 -2
- package/dist/{renderer-V6LLASGN.js → renderer-X5A5VIRD.js} +5 -4
- package/dist/{renderer-ADX4DWRJ.js → renderer-XUPLAO4B.js} +4 -2
- package/dist/{renderer-EWJS2RAZ.js → renderer-YDAVCRTP.js} +3 -2
- package/dist/{state-renderer-DDVJ43HR.js → state-renderer-5IQ4OJUI.js} +7 -6
- package/gallery/fixtures/journey-map.dgmo +28 -0
- package/gallery/fixtures/mindmap.dgmo +31 -0
- package/gallery/fixtures/pert.dgmo +27 -0
- package/gallery/fixtures/wireframe.dgmo +30 -0
- package/package.json +2 -2
|
@@ -10,6 +10,7 @@ var NODE_HEIGHT = 60;
|
|
|
10
10
|
var NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
|
|
11
11
|
|
|
12
12
|
// src/boxes-and-lines/label-placement.ts
|
|
13
|
+
import { curveBasis } from "d3-shape";
|
|
13
14
|
var EDGE_LABEL_FONT_SIZE = 11;
|
|
14
15
|
var LABEL_MAX_WIDTH = 160;
|
|
15
16
|
var MAX_LABEL_LINES = 3;
|
|
@@ -21,6 +22,12 @@ var PERP_STEP = 8;
|
|
|
21
22
|
var LABEL_REACH_NEAR = 40;
|
|
22
23
|
var LABEL_REACH_WIDE = 56;
|
|
23
24
|
var SLIDE_SAMPLES = 9;
|
|
25
|
+
var CURVE_STEP = 4;
|
|
26
|
+
var EDGE_CLEAR_PAD = 2;
|
|
27
|
+
var GROUP_BORDER_BAND = 4;
|
|
28
|
+
var GROUP_TITLE_FONT_SIZE = 14;
|
|
29
|
+
var GROUP_TITLE_DEPTH = 24;
|
|
30
|
+
var GROUP_LABEL_ZONE = 32;
|
|
24
31
|
function measureEdgeLabel(label, fontSize = EDGE_LABEL_FONT_SIZE, maxWidth = LABEL_MAX_WIDTH) {
|
|
25
32
|
let lines = wrapTextToWidth(label, fontSize, maxWidth, { hardBreak: true });
|
|
26
33
|
if (lines.length > MAX_LABEL_LINES) {
|
|
@@ -108,24 +115,69 @@ function slideFractions() {
|
|
|
108
115
|
}
|
|
109
116
|
return out;
|
|
110
117
|
}
|
|
111
|
-
function findClearPosition(
|
|
118
|
+
function findClearPosition(points, blocked, perpMax, firstSide = -1) {
|
|
112
119
|
const ts = slideFractions();
|
|
113
120
|
for (const t of ts) {
|
|
114
121
|
const { p } = pointAtArcFraction(points, t);
|
|
115
|
-
if (!
|
|
122
|
+
if (!blocked(p.x, p.y)) return p;
|
|
116
123
|
}
|
|
117
124
|
for (let mag = PERP_STEP; mag <= perpMax; mag += PERP_STEP) {
|
|
118
125
|
for (const t of ts) {
|
|
119
126
|
const { p, nx, ny } = pointAtArcFraction(points, t);
|
|
120
|
-
for (const sign of [
|
|
127
|
+
for (const sign of [firstSide, -firstSide]) {
|
|
121
128
|
const x = p.x + nx * mag * sign;
|
|
122
129
|
const y = p.y + ny * mag * sign;
|
|
123
|
-
if (!
|
|
130
|
+
if (!blocked(x, y)) return { x, y };
|
|
124
131
|
}
|
|
125
132
|
}
|
|
126
133
|
}
|
|
127
134
|
return null;
|
|
128
135
|
}
|
|
136
|
+
function sampleDrawnCurve(points) {
|
|
137
|
+
const out = [];
|
|
138
|
+
if (points.length < 2) return out;
|
|
139
|
+
let cx = 0;
|
|
140
|
+
let cy = 0;
|
|
141
|
+
const ctx = {
|
|
142
|
+
moveTo(x, y) {
|
|
143
|
+
out.push({ x, y });
|
|
144
|
+
cx = x;
|
|
145
|
+
cy = y;
|
|
146
|
+
},
|
|
147
|
+
lineTo(x, y) {
|
|
148
|
+
const n = Math.max(1, Math.ceil(Math.hypot(x - cx, y - cy) / CURVE_STEP));
|
|
149
|
+
for (let k = 1; k <= n; k++)
|
|
150
|
+
out.push({ x: cx + (x - cx) * k / n, y: cy + (y - cy) * k / n });
|
|
151
|
+
cx = x;
|
|
152
|
+
cy = y;
|
|
153
|
+
},
|
|
154
|
+
bezierCurveTo(x1, y1, x2, y2, x, y) {
|
|
155
|
+
const n = Math.max(
|
|
156
|
+
1,
|
|
157
|
+
Math.ceil(
|
|
158
|
+
(Math.hypot(x1 - cx, y1 - cy) + Math.hypot(x2 - x1, y2 - y1) + Math.hypot(x - x2, y - y2)) / CURVE_STEP
|
|
159
|
+
)
|
|
160
|
+
);
|
|
161
|
+
for (let k = 1; k <= n; k++) {
|
|
162
|
+
const t = k / n;
|
|
163
|
+
const u = 1 - t;
|
|
164
|
+
out.push({
|
|
165
|
+
x: u * u * u * cx + 3 * u * u * t * x1 + 3 * u * t * t * x2 + t * t * t * x,
|
|
166
|
+
y: u * u * u * cy + 3 * u * u * t * y1 + 3 * u * t * t * y2 + t * t * t * y
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
cx = x;
|
|
170
|
+
cy = y;
|
|
171
|
+
},
|
|
172
|
+
closePath() {
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const curve = curveBasis(ctx);
|
|
176
|
+
curve.lineStart();
|
|
177
|
+
for (const p of points) curve.point(p.x, p.y);
|
|
178
|
+
curve.lineEnd();
|
|
179
|
+
return out;
|
|
180
|
+
}
|
|
129
181
|
function buildGroupContainers(groups) {
|
|
130
182
|
const byLabel = new Map(groups.map((g) => [g.label, g]));
|
|
131
183
|
const parent = /* @__PURE__ */ new Map();
|
|
@@ -218,6 +270,81 @@ function placeEdgeLabels(layout, opts) {
|
|
|
218
270
|
obstacleCache.set(edgeIdx, out);
|
|
219
271
|
return out;
|
|
220
272
|
};
|
|
273
|
+
const curves = layout.edges.map((e) => {
|
|
274
|
+
const pts = sampleDrawnCurve(e.points);
|
|
275
|
+
let minX = Infinity;
|
|
276
|
+
let minY = Infinity;
|
|
277
|
+
let maxX = -Infinity;
|
|
278
|
+
let maxY = -Infinity;
|
|
279
|
+
for (const p of pts) {
|
|
280
|
+
if (p.x < minX) minX = p.x;
|
|
281
|
+
if (p.y < minY) minY = p.y;
|
|
282
|
+
if (p.x > maxX) maxX = p.x;
|
|
283
|
+
if (p.y > maxY) maxY = p.y;
|
|
284
|
+
}
|
|
285
|
+
return { pts, minX, minY, maxX, maxY };
|
|
286
|
+
});
|
|
287
|
+
const crossesOtherEdge = (edgeIdx, cx, cy, w, h) => {
|
|
288
|
+
const minX = cx - w / 2 - EDGE_CLEAR_PAD;
|
|
289
|
+
const minY = cy - h / 2 - EDGE_CLEAR_PAD;
|
|
290
|
+
const maxX = cx + w / 2 + EDGE_CLEAR_PAD;
|
|
291
|
+
const maxY = cy + h / 2 + EDGE_CLEAR_PAD;
|
|
292
|
+
for (let j = 0; j < curves.length; j++) {
|
|
293
|
+
if (j === edgeIdx) continue;
|
|
294
|
+
const c = curves[j];
|
|
295
|
+
if (c.maxX < minX || c.minX > maxX || c.maxY < minY || c.minY > maxY)
|
|
296
|
+
continue;
|
|
297
|
+
for (const p of c.pts)
|
|
298
|
+
if (p.x > minX && p.x < maxX && p.y > minY && p.y < maxY) return true;
|
|
299
|
+
}
|
|
300
|
+
return false;
|
|
301
|
+
};
|
|
302
|
+
const hasSubGroup = new Set(
|
|
303
|
+
(opts?.groups ?? []).flatMap((g) => g.parentGroup ? [g.parentGroup] : [])
|
|
304
|
+
);
|
|
305
|
+
const drawnTop = (g) => g.y - g.height / 2 - (hasSubGroup.has(g.label) ? GROUP_LABEL_ZONE : 0);
|
|
306
|
+
const titleRects = layout.groups.filter((g) => !g.collapsed).map((g) => {
|
|
307
|
+
const tw = measureText(g.label, GROUP_TITLE_FONT_SIZE, { bold: true });
|
|
308
|
+
const top = drawnTop(g);
|
|
309
|
+
return {
|
|
310
|
+
minX: g.x - tw / 2,
|
|
311
|
+
minY: top,
|
|
312
|
+
maxX: g.x + tw / 2,
|
|
313
|
+
maxY: top + GROUP_TITLE_DEPTH
|
|
314
|
+
};
|
|
315
|
+
});
|
|
316
|
+
const borderBands = (g) => {
|
|
317
|
+
const B = GROUP_BORDER_BAND;
|
|
318
|
+
const l = g.x - g.width / 2;
|
|
319
|
+
const r = g.x + g.width / 2;
|
|
320
|
+
const t = drawnTop(g);
|
|
321
|
+
const b = g.y + g.height / 2;
|
|
322
|
+
return [
|
|
323
|
+
{ minX: l - B, minY: t - B, maxX: r + B, maxY: t + B },
|
|
324
|
+
{ minX: l - B, minY: b - B, maxX: r + B, maxY: b + B },
|
|
325
|
+
{ minX: l - B, minY: t - B, maxX: l + B, maxY: b + B },
|
|
326
|
+
{ minX: r - B, minY: t - B, maxX: r + B, maxY: b + B }
|
|
327
|
+
];
|
|
328
|
+
};
|
|
329
|
+
const preferredCache = /* @__PURE__ */ new Map();
|
|
330
|
+
const preferredFor = (edgeIdx) => {
|
|
331
|
+
const cached = preferredCache.get(edgeIdx);
|
|
332
|
+
if (cached !== void 0) return cached;
|
|
333
|
+
const e = layout.edges[edgeIdx];
|
|
334
|
+
const src = containers.get(e.source) ?? noContainers;
|
|
335
|
+
const tgt = containers.get(e.target) ?? noContainers;
|
|
336
|
+
const own = layout.groups.filter(
|
|
337
|
+
(g) => !g.collapsed && src.has(g.label) && tgt.has(g.label)
|
|
338
|
+
);
|
|
339
|
+
const out = [
|
|
340
|
+
...obstaclesFor(edgeIdx),
|
|
341
|
+
...titleRects,
|
|
342
|
+
...own.flatMap(borderBands)
|
|
343
|
+
];
|
|
344
|
+
preferredCache.set(edgeIdx, out);
|
|
345
|
+
return out;
|
|
346
|
+
};
|
|
347
|
+
const clearOfAll = (edgeIdx, cx, cy, w, h) => !overlapsAny(cx, cy, w, h, preferredFor(edgeIdx), BOX_CLEAR_PAD) && !crossesOtherEdge(edgeIdx, cx, cy, w, h);
|
|
221
348
|
const boxes = [];
|
|
222
349
|
layout.edges.forEach((e, idx) => {
|
|
223
350
|
if (!e.label || e.points.length < 2) return;
|
|
@@ -238,10 +365,32 @@ function placeEdgeLabels(layout, opts) {
|
|
|
238
365
|
});
|
|
239
366
|
for (const box of boxes) {
|
|
240
367
|
const obstacles = obstaclesFor(box.edgeIdx);
|
|
241
|
-
if (
|
|
242
|
-
continue;
|
|
368
|
+
if (clearOfAll(box.edgeIdx, box.cx, box.cy, box.w, box.h)) continue;
|
|
243
369
|
const e = layout.edges[box.edgeIdx];
|
|
244
|
-
const
|
|
370
|
+
const { w, h } = box;
|
|
371
|
+
const mid = pointAtArcFraction(e.points, 0.5);
|
|
372
|
+
const side = (box.cx - mid.p.x) * mid.nx + (box.cy - mid.p.y) * mid.ny > 0 ? 1 : -1;
|
|
373
|
+
const ideal = findClearPosition(
|
|
374
|
+
e.points,
|
|
375
|
+
(x, y) => !clearOfAll(box.edgeIdx, x, y, w, h),
|
|
376
|
+
perpMax,
|
|
377
|
+
side
|
|
378
|
+
);
|
|
379
|
+
if (ideal) {
|
|
380
|
+
box.cx = ideal.x;
|
|
381
|
+
box.cy = ideal.y;
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
if (!overlapsAny(box.cx, box.cy, w, h, obstacles, BOX_CLEAR_PAD)) continue;
|
|
385
|
+
const clear = findClearPosition(
|
|
386
|
+
e.points,
|
|
387
|
+
(x, y) => overlapsAny(x, y, w, h, obstacles, BOX_CLEAR_PAD),
|
|
388
|
+
perpMax
|
|
389
|
+
) ?? findClearPosition(
|
|
390
|
+
e.points,
|
|
391
|
+
(x, y) => overlapsAny(x, y, w, h, baseObstacles, BOX_CLEAR_PAD),
|
|
392
|
+
perpMax
|
|
393
|
+
);
|
|
245
394
|
if (clear) {
|
|
246
395
|
box.cx = clear.x;
|
|
247
396
|
box.cy = clear.y;
|
|
@@ -1,26 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
safeHref
|
|
3
|
+
} from "./chunk-Z6DXWULM.js";
|
|
1
4
|
import {
|
|
2
5
|
MONO_FAMILY
|
|
3
6
|
} from "./chunk-ICLB27PZ.js";
|
|
4
7
|
|
|
5
|
-
// src/utils/safe-href.ts
|
|
6
|
-
var ALLOWED_SCHEMES = ["http", "https", "mailto"];
|
|
7
|
-
var SCHEME_RE = /^([a-z][a-z0-9+.-]*):/i;
|
|
8
|
-
var LEADING_TRIM_RE = /^[\x00-\x20]+/;
|
|
9
|
-
function safeHref(url) {
|
|
10
|
-
if (typeof url !== "string") return null;
|
|
11
|
-
const trimmed = url.replace(LEADING_TRIM_RE, "");
|
|
12
|
-
if (trimmed.length === 0) return null;
|
|
13
|
-
const match = SCHEME_RE.exec(trimmed);
|
|
14
|
-
if (!match) {
|
|
15
|
-
return url;
|
|
16
|
-
}
|
|
17
|
-
const scheme = match[1].toLowerCase();
|
|
18
|
-
if (ALLOWED_SCHEMES.includes(scheme)) {
|
|
19
|
-
return url;
|
|
20
|
-
}
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
8
|
// src/utils/inline-markdown.ts
|
|
25
9
|
function parseInlineMarkdown(text) {
|
|
26
10
|
const spans = [];
|
|
@@ -88,7 +72,6 @@ function renderInlineText(textEl, text, palette, fontSize) {
|
|
|
88
72
|
}
|
|
89
73
|
|
|
90
74
|
export {
|
|
91
|
-
safeHref,
|
|
92
75
|
parseInlineMarkdown,
|
|
93
76
|
truncateBareUrl,
|
|
94
77
|
stripInlineMarkdown,
|