@diagrammo/dgmo 0.92.0 → 0.93.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 (166) hide show
  1. package/dist/advanced.d.ts +85 -21
  2. package/dist/advanced.js +455 -422
  3. package/dist/block.d.ts +2 -2
  4. package/dist/block.js +75 -70
  5. package/dist/{chart-meta-BBqLnv5q.d.ts → chart-meta-BbjsRY7o.d.ts} +2 -2
  6. package/dist/chart-meta.d.ts +3 -3
  7. package/dist/chart-meta.js +25 -19
  8. package/dist/{chart-types-CbXlZFLd.d.ts → chart-types-Cppnp31G.d.ts} +173 -4
  9. package/dist/{charts-d3-QUUDVETP.js → charts-d3-ERYYVGP6.js} +7 -6
  10. package/dist/{chunk-HIWHIYLD.js → chunk-2TFXRBCD.js} +19 -19
  11. package/dist/{chunk-F7326NVM.js → chunk-3GCASUWA.js} +58 -25
  12. package/dist/{chunk-ZJAK6C7Y.js → chunk-3PP746YM.js} +6 -1
  13. package/dist/{chunk-WLLO3PZ3.js → chunk-472EOHVW.js} +17 -17
  14. package/dist/{chunk-LMP6Y7QO.js → chunk-4WQX55VX.js} +56 -24
  15. package/dist/{chunk-JLU52ZDT.js → chunk-5CBX66KB.js} +10 -10
  16. package/dist/{chunk-DEFBUZWV.js → chunk-5HAYT43L.js} +70 -54
  17. package/dist/{chunk-S7W75MIM.js → chunk-65GPEV5V.js} +21 -3
  18. package/dist/{chunk-Q6W2K33N.js → chunk-6XLMTAEX.js} +1 -1
  19. package/dist/{chunk-JKST4RTT.js → chunk-7OWK5K5C.js} +6 -6
  20. package/dist/{chunk-73EYNV4O.js → chunk-A5WIAMCT.js} +4 -6
  21. package/dist/{chunk-X5BUX2GK.js → chunk-ADVGV3P7.js} +1 -1
  22. package/dist/{chunk-45QUTYPD.js → chunk-CYDM2XII.js} +17 -17
  23. package/dist/chunk-CYTFO2LF.js +209 -0
  24. package/dist/{chunk-JRWUHLRP.js → chunk-D6PVMUCX.js} +51 -8
  25. package/dist/{chunk-BRSM6Z34.js → chunk-DAHQL57W.js} +14 -14
  26. package/dist/{chunk-RBFJT23E.js → chunk-EQWC76GQ.js} +6 -6
  27. package/dist/{chunk-ADNIO3XY.js → chunk-FIYW7JW4.js} +5 -5
  28. package/dist/{chunk-7ENDOHAA.js → chunk-FMAVHTYB.js} +919 -927
  29. package/dist/{chunk-3PFMGNOM.js → chunk-GJXMG4S3.js} +26 -11
  30. package/dist/chunk-GXCDD6NG.js +24 -0
  31. package/dist/{chunk-RJ2JW3FG.js → chunk-IESUM4N5.js} +2331 -2236
  32. package/dist/{chunk-62BP7AJU.js → chunk-IIV4SMJL.js} +18 -18
  33. package/dist/{chunk-5EBYPETE.js → chunk-J43OCO22.js} +3 -5
  34. package/dist/{chunk-L5NW3PVL.js → chunk-J6AEKIRQ.js} +1 -1
  35. package/dist/{chunk-2BJW7FSF.js → chunk-KBEWVCK3.js} +1 -1
  36. package/dist/{chunk-LRP5FXST.js → chunk-KCHQVED5.js} +18 -17
  37. package/dist/{chunk-Q6ZQX2HX.js → chunk-KCMGIYPO.js} +4 -6
  38. package/dist/{chunk-MDVJYRJT.js → chunk-KPGPK4SK.js} +22 -22
  39. package/dist/{chunk-Q2UFOKPB.js → chunk-KPSSNGAE.js} +22 -22
  40. package/dist/{chunk-V4D2ZQBE.js → chunk-KRPLP5LP.js} +6 -1
  41. package/dist/{chunk-BZX7QCXJ.js → chunk-KRU2LCIP.js} +15 -15
  42. package/dist/{chunk-HXULJZA2.js → chunk-LDDDKWL6.js} +6 -1
  43. package/dist/{chunk-NREU4JFE.js → chunk-LNVB75QU.js} +6 -8
  44. package/dist/{chunk-MX4SZLSV.js → chunk-LUDUDBO6.js} +16 -8
  45. package/dist/{chunk-2YAFDND3.js → chunk-M4NV5PPU.js} +4 -6
  46. package/dist/{chunk-26BBJUBW.js → chunk-M6ZQAFPD.js} +4 -6
  47. package/dist/{chunk-NPWVOFB3.js → chunk-MB2SQF7N.js} +1 -1
  48. package/dist/{chunk-6ZL2XYM7.js → chunk-MLY5ALOV.js} +6 -6
  49. package/dist/chunk-NJJCTEBM.js +416 -0
  50. package/dist/{chunk-OQW4ETJX.js → chunk-NM5V5EKY.js} +6 -1
  51. package/dist/{chunk-ONYO5WJW.js → chunk-NMK7KJZZ.js} +21 -21
  52. package/dist/{chunk-6BNNLVAR.js → chunk-NPDVWFAQ.js} +6 -1
  53. package/dist/{chunk-FTUMRSGT.js → chunk-P5FUWXPW.js} +4 -286
  54. package/dist/chunk-P7TRFL4P.js +54 -0
  55. package/dist/{chunk-A4PNWAUW.js → chunk-PGSGJLUR.js} +6 -1
  56. package/dist/{chunk-DRFGIOZ6.js → chunk-Q7Y6JQ3R.js} +4 -6
  57. package/dist/{chunk-J2E7EUER.js → chunk-QDRCWVV3.js} +17 -17
  58. package/dist/{chunk-MXAP37W6.js → chunk-TNV4F5WA.js} +16 -7
  59. package/dist/{chunk-EBSFSOJC.js → chunk-U7U64UUN.js} +22 -22
  60. package/dist/chunk-UCHZJJIT.js +421 -0
  61. package/dist/{chunk-FSJ3ZA6N.js → chunk-UG7AQQNR.js} +12 -12
  62. package/dist/{chunk-WFA6IULY.js → chunk-URRAWU5D.js} +5 -0
  63. package/dist/{chunk-VOR32OHN.js → chunk-USAGHYRD.js} +13 -15
  64. package/dist/{chunk-QUGC7GWB.js → chunk-UVX3IYXF.js} +15 -15
  65. package/dist/{chunk-B5PEKSRH.js → chunk-VSAKEMDD.js} +6 -1
  66. package/dist/{chunk-YRYKTYMQ.js → chunk-VSOZZYLK.js} +106 -12
  67. package/dist/{chunk-5SSTVFPX.js → chunk-WK5QEYFA.js} +5 -7
  68. package/dist/{chunk-KTGZDMDX.js → chunk-XUTR7GNT.js} +76 -28
  69. package/dist/{chunk-6WVX4KNP.js → chunk-YDZIVDVR.js} +97 -297
  70. package/dist/{chunk-URQIWIKX.js → chunk-YXXIRM4C.js} +3 -3
  71. package/dist/{chunk-H5UEVW6Q.js → chunk-ZD3QCNB7.js} +1 -1
  72. package/dist/{chunk-DUPZ2BBY.js → chunk-ZTLMEBAC.js} +66 -4
  73. package/dist/clock.js +168 -0
  74. package/dist/completion-registry.js +3 -1
  75. package/dist/countdown.js +36 -395
  76. package/dist/{dgmo-router-4UAPPIKN.js → dgmo-router-CZN36TR3.js} +50 -43
  77. package/dist/{dimensions-SCNVYLRF.js → dimensions-7HHKO5BS.js} +3 -3
  78. package/dist/{d3-BThYBTQk.d.ts → export-context-Ceh3wr0E.d.ts} +2 -8
  79. package/dist/{flowchart-parser-NA75YQ77.js → flowchart-parser-4MZPWYK6.js} +8 -3
  80. package/dist/{flowchart-renderer-6MGGX4RC.js → flowchart-renderer-5XDN575E.js} +13 -17
  81. package/dist/index.d.ts +8 -7
  82. package/dist/index.js +80 -74
  83. package/dist/{layout-S3RLVPH4.js → layout-33FHGDEV.js} +10 -12
  84. package/dist/{layout-MBVBAMPA.js → layout-3TSVAGWH.js} +2 -2
  85. package/dist/{layout-WRG4APSJ.js → layout-5GHV7HNM.js} +9 -13
  86. package/dist/layout-FTOGDNUL.js +23 -0
  87. package/dist/{layout-BNLFQHSB.js → layout-QXGPY7KA.js} +7 -9
  88. package/dist/{layout-search-PMYL3VWS.js → layout-search-EMTCDC3C.js} +8 -10
  89. package/dist/{palettes-IN7ZFRJM.js → palettes-4Y7CL2QL.js} +4 -2
  90. package/dist/{parser-3MK56JZC.js → parser-4Y6PODW6.js} +2 -2
  91. package/dist/{parser-2NWH5JUS.js → parser-A3AN76RQ.js} +2 -1
  92. package/dist/{parser-LCJ76UXS.js → parser-BT4NI6JY.js} +5 -1
  93. package/dist/{parser-FXDS4JDK.js → parser-F7NDRPMA.js} +2 -2
  94. package/dist/{parser-BES6LV3G.js → parser-GDLKUBTO.js} +5 -1
  95. package/dist/{parser-SEUTXN6U.js → parser-KJPPUN4D.js} +2 -2
  96. package/dist/{parser-SIKL4PLF.js → parser-KMKVFET2.js} +5 -1
  97. package/dist/{parser-5LW5JDYG.js → parser-NL73FSFI.js} +5 -1
  98. package/dist/{parser-VA7ZQQTA.js → parser-NUU3DVW4.js} +5 -1
  99. package/dist/{parser-L6RWDXQN.js → parser-OGF2CDA6.js} +8 -3
  100. package/dist/{parser-XZUKNZPB.js → parser-R3LPEQIT.js} +7 -1
  101. package/dist/{parser-X23GRTQJ.js → parser-RCIEKN7Y.js} +5 -1
  102. package/dist/{parser-GX5YLRIP.js → parser-VKYUAT4Y.js} +8 -3
  103. package/dist/{parser-QYISOAGR.js → parser-YX72VLDZ.js} +8 -3
  104. package/dist/redraw-MSXU4ZD2.js +73 -0
  105. package/dist/redraw-T324XAF3.js +1698 -0
  106. package/dist/{renderer-5VKPB4LL.js → renderer-37PLQHVB.js} +5 -5
  107. package/dist/{renderer-ISSDGK54.js → renderer-3F47TPZ2.js} +3 -3
  108. package/dist/{renderer-3QAFDXEY.js → renderer-5ITLW7MX.js} +14 -12
  109. package/dist/{renderer-ZZ6MWVB7.js → renderer-6GJWADLO.js} +4 -4
  110. package/dist/{renderer-MM27BSBO.js → renderer-7Y3LR4R2.js} +3 -4
  111. package/dist/{renderer-2FVUPBGV.js → renderer-AM7P4LN7.js} +1 -1
  112. package/dist/{renderer-ZHGHTSNG.js → renderer-BO73LSVT.js} +13 -12
  113. package/dist/{renderer-3IHQI4A4.js → renderer-CNRQFIEI.js} +11 -10
  114. package/dist/{renderer-OAR5VPH4.js → renderer-DAZWHNLI.js} +2 -2
  115. package/dist/{renderer-NDA2FFYB.js → renderer-DD6T3C4J.js} +5 -5
  116. package/dist/{renderer-WIU5BJUK.js → renderer-DDWDCM2K.js} +2 -2
  117. package/dist/{renderer-7ZZG5HR3.js → renderer-EVKWGUGT.js} +8 -9
  118. package/dist/{renderer-3JY6JAQJ.js → renderer-FL7EOSBU.js} +5 -6
  119. package/dist/{renderer-NIE5IW24.js → renderer-GFALLIYT.js} +8 -7
  120. package/dist/{renderer-O6DY46AV.js → renderer-GFGFHYWY.js} +7 -7
  121. package/dist/{renderer-5TZVFQ7K.js → renderer-GOXAP2IE.js} +7 -8
  122. package/dist/{renderer-NHTR7IRR.js → renderer-GPAVVUET.js} +4 -5
  123. package/dist/{renderer-TO2NVJP3.js → renderer-HJ54YXT3.js} +50 -45
  124. package/dist/{renderer-LM4ICK6I.js → renderer-HYGTMBHT.js} +4 -5
  125. package/dist/{renderer-S3YCLJKL.js → renderer-IHCWBFPI.js} +17 -20
  126. package/dist/{renderer-XO57LTU4.js → renderer-ISDKO3DI.js} +5 -5
  127. package/dist/{renderer-LQP3AGEJ.js → renderer-J3QWK6IM.js} +3 -4
  128. package/dist/{renderer-J666LZXJ.js → renderer-J6H4Q3RM.js} +7 -8
  129. package/dist/{renderer-ALWVK3EJ.js → renderer-JJ4QW3SK.js} +6 -6
  130. package/dist/{renderer-DC7C5Q3G.js → renderer-NOYLNVTI.js} +2 -2
  131. package/dist/{renderer-ZGY7P4BM.js → renderer-PBKTAWQV.js} +16 -20
  132. package/dist/{renderer-XGG2UNXT.js → renderer-POBGKIUT.js} +3 -4
  133. package/dist/{renderer-QGIHLZOJ.js → renderer-RDI2RYUP.js} +9 -10
  134. package/dist/{renderer-JEJT3YET.js → renderer-TSCSZ6CL.js} +2 -3
  135. package/dist/{renderer-VPIELEE5.js → renderer-VDBNC7A6.js} +8 -9
  136. package/dist/{renderer-J67LMOD5.js → renderer-VI34SD5V.js} +15 -15
  137. package/dist/{renderer-J5FKF423.js → renderer-W4MUMXJE.js} +7 -4
  138. package/dist/{renderer-RSK6QFWN.js → renderer-XJMVG2WJ.js} +7 -9
  139. package/dist/{state-parser-TIR2ORJY.js → state-parser-NPYTMRXP.js} +8 -3
  140. package/dist/{state-renderer-G6SUXU4J.js → state-renderer-44K2KDX7.js} +15 -19
  141. package/dist/{tag-groups-DsoVpAY-.d.ts → tag-groups-DydewK3D.d.ts} +2 -173
  142. package/dist/{themes-DRNjxX7Q.d.ts → themes-DzIH3Hjv.d.ts} +3 -2
  143. package/docs/ai-integration.md +1 -1
  144. package/docs/language-reference.md +23 -2
  145. package/gallery/fixtures/map-undirected-edges.dgmo +5 -5
  146. package/gallery/fixtures/whiteboard.dgmo +3 -0
  147. package/package.json +4 -6
  148. package/dist/chunk-3Y63RFJL.js +0 -75
  149. package/dist/chunk-5DH3KYFH.js +0 -20
  150. package/dist/chunk-O753JUEZ.js +0 -67
  151. package/dist/chunk-RJNZHFNG.js +0 -51
  152. package/dist/chunk-Z6DXWULM.js +0 -23
  153. package/dist/layout-5USEVQBY.js +0 -25
  154. package/dist/{chunk-YITHYQCL.js → chunk-4FT5KQ7H.js} +7 -7
  155. package/dist/{chunk-GE7ICBX6.js → chunk-4RY5D5RE.js} +4 -4
  156. package/dist/{chunk-DGUGE67L.js → chunk-CDYV46JE.js} +3 -3
  157. package/dist/{chunk-IGKFOHBG.js → chunk-CQYFZOUC.js} +13 -13
  158. package/dist/{chunk-TKAB3FTK.js → chunk-DRQSB72S.js} +11 -11
  159. package/dist/{chunk-ZKP77MB3.js → chunk-FVTYJUXR.js} +5 -5
  160. package/dist/{chunk-MA42PIGJ.js → chunk-H5NVCOEJ.js} +4 -4
  161. package/dist/{chunk-BEA4D7OS.js → chunk-IXHWS2HI.js} +3 -3
  162. package/dist/{chunk-QKY6W4NA.js → chunk-KHL652SX.js} +25 -25
  163. package/dist/{chunk-6OIMUSDX.js → chunk-MUJVNSEW.js} +9 -9
  164. package/dist/{chunk-YO6AQU4A.js → chunk-QJOVZ4TC.js} +12 -12
  165. package/dist/{chunk-SOHZDW6N.js → chunk-UXNA2H2V.js} +3 -3
  166. package/dist/{chunk-NO3UX6AP.js → chunk-V2NQV7VL.js} +4 -4
