prographs 0.12.0 → 0.13.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 (269) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +6 -4
  3. package/dist/AutoGraph-PDPEAIXL.cjs +145 -0
  4. package/dist/GraphType.js +19 -0
  5. package/dist/autograph/chartIndex.js +521 -0
  6. package/dist/autograph/chartModules.js +2 -1
  7. package/dist/autograph/index.cjs +98 -93
  8. package/dist/catalog-DI4XZ46L.cjs +142 -0
  9. package/dist/catalog.js +2 -1
  10. package/dist/charts/biologycharts/BiologySamples.js +59 -0
  11. package/dist/charts/biologycharts/PunnettSquare.js +342 -0
  12. package/dist/charts/biologycharts/biologyEnums.js +22 -1
  13. package/dist/charts/biologycharts/index.js +5 -3
  14. package/dist/charts/doecharts/DoeSamples.js +78 -0
  15. package/dist/charts/doecharts/SipocDiagram.js +453 -0
  16. package/dist/charts/doecharts/index.js +4 -2
  17. package/dist/charts/fieldcharts/SpeciesAccumulationCurve.js +350 -0
  18. package/dist/charts/fieldcharts/fieldEnums.js +8 -1
  19. package/dist/charts/fieldcharts/index.js +5 -3
  20. package/dist/charts/signals/AntennaPatternChart.js +492 -0
  21. package/dist/charts/signals/SignalSamples.js +17 -0
  22. package/dist/charts/signals/index.js +5 -3
  23. package/dist/charts/softwarediagrams/ComponentDiagram.js +504 -0
  24. package/dist/charts/softwarediagrams/DeploymentDiagram.js +419 -0
  25. package/dist/charts/softwarediagrams/SoftwareSamples.js +283 -1
  26. package/dist/charts/softwarediagrams/index.js +7 -3
  27. package/dist/charts/softwarediagrams/softwareEnums.js +45 -1
  28. package/dist/charts/sportscharts/PowerDurationCurve.js +301 -0
  29. package/dist/charts/sportscharts/SportsSamples.js +102 -0
  30. package/dist/charts/sportscharts/TrainingLoadChart.js +325 -0
  31. package/dist/charts/sportscharts/index.js +6 -2
  32. package/dist/charts/strategycharts/BassDiffusionChart.js +362 -0
  33. package/dist/charts/strategycharts/BassModel.js +96 -0
  34. package/dist/charts/strategycharts/BurnRunwayChart.js +284 -0
  35. package/dist/charts/strategycharts/CapTableChart.js +366 -0
  36. package/dist/charts/strategycharts/KanbanBoard.js +324 -0
  37. package/dist/charts/strategycharts/OkrTree.js +339 -0
  38. package/dist/charts/strategycharts/StrategyPane.js +27 -0
  39. package/dist/charts/strategycharts/StrategySamples.js +251 -0
  40. package/dist/charts/strategycharts/index.js +15 -3
  41. package/dist/charts/threefields/BsfcMap3DChart.js +231 -0
  42. package/dist/charts/threefields/CompressorMap3DChart.js +217 -0
  43. package/dist/charts/threefields/FieldGrid.js +50 -0
  44. package/dist/charts/threefields/LossLandscape3DChart.js +201 -0
  45. package/dist/charts/threefields/MapSheet.js +77 -0
  46. package/dist/charts/threefields/TerrainRoute3DChart.js +201 -0
  47. package/dist/charts/threefields/TerrainRouteMath.js +40 -0
  48. package/dist/charts/threefields/ThreeFieldBase.js +117 -0
  49. package/dist/charts/threefields/ThreeFieldsSamples.js +80 -0
  50. package/dist/charts/threefields/WaferMap3DChart.js +218 -0
  51. package/dist/charts/threefields/index.js +19 -0
  52. package/dist/charts/threesurfaces/index.js +2 -2
  53. package/dist/charts/tradingcharts/KeltnerChannelChart.js +171 -0
  54. package/dist/charts/tradingcharts/TradingMath.js +20 -0
  55. package/dist/charts/tradingcharts/index.js +4 -2
  56. package/dist/{chunk-ZL6XDXMK.cjs → chunk-26PSLEP4.cjs} +8 -8
  57. package/dist/{chunk-W3US6EFP.cjs → chunk-2BO5DZUP.cjs} +12 -12
  58. package/dist/{chunk-5DP7OUSE.cjs → chunk-2GG5YYSC.cjs} +6 -6
  59. package/dist/{chunk-7FG4JSVO.cjs → chunk-2GL2VNJU.cjs} +253 -33
  60. package/dist/{chunk-LCWMRCLF.cjs → chunk-2PYOI7OY.cjs} +21 -21
  61. package/dist/{chunk-JFWJAEBD.cjs → chunk-3U4MCSKI.cjs} +4 -4
  62. package/dist/{chunk-CUPLHZRR.cjs → chunk-3ZMM3FSK.cjs} +4 -4
  63. package/dist/{chunk-L2AV62DP.cjs → chunk-4767WQJ7.cjs} +6 -6
  64. package/dist/{chunk-DA2EYIIP.cjs → chunk-4E7FSSBF.cjs} +1210 -168
  65. package/dist/{chunk-VS5LQEZB.cjs → chunk-526STI2S.cjs} +5 -5
  66. package/dist/{chunk-RXIMEK6C.cjs → chunk-55767YPI.cjs} +20 -20
  67. package/dist/{chunk-JXLSKIUV.cjs → chunk-5FBQOMMT.cjs} +26 -26
  68. package/dist/{chunk-27PZV5BR.cjs → chunk-5N4Z7MTS.cjs} +4 -4
  69. package/dist/{chunk-KEWCUIQA.cjs → chunk-5WEV6YWA.cjs} +22 -22
  70. package/dist/chunk-5XOVVC5X.cjs +3281 -0
  71. package/dist/{chunk-HK5J7Q2W.cjs → chunk-6HLXVWXU.cjs} +9 -9
  72. package/dist/{chunk-7JG47RW4.cjs → chunk-6LQT4WJ5.cjs} +25 -25
  73. package/dist/{chunk-OCVTI6X4.cjs → chunk-6YTWOUFD.cjs} +329 -36
  74. package/dist/{chunk-W7IQCAVN.cjs → chunk-7F6W6HKL.cjs} +11 -11
  75. package/dist/{chunk-F2DCJXDM.cjs → chunk-7L6KYU5A.cjs} +21 -21
  76. package/dist/{chunk-GTGR6LPR.cjs → chunk-A4GIN4FE.cjs} +17 -17
  77. package/dist/{chunk-B2CETSR6.cjs → chunk-A4US7SA7.cjs} +5 -5
  78. package/dist/{chunk-3DIF2YYW.cjs → chunk-AOXPBLPW.cjs} +10 -10
  79. package/dist/{chunk-7TTR4UF5.cjs → chunk-ATI45Z4M.cjs} +2 -2
  80. package/dist/{chunk-5BFCIX2V.cjs → chunk-CPPMO4IQ.cjs} +434 -148
  81. package/dist/{chunk-AYZZQ6AC.cjs → chunk-CZ5KGF6Q.cjs} +9 -9
  82. package/dist/{chunk-7THJ3ZBK.cjs → chunk-D4I35MCE.cjs} +2 -2
  83. package/dist/{chunk-MCPPFRLN.cjs → chunk-DCGAAN3Z.cjs} +2 -2
  84. package/dist/{chunk-VABL6CVX.cjs → chunk-DEY36N37.cjs} +21 -21
  85. package/dist/{chunk-RNCKGJCC.cjs → chunk-DXHXD3DK.cjs} +3 -3
  86. package/dist/{chunk-A56ZGMVZ.cjs → chunk-E7B45DBZ.cjs} +11 -11
  87. package/dist/{chunk-DOR6L4MT.cjs → chunk-EJC6EAC5.cjs} +18 -18
  88. package/dist/{chunk-UPGNM7MA.cjs → chunk-EULJOOMA.cjs} +11 -11
  89. package/dist/{chunk-G4AZL4GO.cjs → chunk-EYM6LEIF.cjs} +474 -70
  90. package/dist/{chunk-NJ4X6XGV.cjs → chunk-EZTYX2GH.cjs} +5 -5
  91. package/dist/chunk-FDD4UP73.cjs +521 -0
  92. package/dist/{chunk-WJ3VH2Q4.cjs → chunk-GEAIGM3J.cjs} +110 -615
  93. package/dist/{chunk-P3SBHF43.cjs → chunk-GRUYVXTS.cjs} +2 -2
  94. package/dist/{chunk-NX4Z5LMS.cjs → chunk-H3SZXND5.cjs} +5 -5
  95. package/dist/{chunk-EE4S4TOE.cjs → chunk-HS45TOFJ.cjs} +21 -21
  96. package/dist/chunk-INGOG6OV.cjs +899 -0
  97. package/dist/{chunk-UDKA6DGT.cjs → chunk-J3CDXZHF.cjs} +4 -4
  98. package/dist/{chunk-YO6G7TKI.cjs → chunk-JAU5ADEU.cjs} +11 -11
  99. package/dist/{chunk-22LBK4GA.cjs → chunk-JQEBSHX3.cjs} +4 -4
  100. package/dist/{chunk-RXX3U7VQ.cjs → chunk-KLXGLMFU.cjs} +10 -10
  101. package/dist/chunk-KVOX36J3.cjs +327 -0
  102. package/dist/chunk-L6BGNHFL.cjs +139 -0
  103. package/dist/{chunk-GMER35L3.cjs → chunk-L7TB7PU5.cjs} +20 -20
  104. package/dist/{chunk-AFXYNBL2.cjs → chunk-LBTRYEM2.cjs} +4 -4
  105. package/dist/{chunk-WYYCKIOD.cjs → chunk-LLULNJSP.cjs} +11 -11
  106. package/dist/{chunk-J27XOSLP.cjs → chunk-LSO46AFV.cjs} +8 -8
  107. package/dist/{chunk-5XJO45ES.cjs → chunk-LZ2KJ7ZX.cjs} +11 -11
  108. package/dist/chunk-M4IQ5LIZ.cjs +422 -0
  109. package/dist/{chunk-Y2KIUKJF.cjs → chunk-MPDHDKYZ.cjs} +11 -11
  110. package/dist/{chunk-4EMPKRZU.cjs → chunk-MRQ42ZJE.cjs} +3 -3
  111. package/dist/{chunk-EU5D2MF4.cjs → chunk-MYV4KZWP.cjs} +9 -9
  112. package/dist/{chunk-XD7KN4UN.cjs → chunk-MZXVLC24.cjs} +6 -6
  113. package/dist/{chunk-PPSONARU.cjs → chunk-NLBVDFIR.cjs} +41 -2
  114. package/dist/{chunk-L3PEGMGM.cjs → chunk-NY3TBZY4.cjs} +33 -33
  115. package/dist/{chunk-6YNYXXB6.cjs → chunk-OGVVSFAR.cjs} +3 -3
  116. package/dist/{chunk-MLV7QLB6.cjs → chunk-OMTQIQMN.cjs} +6 -6
  117. package/dist/{chunk-BEEOSNK7.cjs → chunk-PEJJ6TXJ.cjs} +15 -144
  118. package/dist/{chunk-SOKOWUF5.cjs → chunk-PPGWHIU7.cjs} +2 -2
  119. package/dist/{chunk-IELWOM2J.cjs → chunk-PPO6SDAN.cjs} +6 -6
  120. package/dist/{chunk-6JTZZCSL.cjs → chunk-PUMKX5F2.cjs} +3 -3
  121. package/dist/{chunk-RFOXFY2U.cjs → chunk-PXBYWCNB.cjs} +190 -799
  122. package/dist/{chunk-3BYXOISI.cjs → chunk-Q3HB3IX6.cjs} +4 -4
  123. package/dist/{chunk-RXCOVONX.cjs → chunk-RBMUOIXE.cjs} +289 -34
  124. package/dist/{chunk-MSBNHCSE.cjs → chunk-RJHGCUUD.cjs} +6 -6
  125. package/dist/{chunk-I6VG7F6Z.cjs → chunk-RSONDMYW.cjs} +708 -141
  126. package/dist/{chunk-GZDNPHMT.cjs → chunk-SHMPFCUE.cjs} +19 -19
  127. package/dist/{chunk-ZIBVCOW6.cjs → chunk-SN4FCXFC.cjs} +19 -19
  128. package/dist/{chunk-7KM52NMN.cjs → chunk-SN5T7WYO.cjs} +2 -2
  129. package/dist/{chunk-7MSZR65Z.cjs → chunk-SQJZGVDR.cjs} +7 -7
  130. package/dist/chunk-SYABFMD7.cjs +633 -0
  131. package/dist/{chunk-2RRFEYFH.cjs → chunk-TICB3MAC.cjs} +16 -16
  132. package/dist/{chunk-AOOKHUV5.cjs → chunk-U7Z7XYR2.cjs} +5 -5
  133. package/dist/{chunk-JEWQAXVG.cjs → chunk-UA2THQFV.cjs} +6 -6
  134. package/dist/{chunk-LHZPAHU3.cjs → chunk-VIK4L2YF.cjs} +112 -521
  135. package/dist/{chunk-4YWMAQ4J.cjs → chunk-VM2Y6BDY.cjs} +4 -4
  136. package/dist/{chunk-IRRKE2ZE.cjs → chunk-VMS3KWYI.cjs} +21 -21
  137. package/dist/{chunk-4SLARW6F.cjs → chunk-VU5NUD46.cjs} +17 -17
  138. package/dist/{chunk-XHY6TVYG.cjs → chunk-VV5CVOF7.cjs} +13 -13
  139. package/dist/{chunk-CCIBPGPZ.cjs → chunk-VYSAWPSS.cjs} +57 -57
  140. package/dist/{chunk-TTNEMQ2A.cjs → chunk-W7YRWEWQ.cjs} +22 -22
  141. package/dist/{chunk-C7MUOGEW.cjs → chunk-X7R5SY62.cjs} +6 -6
  142. package/dist/{chunk-ILR5KBMB.cjs → chunk-XOK3KTSS.cjs} +6 -6
  143. package/dist/{chunk-2CZM2I3T.cjs → chunk-XUIX45VU.cjs} +19 -19
  144. package/dist/{chunk-TGRMPS3A.cjs → chunk-XWH46PVJ.cjs} +165 -43
  145. package/dist/{chunk-WQYXXECR.cjs → chunk-Y5XVMK3K.cjs} +6 -6
  146. package/dist/{chunk-AK4TX2WG.cjs → chunk-YCNKEDTG.cjs} +13 -13
  147. package/dist/{chunk-PJJB24DU.cjs → chunk-YEF7SE3X.cjs} +20 -20
  148. package/dist/{chunk-RVLV4XW6.cjs → chunk-YMTVPMU3.cjs} +22 -22
  149. package/dist/data/index.cjs +2 -2
  150. package/dist/entries/autograph-lazy.cjs +2 -2
  151. package/dist/entries/charts/acoustictransport.cjs +3 -3
  152. package/dist/entries/charts/analysischarts.cjs +3 -3
  153. package/dist/entries/charts/astrocharts.cjs +3 -3
  154. package/dist/entries/charts/bars.cjs +3 -3
  155. package/dist/entries/charts/bayesiancharts.cjs +3 -3
  156. package/dist/entries/charts/biocharts.cjs +3 -3
  157. package/dist/entries/charts/biologycharts.cjs +11 -3
  158. package/dist/entries/charts/biologycharts.d.ts +1 -1
  159. package/dist/entries/charts/biologycharts.js +3 -2
  160. package/dist/entries/charts/business.cjs +3 -3
  161. package/dist/entries/charts/carecharts.cjs +3 -3
  162. package/dist/entries/charts/chemistrycharts.cjs +3 -3
  163. package/dist/entries/charts/civicscharts.cjs +3 -3
  164. package/dist/entries/charts/clinicalcharts.cjs +3 -3
  165. package/dist/entries/charts/comparison.cjs +3 -3
  166. package/dist/entries/charts/demography.cjs +3 -3
  167. package/dist/entries/charts/density.cjs +3 -3
  168. package/dist/entries/charts/diagrams.cjs +3 -3
  169. package/dist/entries/charts/distribution.cjs +3 -3
  170. package/dist/entries/charts/doecharts.cjs +13 -3
  171. package/dist/entries/charts/doecharts.d.ts +1 -1
  172. package/dist/entries/charts/doecharts.js +2 -1
  173. package/dist/entries/charts/earthscience.cjs +3 -3
  174. package/dist/entries/charts/economicscharts.cjs +3 -3
  175. package/dist/entries/charts/energycharts.cjs +3 -3
  176. package/dist/entries/charts/engineering.cjs +3 -3
  177. package/dist/entries/charts/fieldcharts.cjs +7 -3
  178. package/dist/entries/charts/fieldcharts.d.ts +1 -1
  179. package/dist/entries/charts/fieldcharts.js +3 -2
  180. package/dist/entries/charts/financial.cjs +3 -3
  181. package/dist/entries/charts/flow.cjs +3 -3
  182. package/dist/entries/charts/frameworks.cjs +3 -3
  183. package/dist/entries/charts/genomics.cjs +3 -3
  184. package/dist/entries/charts/geoflows.cjs +3 -3
  185. package/dist/entries/charts/geomaps.cjs +3 -3
  186. package/dist/entries/charts/geosciencecharts.cjs +3 -3
  187. package/dist/entries/charts/hierarchy.cjs +3 -3
  188. package/dist/entries/charts/indicators.cjs +3 -3
  189. package/dist/entries/charts/inferencecharts.cjs +3 -3
  190. package/dist/entries/charts/layoutcharts.cjs +3 -3
  191. package/dist/entries/charts/lifescience.cjs +4 -4
  192. package/dist/entries/charts/linesareas.cjs +3 -3
  193. package/dist/entries/charts/logisticscharts.cjs +3 -3
  194. package/dist/entries/charts/machinecharts.cjs +7 -3
  195. package/dist/entries/charts/machinecharts.d.ts +1 -1
  196. package/dist/entries/charts/machinecharts.js +2 -1
  197. package/dist/entries/charts/massive.cjs +3 -3
  198. package/dist/entries/charts/mathematical.cjs +3 -3
  199. package/dist/entries/charts/matrix.cjs +3 -3
  200. package/dist/entries/charts/medicalcharts.cjs +4 -4
  201. package/dist/entries/charts/mlcharts.cjs +4 -4
  202. package/dist/entries/charts/modelcharts.cjs +6 -5
  203. package/dist/entries/charts/multivariate.cjs +3 -3
  204. package/dist/entries/charts/musiccharts.cjs +3 -3
  205. package/dist/entries/charts/network.cjs +3 -3
  206. package/dist/entries/charts/physicscharts.cjs +3 -3
  207. package/dist/entries/charts/pictorial.cjs +4 -4
  208. package/dist/entries/charts/portfoliocharts.cjs +3 -3
  209. package/dist/entries/charts/productcharts.cjs +3 -3
  210. package/dist/entries/charts/proportion.cjs +3 -3
  211. package/dist/entries/charts/qualitycharts.cjs +3 -3
  212. package/dist/entries/charts/radial.cjs +3 -3
  213. package/dist/entries/charts/reliabilitycharts.cjs +5 -3
  214. package/dist/entries/charts/scatter.cjs +3 -3
  215. package/dist/entries/charts/scientific.cjs +3 -3
  216. package/dist/entries/charts/seriescharts.cjs +3 -3
  217. package/dist/entries/charts/signals.cjs +7 -3
  218. package/dist/entries/charts/signals.d.ts +1 -1
  219. package/dist/entries/charts/signals.js +2 -1
  220. package/dist/entries/charts/softwarediagrams.cjs +21 -3
  221. package/dist/entries/charts/softwarediagrams.d.ts +1 -1
  222. package/dist/entries/charts/softwarediagrams.js +4 -2
  223. package/dist/entries/charts/sportscharts.cjs +13 -3
  224. package/dist/entries/charts/sportscharts.d.ts +1 -1
  225. package/dist/entries/charts/sportscharts.js +3 -1
  226. package/dist/entries/charts/statistics.cjs +6 -6
  227. package/dist/entries/charts/strategycharts.cjs +30 -3
  228. package/dist/entries/charts/strategycharts.d.ts +1 -1
  229. package/dist/entries/charts/strategycharts.js +6 -1
  230. package/dist/entries/charts/structure.cjs +3 -3
  231. package/dist/entries/charts/surveycharts.cjs +3 -3
  232. package/dist/entries/charts/systemscharts.cjs +3 -3
  233. package/dist/entries/charts/textcharts.cjs +5 -5
  234. package/dist/entries/charts/thematicmaps.cjs +4 -4
  235. package/dist/entries/charts/threebars.cjs +3 -3
  236. package/dist/entries/charts/threefields.cjs +53 -0
  237. package/dist/entries/charts/threefields.d.ts +1 -0
  238. package/dist/entries/charts/threefields.js +6 -0
  239. package/dist/entries/charts/threeglobe.cjs +3 -3
  240. package/dist/entries/charts/threenetwork.cjs +3 -3
  241. package/dist/entries/charts/threestrata.cjs +3 -3
  242. package/dist/entries/charts/threesurfaces.cjs +7 -3
  243. package/dist/entries/charts/threesurfaces.d.ts +1 -1
  244. package/dist/entries/charts/threesurfaces.js +2 -1
  245. package/dist/entries/charts/threevolume.cjs +4 -4
  246. package/dist/entries/charts/timeline.cjs +3 -3
  247. package/dist/entries/charts/tracecharts.cjs +3 -3
  248. package/dist/entries/charts/trackscharts.cjs +3 -3
  249. package/dist/entries/charts/tradingcharts.cjs +6 -4
  250. package/dist/entries/charts/tradingcharts.d.ts +1 -1
  251. package/dist/entries/charts/tradingcharts.js +2 -1
  252. package/dist/entries/three.cjs +60 -20
  253. package/dist/entries/three.d.ts +1 -1
  254. package/dist/entries/three.js +7 -1
  255. package/dist/index.cjs +258 -97
  256. package/dist/index.d.cts +1953 -10
  257. package/dist/index.d.ts +1953 -10
  258. package/dist/index.js +26 -5
  259. package/dist/page/index.cjs +2 -2
  260. package/dist/react/components.js +58 -1
  261. package/dist/react/index.cjs +135 -92
  262. package/dist/react/index.d.ts +1 -1
  263. package/dist/react/index.js +2 -2
  264. package/package.json +1 -1
  265. package/dist/AutoGraph-XLBJQDRB.cjs +0 -140
  266. package/dist/catalog-O7XGDD2H.cjs +0 -137
  267. package/dist/chunk-77K2HTRC.cjs +0 -3220
  268. package/dist/chunk-XEK47TVD.cjs +0 -323
  269. /package/dist/{chunk-UMEKIIHJ.cjs → chunk-LNWTC72Y.cjs} +0 -0
