@diagrammo/dgmo 0.54.0 → 0.55.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 (196) hide show
  1. package/dist/advanced.d.ts +76 -9
  2. package/dist/advanced.js +118 -95
  3. package/dist/auto.js +125 -124
  4. package/dist/auto.mjs +1579 -282
  5. package/dist/block.js +49 -48
  6. package/dist/chart-meta.js +43 -43
  7. package/dist/{charts-d3-25E4VWXO.js → charts-d3-KZ6V4OP2.js} +7 -6
  8. package/dist/{chunk-MTZOXISJ.js → chunk-2HX6ZGY7.js} +3 -3
  9. package/dist/{chunk-ICKXIMBA.js → chunk-2R6HG6D5.js} +5 -5
  10. package/dist/{chunk-NUTWTV6G.js → chunk-2ZJXKJSI.js} +102 -56
  11. package/dist/{chunk-LPJ6H5X4.js → chunk-32HUNA33.js} +53 -11
  12. package/dist/{chunk-UIT7E6UF.js → chunk-3BFXELBL.js} +51 -4
  13. package/dist/{chunk-C2UORMIA.js → chunk-3BZJ5KD5.js} +7 -3
  14. package/dist/{chunk-A3BDLDYG.js → chunk-3FUTFYSP.js} +57 -18
  15. package/dist/{chunk-DPGQ5UMO.js → chunk-4MZCJV4M.js} +6 -6
  16. package/dist/{chunk-WWHECSYZ.js → chunk-4R5KIPNX.js} +2 -2
  17. package/dist/{chunk-47JNEKJA.js → chunk-5D5VHDJM.js} +43 -8
  18. package/dist/{chunk-KQYQECWQ.js → chunk-5H5GWWA4.js} +49 -13
  19. package/dist/{chunk-RRGKMJYL.js → chunk-5K5XBEXT.js} +8 -3
  20. package/dist/{chunk-HAA25PLC.js → chunk-6NJWBMJV.js} +44 -9
  21. package/dist/{chunk-3FRO35WW.js → chunk-A2ARDILY.js} +17 -3
  22. package/dist/{chunk-TLNVYWPA.js → chunk-A2PTRSAO.js} +2 -2
  23. package/dist/{chunk-APKUAJ2L.js → chunk-A2RUBBVT.js} +14 -1
  24. package/dist/{chunk-KS5ZSM5T.js → chunk-A4UJP4IS.js} +61 -13
  25. package/dist/{chunk-LRSW4JLE.js → chunk-AKE6C2D7.js} +3 -3
  26. package/dist/{chunk-2NZOHEP4.js → chunk-ASPS5O6F.js} +3 -3
  27. package/dist/{chunk-KV4HLIJE.js → chunk-AU75JHSR.js} +6 -3
  28. package/dist/{chunk-R5BGGBFF.js → chunk-DS4MDEQ7.js} +2 -2
  29. package/dist/{chunk-7JDTNFAK.js → chunk-EFUQENO5.js} +76 -32
  30. package/dist/{chunk-BULHGPHK.js → chunk-EMSOFHEN.js} +2 -2
  31. package/dist/{chunk-IYNKLCAZ.js → chunk-ETTDF3S2.js} +45 -7
  32. package/dist/{chunk-KDK5EKUR.js → chunk-ETYF5QZR.js} +2 -2
  33. package/dist/{chunk-COJW2NEY.js → chunk-F5ZNUMSY.js} +50 -11
  34. package/dist/{chunk-EAI6XJ7D.js → chunk-FBP33UM6.js} +3 -3
  35. package/dist/{chunk-KINOX74I.js → chunk-FGAMFJNJ.js} +48 -10
  36. package/dist/{chunk-J7HQPVYH.js → chunk-GRXPFBYC.js} +23 -2
  37. package/dist/{chunk-GQ5ECRP4.js → chunk-GTO5VCYG.js} +3 -3
  38. package/dist/{chunk-RJ5LBZ5U.js → chunk-HES4K6DV.js} +13 -13
  39. package/dist/{chunk-ADCHLNWT.js → chunk-HGKOVKAX.js} +3 -3
  40. package/dist/{chunk-EPRF3ZRV.js → chunk-HLGOG44K.js} +2 -2
  41. package/dist/{chunk-KQ3FNRGR.js → chunk-HUTP35XT.js} +5 -4
  42. package/dist/{chunk-OJ435DQZ.js → chunk-HX7QNHC6.js} +3 -3
  43. package/dist/{chunk-6KL7TFLS.js → chunk-IALX52TR.js} +2 -2
  44. package/dist/{chunk-7SP4C6EV.js → chunk-IF4KYSJZ.js} +7 -3
  45. package/dist/{chunk-5XSNLXU5.js → chunk-IG6J7JWH.js} +51 -12
  46. package/dist/{chunk-M24VXUFG.js → chunk-IIUYKQ5J.js} +3 -3
  47. package/dist/{chunk-5VXU6MND.js → chunk-INTAQV2Y.js} +2 -2
  48. package/dist/{chunk-3KHJJP3J.js → chunk-ITXL2KU5.js} +2 -2
  49. package/dist/{chunk-I47VHSPS.js → chunk-IWG2ECAO.js} +2 -2
  50. package/dist/{chunk-CSHFU6LT.js → chunk-JGCEFKZP.js} +7 -7
  51. package/dist/{chunk-O576GYAP.js → chunk-JQLSFZZP.js} +2 -2
  52. package/dist/{chunk-AHTTKERF.js → chunk-JR7Q6GHE.js} +2 -2
  53. package/dist/{chunk-4T6OCSJ2.js → chunk-KC3WBBI7.js} +3 -3
  54. package/dist/{chunk-BM7MG6HT.js → chunk-KK3L5NVK.js} +3 -3
  55. package/dist/{chunk-FR6UFVSV.js → chunk-L2DIXZUT.js} +91 -41
  56. package/dist/{chunk-WW4BQ744.js → chunk-LCRPGGGS.js} +6 -6
  57. package/dist/{chunk-GKYHWJXI.js → chunk-LKGQ46P4.js} +3 -3
  58. package/dist/{chunk-IOIMQHQ6.js → chunk-LW7STMYZ.js} +2 -2
  59. package/dist/{chunk-OR3R27CU.js → chunk-M53MDBIW.js} +2 -2
  60. package/dist/{chunk-T7Y554OK.js → chunk-MEH4TJEX.js} +4 -4
  61. package/dist/{chunk-T3FAJAJT.js → chunk-MNS2ENXF.js} +3 -3
  62. package/dist/{chunk-CCGWX6AO.js → chunk-MSWIBF6J.js} +2 -2
  63. package/dist/{chunk-B7N5KYXQ.js → chunk-NL7FUIVD.js} +4 -4
  64. package/dist/{chunk-EQOMY4PY.js → chunk-NN5TF4OV.js} +2 -2
  65. package/dist/{chunk-BZJIITYM.js → chunk-NPPUZ4SK.js} +4 -4
  66. package/dist/{chunk-XWODFBHJ.js → chunk-NYOOPQFD.js} +7 -3
  67. package/dist/{chunk-VQFDBNYF.js → chunk-O4CZDTQA.js} +3 -3
  68. package/dist/{chunk-FVMKCZHF.js → chunk-P5XXIVEU.js} +2 -2
  69. package/dist/{chunk-F7XM366V.js → chunk-PC4YLEKA.js} +3 -3
  70. package/dist/{chunk-AQEYUVGJ.js → chunk-PCVXXPYU.js} +12 -5
  71. package/dist/{chunk-TJN2OIVG.js → chunk-PKUWYPI5.js} +180 -12
  72. package/dist/{chunk-W6PCFRPL.js → chunk-PSIDVCBA.js} +2 -2
  73. package/dist/{chunk-RIEAN4D5.js → chunk-PV7ND5WL.js} +48 -8
  74. package/dist/{chunk-7K6NDSXH.js → chunk-Q5CMQVWF.js} +3 -3
  75. package/dist/{chunk-FFVFZLRT.js → chunk-QQXFYTLC.js} +346 -46
  76. package/dist/{chunk-N7BSBAVP.js → chunk-QZYGRDMM.js} +108 -89
  77. package/dist/{chunk-U4IN6AHE.js → chunk-RKBCKCSF.js} +2 -2
  78. package/dist/{chunk-GK32ZFZY.js → chunk-RSBH2C7O.js} +3 -3
  79. package/dist/{chunk-OSXQKC3S.js → chunk-RYNCWA5X.js} +6 -3
  80. package/dist/{chunk-S7YFT3PO.js → chunk-RZWIPDZ2.js} +3 -3
  81. package/dist/{chunk-7UPFTBOW.js → chunk-S52F62GW.js} +4 -4
  82. package/dist/{chunk-WKNAJ4BR.js → chunk-SCOHNGPG.js} +51 -10
  83. package/dist/{chunk-BWYFIVZF.js → chunk-UBQU2BY6.js} +3 -3
  84. package/dist/{chunk-VMSBMIHW.js → chunk-UES4P7FN.js} +2 -2
  85. package/dist/chunk-US3P2DQO.js +87 -0
  86. package/dist/{chunk-AJFHNS67.js → chunk-UXXLE6AH.js} +5 -5
  87. package/dist/{chunk-M3H7ZE6C.js → chunk-VMWSZCAK.js} +5 -4
  88. package/dist/{chunk-S7FOIURR.js → chunk-VVIRAGID.js} +6 -6
  89. package/dist/{chunk-3SBHODJ4.js → chunk-VXTUWXFB.js} +48 -9
  90. package/dist/{chunk-HFEOOQ46.js → chunk-W4TSD3IP.js} +2 -2
  91. package/dist/{chunk-7U4OR7CD.js → chunk-WB3NA3JJ.js} +2 -2
  92. package/dist/{chunk-3SEEP2JM.js → chunk-WITOJZGL.js} +8 -4
  93. package/dist/{chunk-6OYDOQ2Q.js → chunk-WVGNXDEE.js} +2 -2
  94. package/dist/{chunk-UEU6IYKY.js → chunk-X3X4LZDC.js} +2 -2
  95. package/dist/{chunk-SBOAZ7YK.js → chunk-XKKH2DPG.js} +39 -39
  96. package/dist/{chunk-NR5HCAUD.js → chunk-XSVWUOUZ.js} +1 -1
  97. package/dist/{chunk-62Y27T4C.js → chunk-Y4BBGFKY.js} +2 -2
  98. package/dist/{chunk-YENNFS5F.js → chunk-YP2T5YUP.js} +8 -3
  99. package/dist/{chunk-2NYXI35Z.js → chunk-YXKNXIWA.js} +5 -4
  100. package/dist/{chunk-KBVOVDYP.js → chunk-ZGIBV36U.js} +3 -3
  101. package/dist/{chunk-4ZIKWVSQ.js → chunk-ZP265ICS.js} +4 -4
  102. package/dist/{chunk-DLU643TF.js → chunk-ZWVKTWK6.js} +3 -3
  103. package/dist/{chunk-QBYP2FBZ.js → chunk-ZXNHHO6D.js} +2 -2
  104. package/dist/cli.cjs +150 -147
  105. package/dist/clock.js +34 -1
  106. package/dist/completion-registry.js +12 -4
  107. package/dist/dgmo-router-T4HGLIGA.js +88 -0
  108. package/dist/{dimensions-L6BXQXXL.js → dimensions-3JINHSYK.js} +6 -6
  109. package/dist/editor.js +10 -1
  110. package/dist/element.js +124 -123
  111. package/dist/element.mjs +1579 -282
  112. package/dist/{flowchart-parser-UKYOW3VM.js → flowchart-parser-M7KKTLX7.js} +4 -4
  113. package/dist/{flowchart-renderer-DCFKUDDR.js → flowchart-renderer-FFEQFQEU.js} +5 -5
  114. package/dist/highlight.js +10 -1
  115. package/dist/index.js +58 -48
  116. package/dist/{layout-G2ABQJQZ.js → layout-3ZZBKUQC.js} +3 -3
  117. package/dist/{layout-CH4HFFRD.js → layout-AUKTWGYL.js} +4 -4
  118. package/dist/{layout-QBNAMEOA.js → layout-CRLTSFYQ.js} +3 -3
  119. package/dist/{layout-25Y3VDYF.js → layout-FNZDJGKF.js} +4 -4
  120. package/dist/{layout-NY7MHJCL.js → layout-GHWRJKZQ.js} +4 -4
  121. package/dist/{layout-ITLPDG6M.js → layout-LGXOKUCD.js} +4 -4
  122. package/dist/{layout-A6OIGZN2.js → layout-UR7CYAHL.js} +2 -2
  123. package/dist/{layout-4SPLI4HG.js → layout-UTMEVFHN.js} +4 -4
  124. package/dist/{layout-search-LUI475P3.js → layout-search-U2H4ORFJ.js} +8 -6
  125. package/dist/{parser-XRDUX2AR.js → parser-2AXPSKWB.js} +5 -5
  126. package/dist/{parser-B2A7XOAK.js → parser-2AZ2KQTO.js} +4 -4
  127. package/dist/{parser-VVE4THG3.js → parser-2LF33IS2.js} +4 -4
  128. package/dist/{parser-MHKYQPC2.js → parser-3QJ2Z4H4.js} +3 -3
  129. package/dist/parser-5GCQFSTQ.js +13 -0
  130. package/dist/{parser-XCPMEB2Z.js → parser-62OHBRU5.js} +3 -3
  131. package/dist/{parser-GML6V2KZ.js → parser-7LYJFZCP.js} +4 -4
  132. package/dist/{parser-LTA2BOZO.js → parser-BMOTF72G.js} +3 -3
  133. package/dist/{parser-FHRMFUNX.js → parser-CIFLYZYP.js} +3 -3
  134. package/dist/{parser-KTYF6WO5.js → parser-D2UL2G5U.js} +3 -3
  135. package/dist/{parser-5C3PEZK3.js → parser-DM2APTKB.js} +3 -3
  136. package/dist/{parser-X5XLFY4Z.js → parser-DYYTPLBL.js} +4 -4
  137. package/dist/{parser-WPPJGB4R.js → parser-GOUGUTPU.js} +4 -4
  138. package/dist/{parser-T3D7BV6O.js → parser-HGVUVD6J.js} +3 -3
  139. package/dist/{parser-F4FEU57T.js → parser-IEJD3CZB.js} +3 -3
  140. package/dist/{parser-FY3YFFBS.js → parser-JBEWNLAV.js} +5 -5
  141. package/dist/{parser-2UWWNTFL.js → parser-JMXPHNZD.js} +4 -4
  142. package/dist/{parser-YULS5MLD.js → parser-JMXSQY3K.js} +4 -4
  143. package/dist/{parser-YPWYT46P.js → parser-LUXS7J32.js} +4 -4
  144. package/dist/{parser-O7YQYFEN.js → parser-M5BUHULF.js} +4 -4
  145. package/dist/{parser-MVSYFK63.js → parser-MESRHUS4.js} +4 -4
  146. package/dist/{parser-HA3PF5FL.js → parser-OOYNI2UT.js} +4 -4
  147. package/dist/{parser-OPIXXUY4.js → parser-PVBUAVRR.js} +4 -4
  148. package/dist/{parser-3RXYQSA7.js → parser-QKRBSQLJ.js} +5 -5
  149. package/dist/{parser-CCNJKDDA.js → parser-S6NWSIJO.js} +4 -4
  150. package/dist/{parser-S4EJPNVN.js → parser-SFEK6Q7Z.js} +4 -4
  151. package/dist/{parser-7UI6UQ7B.js → parser-SUV52NQW.js} +4 -4
  152. package/dist/{parser-ESHNUFME.js → parser-SZHGLOOZ.js} +4 -4
  153. package/dist/{parser-66RYGJRB.js → parser-TO7IENWL.js} +4 -4
  154. package/dist/{parser-FPCWDYQV.js → parser-TVAMC7CQ.js} +4 -4
  155. package/dist/{parser-LU7UAKNB.js → parser-VAW46R57.js} +4 -4
  156. package/dist/{parser-6MQM7WT3.js → parser-XDSPOXSE.js} +4 -4
  157. package/dist/pert.d.ts +2 -0
  158. package/dist/{renderer-YVMETH6V.js → renderer-3PWLOJPD.js} +8 -8
  159. package/dist/{renderer-7HMZ5OCJ.js → renderer-5EMHIQL5.js} +3 -3
  160. package/dist/{renderer-2DME63VZ.js → renderer-5PODNLYP.js} +4 -4
  161. package/dist/{renderer-4A32DX5L.js → renderer-AQJIQ2XU.js} +7 -6
  162. package/dist/{renderer-RMAM2SOJ.js → renderer-BEW3AYFT.js} +8 -8
  163. package/dist/{renderer-YP3P6UVT.js → renderer-C3UYAXA6.js} +8 -6
  164. package/dist/{renderer-X2LYSMLU.js → renderer-CENXCMWG.js} +3 -3
  165. package/dist/{renderer-6CFML5G3.js → renderer-CXM3ARYN.js} +8 -7
  166. package/dist/{renderer-LHVCKEWF.js → renderer-DW6TEBLA.js} +8 -7
  167. package/dist/{renderer-Y3NXZINM.js → renderer-FE5M6SEZ.js} +8 -7
  168. package/dist/{renderer-G4UOW3RH.js → renderer-FXK6ZL3P.js} +3 -3
  169. package/dist/{renderer-4K5YYX5R.js → renderer-G5ESLCJB.js} +9 -8
  170. package/dist/{renderer-P3YQES7B.js → renderer-HTDS4FED.js} +9 -8
  171. package/dist/{renderer-YEFOOULC.js → renderer-IO4KCFVL.js} +8 -8
  172. package/dist/{renderer-FXMGCSRP.js → renderer-IRAFJNTK.js} +7 -6
  173. package/dist/{renderer-SES7QZYL.js → renderer-MFTTFW32.js} +9 -8
  174. package/dist/{renderer-Z4GNKNXO.js → renderer-MPXI4FVL.js} +6 -6
  175. package/dist/{renderer-RA4PTAMF.js → renderer-NVBEMQ6L.js} +5 -5
  176. package/dist/{renderer-7ZNVOVFG.js → renderer-OOGDCR6K.js} +3 -3
  177. package/dist/{renderer-CJ56SUMF.js → renderer-Q5P72O4A.js} +7 -7
  178. package/dist/{renderer-WCWI4I6A.js → renderer-QZESC66H.js} +2 -2
  179. package/dist/{renderer-B7Y6I7JX.js → renderer-RDBUXW7P.js} +4 -4
  180. package/dist/{renderer-V5SNTPAM.js → renderer-S4XB3JR2.js} +9 -9
  181. package/dist/{renderer-COJZZ4F6.js → renderer-SIWEEWJ5.js} +7 -6
  182. package/dist/{renderer-C3RI4OPJ.js → renderer-TKTM2SL4.js} +8 -7
  183. package/dist/{renderer-WVD6G2TS.js → renderer-TXTTV4HA.js} +8 -7
  184. package/dist/{renderer-HQ4JFZOV.js → renderer-UZIU4AHK.js} +7 -6
  185. package/dist/{renderer-3VY3VXJE.js → renderer-V72VJIGG.js} +9 -8
  186. package/dist/{renderer-PLVIARM7.js → renderer-VEGOEZOI.js} +7 -6
  187. package/dist/{renderer-OZX5KGQM.js → renderer-W6I6T2TA.js} +6 -6
  188. package/dist/{renderer-TQ5QDZOE.js → renderer-WSHJRR2T.js} +6 -6
  189. package/dist/{renderer-radial-VYBZAXXE.js → renderer-radial-AG75PBYD.js} +7 -7
  190. package/dist/{resolver-WFKZYBJ2.js → resolver-ZSFQQRTH.js} +3 -3
  191. package/dist/{state-parser-VIW2WNA5.js → state-parser-KIPZGIB4.js} +5 -5
  192. package/dist/{state-renderer-H22AQD3U.js → state-renderer-U6OSJG52.js} +9 -8
  193. package/docs/language-reference.md +2 -1
  194. package/package.json +1 -1
  195. package/dist/dgmo-router-TGZWFIZO.js +0 -88
  196. package/dist/parser-6GN5YJBJ.js +0 -13