@@ -1,4 +1,10 @@
1
+ import {
2
+ measureText,
3
+ truncateText
4
+ } from "./chunk-KAO7JL4I.js";
5
+
1
6
  // src/utils/time-ticks.ts
7
+ var TICK_LABEL_GAP = 8;
2
8
  var MONTH_ABBR = [
3
9
  "Jan",
4
10
  "Feb",
@@ -35,11 +41,12 @@ function dateToFractionalYear(d) {
35
41
  function formatYearTick(y) {
36
42
  return y < 0 ? `${-y} BCE` : String(y);
37
43
  }
38
- function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEnd, boundaryStartLabel, boundaryEndLabel) {
44
+ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEnd, boundaryStartLabel, boundaryEndLabel, labelFit = { fontSize: 10 }) {
39
45
  const minYear = Math.floor(domainMin);
40
46
  const maxYear = Math.floor(domainMax);
41
47
  const span = domainMax - domainMin;
42
48
  let ticks = [];
49
+ let strides = [];
43
50
  const firstYear = Math.ceil(domainMin);
44
51
  const lastYear = Math.floor(domainMax);
45
52
  if (lastYear >= firstYear + 1) {
@@ -52,9 +59,12 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
52
59
  else if (yearSpan > 40) step = 10;
53
60
  else if (yearSpan > 20) step = 5;
54
61
  else if (yearSpan > 10) step = 2;
62
+ strides = [1, 2, 5, 10, 20, 50, 100, 200, 500, 1e3, 2e3, 5e3].filter(
63
+ (c) => c % step === 0
64
+ );
55
65
  const alignedFirst = Math.ceil(firstYear / step) * step;
56
66
  for (let y = alignedFirst; y <= lastYear; y += step) {
57
- ticks.push({ pos: scale(y), label: formatYearTick(y) });
67
+ ticks.push({ pos: scale(y), label: formatYearTick(y), slot: y });
58
68
  }
59
69
  } else if (span > 0.25) {
60
70
  const crossesYear = maxYear > minYear;
@@ -66,7 +76,9 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
66
76
  const abbr = MONTH_ABBR[m - 1];
67
77
  ticks.push({
68
78
  pos: scale(val),
69
- label: crossesYear ? `${abbr} '${String(y).slice(-2)}` : abbr
79
+ label: crossesYear ? `${abbr} '${String(y).slice(-2)}` : abbr,
80
+ // Month index, so a stride of 3 lands on Jan, Apr, Jul, Oct.
81
+ slot: y * 12 + (m - 1)
70
82
  });
71
83
  }
72
84
  }
@@ -89,7 +101,11 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
89
101
  const hh = String(startDate.getHours()).padStart(2, "0");
90
102
  const mm = String(startDate.getMinutes()).padStart(2, "0");
91
103
  const ss = String(startDate.getSeconds()).padStart(2, "0");
92
- ticks.push({ pos: scale(val), label: `${hh}:${mm}:${ss}` });
104
+ ticks.push({
105
+ pos: scale(val),
106
+ label: `${hh}:${mm}:${ss}`,
107
+ slot: ticks.length
108
+ });
93
109
  }