@@ -0,0 +1,504 @@
1
+ import { ChartFamily, DataShape, Dimension, Orientation } from "../../core/enums.js";
2
+ import { ComponentGrouping, ComponentInterfaceForm, ComponentLinkKind, ComponentNodeKind, SoftwareRouting } from "./softwareEnums.js";
3
+ import { SoftwareDiagram } from "./SoftwareDiagram.js";
4
+ import { SoftwareGraph } from "./SoftwareGraph.js";
5
+ import { SoftwareLayers } from "./SoftwareLayers.js";
6
+ import { SoftwarePlacer } from "./SoftwarePlacer.js";
7
+ import { SoftwareSamples } from "./SoftwareSamples.js";
8
+ import { SoftwareShapes } from "./SoftwareShapes.js";
9
+ import { SoftwareText } from "./SoftwareText.js";
10
+ import { SoftwareWiring } from "./SoftwareWiring.js";
11
+ // src/charts/softwarediagrams/ComponentDiagram.ts
12
+ var SIZE = 10.5;
13
+ var FACE = 10;
14
+ var BALL = 5;
15
+ var SOCKET = 8;
16
+ var PORT = 3.5;
17
+ var PAD = 8;
18
+ var TAB = 16;
19
+ /** How far an interface name may reach past the drawing along the flow. */
20
+ var REACH = 40;
21
+ var { Provides, Requires, Dependency } = ComponentLinkKind;
22
+ var stated = (raw, column) => String(raw[column] ?? "").toLowerCase();
23
+ var apart = (a, b, by = 0) => a[1] + by < b[0] || b[1] + by < a[0];
24
+ var list = (names) => names.join(", ") || "none";
25
+ /**
26
+ * UML component diagram: components wired through the interfaces they provide (a ball) and require (a socket), with
27
+ * ports where interfaces attach, dashed dependencies, and packages as enclosing frames. Use it to show how the parts
28
+ * of a system plug together. For the C4 view of the same system use the architecture diagram.
29
+ */
30
+ var ComponentDiagram = class ComponentDiagram extends SoftwareDiagram {
31
+ static meta = {
32
+ id: "uml-component-diagram",
33
+ name: "UML component diagram",
34
+ family: ChartFamily.Network,
35
+ dimension: Dimension.Two,
36
+ shape: DataShape.Graph,
37
+ description: "Wires components through provided and required interfaces in ball and socket notation, with ports, dependencies and package frames.",
38
+ tags: [
39
+ "uml",
40
+ "component",
41
+ "interface",
42
+ "ball and socket",
43
+ "lollipop",
44
+ "port",
45
+ "package",
46
+ "software"
47
+ ],
48
+ sample: (seed) => SoftwareSamples.components(seed),
49
+ variants: {
50
+ orientation: [Orientation.Horizontal, Orientation.Vertical],
51
+ routing: [SoftwareRouting.Curved, SoftwareRouting.Orthogonal],
52
+ interfaces: [ComponentInterfaceForm.BallSocket, ComponentInterfaceForm.Dependency],
53
+ grouping: [ComponentGrouping.Frames, ComponentGrouping.Flat]
54
+ }
55
+ };
56
+ defaults() {
57
+ return {
58
+ nodeId: "id",
59
+ label: "label",
60
+ kind: "kind",
61
+ group: "package",
62
+ source: "source",
63
+ target: "target",
64
+ linkKind: "kind",
65
+ linkLabel: "label",
66
+ orientation: Orientation.Horizontal,
67
+ routing: SoftwareRouting.Curved,
68
+ interfaces: ComponentInterfaceForm.BallSocket,
69
+ grouping: ComponentGrouping.Frames,
70
+ ports: true
71
+ };
72
+ }
73
+ legendItems() {
74
+ return this.options.grouping === ComponentGrouping.Frames ? [] : this.palette.items();
75
+ }
76
+ #graph() {
77
+ const { nodeId, source, target } = this.options;
78
+ return SoftwareGraph.read(this.options.data, {
79
+ nodeId,
80
+ source,
81
+ target
82
+ });
83
+ }
84
+ table() {
85
+ const { source, target, linkKind, linkLabel } = this.options;
86
+ return this.rowsOf(this.#graph().arcs.map((arc) => arc.raw), [.../* @__PURE__ */ new Set([
87
+ source,
88
+ target,
89
+ linkKind,
90
+ linkLabel
91
+ ])]);
92
+ }
93
+ /**
94
+ * Components, interfaces and the links between them. A link between two components is a dependency, one between a
95
+ * component and an interface provides or requires it whichever end names the component, and the rest are dropped.
96
+ */
97
+ static model(graph, columns) {
98
+ const offered = new Set(graph.arcs.filter((arc) => [Provides, Requires].includes(stated(arc.raw, columns.linkKind))).map((arc) => arc.target));
99
+ const parts = graph.vertices.map(({ id, raw }) => {
100
+ const kind = stated(raw, columns.kind);
101
+ return {
102
+ id,
103
+ raw,
104
+ label: SoftwareGraph.text(raw[columns.label]) ?? id,
105
+ face: kind === ComponentNodeKind.Interface || !kind && offered.has(id),
106
+ group: SoftwareGraph.text(raw[columns.group]) ?? "",
107
+ shared: false
108
+ };
109
+ });
110
+ const byId = new Map(parts.map((part) => [part.id, part]));
111
+ const joins = graph.arcs.flatMap((arc) => {
112
+ const a = byId.get(arc.source), b = byId.get(arc.target);
113
+ if (a === b || a.face && b.face) return [];
114
+ if (!a.face && !b.face) return [{
115
+ key: arc.key,
116
+ kind: Dependency,
117
+ component: a.id,
118
+ other: b.id,
119
+ raw: arc.raw
120
+ }];
121
+ const [component, face] = a.face ? [b, a] : [a, b];
122
+ return [{
123
+ key: arc.key,
124
+ kind: stated(arc.raw, columns.linkKind) === Provides ? Provides : Requires,
125
+ component: component.id,
126
+ other: face.id,
127
+ raw: arc.raw
128
+ }];
129
+ });
130
+ for (const part of parts) {
131
+ if (!part.face) continue;
132
+ const users = joins.filter((join) => join.other === part.id), owner = users.find((join) => join.kind === Provides) ?? users[0];
133
+ part.group = owner ? byId.get(owner.component).group : "";
134
+ part.shared = !users.some((join) => join.kind === Provides) || !users.some((join) => join.kind === Requires) || users.some((join) => byId.get(join.component).group !== part.group);
135
+ }
136
+ return {
137
+ parts,
138
+ joins
139
+ };
140
+ }
141
+ /**
142
+ * The lane across the flow that each package takes. Packages share a lane when their frames sit at least a rank
143
+ * apart along the flow and neither frame takes in an interface of the other, so frames in one lane never touch.
144
+ */
145
+ static lanes(spans) {
146
+ const lanes = [];
147
+ for (const span of spans) {
148
+ const fits = (other) => (!other.frame || apart(span.owned, other.frame)) && (!span.frame || apart(other.owned, span.frame)) && (!span.frame || !other.frame || apart(span.frame, other.frame, 1));
149
+ const free = lanes.find((lane) => lane.every(fits));
150
+ if (free) free.push(span);
151
+ else lanes.push([span]);
152
+ }
153
+ return new Map(lanes.flatMap((lane, at) => lane.map((span) => [span.name, at])));
154
+ }
155
+ /** The half circle of a required interface, cupped around the ball at `centre` and open along `angle`, the way its connector runs. */
156
+ static socket([cx, cy], angle, radius = SOCKET) {
157
+ const end = (turn) => `${+(cx + radius * Math.cos(angle + turn)).toFixed(2)},${+(cy + radius * Math.sin(angle + turn)).toFixed(2)}`;
158
+ return `M${end(Math.PI / 2)}A${radius},${radius} 0 0 1 ${end(-Math.PI / 2)}`;
159
+ }
160
+ draw(ctx) {
161
+ const { orientation, routing, interfaces, grouping, ports, label, kind, group, linkKind, linkLabel } = this.options;
162
+ const vertical = orientation === Orientation.Vertical, socketed = interfaces === ComponentInterfaceForm.BallSocket;
163
+ const { theme, palette } = ctx, ink = theme.inkSecondary;
164
+ const { parts, joins } = ComponentDiagram.model(this.#graph(), {
165
+ label,
166
+ kind,
167
+ group,
168
+ linkKind
169
+ });
170
+ const byId = new Map(parts.map((part) => [part.id, part]));
171
+ const links = joins.map((join) => join.kind === Provides ? {
172
+ source: join.other,
173
+ target: join.component
174
+ } : {
175
+ source: join.component,
176
+ target: join.other
177
+ });
178
+ const framed = grouping === ComponentGrouping.Frames && parts.some((part) => part.group);
179
+ const rank = SoftwareLayers.ranks(parts.map((part) => part.id), links);
180
+ const reach = (members) => members.length ? [Math.min(...members.map((part) => rank.get(part.id))), Math.max(...members.map((part) => rank.get(part.id)))] : null;
181
+ const lanes = ComponentDiagram.lanes(framed ? [...new Set(parts.map((part) => part.group))].map((name) => {
182
+ const owned = parts.filter((part) => part.group === name);
183
+ return {
184
+ name,
185
+ owned: reach(owned),
186
+ frame: name ? reach(owned.filter((part) => !part.shared)) : null
187
+ };
188
+ }) : []);
189
+ const lane = (part) => lanes.get(part.group) ?? 0, count = Math.max(1, ...[...lanes.values()].map((at) => at + 1));
190
+ const half = socketed ? SOCKET : BALL;
191
+ const lines = new Map(parts.map((part) => [part.id, part.face ? [SoftwareText.fit(part.label, framed && !vertical ? 64 : 78, FACE)] : SoftwareText.wrap(part.label, 96, SIZE)]));
192
+ const widest = (id, size) => Math.max(0, ...lines.get(id).map((line) => SoftwareText.width(line, size)));
193
+ const words = joins.map((join) => join.kind === Dependency ? SoftwareText.fit(SoftwareGraph.text(join.raw[linkLabel]) ?? "", 80, 10) : "");
194
+ const edge = framed ? 16 : 0;
195
+ const plan = SoftwareWiring.build({
196
+ nodes: parts.map((part) => {
197
+ if (part.face) {
198
+ const room = vertical ? widest(part.id, FACE) + 8 : 26;
199
+ return {
200
+ id: part.id,
201
+ along: 2 * half,
202
+ across: 2 * half,
203
+ slot: 2 * half + room,
204
+ shift: vertical ? -room / 2 : 0,
205
+ lane: lane(part)
206
+ };
207
+ }
208
+ const width = Math.max(80, widest(part.id, SIZE) + 42), height = lines.get(part.id).length > 1 ? 44 : 32;
209
+ return {
210
+ id: part.id,
211
+ along: vertical ? height : width,
212
+ across: vertical ? width : height,
213
+ ports: "spread",
214
+ lane: lane(part)
215
+ };
216
+ }),
217
+ links,
218
+ vertical,
219
+ routing,
220
+ nodeGap: 16,
221
+ rankGap: vertical ? 30 : 34,
222
+ inset: 0,
223
+ labelRoom: words.map((text) => text ? SoftwareText.width(text, 10) + 16 : 0),
224
+ lanes: count,
225
+ lanePad: framed ? vertical ? 10 : 28 : 0,
226
+ laneMin: framed && vertical ? Array.from({ length: count }, (_, at) => Math.max(0, ...[...lanes].filter(([name, own]) => name && own === at).map(([name]) => Math.min(130, SoftwareText.width(name, SIZE, true)) + 32 + 6))) : void 0,
227
+ room: vertical ? {
228
+ length: ctx.plot.height - edge - (framed ? TAB : 0),
229
+ breadth: ctx.plot.width
230
+ } : {
231
+ length: ctx.plot.width - edge,
232
+ breadth: ctx.plot.height
233
+ }
234
+ });
235
+ const placer = this.placer(plan, vertical ? {
236
+ x0: 0,
237
+ y0: -40,
238
+ x1: plan.width,
239
+ y1: plan.height + REACH
240
+ } : {
241
+ x0: -40,
242
+ y0: 0,
243
+ x1: plan.width + REACH,
244
+ y1: plan.height
245
+ });
246
+ const shapes = [], balls = [], squares = /* @__PURE__ */ new Map(), labels = [];
247
+ /** The room each package's frame must enclose, and everything drawn outside the plan's own box. */
248
+ const held = /* @__PURE__ */ new Map(), loose = [];
249
+ const hold = (part, box) => {
250
+ if (!part.shared) held.set(part.group, [...held.get(part.group) ?? [], box]);
251
+ };
252
+ /** Tooltips of the interfaces nobody provides: with no ball to point at, their socket carries it. */
253
+ const bare = /* @__PURE__ */ new Map();
254
+ const naming = (id, sort) => joins.filter((join) => join.kind === sort && join.component === id).map((join) => byId.get(join.other).label);
255
+ const users = (id, sort) => joins.filter((join) => join.kind === sort && join.other === id).map((join) => byId.get(join.component).label);
256
+ for (const part of parts) {
257
+ const { x, y, width: w, height: h } = plan.boxes.get(part.id);
258
+ hold(part, {
259
+ x0: x - w / 2,
260
+ y0: y - h / 2,
261
+ x1: x + w / 2,
262
+ y1: y + h / 2
263
+ });
264
+ if (part.face) {
265
+ const text = lines.get(part.id)[0], tip = {
266
+ title: part.label,
267
+ rows: [["Provided by", list(users(part.id, Provides))], ["Required by", list(users(part.id, Requires))]]
268
+ };
269
+ if (!socketed || users(part.id, Provides).length) balls.push({
270
+ key: part.id,
271
+ raw: part.raw,
272
+ d: SoftwareShapes.ellipse(x, y, 4.25),
273
+ fill: theme.surface,
274
+ stroke: ink,
275
+ tip
276
+ });
277
+ else bare.set(part.id, tip);
278
+ const spots = vertical ? [[
279
+ "start",
280
+ x + half + 4,
281
+ y + 3.5
282
+ ]] : [[
283
+ "middle",
284
+ x,
285
+ y - half - 4
286
+ ], [
287
+ "middle",
288
+ x,
289
+ y + half + 11
290
+ ]];
291
+ const spot = text ? placer.claim(spots.map(([anchor, lx, ly]) => ({
292
+ anchor,
293
+ x: lx,
294
+ y: ly,
295
+ box: SoftwarePlacer.text(lx, ly, text, FACE, anchor)
296
+ }))) : null;
297
+ if (!spot) continue;
298
+ labels.push({
299
+ key: `${part.id}/name`,
300
+ x: spot.x,
301
+ y: spot.y,
302
+ text,
303
+ anchor: spot.anchor,
304
+ size: FACE,
305
+ halo: true
306
+ });
307
+ hold(part, spot.box);
308
+ loose.push(spot.box);
309
+ continue;
310
+ }
311
+ const fill = palette.color(part.group || "Component"), on = palette.inkOn(fill), text = lines.get(part.id), left = x - w / 2, top = y - h / 2;
312
+ shapes.push({
313
+ key: part.id,
314
+ raw: part.raw,
315
+ d: SoftwareShapes.rect(left, top, w, h, 2),
316
+ fill,
317
+ tip: {
318
+ title: part.label,
319
+ color: fill,
320
+ rows: [
321
+ ...part.group ? [["Package", part.group]] : [],
322
+ ["Provides", list(naming(part.id, Provides))],
323
+ ["Requires", list(naming(part.id, Requires))]
324
+ ]
325
+ }
326
+ });
327
+ const ix = left + w - 17, iy = top + 5;
328
+ shapes.push({
329
+ key: `${part.id}/icon`,
330
+ d: SoftwareShapes.rect(ix + 3, iy, 9, 11),
331
+ fill,
332
+ stroke: on,
333
+ strokeWidth: 1.2
334
+ });
335
+ shapes.push({
336
+ key: `${part.id}/tabs`,
337
+ d: `${SoftwareShapes.rect(ix, iy + 2, 6, 2.5)}${SoftwareShapes.rect(ix, iy + 6.5, 6, 2.5)}`,
338
+ fill,
339
+ stroke: on,
340
+ strokeWidth: 1.2
341
+ });
342
+ const centre = widest(part.id, SIZE) / 2 <= w / 2 - 20 ? x : x - 7;
343
+ text.forEach((line, i) => labels.push({
344
+ key: `${part.id}/${i}`,
345
+ x: centre,
346
+ y: y + 3.5 + (i - (text.length - 1) / 2) * 12,
347
+ text: line,
348
+ anchor: "middle",
349
+ size: SIZE,
350
+ weight: 600,
351
+ fill: on
352
+ }));
353
+ }
354
+ const port = ([px, py]) => {
355
+ if (ports) squares.set(`${px.toFixed(1)}/${py.toFixed(1)}`, {
356
+ key: `port/${squares.size}`,
357
+ d: SoftwareShapes.rect(px - PORT, py - PORT, 2 * PORT, 2 * PORT),
358
+ fill: theme.surface,
359
+ stroke: ink
360
+ });
361
+ };
362
+ const sockets = /* @__PURE__ */ new Map();
363
+ const wires = plan.wires.map((wire, i) => {
364
+ const join = joins[i], from = byId.get(join.component).label, to = byId.get(join.other).label;
365
+ const arrow = {
366
+ d: SoftwareShapes.arrow(wire.tip, wire.angle, 8, true),
367
+ fill: "none"
368
+ };
369
+ if (join.kind === Dependency) return {
370
+ key: join.key,
371
+ raw: join.raw,
372
+ d: wire.d,
373
+ dash: "5 4",
374
+ head: arrow,
375
+ tip: {
376
+ title: `${from} → ${to}`,
377
+ rows: [["Relation", words[i] || "dependency"]]
378
+ }
379
+ };
380
+ const face = plan.boxes.get(join.other), centre = [face.x, face.y];
381
+ if (join.kind === Requires) {
382
+ port(wire.points[0]);
383
+ const cup = ComponentDiagram.socket(centre, wire.angle);
384
+ if (socketed) sockets.set(cup, {
385
+ key: `${join.other}/socket/${sockets.size}`,
386
+ raw: byId.get(join.other).raw,
387
+ d: cup,
388
+ stroke: ink,
389
+ strokeWidth: 2,
390
+ tip: bare.get(join.other)
391
+ });
392
+ return {
393
+ key: join.key,
394
+ raw: join.raw,
395
+ d: wire.d,
396
+ dash: socketed ? void 0 : "5 4",
397
+ head: socketed ? void 0 : arrow,
398
+ tip: { title: `${from} requires ${to}` }
399
+ };
400
+ }
401
+ port(wire.tip);
402
+ const start = wire.points[0], away = Math.atan2(start[1] - centre[1], start[0] - centre[0]);
403
+ const stick = socketed ? SoftwareShapes.line([[centre[0] + BALL * Math.cos(away), centre[1] + BALL * Math.sin(away)], start]) : "";
404
+ return {
405
+ key: join.key,
406
+ raw: join.raw,
407
+ d: `${stick}${wire.d}`,
408
+ tip: { title: `${from} provides ${to}` }
409
+ };
410
+ });
411
+ const frames = [...held].flatMap(([name, boxes]) => {
412
+ if (!framed || !name) return [];
413
+ let x0 = Math.min(...boxes.map((box) => box.x0)) - PAD, x1 = Math.max(...boxes.map((box) => box.x1)) + PAD;
414
+ const y0 = Math.min(...boxes.map((box) => box.y0)) - PAD, y1 = Math.max(...boxes.map((box) => box.y1)) + PAD, band = plan.lanes[lanes.get(name)];
415
+ const title = SoftwareText.fit(name, vertical ? 130 : x1 - x0 - 16, SIZE, true), tab = SoftwareText.width(title, SIZE, true) + 16;
416
+ if (vertical) {
417
+ x1 = Math.max(x1, x0 + tab + 16);
418
+ const over = Math.max(0, Math.min(x1 - (band.start + band.size - 2), x0 - band.start - 2));
419
+ x0 -= over;
420
+ x1 -= over;
421
+ }
422
+ /** The tab slides along the frame's top edge to the first place no connector crosses. */
423
+ const spot = placer.claim(Array.from({ length: Math.floor(Math.max(0, x1 - x0 - tab) / 4) + 1 }, (_, k) => ({
424
+ at: x0 + k * 4,
425
+ box: {
426
+ x0: x0 + k * 4,
427
+ y0: y0 - TAB,
428
+ x1: x0 + k * 4 + tab,
429
+ y1: y0
430
+ }
431
+ })));
432
+ return [{
433
+ name,
434
+ title,
435
+ x0,
436
+ y0,
437
+ x1,
438
+ y1,
439
+ tab,
440
+ at: spot?.at ?? x0
441
+ }];
442
+ });
443
+ const marks = this.wireLabels(placer, plan.wires, (i) => words[i]);
444
+ const all = [
445
+ {
446
+ x0: 0,
447
+ y0: 0,
448
+ x1: plan.width,
449
+ y1: plan.height
450
+ },
451
+ ...frames.map((frame) => ({
452
+ ...frame,
453
+ y0: frame.y0 - TAB
454
+ })),
455
+ ...loose
456
+ ];
457
+ const x0 = Math.min(...all.map((box) => box.x0)), y0 = Math.min(...all.map((box) => box.y0));
458
+ const body = this.stage(ctx, Math.max(...all.map((box) => box.x1)) - x0, Math.max(...all.map((box) => box.y1)) - y0).nest(`translate(${+(-x0).toFixed(2)},${+(-y0).toFixed(2)})`, "body");
459
+ this.paths(body, ctx, "frames", frames.map((frame) => ({
460
+ key: frame.name,
461
+ fill: theme.grid,
462
+ opacity: .45,
463
+ d: SoftwareShapes.polygon([
464
+ [frame.at, frame.y0],
465
+ [frame.at, frame.y0 - TAB],
466
+ [frame.at + frame.tab, frame.y0 - TAB],
467
+ [frame.at + frame.tab, frame.y0],
468
+ [frame.x1, frame.y0],
469
+ [frame.x1, frame.y1],
470
+ [frame.x0, frame.y1],
471
+ [frame.x0, frame.y0]
472
+ ])
473
+ })));
474
+ this.wires(body, ctx, wires);
475
+ /** Each tab again over the connectors, on a surface underlay, so a line that must cross a tab runs behind the package name. */
476
+ this.paths(body, ctx, "frame-tabs", frames.flatMap((frame) => {
477
+ const d = SoftwareShapes.rect(frame.at, frame.y0 - TAB, frame.tab, TAB);
478
+ return [{
479
+ key: `${frame.name}/under`,
480
+ d,
481
+ fill: theme.surface
482
+ }, {
483
+ key: frame.name,
484
+ d,
485
+ fill: theme.grid,
486
+ opacity: .45
487
+ }];
488
+ }));
489
+ this.texts(body, ctx, "frame-names", frames.map((frame) => ({
490
+ key: frame.name,
491
+ x: frame.at + PAD,
492
+ y: frame.y0 - 4.5,
493
+ text: frame.title,
494
+ size: SIZE,
495
+ weight: 600
496
+ })));
497
+ this.paths(body, ctx, "nodes", shapes);
498
+ this.paths(body, ctx, "interfaces", [...sockets.values(), ...balls]);
499
+ this.paths(body, ctx, "ports", [...squares.values()]);
500
+ this.texts(body, ctx, "node-text", labels);
501
+ this.texts(body, ctx, "wire-text", marks);
502
+ }
503
+ };
504
+ export { ComponentDiagram };