@@ -7,7 +7,8 @@ import {
7
7
  FONT_FAMILY
8
8
  } from "./chunk-6KFWC4CO.js";
9
9
  import {
10
- getSeriesColors
10
+ getSeriesColors,
11
+ mix
11
12
  } from "./chunk-JYDMBWRP.js";
12
13
  import {
13
14
  resolveColor
@@ -15,13 +16,19 @@ import {
15
16
 
16
17
  // src/version-control/renderer.ts
17
18
  import * as d3Selection from "d3-selection";
18
- var LINE = 5.5;
19
- var DOT = 8;
20
- var CORNER = 13;
21
- var ANG = 32;
19
+ var LINE = 3;
20
+ var DOT = 5.5;
21
+ var CORNER = 10;
22
22
  var STACK = 19;
23
23
  var CIRCLED = "\u2460\u2461\u2462\u2463\u2464\u2465\u2466\u2467\u2468";
24
24
  var TITLE_AREA = 40;
25
+ var SHELF_TINT = 13;
26
+ var SHELF_EDGE = 4;
27
+ var SHELF_LIP = 2;
28
+ var SHELF_PAD = 8;
29
+ var SHELF_H = 21;
30
+ var LEADER_GAP = 22;
31
+ var ROW_GAP = 7;
25
32
  function clip(s, max) {
26
33
  return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
27
34
  }
@@ -94,12 +101,9 @@ function renderVersionControl(container, parsed, palette, isDark, onClickItem, e
94
101
  const pos = /* @__PURE__ */ new Map();
95
102
  const placements = [];
96
103
  let contentW, contentH, gutter, cross0, captionY = 0;
97
- const cos = Math.cos(ANG * Math.PI / 180);
98
- const sin = Math.sin(ANG * Math.PI / 180);
99
104
  if (!TB) {
100
- const maxName = Math.max(4, ...parsed.branches.map((b) => b.name.length));
101
- gutter = maxName * 7.5 + 18;
102
- const along0 = gutter + 34, step = 86, laneGap = 54;
105
+ gutter = 14;
106
+ const along0 = gutter + 20, step = 88, laneGap = 50;
103
107
  cross0 = 16 + maxStack * STACK + 14;
104
108
  for (const n of nodes)
105
109
  pos.set(n.key, {
@@ -107,17 +111,34 @@ function renderVersionControl(container, parsed, palette, isDark, onClickItem, e
107
111
  y: cross0 + n.lane * laneGap
108
112
  });
109
113
  const lanesBottom = cross0 + (laneCount - 1) * laneGap;
110
- const bandY = lanesBottom + 26;
111
- for (const n of nodes) {
114
+ const bandTop = lanesBottom + LEADER_GAP;
115
+ const shelfGap = 6;
116
+ const rowRight = [];
117
+ const sorted = [...nodes].sort(
118
+ (a, b) => pos.get(a.key).x - pos.get(b.key).x
119
+ );
120
+ for (const n of sorted) {
112
121
  const p = pos.get(n.key);
122
+ const w = label.get(n.key).lw + SHELF_PAD * 2;
123
+ const left = p.x - w / 2;
124
+ let row = rowRight.length;
125
+ for (let l = 0; l < rowRight.length; l++)
126
+ if (rowRight[l] + shelfGap <= left) {
127
+ row = l;
128
+ break;
129
+ }
130
+ const top = bandTop + row * (SHELF_H + ROW_GAP);
131
+ rowRight[row] = left + w;
113
132
  placements.push({
114
133
  node: n,
115
134
  kind: "msg",
116
- diag: true,
117
135
  x: p.x,
118
- y: bandY,
136
+ y: top,
119
137
  anchor: "start",
120
- leader: { x1: p.x, y1: p.y + DOT, x2: p.x, y2: bandY - 3 }
138
+ shelfLeft: Math.max(4, left),
139
+ shelfTop: top,
140
+ shelfW: w,
141
+ leader: { x1: p.x, y1: p.y + DOT, x2: p.x, y2: top }
121
142
  });
122
143
  const stack = above.get(n.key) ?? [];
123
144
  stack.forEach(
@@ -133,6 +154,7 @@ function renderVersionControl(container, parsed, palette, isDark, onClickItem, e
133
154
  })
134
155
  );
135
156
  }
157
+ const rowCount = rowRight.length;
136
158
  for (const b of parsed.branches) {
137
159
  if (!b.ab || b.ab.ahead + b.ab.behind === 0 || b.tip == null) continue;
138
160
  const tip = pos.get(b.tip);
@@ -146,10 +168,12 @@ function renderVersionControl(container, parsed, palette, isDark, onClickItem, e
146
168
  });
147
169
  }
148
170
  contentW = Math.max(
149
- along0 + (K - 1) * step + DOT + 70,
150
- ...[...pos.entries()].map(([k, p]) => p.x + label.get(k).lw * cos)
151
- ) + 18;
152
- contentH = bandY + maxLW * sin + 12 * cos + 16;
171
+ along0 + (K - 1) * step + DOT + 40,
172
+ ...[...pos.entries()].map(
173
+ ([k, p]) => p.x + label.get(k).lw / 2 + SHELF_PAD + 8
174
+ )
175
+ ) + 8;
176
+ contentH = bandTop + rowCount * (SHELF_H + ROW_GAP) + 8;
153
177
  if (parsed.notes.length) {
154
178
  captionY = contentH + 4;
155
179
  contentH += 8 + parsed.notes.length * 16 + 8;
@@ -169,7 +193,6 @@ function renderVersionControl(container, parsed, palette, isDark, onClickItem, e
169
193
  placements.push({
170
194
  node: n,
171
195
  kind: "msg",
172
- diag: false,
173
196
  x: bandX,
174
197
  y: p.y,
175
198
  anchor: "start",
@@ -194,10 +217,16 @@ function renderVersionControl(container, parsed, palette, isDark, onClickItem, e
194
217
  }
195
218
  const showTitle = !!parsed.title;
196
219
  const titleH = showTitle ? TITLE_AREA : 0;
197
- const W = Math.round(contentW);
198
- const H = Math.round(contentH + titleH);
220
+ const baseW = contentW;
221
+ const baseH = contentH + titleH;
199
222
  const exportMode = !!exportDims;
200
- const svg = d3Selection.select(container).append("svg").attr("width", W).attr("height", H).attr("viewBox", `0 0 ${W} ${H}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY);
223
+ const paneW = exportMode ? 0 : container.clientWidth || 0;
224
+ const paneH = exportMode ? 0 : container.clientHeight || 0;
225
+ const W = Math.round(Math.max(baseW, paneW));
226
+ const H = Math.round(Math.max(baseH, paneH));
227
+ const vw = exportMode ? W : paneW || W;
228
+ const vh = exportMode ? H : paneH || H;
229
+ const svg = d3Selection.select(container).append("svg").attr("width", vw).attr("height", vh).attr("viewBox", `0 0 ${W} ${H}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY);
201
230
  svg.append("rect").attr("width", W).attr("height", H).attr("fill", palette.bg);
202
231
  if (showTitle) {
203
232
  const t = svg.append("text").attr("class", "chart-title").attr("x", W / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("data-line-number", parsed.titleLineNumber ?? 1).text(parsed.title);
@@ -217,7 +246,6 @@ function renderVersionControl(container, parsed, palette, isDark, onClickItem, e
217
246
  label,
218
247
  colorOf,
219
248
  byKey,
220
- gutter,
221
249
  cross0,
222
250
  captionY,
223
251
  onClickItem && !exportMode ? onClickItem : void 0
@@ -229,7 +257,7 @@ function abText(ab) {
229
257
  if (ab.behind) a.push("\u2193" + ab.behind);
230
258
  return a.join(" ");
231
259
  }
232
- function drawGraph(g, parsed, palette, TB, pos, placements, label, colorOf, byKey, gutter, cross0, captionY, onClickItem) {
260
+ function drawGraph(g, parsed, palette, TB, pos, placements, label, colorOf, byKey, cross0, captionY, onClickItem) {
233
261
  const nodes = parsed.nodes;
234
262
  const P = (k) => pos.get(k);
235
263
  const branchCorner = (par, n) => TB ? { x: P(n.key).x, y: P(par.key).y } : { x: P(par.key).x, y: P(n.key).y };
@@ -253,17 +281,17 @@ function drawGraph(g, parsed, palette, TB, pos, placements, label, colorOf, byKe
253
281
  const N = P(n.key);
254
282
  if (n.prev != null) {
255
283
  const a = P(n.prev);
256
- const e = g.append("line").attr("x1", a.x).attr("y1", a.y).attr("x2", N.x).attr("y2", N.y).attr("stroke", c).attr("stroke-width", LINE).attr("stroke-linecap", "round").attr("opacity", o);
284
+ const e = g.append("line").attr("x1", a.x).attr("y1", a.y).attr("x2", N.x).attr("y2", N.y).attr("stroke", c).attr("stroke-width", LINE).attr("stroke-linecap", "round").attr("data-branch", n.branch).attr("opacity", o);
257
285
  if (n.ghost) e.attr("stroke-dasharray", "5 5");
258
286
  }
259
287
  if (n.parent != null) {
260
288
  const par = byKey(n.parent), cc = branchCorner(par, n), pp = P(par.key);
261
- const e = g.append("path").attr("d", roundedL(pp.x, pp.y, cc.x, cc.y, N.x, N.y, CORNER)).attr("fill", "none").attr("stroke", c).attr("stroke-width", LINE).attr("stroke-linecap", "round").attr("opacity", o);
289
+ const e = g.append("path").attr("d", roundedL(pp.x, pp.y, cc.x, cc.y, N.x, N.y, CORNER)).attr("fill", "none").attr("stroke", c).attr("stroke-width", LINE).attr("stroke-linecap", "round").attr("data-branch", n.branch).attr("opacity", o);
262
290
  if (n.ghost) e.attr("stroke-dasharray", "5 5");
263
291
  }
264
292
  if (n.mergeFrom != null) {
265
293
  const s = byKey(n.mergeFrom), cc = mergeCorner(s, n), sp = P(s.key);
266
- g.append("path").attr("d", roundedL(sp.x, sp.y, cc.x, cc.y, N.x, N.y, CORNER)).attr("fill", "none").attr("stroke", colorOf(s)).attr("stroke-width", LINE).attr("stroke-linecap", "round").attr("opacity", 0.92 * o);
294
+ g.append("path").attr("d", roundedL(sp.x, sp.y, cc.x, cc.y, N.x, N.y, CORNER)).attr("fill", "none").attr("stroke", colorOf(s)).attr("stroke-width", LINE).attr("stroke-linecap", "round").attr("data-branch", s.branch).attr("opacity", 0.92 * o);
267
295
  }
268
296
  if (n.cherryFrom != null)
269
297
  dlink(byKey(n.cherryFrom), n, colorOf(byKey(n.cherryFrom)), false);
@@ -284,7 +312,7 @@ function drawGraph(g, parsed, palette, TB, pos, placements, label, colorOf, byKe
284
312
  if (TB) {
285
313
  g.append("text").attr("x", fp.x).attr("y", 14).attr("text-anchor", "middle").attr("font-size", 12.5).attr("font-weight", 800).attr("fill", col).text(b.name);
286
314
  } else {
287
- g.append("text").attr("x", gutter).attr("y", fp.y + 4).attr("text-anchor", "end").attr("font-size", 12.5).attr("font-weight", 800).attr("fill", col).text(b.name);
315
+ g.append("text").attr("x", fp.x - DOT - 1).attr("y", fp.y - DOT - 7).attr("text-anchor", "start").attr("font-size", 12.5).attr("font-weight", 800).attr("fill", col).attr("data-branch", b.name).text(b.name);
288
316
  }
289
317
  }
290
318
  }
@@ -338,11 +366,12 @@ function drawGraph(g, parsed, palette, TB, pos, placements, label, colorOf, byKe
338
366
  }
339
367
  g.append("text").attr("x", cx).attr("y", cy + 4).attr("text-anchor", "middle").attr("font-size", 10.5).attr("font-weight", weight).attr("fill", textColor).text(text);
340
368
  };
369
+ let shelfSeq = 0;
341
370
  for (const pl of placements) {
342
371
  const n = pl.node;
343
372
  const c = colorOf(n);
344
373
  if (pl.leader) {
345
- g.append("line").attr("x1", pl.leader.x1).attr("y1", pl.leader.y1).attr("x2", pl.leader.x2).attr("y2", pl.leader.y2).attr("stroke", c).attr("stroke-width", 1).attr("opacity", 0.34 * gop(n));
374
+ g.append("line").attr("x1", pl.leader.x1).attr("y1", pl.leader.y1).attr("x2", pl.leader.x2).attr("y2", pl.leader.y2).attr("stroke", c).attr("stroke-width", 1.5).attr("stroke-linecap", "round").attr("data-branch", n.branch).attr("opacity", 0.55 * gop(n));
346
375
  }
347
376
  if (pl.kind === "tag") pill(pl.x, pl.y, pl.w, pl.label, c, palette.bg);
348
377
  else if (pl.kind === "head")
@@ -368,7 +397,22 @@ function drawGraph(g, parsed, palette, TB, pos, placements, label, colorOf, byKe
368
397
  const L = label.get(n.key);
369
398
  const gh = n.ghost;
370
399
  const mfill = gh ? palette.textMuted : c;
371
- const t = pl.diag ? g.append("text").attr("transform", `translate(${pl.x},${pl.y}) rotate(${ANG})`).attr("font-size", 12).attr("opacity", gh ? 0.55 : 1) : g.append("text").attr("x", pl.x).attr("y", pl.y + 4).attr("text-anchor", pl.anchor).attr("font-size", 12).attr("opacity", gh ? 0.55 : 1);
400
+ let tx = pl.x;
401
+ let ty = pl.y + 4;
402
+ let anchor = pl.anchor;
403
+ if (pl.shelfW != null) {
404
+ const left = pl.shelfLeft;
405
+ const top = pl.shelfTop;
406
+ const w = pl.shelfW;
407
+ const clipId = `dgmo-vc-shelf-${shelfSeq++}`;
408
+ g.append("clipPath").attr("id", clipId).append("rect").attr("x", left).attr("y", top).attr("width", w).attr("height", SHELF_H).attr("rx", SHELF_EDGE);
409
+ g.append("rect").attr("x", left).attr("y", top).attr("width", w).attr("height", SHELF_H).attr("rx", SHELF_EDGE).attr("fill", gh ? palette.bg : mix(c, palette.bg, SHELF_TINT)).attr("data-branch", n.branch).attr("opacity", gh ? 0.5 : 1);
410
+ g.append("rect").attr("x", left).attr("y", top).attr("width", w).attr("height", SHELF_LIP).attr("clip-path", `url(#${clipId})`).attr("fill", c).attr("data-branch", n.branch).attr("opacity", gh ? 0.4 : 1);
411
+ tx = left + SHELF_PAD;
412
+ ty = top + SHELF_H / 2 + 4;
413
+ anchor = "start";
414
+ }
415
+ const t = g.append("text").attr("x", tx).attr("y", ty).attr("text-anchor", anchor).attr("font-size", 12).attr("data-branch", n.branch).attr("opacity", gh ? 0.6 : 1);
372
416
  if (L.sha)
373
417
  t.append("tspan").attr("font-family", "ui-monospace, monospace").attr("font-size", 11).attr("fill", palette.textMuted).text(L.sha + " ");
374
418
  t.append("tspan").attr("fill", mfill).attr("font-weight", n.kind === "cherry" ? 400 : 700).attr("font-style", n.kind === "cherry" ? "italic" : "normal").text(L.msg);
@@ -399,4 +443,4 @@ export {
399
443
  renderVersionControl,
400
444
  renderVersionControlForExport
401
445
  };
402
- //# sourceMappingURL=chunk-7JDTNFAK.js.map
446
+ //# sourceMappingURL=chunk-EFUQENO5.js.map
@@ -14,7 +14,7 @@ import {
14
14
  formatOffsetLabel,
15
15
  isValidZone,
16
16
  parseFixedOffset
17
- } from "./chunk-APKUAJ2L.js";
17
+ } from "./chunk-A2RUBBVT.js";
18
18
  import {
19
19
  emit,
20
20
  formatDgmoError,
@@ -775,4 +775,4 @@ export {
775
775
  isSubNationalUsExtent,
776
776
  resolveMap
777
777
  };
778
- //# sourceMappingURL=chunk-BULHGPHK.js.map
778
+ //# sourceMappingURL=chunk-EMSOFHEN.js.map
@@ -6,12 +6,16 @@ import {
6
6
  CARD_RADIUS,
7
7
  CONTAINER_RADIUS
8
8
  } from "./chunk-3CIOJ5YJ.js";
9
+ import {
10
+ layoutInlineHeader
11
+ } from "./chunk-US3P2DQO.js";
9
12
  import {
10
13
  renderIntegratedLegend
11
- } from "./chunk-2NZOHEP4.js";
14
+ } from "./chunk-ASPS5O6F.js";
12
15
  import {
16
+ getLegendExtent,
13
17
  getMaxLegendReservedHeight
14
- } from "./chunk-J7HQPVYH.js";
18
+ } from "./chunk-GRXPFBYC.js";
15
19
  import {
16
20
  FONT_FAMILY
17
21
  } from "./chunk-6KFWC4CO.js";
@@ -29,7 +33,7 @@ import {
29
33
  resolveActiveTagGroup,
30
34
  resolveTagColor,
31
35
  tagAttrKey
32
- } from "./chunk-AHTTKERF.js";
36
+ } from "./chunk-JR7Q6GHE.js";
33
37
 
34
38
  // src/sketch/renderer.ts
35
39
  import * as d3 from "d3-selection";
@@ -377,7 +381,34 @@ function renderSketch(container, parsed, layout, palette, isDark, options = {})
377
381
  },
378
382
  width
379
383
  ) : 0;
380
- const contentTop = titleOffset + legendHeight + DIAGRAM_PADDING + extraTop;
384
+ const hasLegend = legendGroups.length > 0;
385
+ const inlineRequested = parsed.options.legendInline === true;
386
+ const legendExtent = inlineRequested && hasLegend ? getLegendExtent(
387
+ {
388
+ groups: legendGroups,
389
+ position: {
390
+ placement: "top-center",
391
+ titleRelation: "inline-with-title"
392
+ },
393
+ mode: exportMode ? "export" : "preview",
394
+ showInactivePills: true
395
+ },
396
+ { activeGroup: activeName },
397
+ width
398
+ ) : { width: 0, height: 0 };
399
+ const header = layoutInlineHeader({
400
+ requested: inlineRequested,
401
+ title: parsed.title ?? "",
402
+ hasLegend,
403
+ legendWidth: legendExtent.width,
404
+ legendHeight: legendExtent.height,
405
+ containerWidth: width,
406
+ titleBandHeight: titleOffset,
407
+ legendReserve: legendHeight,
408
+ titleBaselineY: TITLE_Y,
409
+ titleFontSize: TITLE_FONT_SIZE
410
+ });
411
+ const contentTop = titleOffset + (header.inline ? 0 : legendHeight) + DIAGRAM_PADDING + extraTop;
381
412
  const height = Math.max(
382
413
  contentTop + maxY + DIAGRAM_PADDING,
383
414
  options.exportDims?.height ?? 0
@@ -403,15 +434,22 @@ function renderSketch(container, parsed, layout, palette, isDark, options = {})
403
434
  ).attr("fill", color);
404
435
  }
405
436
  if (showTitle) {
406
- svg.append("text").attr("x", width / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("font-size", TITLE_FONT_SIZE).attr("font-weight", 700).attr("fill", palette.text).text(parsed.title);
437
+ svg.append("text").attr("class", "chart-title").attr("x", header.titleX).attr("y", TITLE_Y).attr("text-anchor", header.titleAnchor).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", 700).attr("fill", palette.text).text(parsed.title);
407
438
  }
408
439
  if (legendGroups.length > 0) {
409
- const legendG = svg.append("g").attr("transform", `translate(0,${titleOffset + 4})`);
440
+ const legendG = svg.append("g").attr(
441
+ "transform",
442
+ header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0,${titleOffset + 4})`
443
+ );
410
444
  renderIntegratedLegend(legendG, {
411
445
  groups: legendGroups,
412
446
  ...activeName !== null && { activeGroup: activeName },
413
447
  mode: exportMode ? "export" : "preview",
414
448
  showInactivePills: true,
449
+ position: {
450
+ placement: "top-center",
451
+ titleRelation: header.inline ? "inline-with-title" : "below-title"
452
+ },
415
453
  palette,
416
454
  isDark,
417
455
  width
@@ -1059,4 +1097,4 @@ export {
1059
1097
  sketchEdgeGeometry,
1060
1098
  renderSketchForExport
1061
1099
  };
1062
- //# sourceMappingURL=chunk-IYNKLCAZ.js.map
1100
+ //# sourceMappingURL=chunk-ETTDF3S2.js.map
@@ -5,7 +5,7 @@ import {
5
5
  splitNameAndMeta,
6
6
  tryParseSharedOption,
7
7
  warnUnknownMetaKeys
8
- } from "./chunk-3FRO35WW.js";
8
+ } from "./chunk-A2ARDILY.js";
9
9
  import {
10
10
  makeDgmoError,
11
11
  makeFail
@@ -127,4 +127,4 @@ function parsePyramid(content) {
127
127
  export {
128
128
  parsePyramid
129
129
  };
130
- //# sourceMappingURL=chunk-KDK5EKUR.js.map
130
+ //# sourceMappingURL=chunk-ETYF5QZR.js.map
@@ -22,12 +22,16 @@ import {
22
22
  import {
23
23
  ScaleContext
24
24
  } from "./chunk-YYVTBZZC.js";
25
+ import {
26
+ layoutInlineHeader
27
+ } from "./chunk-US3P2DQO.js";
25
28
  import {
26
29
  renderIntegratedLegend
27
- } from "./chunk-2NZOHEP4.js";
30
+ } from "./chunk-ASPS5O6F.js";
28
31
  import {
32
+ getLegendExtent,
29
33
  getMaxLegendReservedHeight
30
- } from "./chunk-J7HQPVYH.js";
34
+ } from "./chunk-GRXPFBYC.js";
31
35
  import {
32
36
  TITLE_FONT_SIZE,
33
37
  TITLE_FONT_WEIGHT,
@@ -38,7 +42,7 @@ import {
38
42
  } from "./chunk-6KFWC4CO.js";
39
43
  import {
40
44
  parseState
41
- } from "./chunk-T7Y554OK.js";
45
+ } from "./chunk-MEH4TJEX.js";
42
46
  import {
43
47
  measureText
44
48
  } from "./chunk-4ASYQ347.js";
@@ -52,11 +56,12 @@ import {
52
56
  resolveActiveTagGroup,
53
57
  resolveTagColor,
54
58
  tagAttrKey
55
- } from "./chunk-AHTTKERF.js";
59
+ } from "./chunk-JR7Q6GHE.js";
56
60
  import {
57
61
  fillModeFromOptions,
62
+ legendInlineRequested,
58
63
  legendSuppressed
59
- } from "./chunk-3FRO35WW.js";
64
+ } from "./chunk-A2ARDILY.js";
60
65
 
61
66
  // src/graph/state-renderer.ts
62
67
  import * as d3Selection from "d3-selection";
@@ -129,6 +134,32 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
129
134
  width
130
135
  )
131
136
  ) + 8 : 0;
137
+ const inlineRequested = legendInlineRequested(graph.options);
138
+ const legendExtent = inlineRequested && hasLegend ? getLegendExtent(
139
+ {
140
+ groups: legendGroups,
141
+ position: {
142
+ placement: "top-center",
143
+ titleRelation: "inline-with-title"
144
+ },
145
+ mode: exportDims ? "export" : "preview",
146
+ showInactivePills: true
147
+ },
148
+ { activeGroup: activeTagGroup },
149
+ width
150
+ ) : { width: 0, height: 0 };
151
+ const header = layoutInlineHeader({
152
+ requested: inlineRequested,
153
+ title: graph.title ?? "",
154
+ hasLegend,
155
+ legendWidth: legendExtent.width,
156
+ legendHeight: legendExtent.height,
157
+ containerWidth: width,
158
+ titleBandHeight: titleHeight,
159
+ legendReserve: legendH,
160
+ titleBaselineY: sTitleY,
161
+ titleFontSize: sTitleFontSize
162
+ });
132
163
  const diagramW = layout.width;
133
164
  const diagramH = layout.height;
134
165
  const { scale, offsetX, offsetY, canvasHeight } = fitDiagramToCanvas({
@@ -137,9 +168,8 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
137
168
  diagramW,
138
169
  diagramH,
139
170
  padding: sDiagramPadding,
140
- // The legend band sits directly under the title, so it reserves the same
141
- // top strip fitDiagramToCanvas already offsets the diagram by.
142
- titleHeight: titleHeight + legendH,
171
+ // Inline → one band (title only); stacked → title + legend band.
172
+ titleHeight: header.inline ? titleHeight : titleHeight + legendH,
143
173
  maxScale: MAX_SCALE,
144
174
  exportMode: !!exportDims
145
175
  });
@@ -157,7 +187,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
157
187
  colors: edgeColors
158
188
  });
159
189
  if (showTitle) {
160
- const titleEl = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", sTitleY).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-size", sTitleFontSize).attr("font-weight", TITLE_FONT_WEIGHT).style(
190
+ const titleEl = svg.append("text").attr("class", "chart-title").attr("x", header.titleX).attr("y", sTitleY).attr("text-anchor", header.titleAnchor).attr("fill", palette.text).attr("font-size", sTitleFontSize).attr("font-weight", TITLE_FONT_WEIGHT).style(
161
191
  "cursor",
162
192
  onClickItem && graph.titleLineNumber ? "pointer" : "default"
163
193
  ).text(graph.title);
@@ -173,7 +203,10 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
173
203
  }
174
204
  }
175
205
  if (hasLegend) {
176
- const legendG = svg.append("g").attr("transform", `translate(0, ${titleHeight + 4})`);
206
+ const legendG = svg.append("g").attr(
207
+ "transform",
208
+ header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0, ${titleHeight + 4})`
209
+ );
177
210
  renderIntegratedLegend(legendG, {
178
211
  groups: legendGroups,
179
212
  activeGroup: activeTagGroup,
@@ -181,6 +214,12 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
181
214
  // Inactive sibling groups stay visible as collapsed pills so the user
182
215
  // can click one to flip the active colouring dimension (as in b&l).
183
216
  showInactivePills: true,
217
+ // Inline → left-origin so the wrapper's right-flush translate lands the
218
+ // legend at the chart's right edge; stacked → centered below the title.
219
+ position: {
220
+ placement: "top-center",
221
+ titleRelation: header.inline ? "inline-with-title" : "below-title"
222
+ },
184
223
  palette,
185
224
  isDark,
186
225
  width
@@ -439,4 +478,4 @@ export {
439
478
  renderState,
440
479
  renderStateForExport
441
480
  };
442
- //# sourceMappingURL=chunk-COJW2NEY.js.map
481
+ //# sourceMappingURL=chunk-F5ZNUMSY.js.map
@@ -4,13 +4,13 @@ import {
4
4
  matchTagBlockHeading,
5
5
  stripDefaultModifier,
6
6
  tagAttrKey
7
- } from "./chunk-AHTTKERF.js";
7
+ } from "./chunk-JR7Q6GHE.js";
8
8
  import {
9
9
  FILL_FAMILY_TOKENS,
10
10
  extractColor,
11
11
  measureIndent,
12
12
  parseFirstLine
13
- } from "./chunk-3FRO35WW.js";
13
+ } from "./chunk-A2ARDILY.js";
14
14
  import {
15
15
  emit
16
16
  } from "./chunk-4W2PE66Q.js";
@@ -692,4 +692,4 @@ export {
692
692
  SWIMLANE_DIAGNOSTICS,
693
693
  parseSwimlane
694
694
  };
695
- //# sourceMappingURL=chunk-EAI6XJ7D.js.map
695
+ //# sourceMappingURL=chunk-FBP33UM6.js.map
@@ -5,13 +5,18 @@ import {
5
5
  import {
6
6
  ScaleContext
7
7
  } from "./chunk-YYVTBZZC.js";
8
+ import {
9
+ INLINE_HEADER_PAD,
10
+ layoutInlineHeader
11
+ } from "./chunk-US3P2DQO.js";
8
12
  import {
9
13
  renderIntegratedLegend
10
- } from "./chunk-2NZOHEP4.js";
14
+ } from "./chunk-ASPS5O6F.js";
11
15
  import {
12
16
  controlsGroupCapsuleWidth,
17
+ getLegendExtent,
13
18
  getMaxLegendReservedHeight
14
- } from "./chunk-J7HQPVYH.js";
19
+ } from "./chunk-GRXPFBYC.js";
15
20
  import {
16
21
  TITLE_FONT_SIZE,
17
22
  TITLE_FONT_WEIGHT,
@@ -53,7 +58,7 @@ import {
53
58
  resolveActiveTagGroup,
54
59
  resolveTagColor,
55
60
  tagAttrKey
56
- } from "./chunk-AHTTKERF.js";
61
+ } from "./chunk-JR7Q6GHE.js";
57
62
 
58
63
  // src/gantt/renderer.ts
59
64
  import * as d3Scale from "d3-scale";
@@ -217,12 +222,38 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
217
222
  const sSprintLabelReserve = ctx.structural(sprintLabelReserve);
218
223
  const sTitleHeight = ctx.aesthetic(titleHeight);
219
224
  const sTagLegendReserve = ctx.structural(tagLegendReserve);
225
+ const inlineRequested = resolved.options.legendInline === true && resolved.tagGroups.length > 0;
226
+ const legendExtent = inlineRequested ? getLegendExtent(
227
+ {
228
+ groups: resolved.tagGroups.map((tg) => ({
229
+ name: tg.name,
230
+ entries: tg.entries
231
+ })),
232
+ position: { placement: "top-center", titleRelation: "inline-with-title" },
233
+ mode: "preview",
234
+ capsulePillAddonWidth: LEGEND_ICON_W
235
+ },
236
+ { activeGroup: currentActiveGroup },
237
+ containerWidth
238
+ ) : { width: 0, height: 0 };
239
+ const header = layoutInlineHeader({
240
+ requested: inlineRequested,
241
+ title: title ?? "",
242
+ hasLegend: hasTagLegend,
243
+ legendWidth: legendExtent.width,
244
+ legendHeight: legendExtent.height,
245
+ containerWidth,
246
+ titleBandHeight: sTitleHeight,
247
+ legendReserve: sTagLegendReserve,
248
+ titleBaselineY: sTitleY,
249
+ titleFontSize: sTitleFontSize
250
+ });
220
251
  const sEraReserve = ctx.structural(eraReserve);
221
252
  const sMarkerReserve = ctx.structural(markerReserve);
222
253
  const sTodayReserve = ctx.structural(todayReserve);
223
254
  const sFont10 = ctx.text(10);
224
255
  const sFont11 = ctx.text(11);
225
- const sMarginTop = sTitleHeight + sTagLegendReserve + sEraReserve + sMarkerReserve + sTodayReserve + sTopDateLabelReserve + sSprintLabelReserve;
256
+ const sMarginTop = sTitleHeight + (header.inline ? 0 : sTagLegendReserve) + sEraReserve + sMarkerReserve + sTodayReserve + sTopDateLabelReserve + sSprintLabelReserve;
226
257
  const sTodayLabelY = sTodayReserve ? -(sTopDateLabelReserve + sHeaderRowH / 2) : 0;
227
258
  const sMarkerLabelY = sMarkerReserve ? -(sTopDateLabelReserve + sTodayReserve + sHeaderRowH / 2) : 0;
228
259
  const sEraLabelY = sEraReserve ? -(sTopDateLabelReserve + sTodayReserve + sMarkerReserve + sHeaderRowH / 2) : 0;
@@ -234,12 +265,12 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
234
265
  const svg = d3Selection.select(container).append("svg").attr("viewBox", `0 0 ${containerWidth} ${sOuterHeight}`).attr("width", exportDims ? containerWidth : "100%").attr("preserveAspectRatio", "xMidYMin meet").attr("font-family", FONT_FAMILY).style("overflow", "visible");
235
266
  const g = svg.append("g").attr("transform", `translate(${leftMargin}, ${sMarginTop})`);
236
267
  if (showTitle) {
237
- svg.append("text").attr("class", "chart-title").attr("x", containerWidth / 2).attr("y", sTitleY).attr("text-anchor", "middle").attr("font-size", sTitleFontSize).attr("font-weight", TITLE_FONT_WEIGHT).attr("fill", palette.text).text(title);
268
+ svg.append("text").attr("class", "chart-title").attr("x", header.titleX).attr("y", sTitleY).attr("text-anchor", header.titleAnchor).attr("font-size", sTitleFontSize).attr("font-weight", TITLE_FONT_WEIGHT).attr("fill", palette.text).text(title);
238
269
  }
239
270
  function drawLegend() {
240
271
  svg.selectAll(".gantt-tag-legend-container").remove();
241
272
  if (hasTagLegend) {
242
- const legendY = sTitleHeight;
273
+ const legendY = header.inline ? header.legendY : sTitleHeight;
243
274
  renderTagLegend(
244
275
  svg,
245
276
  g,
@@ -288,7 +319,8 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
288
319
  drawLegend();
289
320
  },
290
321
  options?.exportMode ?? false,
291
- controlsHost
322
+ controlsHost,
323
+ header.inline
292
324
  );
293
325
  }
294
326
  }
@@ -1116,7 +1148,7 @@ function buildControlsToggles(hasCriticalPath, criticalPathActive, hasDependenci
1116
1148
  }
1117
1149
  return toggles;
1118
1150
  }
1119
- function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive, _optionLineNumbers, onToggle, onToggleControlsExpand, currentSwimlaneGroup, onSwimlaneChange, legendViewMode, resolvedTasks, controlsExpanded = false, hasDependencies = false, dependenciesActive = false, onControlsToggle, exportMode = false, controlsHost = "inline") {
1151
+ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive, _optionLineNumbers, onToggle, onToggleControlsExpand, currentSwimlaneGroup, onSwimlaneChange, legendViewMode, resolvedTasks, controlsExpanded = false, hasDependencies = false, dependenciesActive = false, onControlsToggle, exportMode = false, controlsHost = "inline", inlineHeader = false) {
1120
1152
  let visibleGroups;
1121
1153
  if (activeGroupName) {
1122
1154
  const activeGroup = tagGroups.filter(
@@ -1186,7 +1218,7 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
1186
1218
  totalW += controlsExpanded ? controlsGroupCapsuleWidth(controlsToggleLabels) : LEGEND_GEAR_PILL_W;
1187
1219
  }
1188
1220
  const containerWidth = chartLeftMargin + chartInnerWidth + RIGHT_MARGIN;
1189
- const legendX = (containerWidth - totalW) / 2;
1221
+ const legendX = inlineHeader ? containerWidth - INLINE_HEADER_PAD - totalW : (containerWidth - totalW) / 2;
1190
1222
  const legendRow = svg.append("g").attr("class", "gantt-tag-legend-container").attr("transform", `translate(${legendX}, ${legendY})`);
1191
1223
  if (visibleGroups.length > 0) {
1192
1224
  const showIcon = !legendViewMode && tagGroups.length > 0;
@@ -1294,6 +1326,12 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
1294
1326
  width: tagGroupsW,
1295
1327
  mode: exportMode ? "export" : "preview",
1296
1328
  capsulePillAddonWidth: iconReserve,
1329
+ ...inlineHeader && {
1330
+ position: {
1331
+ placement: "top-center",
1332
+ titleRelation: "inline-with-title"
1333
+ }
1334
+ },
1297
1335
  ...controlsToggles.length > 0 && {
1298
1336
  controlsGroup: { toggles: controlsToggles }
1299
1337
  },
@@ -2105,4 +2143,4 @@ export {
2105
2143
  renderGantt,
2106
2144
  buildTagLaneRowList
2107
2145
  };
2108
- //# sourceMappingURL=chunk-KINOX74I.js.map
2146
+ //# sourceMappingURL=chunk-FGAMFJNJ.js.map
@@ -537,12 +537,33 @@ function getMaxLegendReservedHeight(config, containerWidth) {
537
537
  }
538
538
  return max;
539
539
  }
540
+ function getLegendExtent(config, state, containerWidth) {
541
+ const layout = computeLegendLayout(config, state, containerWidth);
542
+ let left = Infinity;
543
+ let right = 0;
544
+ let bottom = 0;
545
+ const track = (x, y, w, h) => {
546
+ left = Math.min(left, x);
547
+ right = Math.max(right, x + w);
548
+ bottom = Math.max(bottom, y + h);
549
+ };
550
+ if (layout.activeCapsule) {
551
+ const c = layout.activeCapsule;
552
+ track(c.x, c.y, c.width, c.height);
553
+ }
554
+ for (const pill of layout.pills) track(pill.x, pill.y, pill.width, pill.height);
555
+ return {
556
+ width: right - (left === Infinity ? 0 : left),
557
+ height: bottom || LEGEND_HEIGHT
558
+ };
559
+ }
540
560
 
541
561
  export {
542
562
  compactNumber,
543
563
  controlsGroupCapsuleWidth,
544
564
  computeLegendLayout,
545
565
  getLegendReservedHeight,
546
- getMaxLegendReservedHeight
566
+ getMaxLegendReservedHeight,
567
+ getLegendExtent
547
568
  };
548
- //# sourceMappingURL=chunk-J7HQPVYH.js.map
569
+ //# sourceMappingURL=chunk-GRXPFBYC.js.map