94
110
  startDate.setSeconds(startDate.getSeconds() + stepSec);
95
111
  }
@@ -111,7 +127,11 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
111
127
  if (val >= domainMin) {
112
128
  const hh = String(startDate.getHours()).padStart(2, "0");
113
129
  const mm = String(startDate.getMinutes()).padStart(2, "0");
114
- ticks.push({ pos: scale(val), label: `${hh}:${mm}` });
130
+ ticks.push({
131
+ pos: scale(val),
132
+ label: `${hh}:${mm}`,
133
+ slot: ticks.length
134
+ });
115
135
  }
116
136
  startDate.setMinutes(startDate.getMinutes() + stepMin);
117
137
  }
@@ -136,11 +156,19 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
136
156
  const hh = String(startDate.getHours()).padStart(2, "0");
137
157
  const mm = String(startDate.getMinutes()).padStart(2, "0");
138
158
  if (singleDay) {
139
- ticks.push({ pos: scale(val), label: `${hh}:${mm}` });
159
+ ticks.push({
160
+ pos: scale(val),
161
+ label: `${hh}:${mm}`,
162
+ slot: ticks.length
163
+ });
140
164
  } else {
141
165
  const mon = MONTH_ABBR[startDate.getMonth()];
142
166
  const d = startDate.getDate();
143
- ticks.push({ pos: scale(val), label: `${mon} ${d} ${hh}:${mm}` });
167
+ ticks.push({
168
+ pos: scale(val),
169
+ label: `${mon} ${d} ${hh}:${mm}`,
170
+ slot: ticks.length
171
+ });
144
172
  }
