@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.
Files changed (76) hide show
  1. package/dist/advanced.d.ts +6 -18
  2. package/dist/advanced.js +40 -37
  3. package/dist/block.js +6 -17
  4. package/dist/{chunk-FAV4RDVT.js → chunk-2A4DQAXG.js} +1 -1
  5. package/dist/{chunk-JIPUBFAM.js → chunk-5KGM44TG.js} +2 -2
  6. package/dist/{chunk-VEE777MD.js → chunk-5LD7SHXO.js} +3 -3
  7. package/dist/{chunk-QJ2JOLFN.js → chunk-6I5UN4FD.js} +2 -2
  8. package/dist/{chunk-ETBXIKK6.js → chunk-ABP5BUD6.js} +9 -430
  9. package/dist/{chunk-PKXKWHDW.js → chunk-AUS7V54P.js} +1 -1
  10. package/dist/{chunk-BF7JAFJI.js → chunk-B7CU2HW5.js} +2 -2
  11. package/dist/{chunk-X2VEJ5NT.js → chunk-BMUWF77V.js} +2 -2
  12. package/dist/{chunk-BP4BT5TH.js → chunk-CLQIXD2C.js} +1 -1
  13. package/dist/{chunk-QJFT5MAH.js → chunk-DSG6GBUQ.js} +2 -2
  14. package/dist/{chunk-EWSESGC2.js → chunk-EJS3K44P.js} +117 -78
  15. package/dist/{chunk-5JO443MB.js → chunk-HAH5X345.js} +1 -1
  16. package/dist/{chunk-HBCAY3KR.js → chunk-HTNLLT34.js} +1 -1
  17. package/dist/{chunk-HUMQIRJK.js → chunk-HTPZDZKQ.js} +2 -2
  18. package/dist/{chunk-VPVWG2GH.js → chunk-J7Q4VPBJ.js} +1 -1
  19. package/dist/{chunk-QPE646M2.js → chunk-JLETTWUJ.js} +30 -10
  20. package/dist/{chunk-3CQS3CIO.js → chunk-LL6D3MES.js} +1 -1
  21. package/dist/{chunk-ERYHC4KJ.js → chunk-LSQGJN5H.js} +1 -1
  22. package/dist/{chunk-AGO3PFGS.js → chunk-MVCPO6LI.js} +15 -10
  23. package/dist/{chunk-E6S2K6O2.js → chunk-N7XRBWXA.js} +2 -2
  24. package/dist/{chunk-WMIKC5XO.js → chunk-NPWVOFB3.js} +1 -1
  25. package/dist/{chunk-MYHPRQHR.js → chunk-O6MMQQLF.js} +3 -3
  26. package/dist/{chunk-GYORDNOM.js → chunk-P5V63L35.js} +1 -1
  27. package/dist/{chunk-BHZE36F7.js → chunk-PUVTFUNH.js} +1 -1
  28. package/dist/{chunk-TW6WMZFW.js → chunk-QT3KDDXK.js} +156 -7
  29. package/dist/{chunk-ZGHV4QLK.js → chunk-RJNZHFNG.js} +1 -1
  30. package/dist/{chunk-FWNJDD4U.js → chunk-S7W75MIM.js} +3 -20
  31. package/dist/{chunk-4YA5XW43.js → chunk-VW52W5F6.js} +981 -107
  32. package/dist/chunk-WXPBP4IT.js +438 -0
  33. package/dist/{chunk-C6FZZFYD.js → chunk-WZ23JJ7U.js} +1 -1
  34. package/dist/{chunk-LIYWJ6DV.js → chunk-XIFK423U.js} +108 -13
  35. package/dist/{chunk-4ELXLATB.js → chunk-XUDGZJTJ.js} +2 -2
  36. package/dist/{chunk-H6AFNCN3.js → chunk-XVSJYAK7.js} +1 -1
  37. package/dist/{chunk-LHBMQJC3.js → chunk-XWYR5T52.js} +2 -2
  38. package/dist/{chunk-QNKHJ5CK.js → chunk-YK4N6TBN.js} +4 -2
  39. package/dist/{chunk-XFMQSFS4.js → chunk-YMG7JDEY.js} +16 -6
  40. package/dist/chunk-Z6DXWULM.js +23 -0
  41. package/dist/{chunk-PBEH52A2.js → chunk-ZNNVI5SR.js} +1 -1
  42. package/dist/{flowchart-renderer-H72L7BEC.js → flowchart-renderer-THC6Y7EH.js} +7 -6
  43. package/dist/index.d.ts +68 -1
  44. package/dist/index.js +76 -7
  45. package/dist/{layout-QIPCNUSB.js → layout-BOVTLAOT.js} +7 -6
  46. package/dist/{layout-6JARW64V.js → layout-EHTYSMV4.js} +6 -5
  47. package/dist/{layout-YELNBVPC.js → layout-P6DTD4RT.js} +6 -5
  48. package/dist/{layout-T6TAB5OI.js → layout-RANVNAKI.js} +3 -3
  49. package/dist/{layout-FMKSENGL.js → layout-XUW444O5.js} +5 -4
  50. package/dist/{layout-search-AW5VBDCV.js → layout-search-VKSBUCDM.js} +57 -28
  51. package/dist/{renderer-AI2MD52D.js → renderer-222OTVQV.js} +3 -2
  52. package/dist/{renderer-UUWR7NGF.js → renderer-2KVQGGTT.js} +4 -3
  53. package/dist/{renderer-E5EKGIX2.js → renderer-2OOPQ4CH.js} +4 -3
  54. package/dist/{renderer-CZJ4AMYV.js → renderer-3FF4QVGW.js} +3 -2
  55. package/dist/{renderer-R6VJDZFO.js → renderer-4BHOELCE.js} +4 -3
  56. package/dist/{renderer-425QUIYO.js → renderer-4BIMRO4X.js} +4 -3
  57. package/dist/{renderer-5JVVJBAS.js → renderer-A4LMOBZL.js} +8 -7
  58. package/dist/{renderer-3AOOLHJU.js → renderer-A6ACVK4X.js} +3 -2
  59. package/dist/{renderer-ML2CLU25.js → renderer-DCFQDBGJ.js} +4 -3
  60. package/dist/{renderer-RH4U3UVM.js → renderer-LODEVN3V.js} +3 -2
  61. package/dist/{renderer-E7WF75GY.js → renderer-NHPKNNBD.js} +5 -4
  62. package/dist/{renderer-JEEGPLMM.js → renderer-R34GJL7U.js} +8 -7
  63. package/dist/{renderer-2BWRW23Z.js → renderer-RENDISO5.js} +1 -1
  64. package/dist/{renderer-NX4YKWCJ.js → renderer-RNCYODNF.js} +1 -1
  65. package/dist/{renderer-VKAJ52UO.js → renderer-SDUSBCJI.js} +3 -2
  66. package/dist/{renderer-RLSR7N6I.js → renderer-TPOZOAXR.js} +5 -4
  67. package/dist/{renderer-RUGMKHX5.js → renderer-WH2HWE5Z.js} +3 -2
  68. package/dist/{renderer-V6LLASGN.js → renderer-X5A5VIRD.js} +5 -4
  69. package/dist/{renderer-ADX4DWRJ.js → renderer-XUPLAO4B.js} +4 -2
  70. package/dist/{renderer-EWJS2RAZ.js → renderer-YDAVCRTP.js} +3 -2
  71. package/dist/{state-renderer-DDVJ43HR.js → state-renderer-5IQ4OJUI.js} +7 -6
  72. package/gallery/fixtures/journey-map.dgmo +28 -0
  73. package/gallery/fixtures/mindmap.dgmo +31 -0
  74. package/gallery/fixtures/pert.dgmo +27 -0
  75. package/gallery/fixtures/wireframe.dgmo +30 -0
  76. 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(w, h, points, obstacles, perpMax) {
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 (!overlapsAny(p.x, p.y, w, h, obstacles, BOX_CLEAR_PAD)) return p;
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 [-1, 1]) {
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 (!overlapsAny(x, y, w, h, obstacles, BOX_CLEAR_PAD)) return { x, y };
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 (!overlapsAny(box.cx, box.cy, box.w, box.h, obstacles, BOX_CLEAR_PAD))
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 clear = findClearPosition(box.w, box.h, e.points, obstacles, perpMax) ?? findClearPosition(box.w, box.h, e.points, baseObstacles, perpMax);
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;
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-5DH3KYFH.js";
10
10
  import {
11
11
  wrapDescriptionLines
12
- } from "./chunk-WMIKC5XO.js";
12
+ } from "./chunk-NPWVOFB3.js";
13
13
  import {
14
14
  measureText
15
15
  } from "./chunk-KAO7JL4I.js";
@@ -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,