145
173
  }
146
174
  startDate.setHours(startDate.getHours() + stepHour);
@@ -154,32 +182,98 @@ function computeTimeTicks(domainMin, domainMax, scale, boundaryStart, boundaryEn
154
182
  if (val >= domainMin) {
155
183
  ticks.push({
156
184
  pos: scale(val),
157
- label: `${MONTH_ABBR[m - 1]} ${d}`
185
+ label: `${MONTH_ABBR[m - 1]} ${d}`,
186
+ slot: ticks.length
158
187
  });
159
188
  }
160
189
  }
161
190
  }
162
191
  }
163
192
  }
193
+ if (strides.length === 0) strides = [1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48];
164
194
  const collisionThreshold = 40;
195
+ let startBoundary = null;
196
+ let endBoundary = null;
165
197
  if (boundaryStart !== void 0 && boundaryStartLabel) {
166
198
  const boundaryPos = scale(boundaryStart);
167
199
  ticks = ticks.filter(
168
200
  (t) => Math.abs(t.pos - boundaryPos) >= collisionThreshold
169
201
  );
170
- ticks.unshift({ pos: boundaryPos, label: boundaryStartLabel });
202
+ startBoundary = { pos: boundaryPos, label: boundaryStartLabel };
171
203
  }
172
204
  if (boundaryEnd !== void 0 && boundaryEndLabel) {
173
205
  const boundaryPos = scale(boundaryEnd);
174
206
  ticks = ticks.filter(
175
207
  (t) => Math.abs(t.pos - boundaryPos) >= collisionThreshold
176
208
  );
177
- ticks.push({ pos: boundaryPos, label: boundaryEndLabel });
209
+ endBoundary = { pos: boundaryPos, label: boundaryEndLabel };
178
210
  }
179
- return ticks;
211
+ return fitTickLabels(ticks, startBoundary, endBoundary, strides, labelFit);
212
+ }
213
+ function fitTickLabels(standard, startBoundary, endBoundary, strides, fit) {
214
+ const extent = (label) => fit.vertical ? fit.fontSize * 1.2 : measureText(label, fit.fontSize);
215
+ const span = (t) => {
216
+ const half = extent(t.label) / 2;
217
+ return { pos: t.pos, label: t.label, lo: t.pos - half, hi: t.pos + half };
218
+ };
219
+ const apart = (a, b) => a.hi + TICK_LABEL_GAP <= b.lo || b.hi + TICK_LABEL_GAP <= a.lo;
220
+ const fitsInOrder = (spans) => {
221
+ const sorted = [...spans].sort((a, b) => a.lo - b.lo);
222
+ for (let i = 1; i < sorted.length; i++) {
223
+ if (!apart(sorted[i - 1], sorted[i])) return false;
224
+ }
225
+ return true;
226
+ };
227
+ const start = startBoundary ? span(startBoundary) : null;
228
+ let end = endBoundary ? span(endBoundary) : null;
229
+ if (start && end && !apart(start, end)) end = null;
230
+ const pinned = [start, end].filter((p) => p !== null);
231
+ const withPinned = (kept) => [
232
+ ...start ? [start] : [],
233
+ ...kept,
234
+ ...end ? [end] : []
235
+ ];
236
+ const strip = (s) => ({
237
+ pos: s.pos,
238
+ label: s.label
239
+ });
240
+ for (const stride of strides) {
241
+ const kept = standard.filter((t) => t.slot % stride === 0).map(span).filter((s) => pinned.every((p) => apart(p, s)));
242
+ if (kept.length === 0 && pinned.length === 0) continue;
243
+ if (fitsInOrder(kept)) {
244
+ return withPinned(kept).map(strip);
245
+ }
246
+ }
247
+ return withPinned([]).map(strip);
248
+ }
249
+
250
+ // src/utils/label-column.ts
251
+ var LABEL_COLUMN_MAX_SHARE = 1 / 3;
252
+ var LABEL_COLUMN_END_PAD = 12;
253
+ function capLabelColumn(natural, chartWidth, floor) {
254
+ const cap = Math.max(floor, Math.floor(chartWidth * LABEL_COLUMN_MAX_SHARE));
255
+ const width = Math.min(natural, cap);
256
+ const capped = natural > cap;
257
+ return {
258
+ width,
259
+ fit: (text, labelX, fontSize, bold = false) => capped ? truncateText(
260
+ text,
261
+ fontSize,
262
+ Math.max(0, width - labelX - LABEL_COLUMN_END_PAD),
263
+ { bold }
264
+ ) : text
265
+ };
266
+ }
267
+ function showFullOnHover(hoverEl, labelEl, drawEl, full, shown, prefix = "") {
268
+ drawEl.text(prefix + shown);
269
+ if (shown === full) return;
270
+ labelEl.attr("data-full-label", full);
271
+ hoverEl.on("mouseenter.reveal", () => drawEl.text(prefix + full)).on("mouseleave.reveal", () => drawEl.text(prefix + shown));
180
272
  }
181
273
 
182
274
  export {
183
275
  MONTH_ABBR,
184
- computeTimeTicks
276
+ computeTimeTicks,
277
+ capLabelColumn,
278
+ showFullOnHover
185
279
  };
@@ -1,16 +1,14 @@
1
1
  import {
2
2
  searchPlacement
3
- } from "./chunk-HXULJZA2.js";
3
+ } from "./chunk-LDDDKWL6.js";
4
4
  import {
5
5
  noteCanvasShift,
6
- placeNotes
7
- } from "./chunk-FTUMRSGT.js";
6
+ placeNotes,
7
+ resolveNotes
8
+ } from "./chunk-NJJCTEBM.js";
8
9
  import {
9
10
  noteBoxSize
10
- } from "./chunk-RJNZHFNG.js";
11
- import {
12
- resolveNotes
13
- } from "./chunk-O753JUEZ.js";
11
+ } from "./chunk-D6PVMUCX.js";
14
12
 
15
13
  // src/graph/layout.ts
16
14
  import dagre from "@dagrejs/dagre";
@@ -1,15 +1,14 @@
1
- import {
2
- wrapDescriptionLines
3
- } from "./chunk-NPWVOFB3.js";
4
- import {
5
- renderInlineText
6
- } from "./chunk-S7W75MIM.js";
7
1
  import {
8
2
  ScaleContext
9
3
  } from "./chunk-24YPR5EH.js";
10
4
  import {
11
- renderIntegratedLegend
12
- } from "./chunk-NMS5XSLX.js";
5
+ layoutInlineHeader
6
+ } from "./chunk-42UJ23H3.js";
7
+ import {
8
+ TITLE_FONT_SIZE,
9
+ TITLE_FONT_WEIGHT,
10
+ TITLE_Y
11
+ } from "./chunk-VLC6WNRD.js";
13
12
  import {
14
13
  ARROWHEAD_HEIGHT,
15
14
  ARROWHEAD_WIDTH,
@@ -18,25 +17,26 @@ import {
18
17
  HAIRLINE_DASH
19
18
  } from "./chunk-XCKNFFKM.js";
20
19
  import {
21
- layoutInlineHeader
22
- } from "./chunk-42UJ23H3.js";
20
+ renderIntegratedLegend
21
+ } from "./chunk-NMS5XSLX.js";
23
22
  import {
24
23
  getLegendExtent,
25
24
  getMaxLegendReservedHeight
26
25
  } from "./chunk-JILEYZ2V.js";
27
- import {
28
- TITLE_FONT_SIZE,
29
- TITLE_FONT_WEIGHT,
30
- TITLE_Y
31
- } from "./chunk-VLC6WNRD.js";
32
- import {
33
- FONT_FAMILY
34
- } from "./chunk-ICLB27PZ.js";
35
26
  import {
36
27
  isSequenceBlock,
37
28
  isSequenceNote,
38
29
  isSequenceSection
39
- } from "./chunk-B5PEKSRH.js";
30
+ } from "./chunk-VSAKEMDD.js";
31
+ import {
32
+ wrapDescriptionLines
33
+ } from "./chunk-MB2SQF7N.js";
34
+ import {
35
+ renderInlineText
36
+ } from "./chunk-65GPEV5V.js";
37
+ import {
38
+ FONT_FAMILY
39
+ } from "./chunk-ICLB27PZ.js";
40
40
  import {
41
41
  resolveActiveTagGroup,
42
42
  tagAttrKey
@@ -301,10 +301,12 @@ function wrapTextLines(text, maxWidth, fontSize) {
301
301
  );
302
302
  }
303
303
  var labelTextWidth = (boxW) => boxW - 10;
304
+ var PARTICIPANT_LABEL_PAD_V = 2;
305
+ var participantLabelHeight = (lines, fontSize) => lines * (fontSize + 2) + PARTICIPANT_LABEL_PAD_V * 2;
304
306
  function splitParticipantLabel(label, maxWidth, fontSize) {
305
307
  if (measureText(label, fontSize) <= maxWidth) return [label];
306
308
  if (label.includes(" ")) {
307
- return wrapLabelWords(label.split(" "), maxWidth, fontSize);
309
+ return wrapLabelWords(label.split(" "), maxWidth, fontSize, " ");
308
310
  }
309
311
  if (/[-_:/]/.test(label)) {
310
312
  const parts = label.split(/[-_:/]+/);
@@ -316,11 +318,11 @@ function splitParticipantLabel(label, maxWidth, fontSize) {
316
318
  }
317
319
  return [label];
318
320
  }
319
- function wrapLabelWords(words, maxWidth, fontSize) {
321
+ function wrapLabelWords(words, maxWidth, fontSize, sep = "") {
320
322
  const lines = [];
321
323
  let current = "";
322
324
  for (const word of words) {
323
- const test = current ? current + word : word;
325
+ const test = current ? current + sep + word : word;
324
326
  if (measureText(test, fontSize) > maxWidth && current) {
325
327
  lines.push(current);
326
328
  current = word;
@@ -686,6 +688,37 @@ function isSectionCollapsed(sec, collapsedSections) {
686
688
  return collapsedSections?.has(sec.lineNumber) ?? false;
687
689
  }
688
690
  function layoutSequence(parsed, containerWidth, options) {
691
+ let layout = layoutSequencePass(parsed, containerWidth, options);
692
+ if (options?.exportWidth) return layout;
693
+ const target = containerWidth - 1;
694
+ let prev = null;
695
+ for (let i = 0; i < 4 && layout && !layout.ctx.isBelowFloor; i++) {
696
+ if (layout.svgWidth <= containerWidth) return layout;
697
+ let factor = layout.ctx.factor * target / layout.svgWidth;
698
+ if (prev && prev.ctx.factor !== layout.ctx.factor) {
699
+ const slope = (prev.svgWidth - layout.svgWidth) / (prev.ctx.factor - layout.ctx.factor);
700
+ if (slope > 0)
701
+ factor = layout.ctx.factor - (layout.svgWidth - target) / slope;
702
+ }
703
+ prev = layout;
704
+ layout = layoutSequencePass(
705
+ parsed,
706
+ containerWidth,
707
+ options,
708
+ ScaleContext.fromFactor(factor)
709
+ );
710
+ }
711
+ if (layout && !layout.ctx.isBelowFloor && layout.svgWidth > containerWidth) {
712
+ layout = layoutSequencePass(
713
+ parsed,
714
+ containerWidth,
715
+ options,
716
+ ScaleContext.fromFactor(0)
717
+ );
718
+ }
719
+ return layout;
720
+ }
721
+ function layoutSequencePass(parsed, containerWidth, options, fit) {
689
722
  const { title, options: parsedOptions } = parsed;
690
723
  const effectiveCollapsedGroups = options?.collapsedGroups ? new Set(options.collapsedGroups) : new Set(
691
724
  parsed.groups.filter((g) => g.collapsed).map((g) => g.lineNumber)
@@ -752,10 +785,9 @@ function layoutSequence(parsed, containerWidth, options) {
752
785
  participants.length * effectiveGap,
753
786
  uniformBoxWidth + 40
754
787
  );
755
- const ctx = options?.exportWidth ? ScaleContext.identity() : ScaleContext.from(containerWidth, idealWidth);
788
+ const ctx = fit ?? (options?.exportWidth ? ScaleContext.identity() : ScaleContext.from(containerWidth, idealWidth));
756
789
  const sGap = ctx.structural(effectiveGap);
757
790
  const sBoxW = ctx.structural(uniformBoxWidth);
758
- const sBoxH = ctx.structural(PARTICIPANT_BOX_HEIGHT);
759
791
  const sTopMargin = ctx.aesthetic(TOP_MARGIN);
760
792
  const sTitleHeight = ctx.aesthetic(TITLE_HEIGHT);
761
793
  const sParticipantYOffset = ctx.aesthetic(PARTICIPANT_Y_OFFSET);
@@ -777,6 +809,20 @@ function layoutSequence(parsed, containerWidth, options) {
777
809
  const sNoteLaneMax = sGap - sActivationWidth - sNoteGap;
778
810
  const sLabelFontSize = ctx.text(LABEL_FONT_SIZE);
779
811
  const sLabelTextWidth = labelTextWidth(sBoxW);
812
+ let maxInBoxLines = 1;
813
+ for (const p of participants) {
814
+ if (p.type === "actor") continue;
815
+ const n = splitParticipantLabel(
816
+ p.label,
817
+ sLabelTextWidth,
818
+ sLabelFontSize
819
+ ).length;
820
+ maxInBoxLines = Math.max(maxInBoxLines, n);
821
+ }
822
+ const sBoxH = Math.max(
823
+ ctx.structural(PARTICIPANT_BOX_HEIGHT),
824
+ participantLabelHeight(maxInBoxLines, sLabelFontSize)
825
+ );
780
826
  const participantIndexMap = /* @__PURE__ */ new Map();
781
827
  participants.forEach((p, i) => participantIndexMap.set(p.id, i));
782
828
  const effectiveNotePosition = (note) => {
@@ -1398,8 +1444,10 @@ function layoutSequence(parsed, containerWidth, options) {
1398
1444
  }
1399
1445
  };
1400
1446
  for (let pass = 0; pass < 4; pass++) {
1401
- let contentLeft = 0;
1402
- let contentRight = svgWidth;
1447
+ const extentLeft = offsetX - leftMargin;
1448
+ const extentRight = extentLeft + totalWidth;
1449
+ let contentLeft = extentLeft;
1450
+ let contentRight = extentRight;
1403
1451
  for (const step of renderSteps) {
1404
1452
  const displayLabel = displayMessageLabel(step);
1405
1453
  if (!displayLabel) continue;
@@ -1428,8 +1476,8 @@ function layoutSequence(parsed, containerWidth, options) {
1428
1476
  scanNotes(elements, acc);
1429
1477
  contentRight = acc.right;
1430
1478
  }
1431
- const neededLeftPad = Math.max(0, -contentLeft);
1432
- const neededRightPad = Math.max(0, contentRight - svgWidth);
1479
+ const neededLeftPad = Math.max(0, extentLeft - contentLeft);
1480
+ const neededRightPad = Math.max(0, contentRight - extentRight);
1433
1481
  if (neededLeftPad <= 0.5 && neededRightPad <= 0.5) break;
1434
1482
  leftMargin += neededLeftPad;
1435
1483
  rightMargin += neededRightPad;