@peter.prib/renderengine 0.0.0-stage → 0.2.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 (451) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -2
  3. package/REFERENCE.md +2198 -0
  4. package/dist/renderengine-workspace.umd.js +46905 -0
  5. package/dist/renderengine.umd.js +42223 -0
  6. package/examples/archimate.html +66 -0
  7. package/examples/diagram-editor.html +51 -0
  8. package/package.json +65 -4
  9. package/src/BaseRenderer.js +57 -0
  10. package/src/CanvasRenderer.js +194 -0
  11. package/src/Mat4.js +111 -0
  12. package/src/OrbitCamera.js +57 -0
  13. package/src/RendererFactory.js +50 -0
  14. package/src/SVGRenderer.js +439 -0
  15. package/src/archimate.js +723 -0
  16. package/src/archimateArchiFormat.js +1693 -0
  17. package/src/archimateArchiTypes.js +72 -0
  18. package/src/archimateArchive.js +140 -0
  19. package/src/archimateCSV.js +127 -0
  20. package/src/archimateDrawio.js +182 -0
  21. package/src/archimateExchangeFormat.js +546 -0
  22. package/src/archimateRelationshipTable.js +93 -0
  23. package/src/archimateSpecializations.js +161 -0
  24. package/src/chartCatalog.js +589 -0
  25. package/src/charting/ArchimateDiagramEditor.js +1624 -0
  26. package/src/charting/ArchimateSpecializationSelector.js +134 -0
  27. package/src/charting/Axis.js +68 -0
  28. package/src/charting/CameraSeeder.js +30 -0
  29. package/src/charting/CatalogDialog.js +92 -0
  30. package/src/charting/Chart.js +37 -0
  31. package/src/charting/Chart3D.js +99 -0
  32. package/src/charting/ChartBox.js +80 -0
  33. package/src/charting/ChartData.js +27 -0
  34. package/src/charting/ChartRegistry.js +76 -0
  35. package/src/charting/CheckboxTreeSelector.js +304 -0
  36. package/src/charting/ColorField.js +107 -0
  37. package/src/charting/ColorPalette.js +88 -0
  38. package/src/charting/CommandHistory.js +176 -0
  39. package/src/charting/DataFilter.js +52 -0
  40. package/src/charting/Diagram.js +36 -0
  41. package/src/charting/Diagram3D.js +29 -0
  42. package/src/charting/DiagramClipboard.js +31 -0
  43. package/src/charting/DiagramEditor.js +3330 -0
  44. package/src/charting/DiagramEditorCommand.js +110 -0
  45. package/src/charting/DiagramEditorCommands.js +237 -0
  46. package/src/charting/DiagramEditorEdgeCommands.js +142 -0
  47. package/src/charting/DiagramEditorState.js +98 -0
  48. package/src/charting/DiagramRegistry.js +86 -0
  49. package/src/charting/DiagramTypeRegistry.js +326 -0
  50. package/src/charting/DiagramViewPropertiesDialog.js +46 -0
  51. package/src/charting/Edge.js +113 -0
  52. package/src/charting/ErrorBars.js +37 -0
  53. package/src/charting/FilterSystem.js +285 -0
  54. package/src/charting/FindReplaceDialog.js +139 -0
  55. package/src/charting/FormDialog.js +385 -0
  56. package/src/charting/Gauge.js +58 -0
  57. package/src/charting/Hierarchy.js +175 -0
  58. package/src/charting/HintPanel.js +86 -0
  59. package/src/charting/ImageSelector.js +148 -0
  60. package/src/charting/InteractionManager.js +725 -0
  61. package/src/charting/Legend.js +58 -0
  62. package/src/charting/MenuBar.js +62 -0
  63. package/src/charting/ModelFileFormat.js +115 -0
  64. package/src/charting/OrbitControls.js +77 -0
  65. package/src/charting/Palette.js +119 -0
  66. package/src/charting/PopupMenu.js +117 -0
  67. package/src/charting/PropertiesPanel.js +155 -0
  68. package/src/charting/PropertyListEditor.js +96 -0
  69. package/src/charting/PropertyLog.js +92 -0
  70. package/src/charting/SettingsCascade.js +93 -0
  71. package/src/charting/SettingsDialog.js +53 -0
  72. package/src/charting/SettingsManager.js +179 -0
  73. package/src/charting/SettingsViewPropertiesDialog.js +58 -0
  74. package/src/charting/ShapePaths.js +27 -0
  75. package/src/charting/Statistics.js +134 -0
  76. package/src/charting/TemplateCatalog.js +59 -0
  77. package/src/charting/TemplateLibrary.js +103 -0
  78. package/src/charting/TextStyle.js +168 -0
  79. package/src/charting/ViewFit.js +55 -0
  80. package/src/charting/ViewMenu.js +70 -0
  81. package/src/charting/ViewPropertiesDialog.js +77 -0
  82. package/src/charting/ViewTabStrip.js +81 -0
  83. package/src/charting/archimate/ArchiFileFormat.js +32 -0
  84. package/src/charting/archimate/ArchimateCanvasEditor.js +815 -0
  85. package/src/charting/archimate/ArchimateCsvFileFormat.js +35 -0
  86. package/src/charting/archimate/ArchimateEdge.js +137 -0
  87. package/src/charting/archimate/ArchimateElementTemplate.js +195 -0
  88. package/src/charting/archimate/ArchimatePalette.js +102 -0
  89. package/src/charting/archimate/CsvImportDialog.js +105 -0
  90. package/src/charting/archimate/CustomViewpoints.js +74 -0
  91. package/src/charting/archimate/DerivedEdge.js +29 -0
  92. package/src/charting/archimate/DrawioFileFormat.js +24 -0
  93. package/src/charting/archimate/ElementFilterRule.js +21 -0
  94. package/src/charting/archimate/ExchangeFileFormat.js +28 -0
  95. package/src/charting/archimate/ViewGroupTemplate.js +137 -0
  96. package/src/charting/archimate/ViewLineEdge.js +84 -0
  97. package/src/charting/archimate/ViewpointRule.js +45 -0
  98. package/src/charting/archimate/archimateFileFormats.js +12 -0
  99. package/src/charting/archimate/archimateNames.js +5 -0
  100. package/src/charting/archimate/csvMapping.js +122 -0
  101. package/src/charting/archimate/elementMenuItems.js +32 -0
  102. package/src/charting/archimate/elementProperties.js +146 -0
  103. package/src/charting/archimate/elementTypeChoices.js +7 -0
  104. package/src/charting/archimate/elementTypeGroups.js +19 -0
  105. package/src/charting/archimate/index.js +17 -0
  106. package/src/charting/archimate/specializationCatalogDialog.js +64 -0
  107. package/src/charting/archimate/typeGlyph.js +29 -0
  108. package/src/charting/arrangement/Arrangement.js +112 -0
  109. package/src/charting/arrangement/ArrangementCommand.js +29 -0
  110. package/src/charting/arrangement/BackgroundCommand.js +41 -0
  111. package/src/charting/arrangement/BackgroundGroup.js +18 -0
  112. package/src/charting/arrangement/GroupCommand.js +46 -0
  113. package/src/charting/arrangement/ItemGroup.js +62 -0
  114. package/src/charting/arrangement/LockCommand.js +32 -0
  115. package/src/charting/arrangement/UngroupCommand.js +27 -0
  116. package/src/charting/arrangement/alignment.js +88 -0
  117. package/src/charting/arrangement/arrangeMenuItems.js +25 -0
  118. package/src/charting/arrangement/index.js +11 -0
  119. package/src/charting/arrangement/layouts.js +233 -0
  120. package/src/charting/canvas/ArchiHint.js +78 -0
  121. package/src/charting/canvas/CanvasBoxKind.js +39 -0
  122. package/src/charting/canvas/CanvasPalette.js +49 -0
  123. package/src/charting/canvas/CanvasTemplateLibrary.js +61 -0
  124. package/src/charting/canvas/CanvasTemplateMenu.js +151 -0
  125. package/src/charting/canvas/EditHintCommand.js +28 -0
  126. package/src/charting/canvas/canvasBoxKinds.js +27 -0
  127. package/src/charting/canvas/canvasBoxMenuItems.js +40 -0
  128. package/src/charting/canvas/defaultCanvasTemplates.js +186 -0
  129. package/src/charting/canvas/diagramBoxKinds.js +12 -0
  130. package/src/charting/canvas/hintMenuItems.js +49 -0
  131. package/src/charting/charts/ArcGauge.js +55 -0
  132. package/src/charting/charts/AreaChart.js +71 -0
  133. package/src/charting/charts/BarChart.js +80 -0
  134. package/src/charting/charts/BarChart3D.js +56 -0
  135. package/src/charting/charts/BarChart3DOrbit.js +53 -0
  136. package/src/charting/charts/BarChartBase.js +70 -0
  137. package/src/charting/charts/BarGauge.js +42 -0
  138. package/src/charting/charts/BoxPlotChart.js +41 -0
  139. package/src/charting/charts/BubbleChart.js +99 -0
  140. package/src/charting/charts/BubbleChart3D.js +78 -0
  141. package/src/charting/charts/BulletGauge.js +87 -0
  142. package/src/charting/charts/CalendarHeatmapChart.js +204 -0
  143. package/src/charting/charts/CandlestickChart.js +54 -0
  144. package/src/charting/charts/ChordDiagram.js +130 -0
  145. package/src/charting/charts/DensityChart.js +73 -0
  146. package/src/charting/charts/DialGauge.js +65 -0
  147. package/src/charting/charts/DonutChart.js +15 -0
  148. package/src/charting/charts/FunnelChart.js +47 -0
  149. package/src/charting/charts/GanttChart.js +201 -0
  150. package/src/charting/charts/GaugeChart.js +175 -0
  151. package/src/charting/charts/GeoMapChart.js +146 -0
  152. package/src/charting/charts/GroupedBarChart.js +88 -0
  153. package/src/charting/charts/GroupedDistributionChart.js +70 -0
  154. package/src/charting/charts/HeatmapChart.js +80 -0
  155. package/src/charting/charts/HierarchyChart.js +39 -0
  156. package/src/charting/charts/HistogramChart.js +45 -0
  157. package/src/charting/charts/KpiTile.js +72 -0
  158. package/src/charting/charts/LagPlotChart.js +41 -0
  159. package/src/charting/charts/LineChart.js +124 -0
  160. package/src/charting/charts/MultiRingGauge.js +54 -0
  161. package/src/charting/charts/OutlineChart.js +95 -0
  162. package/src/charting/charts/ParallelCoordinatesChart.js +130 -0
  163. package/src/charting/charts/PieChart.js +56 -0
  164. package/src/charting/charts/PipeChart.js +88 -0
  165. package/src/charting/charts/PopulationPyramidChart.js +106 -0
  166. package/src/charting/charts/QQPlotChart.js +64 -0
  167. package/src/charting/charts/RadarChart.js +76 -0
  168. package/src/charting/charts/RadialBarChart.js +96 -0
  169. package/src/charting/charts/RingGauge.js +23 -0
  170. package/src/charting/charts/SankeyDiagram.js +174 -0
  171. package/src/charting/charts/ScatterChart.js +104 -0
  172. package/src/charting/charts/StackedAreaChart.js +15 -0
  173. package/src/charting/charts/StackedBarChart.js +33 -0
  174. package/src/charting/charts/StackedBarChart3DOrbit.js +58 -0
  175. package/src/charting/charts/StreamGraphChart.js +131 -0
  176. package/src/charting/charts/SunburstChart.js +57 -0
  177. package/src/charting/charts/ThermometerGauge.js +43 -0
  178. package/src/charting/charts/TreemapChart.js +54 -0
  179. package/src/charting/charts/ViolinChart.js +37 -0
  180. package/src/charting/charts/WaterfallChart.js +66 -0
  181. package/src/charting/charts/WordCloudChart.js +104 -0
  182. package/src/charting/diagramModel/AddViewCommand.js +33 -0
  183. package/src/charting/diagramModel/DiagramModel.js +39 -0
  184. package/src/charting/diagramModel/DiagramModelSearch.js +22 -0
  185. package/src/charting/diagramModel/DiagramView.js +50 -0
  186. package/src/charting/diagramModel/ModelHistory.js +43 -0
  187. package/src/charting/diagramModel/ModelReport.js +153 -0
  188. package/src/charting/diagramModel/ModelSearch.js +223 -0
  189. package/src/charting/diagramModel/RemoveViewCommand.js +25 -0
  190. package/src/charting/diagramModel/RenameViewCommand.js +21 -0
  191. package/src/charting/diagramModel/ReplaceTextCommand.js +25 -0
  192. package/src/charting/diagramModel/ViewSetChecker.js +34 -0
  193. package/src/charting/diagramModel/ViewSetModel.js +243 -0
  194. package/src/charting/diagramModel/index.js +6 -0
  195. package/src/charting/diagramModel/nameTransforms.js +29 -0
  196. package/src/charting/diagrams/ArchimateCommands.js +141 -0
  197. package/src/charting/diagrams/ArchimateDiagram.js +263 -0
  198. package/src/charting/diagrams/ArchimateModel.js +1155 -0
  199. package/src/charting/diagrams/ArchimateModelChecker.js +125 -0
  200. package/src/charting/diagrams/ArchimateModelReport.js +128 -0
  201. package/src/charting/diagrams/ArchimateModelSearch.js +41 -0
  202. package/src/charting/diagrams/ArchimateValidator.js +357 -0
  203. package/src/charting/diagrams/CanvasView.js +112 -0
  204. package/src/charting/diagrams/ContextMenu.js +37 -0
  205. package/src/charting/diagrams/DataModelDiagram.js +86 -0
  206. package/src/charting/diagrams/DataModelRelationshipStrategy.js +38 -0
  207. package/src/charting/diagrams/DerivedRelationships.js +102 -0
  208. package/src/charting/diagrams/EbnfDiagram.js +39 -0
  209. package/src/charting/diagrams/EdgeGeometry.js +553 -0
  210. package/src/charting/diagrams/EditViewItemCommand.js +128 -0
  211. package/src/charting/diagrams/ElementInstance.js +157 -0
  212. package/src/charting/diagrams/GraphDiagram.js +1340 -0
  213. package/src/charting/diagrams/GraphDiagram3D.js +152 -0
  214. package/src/charting/diagrams/GraphMetrics.js +81 -0
  215. package/src/charting/diagrams/GridOverlay.js +137 -0
  216. package/src/charting/diagrams/ImportRowsCommand.js +62 -0
  217. package/src/charting/diagrams/LabelHelper.js +108 -0
  218. package/src/charting/diagrams/MergeElementsCommand.js +101 -0
  219. package/src/charting/diagrams/NestInstanceCommand.js +34 -0
  220. package/src/charting/diagrams/NodeGeometry.js +158 -0
  221. package/src/charting/diagrams/PlaceItemsCommand.js +77 -0
  222. package/src/charting/diagrams/RadialLayout.js +101 -0
  223. package/src/charting/diagrams/RelationshipInstance.js +93 -0
  224. package/src/charting/diagrams/RemoveGroupFromViewCommand.js +28 -0
  225. package/src/charting/diagrams/RemoveLineCommand.js +27 -0
  226. package/src/charting/diagrams/ShowElementCommand.js +43 -0
  227. package/src/charting/diagrams/SvgCoordinate.js +17 -0
  228. package/src/charting/diagrams/SvgZoom.js +127 -0
  229. package/src/charting/diagrams/Tooltip.js +62 -0
  230. package/src/charting/diagrams/ViewConnectionInstance.js +102 -0
  231. package/src/charting/diagrams/ViewObjectInstance.js +56 -0
  232. package/src/charting/diagrams/commands/AddEdgeCommand.js +34 -0
  233. package/src/charting/diagrams/commands/AddNodeCommand.js +28 -0
  234. package/src/charting/diagrams/commands/AddWaypointCommand.js +27 -0
  235. package/src/charting/diagrams/commands/CreateFolderCommand.js +27 -0
  236. package/src/charting/diagrams/commands/DeleteEdgeCommand.js +30 -0
  237. package/src/charting/diagrams/commands/DeleteFolderCommand.js +47 -0
  238. package/src/charting/diagrams/commands/DeleteNodeCommand.js +35 -0
  239. package/src/charting/diagrams/commands/DeleteWaypointCommand.js +24 -0
  240. package/src/charting/diagrams/commands/GraphCommand.js +65 -0
  241. package/src/charting/diagrams/commands/InvertEdgeCommand.js +24 -0
  242. package/src/charting/diagrams/commands/MoveNodeCommand.js +44 -0
  243. package/src/charting/diagrams/commands/MoveWaypointCommand.js +27 -0
  244. package/src/charting/diagrams/commands/RenameEdgeCommand.js +23 -0
  245. package/src/charting/diagrams/commands/RenameFolderCommand.js +31 -0
  246. package/src/charting/diagrams/commands/RenameNodeCommand.js +27 -0
  247. package/src/charting/diagrams/commands/ResizeNodeCommand.js +46 -0
  248. package/src/charting/diagrams/commands/UpdateEdgeSideCommand.js +40 -0
  249. package/src/charting/diagrams/commands/index.js +17 -0
  250. package/src/charting/diagrams/duplicates.js +49 -0
  251. package/src/charting/diagrams/nesting.js +30 -0
  252. package/src/charting/diagrams/roadmap.js +77 -0
  253. package/src/charting/edgeMarkers/ArrowMarker.js +15 -0
  254. package/src/charting/edgeMarkers/CircleMarker.js +13 -0
  255. package/src/charting/edgeMarkers/CrowsFootMarker.js +16 -0
  256. package/src/charting/edgeMarkers/DiamondMarker.js +15 -0
  257. package/src/charting/edgeMarkers/EdgeMarker.js +34 -0
  258. package/src/charting/edgeMarkers/HalfArrowMarker.js +8 -0
  259. package/src/charting/edgeMarkers/HollowDiamondMarker.js +18 -0
  260. package/src/charting/edgeMarkers/HollowTriangleMarker.js +18 -0
  261. package/src/charting/edgeMarkers/OpenArrowMarker.js +17 -0
  262. package/src/charting/edgeMarkers/index.js +27 -0
  263. package/src/charting/edgeStyle/EdgeStyleCascade.js +22 -0
  264. package/src/charting/edgeStyle/EdgeStyleDialog.js +51 -0
  265. package/src/charting/edgeStyle/EdgeStyleSchema.js +43 -0
  266. package/src/charting/edgeStyle/SetStyleCommand.js +12 -0
  267. package/src/charting/edgeStyle/index.js +4 -0
  268. package/src/charting/emphasis/EmphasisRule.js +42 -0
  269. package/src/charting/emphasis/HighlightRule.js +24 -0
  270. package/src/charting/gauges/ArcTrack.js +51 -0
  271. package/src/charting/gauges/GaugeAnimation.js +51 -0
  272. package/src/charting/gauges/GaugeBands.js +48 -0
  273. package/src/charting/gauges/GaugeScale.js +87 -0
  274. package/src/charting/gauges/GaugeTrack.js +44 -0
  275. package/src/charting/gauges/GaugeValue.js +61 -0
  276. package/src/charting/gauges/HorizontalTrack.js +14 -0
  277. package/src/charting/gauges/LinearTrack.js +29 -0
  278. package/src/charting/gauges/Sparkline.js +42 -0
  279. package/src/charting/gauges/VerticalTrack.js +17 -0
  280. package/src/charting/glyphs/ArrowGlyph.js +21 -0
  281. package/src/charting/glyphs/BatteryGlyph.js +18 -0
  282. package/src/charting/glyphs/ChevronGlyph.js +18 -0
  283. package/src/charting/glyphs/CircleGlyph.js +15 -0
  284. package/src/charting/glyphs/CloudGlyph.js +19 -0
  285. package/src/charting/glyphs/ComponentGlyph.js +18 -0
  286. package/src/charting/glyphs/ConstraintGlyph.js +24 -0
  287. package/src/charting/glyphs/ContractBoxGlyph.js +10 -0
  288. package/src/charting/glyphs/CubeGlyph.js +19 -0
  289. package/src/charting/glyphs/CylinderGlyph.js +19 -0
  290. package/src/charting/glyphs/DashedDoubleArrowGlyph.js +11 -0
  291. package/src/charting/glyphs/DeviceGlyph.js +17 -0
  292. package/src/charting/glyphs/DiamondGlyph.js +17 -0
  293. package/src/charting/glyphs/DocumentGlyph.js +17 -0
  294. package/src/charting/glyphs/DoubleArrowGlyph.js +23 -0
  295. package/src/charting/glyphs/DoubleCircleGlyph.js +24 -0
  296. package/src/charting/glyphs/EllipseGlyph.js +18 -0
  297. package/src/charting/glyphs/FactoryGlyph.js +20 -0
  298. package/src/charting/glyphs/FlagGlyph.js +16 -0
  299. package/src/charting/glyphs/GapCircleGlyph.js +17 -0
  300. package/src/charting/glyphs/GearGlyph.js +37 -0
  301. package/src/charting/glyphs/Glyph.js +98 -0
  302. package/src/charting/glyphs/GroupingBoxGlyph.js +13 -0
  303. package/src/charting/glyphs/HalfCircleGlyph.js +22 -0
  304. package/src/charting/glyphs/HexagonGlyph.js +28 -0
  305. package/src/charting/glyphs/IconGlyph.js +22 -0
  306. package/src/charting/glyphs/ImageGlyph.js +16 -0
  307. package/src/charting/glyphs/JunctionGlyph.js +17 -0
  308. package/src/charting/glyphs/LollipopGlyph.js +22 -0
  309. package/src/charting/glyphs/MagnifierGlyph.js +17 -0
  310. package/src/charting/glyphs/NoteGlyph.js +33 -0
  311. package/src/charting/glyphs/ObjectBoxGlyph.js +21 -0
  312. package/src/charting/glyphs/OrJunctionGlyph.js +17 -0
  313. package/src/charting/glyphs/ParallelogramGlyph.js +20 -0
  314. package/src/charting/glyphs/PersonGlyph.js +23 -0
  315. package/src/charting/glyphs/PillGlyph.js +23 -0
  316. package/src/charting/glyphs/PinGlyph.js +18 -0
  317. package/src/charting/glyphs/PrincipleGlyph.js +23 -0
  318. package/src/charting/glyphs/ProductBoxGlyph.js +16 -0
  319. package/src/charting/glyphs/RectGlyph.js +15 -0
  320. package/src/charting/glyphs/RoundedBoxGlyph.js +13 -0
  321. package/src/charting/glyphs/StackGlyph.js +14 -0
  322. package/src/charting/glyphs/StepsGlyph.js +20 -0
  323. package/src/charting/glyphs/StickFigureGlyph.js +32 -0
  324. package/src/charting/glyphs/SystemSoftwareBoxGlyph.js +16 -0
  325. package/src/charting/glyphs/TabbedBoxGlyph.js +37 -0
  326. package/src/charting/glyphs/TargetGlyph.js +23 -0
  327. package/src/charting/glyphs/WavyBoxGlyph.js +17 -0
  328. package/src/charting/glyphs/WheelGlyph.js +28 -0
  329. package/src/charting/glyphs/drawGlyph.js +28 -0
  330. package/src/charting/glyphs/glyphSvg.js +55 -0
  331. package/src/charting/glyphs/index.js +109 -0
  332. package/src/charting/modelTree/AnalysisPanel.js +159 -0
  333. package/src/charting/modelTree/DiagramTabs.js +217 -0
  334. package/src/charting/modelTree/ModelTree.js +164 -0
  335. package/src/charting/modelTree/ModelTreePanel.js +914 -0
  336. package/src/charting/modelTree/TreeBuilder.js +238 -0
  337. package/src/charting/modelTree/TreeModeRegistry.js +51 -0
  338. package/src/charting/modelTree/TreeViewMode.js +110 -0
  339. package/src/charting/modelTree/buildFilterTrees.js +138 -0
  340. package/src/charting/modelTree/modes/FlatTreeMode.js +46 -0
  341. package/src/charting/modelTree/modes/LayerGroupedTreeMode.js +62 -0
  342. package/src/charting/modelTree/modes/TypeGroupedTreeMode.js +60 -0
  343. package/src/charting/modelTree/treeLayers.js +11 -0
  344. package/src/charting/report/reportHtml.js +82 -0
  345. package/src/charting/report/reportViewer.js +118 -0
  346. package/src/charting/shapes/CircleShape.js +19 -0
  347. package/src/charting/shapes/PathShape.js +17 -0
  348. package/src/charting/shapes/RectShape.js +20 -0
  349. package/src/charting/shapes/Shape.js +20 -0
  350. package/src/charting/shapes/ShapeFactory.js +23 -0
  351. package/src/charting/storage/LocalJsonStore.js +43 -0
  352. package/src/charting/templates/ActorTemplate.js +36 -0
  353. package/src/charting/templates/BoxTemplate.js +27 -0
  354. package/src/charting/templates/CircleTemplate.js +18 -0
  355. package/src/charting/templates/ClassTemplate.js +20 -0
  356. package/src/charting/templates/CloudTemplate.js +43 -0
  357. package/src/charting/templates/ComponentTemplate.js +19 -0
  358. package/src/charting/templates/CylinderTemplate.js +30 -0
  359. package/src/charting/templates/DataStoreTemplate.js +16 -0
  360. package/src/charting/templates/DiamondTemplate.js +10 -0
  361. package/src/charting/templates/DocumentTemplate.js +32 -0
  362. package/src/charting/templates/EllipseTemplate.js +15 -0
  363. package/src/charting/templates/FinalStateTemplate.js +12 -0
  364. package/src/charting/templates/GlyphTemplate.js +47 -0
  365. package/src/charting/templates/HexagonTemplate.js +17 -0
  366. package/src/charting/templates/LifelineTemplate.js +20 -0
  367. package/src/charting/templates/ManualInputTemplate.js +12 -0
  368. package/src/charting/templates/NoteTemplate.js +23 -0
  369. package/src/charting/templates/OctagonTemplate.js +7 -0
  370. package/src/charting/templates/PackageTemplate.js +25 -0
  371. package/src/charting/templates/ParallelogramTemplate.js +11 -0
  372. package/src/charting/templates/PentagonTemplate.js +5 -0
  373. package/src/charting/templates/PolygonTemplate.js +18 -0
  374. package/src/charting/templates/PredefinedProcessTemplate.js +13 -0
  375. package/src/charting/templates/RectangleTemplate.js +28 -0
  376. package/src/charting/templates/RegularPolygonTemplate.js +21 -0
  377. package/src/charting/templates/RoundedRectangleTemplate.js +5 -0
  378. package/src/charting/templates/StadiumTemplate.js +8 -0
  379. package/src/charting/templates/StarTemplate.js +17 -0
  380. package/src/charting/templates/SwimlaneTemplate.js +18 -0
  381. package/src/charting/templates/Template.js +208 -0
  382. package/src/charting/templates/TrapezoidTemplate.js +11 -0
  383. package/src/charting/templates/TriangleTemplate.js +12 -0
  384. package/src/charting/templates/index.js +31 -0
  385. package/src/charting/templates/outline.js +59 -0
  386. package/src/charting/templates/svg.js +19 -0
  387. package/src/charting/textToShapes.js +61 -0
  388. package/src/charting/toolbar/ToolbarButton.js +38 -0
  389. package/src/charting/toolbar/ToolbarCheckbox.js +31 -0
  390. package/src/charting/toolbar/ToolbarItem.js +19 -0
  391. package/src/charting/toolbar/ToolbarMenu.js +36 -0
  392. package/src/charting/toolbar/ToolbarSelect.js +38 -0
  393. package/src/charting/toolbar/ToolbarSeparator.js +7 -0
  394. package/src/charting/toolbar/ToolbarText.js +22 -0
  395. package/src/charting/toolbar/index.js +8 -0
  396. package/src/charting/toolbar/pickFile.js +14 -0
  397. package/src/charting/viewDecorations.js +85 -0
  398. package/src/charting/zOrder.js +57 -0
  399. package/src/csvTable.js +61 -0
  400. package/src/datamodel.js +122 -0
  401. package/src/datawindow/BoundedWindow.js +36 -0
  402. package/src/datawindow/FlatDataWindow.js +34 -0
  403. package/src/datawindow/GraphDataWindow.js +40 -0
  404. package/src/datawindow/GroupedSampleDataWindow.js +16 -0
  405. package/src/datawindow/SeriesDataWindow.js +42 -0
  406. package/src/datawindow/index.js +31 -0
  407. package/src/diagramCatalog.js +30 -0
  408. package/src/ebnfDiagram.js +57 -0
  409. package/src/ebnfParser.js +129 -0
  410. package/src/exportImage.js +233 -0
  411. package/src/index.js +2636 -0
  412. package/src/itIcons.js +84 -0
  413. package/src/kernelExpr.js +243 -0
  414. package/src/propertiesDialog.js +463 -0
  415. package/src/railroadDiagram.js +571 -0
  416. package/src/treeModeCatalog.js +16 -0
  417. package/src/workspace/ContextBus.js +79 -0
  418. package/src/workspace/EditorShell.js +67 -0
  419. package/src/workspace/Part.js +163 -0
  420. package/src/workspace/PartFactory.js +49 -0
  421. package/src/workspace/PartRegistry.js +86 -0
  422. package/src/workspace/Workspace.js +321 -0
  423. package/src/workspace/archimateServices.js +33 -0
  424. package/src/workspace/dom.js +120 -0
  425. package/src/workspace/index.js +75 -0
  426. package/src/workspace/layout/GridNode.js +280 -0
  427. package/src/workspace/layout/LayoutNode.js +89 -0
  428. package/src/workspace/layout/PartNode.js +77 -0
  429. package/src/workspace/layout/SplitNode.js +114 -0
  430. package/src/workspace/layout/TabsNode.js +191 -0
  431. package/src/workspace/layout/index.js +24 -0
  432. package/src/workspace/parts/AdapterPart.js +33 -0
  433. package/src/workspace/parts/ArchimateCanvasPart.js +345 -0
  434. package/src/workspace/parts/ArchimateEditorPart.js +79 -0
  435. package/src/workspace/parts/ChartPart.js +115 -0
  436. package/src/workspace/parts/ContentPart.js +34 -0
  437. package/src/workspace/parts/DetailPart.js +46 -0
  438. package/src/workspace/parts/DiagramEditorPart.js +135 -0
  439. package/src/workspace/parts/EditorPart.js +388 -0
  440. package/src/workspace/parts/HtmlPart.js +25 -0
  441. package/src/workspace/parts/ListPart.js +57 -0
  442. package/src/workspace/parts/ModelFile.js +187 -0
  443. package/src/workspace/parts/ModelsPart.js +135 -0
  444. package/src/workspace/styles.js +258 -0
  445. package/src/workspace/themes.js +96 -0
  446. package/src/workspace/workArea.js +413 -0
  447. package/src/workspace/workAreaModel.js +197 -0
  448. package/src/workspace.js +16 -0
  449. package/src/zip/ZipArchive.js +160 -0
  450. package/src/zip/crc32.js +25 -0
  451. package/src/zip/inflate.js +159 -0
@@ -0,0 +1,152 @@
1
+ import { Diagram3D } from '../Diagram3D.js';
2
+ import { OrbitCamera } from '../../OrbitCamera.js';
3
+ import { GraphMetrics } from './GraphMetrics.js';
4
+ import { LabelHelper } from './LabelHelper.js';
5
+
6
+ /**
7
+ * GraphDiagram3D — interactive 3D node/edge graph viewed through the orbit camera.
8
+ */
9
+ export class GraphDiagram3D extends Diagram3D {
10
+ static diagramType = 'graph3d';
11
+
12
+ constructor(renderer, nodes, edges, options = {}, camera = null, engine = null) {
13
+ super(renderer, { nodes, edges }, options);
14
+ this.camera = camera;
15
+ this.engine = engine;
16
+ this._graph3DPos = null;
17
+ }
18
+
19
+ render() {
20
+ if (!this.renderer || !this.renderer.supportsSceneGraph) {
21
+ console.warn('3D graph diagram is only supported in SVG renderer.');
22
+ return;
23
+ }
24
+ super.render();
25
+ }
26
+
27
+ _render() {
28
+ const { nodes, edges } = this.data;
29
+ const options = this.options;
30
+ const renderer = this.renderer;
31
+
32
+ if (!renderer || !renderer.supportsSceneGraph) {
33
+ console.warn('3D graph diagram is only supported in SVG renderer.');
34
+ return;
35
+ }
36
+
37
+ const {
38
+ onNodeClick, nodeRadius = 8,
39
+ colors = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452'],
40
+ edgeColor: defaultEdgeColor = '#bdc3c7',
41
+ initialTheta = -0.6, initialPhi = 0.35, initialDistance = 2.2,
42
+ sizeBy, minRadius = nodeRadius, maxRadius = nodeRadius * 2.5, sizeScale = 'linear',
43
+ minEdgeWidth = 1.2, maxEdgeWidth = minEdgeWidth * 4, edgeWidthScale = 'linear',
44
+ } = options;
45
+
46
+ const degreeMap = sizeBy === 'degree' ? GraphMetrics.computeNodeDegrees(nodes, edges) : null;
47
+ const sizeDomain = GraphMetrics.computeSizeDomain(nodes, { sizeBy, degreeMap });
48
+ const sizeOptions = { minRadius, maxRadius, sizeScale, sizeBy, degreeMap };
49
+ const edgeWidthDomain = GraphMetrics.computeEdgeWidthDomain(edges);
50
+ const edgeWidthOptions = { minEdgeWidth, maxEdgeWidth, widthScale: edgeWidthScale };
51
+
52
+ this.seedCamera({ theta: initialTheta, phi: initialPhi, distance: initialDistance });
53
+
54
+ // Layout: simulate once per distinct node set, not on every camera-only redraw.
55
+ if (!this._graph3DPos || !nodes.every(n => this._graph3DPos.has(n.id))) {
56
+ this._graph3DPos = GraphDiagram3D.layoutForce3D(nodes, edges);
57
+ }
58
+ const pos = this._graph3DPos;
59
+
60
+ const W = renderer.width, H = renderer.height;
61
+ const cx = W / 2, cy = H / 2;
62
+ const pixelRadius = Math.min(W, H) / 2 - 20;
63
+ const camera = new OrbitCamera(this.camera);
64
+ const toScreen = (p) => {
65
+ const proj = camera.project(p, 1);
66
+ return { x: cx + proj.sx * pixelRadius, y: cy - proj.sy * pixelRadius, depth: proj.depth, scale: proj.scale };
67
+ };
68
+
69
+ const groups = new Map();
70
+ nodes.forEach(n => { if (n.group && !groups.has(n.group)) groups.set(n.group, colors[groups.size % colors.length]); });
71
+
72
+ const nodeItems = nodes.map(n => {
73
+ const p = pos.get(n.id);
74
+ const screen = toScreen(p);
75
+ const color = n.color || (n.group ? groups.get(n.group) : (options.nodeColor || '#4f8ef7'));
76
+ return { kind: 'node', node: n, screen, color, depth: screen.depth };
77
+ });
78
+ const edgeItems = edges.map(e => {
79
+ const a = pos.get(e.source), b = pos.get(e.target);
80
+ if (!a || !b) return null;
81
+ const sa = toScreen(a), sb = toScreen(b);
82
+ return { kind: 'edge', edge: e, sa, sb, depth: (sa.depth + sb.depth) / 2 };
83
+ }).filter(Boolean);
84
+
85
+ const scene = [...edgeItems, ...nodeItems].sort((a, b) => b.depth - a.depth);
86
+ const nodeEls = [];
87
+ for (const item of scene) {
88
+ if (item.kind === 'edge') {
89
+ const edgeWidth = GraphMetrics.effectiveEdgeWidth(item.edge, 1.2, edgeWidthDomain, edgeWidthOptions);
90
+ renderer.path(`M${item.sa.x},${item.sa.y} L${item.sb.x},${item.sb.y}`, 'none',
91
+ { color: item.edge.color || defaultEdgeColor, width: edgeWidth });
92
+ } else {
93
+ const { node, screen, color } = item;
94
+ const baseR = GraphMetrics.effectiveNodeRadius(node, nodeRadius, sizeDomain, sizeOptions);
95
+ const r = Math.max(2, baseR * screen.scale);
96
+ const label3D = LabelHelper.resolveNodeLabel(node) || node.id;
97
+ const g = renderer.group({ transform: `translate(${screen.x},${screen.y})`, nodeId: node.id, tooltip: label3D });
98
+ g.appendChild(renderer.circle(0, 0, r, color, { color: '#fff', width: 1.5 }));
99
+ g.appendChild(renderer.text(label3D, 0, r + 9, { fill: '#333', textAnchor: 'middle', fontSize: '9px', 'pointer-events': 'none' }));
100
+ if (onNodeClick) g.addEventListener('click', () => onNodeClick(node));
101
+ nodeEls.push(g);
102
+ }
103
+ }
104
+ this._graph3D = { nodes, edges, pos, nodeEls };
105
+ }
106
+
107
+ static layoutForce3D(nodes, edges, { iterations = 150 } = {}) {
108
+ const fixed = new Set(nodes.filter(n => n.x != null || n.y != null || n.z != null).map(n => n.id));
109
+ const pos = new Map(nodes.map(n => [n.id, {
110
+ x: n.x ?? (Math.random() * 2 - 1),
111
+ y: n.y ?? (Math.random() * 2 - 1),
112
+ z: n.z ?? (Math.random() * 2 - 1),
113
+ vx: 0, vy: 0, vz: 0,
114
+ }]));
115
+ const K = 1 / Math.cbrt(Math.max(nodes.length, 1));
116
+ let temp = 0.2;
117
+ for (let iter = 0; iter < iterations; iter++) {
118
+ nodes.forEach(n => { if (!fixed.has(n.id)) { const p = pos.get(n.id); p.vx = 0; p.vy = 0; p.vz = 0; } });
119
+ for (let i = 0; i < nodes.length; i++) {
120
+ for (let j = i + 1; j < nodes.length; j++) {
121
+ const a = pos.get(nodes[i].id), b = pos.get(nodes[j].id);
122
+ const dx = b.x - a.x, dy = b.y - a.y, dz = b.z - a.z;
123
+ const dist = Math.sqrt(dx * dx + dy * dy + dz * dz) || 0.01;
124
+ const f = (K * K) / dist;
125
+ const ux = dx / dist, uy = dy / dist, uz = dz / dist;
126
+ a.vx -= ux * f; a.vy -= uy * f; a.vz -= uz * f;
127
+ b.vx += ux * f; b.vy += uy * f; b.vz += uz * f;
128
+ }
129
+ }
130
+ edges.forEach(e => {
131
+ const a = pos.get(e.source), b = pos.get(e.target);
132
+ if (!a || !b) return;
133
+ const dx = b.x - a.x, dy = b.y - a.y, dz = b.z - a.z;
134
+ const dist = Math.sqrt(dx * dx + dy * dy + dz * dz) || 0.01;
135
+ const f = (dist * dist) / (K * 1.5);
136
+ const ux = dx / dist, uy = dy / dist, uz = dz / dist;
137
+ a.vx += ux * f; a.vy += uy * f; a.vz += uz * f;
138
+ b.vx -= ux * f; b.vy -= uy * f; b.vz -= uz * f;
139
+ });
140
+ nodes.forEach(n => {
141
+ if (fixed.has(n.id)) return;
142
+ const p = pos.get(n.id);
143
+ p.vx += -p.x * 0.02; p.vy += -p.y * 0.02; p.vz += -p.z * 0.02; // pull toward origin — no pixel container to center within, in 3D
144
+ const mag = Math.sqrt(p.vx * p.vx + p.vy * p.vy + p.vz * p.vz) || 1;
145
+ const dt = Math.min(mag, temp) / mag;
146
+ p.x += p.vx * dt; p.y += p.vy * dt; p.z += p.vz * dt;
147
+ });
148
+ temp *= 0.97;
149
+ }
150
+ return pos;
151
+ }
152
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * GraphMetrics — pure, stateless helpers for graph-diagram sizing and scaling.
3
+ *
4
+ * These functions used to live on RenderEngine; they are collected here so
5
+ * GraphDiagram, GraphDiagram3D, and any future diagram can use them without
6
+ * going through the engine façade.
7
+ */
8
+ export class GraphMetrics {
9
+ /** Pure — no DOM/renderer access. Map<nodeId, connectionCount> — how many
10
+ * edge ENDPOINTS touch each node (a self-loop, where source===target,
11
+ * counts twice — it really does attach to that node twice). Nodes with
12
+ * no edges at all still get an entry (0), so a domain computed over this
13
+ * always includes them rather than treating "no data" as "not sized". */
14
+ static computeNodeDegrees(nodes, edges) {
15
+ const degrees = new Map(nodes.map(n => [n.id, 0]));
16
+ for (const e of edges) {
17
+ if (degrees.has(e.source)) degrees.set(e.source, degrees.get(e.source) + 1);
18
+ if (degrees.has(e.target)) degrees.set(e.target, degrees.get(e.target) + 1);
19
+ }
20
+ return degrees;
21
+ }
22
+
23
+ /** Pure. What a node's own size VALUE is, before it's mapped to a radius —
24
+ * `node.size` (the default), or that node's connection count when
25
+ * `sizeBy: 'degree'` is in play (`degreeMap` from computeNodeDegrees). */
26
+ static nodeSizeValue(node, sizeBy, degreeMap) {
27
+ return sizeBy === 'degree' ? (degreeMap?.get(node?.id) ?? 0) : node?.size;
28
+ }
29
+
30
+ /** Pure — no DOM/renderer access. {min,max} of every node's size VALUE
31
+ * (see nodeSizeValue) across all nodes, or null if none carry a finite
32
+ * one (keeps effectiveNodeRadius's fixed-R behavior when the feature
33
+ * isn't in use at all). `{sizeBy, degreeMap}` switches the value source
34
+ * from `node.size` to connection count — same {min,max} shape either way. */
35
+ static computeSizeDomain(nodes, { sizeBy, degreeMap } = {}) {
36
+ const values = nodes.map(n => GraphMetrics.nodeSizeValue(n, sizeBy, degreeMap)).filter(Number.isFinite);
37
+ if (!values.length) return null;
38
+ return { min: Math.min(...values), max: Math.max(...values) };
39
+ }
40
+
41
+ /** Pure. Maps a node's size value (see nodeSizeValue) into
42
+ * [minRadius,maxRadius] given a precomputed domain; falls back to R
43
+ * unchanged when this node isn't part of the sizing (no domain, or its
44
+ * value not finite). `node.radius` — set by dragging that node's own
45
+ * resize handle — is a hard per-node override and wins over all of that
46
+ * (sizeBy/domain/plain R alike), the same way an explicit `node.x`/
47
+ * `node.y` already overrides computed layout. */
48
+ static effectiveNodeRadius(node, R, sizeDomain, sizeOptions = {}) {
49
+ if (Number.isFinite(node?.radius)) return node.radius;
50
+ const { minRadius = R, maxRadius = R * 2.5, sizeScale = 'linear', sizeBy, degreeMap } = sizeOptions;
51
+ const value = GraphMetrics.nodeSizeValue(node, sizeBy, degreeMap);
52
+ if (!sizeDomain || !Number.isFinite(value)) return R;
53
+ const { min, max } = sizeDomain;
54
+ if (max === min) return maxRadius;
55
+ let t = (value - min) / (max - min);
56
+ if (sizeScale === 'sqrt') t = Math.sqrt(t);
57
+ return minRadius + t * (maxRadius - minRadius);
58
+ }
59
+
60
+ /** Pure. {min,max} of edge.weight across all edges, or null if none carry
61
+ * a finite one — the edge-thickness counterpart of computeSizeDomain. */
62
+ static computeEdgeWidthDomain(edges) {
63
+ const values = edges.map(e => e.weight).filter(Number.isFinite);
64
+ if (!values.length) return null;
65
+ return { min: Math.min(...values), max: Math.max(...values) };
66
+ }
67
+
68
+ /** Pure. Maps edge.weight into [minEdgeWidth,maxEdgeWidth] given a
69
+ * precomputed domain; falls back to `defaultWidth` when this edge isn't
70
+ * part of the sizing (no domain, or edge.weight not finite) — the
71
+ * edge-thickness counterpart of effectiveNodeRadius. */
72
+ static effectiveEdgeWidth(edge, defaultWidth, widthDomain, widthOptions = {}) {
73
+ if (!widthDomain || !Number.isFinite(edge?.weight)) return defaultWidth;
74
+ const { minEdgeWidth = defaultWidth, maxEdgeWidth = defaultWidth * 4, widthScale = 'linear' } = widthOptions;
75
+ const { min, max } = widthDomain;
76
+ if (max === min) return maxEdgeWidth;
77
+ let t = (edge.weight - min) / (max - min);
78
+ if (widthScale === 'sqrt') t = Math.sqrt(t);
79
+ return minEdgeWidth + t * (maxEdgeWidth - minEdgeWidth);
80
+ }
81
+ }
@@ -0,0 +1,137 @@
1
+ /**
2
+ * GridOverlay — renders a dynamically scaled grid that responds to pan/zoom.
3
+ * Creates a separate SVG layer that redraw whenever the viewBox changes.
4
+ */
5
+ export class GridOverlay {
6
+ constructor(svgContainer, { gridSize = 20, color = '#e5e5e5', width = 0.5 } = {}) {
7
+ this.svgContainer = svgContainer;
8
+ this.gridSize = gridSize;
9
+ this.color = color;
10
+ this.width = width;
11
+
12
+ // Create overlay SVG
13
+ this.overlayElement = this._createOverlay();
14
+ // Prepend so it renders behind other SVGs
15
+ this.svgContainer.insertBefore(this.overlayElement, this.svgContainer.firstChild);
16
+
17
+ // Find the main SVG and listen for viewBox changes
18
+ this.mainSvg = null;
19
+ this._observeViewBoxChanges();
20
+ }
21
+
22
+ /**
23
+ * Create the grid overlay SVG element.
24
+ */
25
+ _createOverlay() {
26
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
27
+ svg.setAttribute('class', 'grid-overlay');
28
+ svg.style.cssText = `
29
+ position: absolute;
30
+ top: 0;
31
+ left: 0;
32
+ width: 100%;
33
+ height: 100%;
34
+ pointer-events: none;
35
+ z-index: 0;
36
+ `;
37
+ return svg;
38
+ }
39
+
40
+ /**
41
+ * Find main SVG and observe its viewBox changes.
42
+ */
43
+ _observeViewBoxChanges() {
44
+ // Find the main SVG element
45
+ const svgs = this.svgContainer.querySelectorAll('svg');
46
+ for (const svg of svgs) {
47
+ if (svg !== this.overlayElement && svg.viewBox?.baseVal) {
48
+ this.mainSvg = svg;
49
+ break;
50
+ }
51
+ }
52
+
53
+ if (!this.mainSvg) return;
54
+
55
+ // The overlay is positioned (absolute, z-index 0), and CSS paints positioned boxes over
56
+ // unpositioned ones whatever their order: lift the drawing above it, so the grid stays behind.
57
+ GridOverlay.stackAbove(this.mainSvg);
58
+
59
+ // Watch for viewBox attribute changes
60
+ const observer = new MutationObserver(() => {
61
+ this._updateGrid();
62
+ });
63
+
64
+ observer.observe(this.mainSvg, { attributes: true, attributeFilter: ['viewBox'] });
65
+
66
+ // Initial draw
67
+ this._updateGrid();
68
+ }
69
+
70
+ /**
71
+ * Update grid based on current viewBox.
72
+ */
73
+ _updateGrid() {
74
+ if (!this.mainSvg) return;
75
+
76
+ const viewBox = this.mainSvg.viewBox.baseVal;
77
+ const W = viewBox.width;
78
+ const H = viewBox.height;
79
+ const x0 = viewBox.x;
80
+ const y0 = viewBox.y;
81
+
82
+ // Clear existing grid
83
+ this.overlayElement.innerHTML = '';
84
+
85
+ // Sync overlay viewBox with main SVG
86
+ this.overlayElement.setAttribute('viewBox', `${x0} ${y0} ${W} ${H}`);
87
+
88
+ // Generate grid path aligned to grid
89
+ const lines = [];
90
+ const { gridSize } = this;
91
+
92
+ // Vertical lines
93
+ const firstX = Math.floor(x0 / gridSize) * gridSize;
94
+ for (let x = firstX; x < x0 + W; x += gridSize) {
95
+ lines.push(`M${x},${y0} L${x},${y0 + H}`);
96
+ }
97
+
98
+ // Horizontal lines
99
+ const firstY = Math.floor(y0 / gridSize) * gridSize;
100
+ for (let y = firstY; y < y0 + H; y += gridSize) {
101
+ lines.push(`M${x0},${y} L${x0 + W},${y}`);
102
+ }
103
+
104
+ // Create path element
105
+ if (lines.length > 0) {
106
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
107
+ path.setAttribute('d', lines.join(' '));
108
+ path.setAttribute('stroke', this.color);
109
+ path.setAttribute('stroke-width', this.width);
110
+ path.setAttribute('fill', 'none');
111
+ this.overlayElement.appendChild(path);
112
+ }
113
+ }
114
+
115
+ /** Make `drawing` paint above the overlay (z-index 0): positioned, one level up. A drawing already given a stacking order keeps it. */
116
+ static stackAbove(drawing) {
117
+ if (!drawing.style.position || drawing.style.position === 'static') drawing.style.position = 'relative';
118
+ if (!drawing.style.zIndex) drawing.style.zIndex = '1';
119
+ }
120
+
121
+ /**
122
+ * Update grid size and redraw.
123
+ */
124
+ setGridSize(gridSize) {
125
+ this.gridSize = gridSize;
126
+ this._updateGrid();
127
+ }
128
+
129
+ /**
130
+ * Remove the grid overlay.
131
+ */
132
+ destroy() {
133
+ if (this.overlayElement && this.overlayElement.parentNode) {
134
+ this.overlayElement.parentNode.removeChild(this.overlayElement);
135
+ }
136
+ }
137
+ }
@@ -0,0 +1,62 @@
1
+ import { Command } from '../CommandHistory.js';
2
+ import { ElementInstance } from './ElementInstance.js';
3
+
4
+ /**
5
+ * ImportRowsCommand — a planned import (csvMapping.js's planCsvImport) carried
6
+ * out as one undo step: the new elements and relationships added, the
7
+ * elements it updates given their new documentation and properties, and,
8
+ * with `view`, a box for each new element on it in a grid from `at`.
9
+ * Undo takes it all back.
10
+ */
11
+ export class ImportRowsCommand extends Command {
12
+ /**
13
+ * @param {ArchimateModel} model
14
+ * @param {{creates, updates, relationships}} plan
15
+ * @param {{view?: ArchimateView, at?: {x, y}, columns?: number}} [options]
16
+ */
17
+ constructor(model, plan, { view = null, at = { x: 60, y: 60 }, columns = 6 } = {}) {
18
+ super(`Import ${plan.creates.length} new, ${plan.updates.length} updated`);
19
+ this.model = model;
20
+ this.plan = plan;
21
+ this.view = view;
22
+ this.at = at;
23
+ this.columns = columns;
24
+ this._before = null;
25
+ this._instances = [];
26
+ }
27
+
28
+ execute() {
29
+ const { model, plan, view } = this;
30
+ this._before = {
31
+ updates: plan.updates.map(({ element }) => [element, { documentation: element.documentation, properties: element.properties }]),
32
+ elementIds: Array.isArray(view?.elementIds) ? [...view.elementIds] : null,
33
+ };
34
+ for (const element of plan.creates) model.addElement(structured(element));
35
+ for (const { element, changes } of plan.updates) Object.assign(element, structured(changes));
36
+ for (const rel of plan.relationships) if (!model.getRelationship(rel.id)) model.addRelationship({ ...rel });
37
+ if (view) {
38
+ this._instances = plan.creates.map((e, i) => {
39
+ const inst = new ElementInstance(e.id, this.at.x + (i % this.columns) * 160 + 60, this.at.y + Math.floor(i / this.columns) * 90 + 28);
40
+ view.addElementInstance(inst);
41
+ return inst;
42
+ });
43
+ if (Array.isArray(view.elementIds)) view.elementIds = [...new Set([...view.elementIds, ...plan.creates.map(e => e.id)])];
44
+ }
45
+ }
46
+
47
+ undo() {
48
+ const { model, plan, view } = this;
49
+ for (const inst of this._instances) view.removeElementInstance(inst.id);
50
+ this._instances = [];
51
+ if (view && this._before.elementIds) view.elementIds = this._before.elementIds;
52
+ for (const rel of plan.relationships) model.removeRelationship(rel.id);
53
+ for (const [element, before] of this._before.updates) {
54
+ for (const k of ['documentation', 'properties']) {
55
+ if (before[k] === undefined) delete element[k]; else element[k] = before[k];
56
+ }
57
+ }
58
+ for (const element of plan.creates) model.removeElement(element.id);
59
+ }
60
+ }
61
+
62
+ const structured = (v) => JSON.parse(JSON.stringify(v));
@@ -0,0 +1,108 @@
1
+ /**
2
+ * LabelHelper — pure, stateless helpers for resolving node labels, word-
3
+ * wrapping them, and surfacing caller-supplied "extra data" lines.
4
+ *
5
+ * These used to live on RenderEngine; they are collected here so diagram
6
+ * classes and property dialogs can use them without going through the engine
7
+ * façade.
8
+ */
9
+ export class LabelHelper {
10
+ /** Pure. The text that actually renders for a node's label — resolved
11
+ * BEFORE wrapping. `node.label`:
12
+ * - a function `(node) => string` — called directly.
13
+ * - a string with `${field}` (Archi-style) or `{field}` placeholders — each
14
+ * is replaced with that field's own value straight off the node.
15
+ * - falsy/unset — falls back to `node.name`, then `''`.
16
+ * Table nodes' header text and graphDiagram3D's node caption both read
17
+ * this too, not just the 2D `shape:'rect'` box. */
18
+ static resolveNodeLabel(node) {
19
+ if (typeof node?.label === 'function') return String(node.label(node) ?? '');
20
+ const raw = node?.label || node?.name || '';
21
+ if (typeof raw !== 'string') return String(raw);
22
+ if (!raw.includes('{') && !raw.includes('$')) return raw;
23
+ let result = raw;
24
+ result = result.replace(/\$\{(\w+)\}/g, (_match, field) => {
25
+ const value = node[field];
26
+ return value == null ? '' : String(value);
27
+ });
28
+ result = result.replace(/\{(\w+)\}/g, (_match, field) => {
29
+ const value = node[field];
30
+ return value == null ? '' : String(value);
31
+ });
32
+ return result;
33
+ }
34
+
35
+ /** Pure. Word-wraps `text` to fit within `maxWidth` px at `fontSize` px,
36
+ * returning as many `lineHeight`-px lines as fit within `maxHeight` — a
37
+ * single word wider than `maxWidth` is hard-broken rather than left
38
+ * overflowing. The last line gets an ellipsis appended if more text existed
39
+ * than fit. Widths come from `measure(text)` (px) when given, e.g. the
40
+ * renderer's measureText; otherwise from an average character width. */
41
+ static wrapLabelLines(text, maxWidth, fontSize, maxHeight, lineHeight, measure = null) {
42
+ const AVG_CHAR_WIDTH_RATIO = 0.55; // rough sans-serif average
43
+ const width = measure ?? ((s) => s.length * fontSize * AVG_CHAR_WIDTH_RATIO);
44
+ const fits = (s) => width(s) <= maxWidth;
45
+ /** The longest prefix of a word that fits (at least one character). */
46
+ const fittingPrefix = (word) => {
47
+ let n = 1;
48
+ while (n < word.length && fits(word.slice(0, n + 1))) n++;
49
+ return n;
50
+ };
51
+ const maxLines = Math.max(1, Math.floor(maxHeight / lineHeight));
52
+ const words = String(text ?? '').split(/\s+/).filter(Boolean);
53
+
54
+ const lines = [];
55
+ let current = '';
56
+ let truncated = false;
57
+ for (let i = 0; i < words.length; i++) {
58
+ if (lines.length >= maxLines) { truncated = true; break; }
59
+ const word = words[i];
60
+ const candidate = current ? `${current} ${word}` : word;
61
+ if (fits(candidate)) {
62
+ current = candidate;
63
+ continue;
64
+ }
65
+ if (current) lines.push(current);
66
+ if (lines.length >= maxLines) { truncated = true; current = ''; break; }
67
+ if (!fits(word)) {
68
+ let rest = word;
69
+ while (!fits(rest) && lines.length < maxLines) {
70
+ const n = fittingPrefix(rest);
71
+ lines.push(rest.slice(0, n));
72
+ rest = rest.slice(n);
73
+ }
74
+ current = lines.length >= maxLines ? '' : rest;
75
+ if (lines.length >= maxLines && rest) truncated = true;
76
+ } else {
77
+ current = word;
78
+ }
79
+ }
80
+ if (current) {
81
+ if (lines.length < maxLines) lines.push(current);
82
+ else truncated = true;
83
+ }
84
+ if (!truncated && lines.length === 0 && String(text ?? '').trim() === '') return [];
85
+
86
+ if (truncated && lines.length) {
87
+ const last = lines[lines.length - 1];
88
+ lines[lines.length - 1] = last.length > 1 ? `${last.slice(0, -1)}…` : `${last}…`;
89
+ }
90
+ return lines;
91
+ }
92
+
93
+ /** Pure. "key: value" lines for any of an object's own fields not in
94
+ * knownKeys and not undefined — surfaces caller-supplied extra data
95
+ * (e.g. `{owner:'Alice', headcount:12}`) in the hover tooltip without
96
+ * the caller having to build a bespoke tooltip string themselves. */
97
+ /** Whether a value is data a person reads and edits as text: a string, number or boolean, or a list of them (not an object). */
98
+ static isDataValue(value) {
99
+ const plain = (v) => ['string', 'number', 'boolean'].includes(typeof v);
100
+ return plain(value) || (Array.isArray(value) && value.every(plain));
101
+ }
102
+
103
+ static nodeExtraDataLines(node, knownKeys) {
104
+ return Object.entries(node)
105
+ .filter(([k, v]) => !knownKeys.has(k) && LabelHelper.isDataValue(v))
106
+ .map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(', ') : v}`);
107
+ }
108
+ }
@@ -0,0 +1,101 @@
1
+ import { Command } from '../CommandHistory.js';
2
+ import { structuredCopy } from './ElementInstance.js';
3
+
4
+ /**
5
+ * MergeElementsCommand — elements that are one thing twice made into one
6
+ * (Archi's merge): the one kept takes the others' relationships, their boxes
7
+ * on every view, the documentation it lacks and the properties it lacks; the
8
+ * others go. A relationship left joining the kept element to itself, or the
9
+ * same as another (kind and ends), goes too, its lines drawn as the other.
10
+ * Undo puts everything back as it was.
11
+ */
12
+ export class MergeElementsCommand extends Command {
13
+ /**
14
+ * @param {ArchimateModel} model
15
+ * @param {string} keepId - The element kept
16
+ * @param {Array<string>} otherIds - The elements merged into it
17
+ */
18
+ constructor(model, keepId, otherIds, label = `Merge ${otherIds.length + 1} elements into "${model.getElement(keepId)?.name || keepId}"`) {
19
+ super(label);
20
+ this.model = model;
21
+ this.keepId = keepId;
22
+ this.otherIds = otherIds.filter(id => id !== keepId && model.getElement(id));
23
+ this._before = null;
24
+ }
25
+
26
+ execute() {
27
+ const { model, keepId } = this;
28
+ const keep = model.getElement(keepId);
29
+ if (!keep || !this.otherIds.length) return;
30
+ this._before = this._snapshot();
31
+ const merged = new Set(this.otherIds);
32
+ const into = (id) => (merged.has(id) ? keepId : id);
33
+ for (const other of this.otherIds.map(id => model.getElement(id))) {
34
+ if (other.documentation && !(keep.documentation ?? '').includes(other.documentation)) {
35
+ keep.documentation = keep.documentation ? `${keep.documentation}\n\n${other.documentation}` : other.documentation;
36
+ }
37
+ const own = new Set((keep.properties ?? []).map(p => p.name ?? p.key));
38
+ const added = (other.properties ?? []).filter(p => !own.has(p.name ?? p.key));
39
+ if (added.length) keep.properties = [...(keep.properties ?? []), ...added.map(p => ({ ...p }))];
40
+ if (!keep.specialization && other.specialization) keep.specialization = other.specialization;
41
+ }
42
+ // Relationships end at the kept element; one left joining it to itself, or doubling another, goes.
43
+ const seen = new Map();
44
+ const replaced = new Map(); // removed relationship id -> the one its lines now draw
45
+ for (const rel of model.relationships()) {
46
+ const touched = merged.has(rel.source) || merged.has(rel.target);
47
+ rel.source = into(rel.source);
48
+ rel.target = into(rel.target);
49
+ if (touched && rel.source === keepId && rel.target === keepId) { replaced.set(rel.id, null); continue; }
50
+ const key = `${rel.kind} ${rel.source} ${rel.target} ${rel.name ?? ''}`;
51
+ if (touched && seen.has(key)) replaced.set(rel.id, seen.get(key));
52
+ else if (!seen.has(key)) seen.set(key, rel.id);
53
+ }
54
+ for (const id of replaced.keys()) model.removeRelationship(id);
55
+ for (const view of model.views()) {
56
+ if (Array.isArray(view.elementIds)) view.elementIds = [...new Set(view.elementIds.map(into))];
57
+ for (const inst of view.elementInstances?.values() ?? []) if (merged.has(inst.elementId)) inst.elementId = keepId;
58
+ for (const inst of [...(view.relationshipInstances?.values() ?? [])]) {
59
+ if (!replaced.has(inst.relationshipId)) continue;
60
+ const now = replaced.get(inst.relationshipId);
61
+ if (now) inst.relationshipId = now;
62
+ else view.relationshipInstances.delete(inst.id);
63
+ }
64
+ }
65
+ for (const id of this.otherIds) model.removeElement(id);
66
+ }
67
+
68
+ undo() {
69
+ if (!this._before) return;
70
+ const { model } = this;
71
+ const b = this._before;
72
+ model._elements = new Map(b.elements.map(([id, el]) => [id, el]));
73
+ const keep = model._elements.get(this.keepId);
74
+ Object.keys(keep).forEach(k => delete keep[k]); // what the merge added too
75
+ Object.assign(keep, structuredCopy(b.keep));
76
+ model._elementFolder = new Map(b.folders);
77
+ model._relationships = new Map(b.relationships.map(([id, rel, ends]) => [id, Object.assign(rel, ends)]));
78
+ for (const v of b.views) {
79
+ v.view.elementIds = v.elementIds;
80
+ for (const [inst, elementId] of v.instances) inst.elementId = elementId;
81
+ v.view.relationshipInstances = new Map(v.lines.map(([inst, relationshipId]) => { inst.relationshipId = relationshipId; return [inst.id, inst]; }));
82
+ }
83
+ }
84
+
85
+ /** Everything the merge changes, to put back. @private */
86
+ _snapshot() {
87
+ const { model } = this;
88
+ return {
89
+ elements: [...model._elements],
90
+ keep: structuredCopy(model.getElement(this.keepId)),
91
+ folders: [...model._elementFolder],
92
+ relationships: [...model._relationships].map(([id, rel]) => [id, rel, { source: rel.source, target: rel.target }]),
93
+ views: model.views().map(view => ({
94
+ view,
95
+ elementIds: Array.isArray(view.elementIds) ? [...view.elementIds] : view.elementIds,
96
+ instances: [...(view.elementInstances?.values() ?? [])].map(inst => [inst, inst.elementId]),
97
+ lines: [...(view.relationshipInstances?.values() ?? [])].map(inst => [inst, inst.relationshipId]),
98
+ })),
99
+ };
100
+ }
101
+ }
@@ -0,0 +1,34 @@
1
+ import { Command } from '../CommandHistory.js';
2
+ import { structuredCopy } from './ElementInstance.js';
3
+
4
+ /**
5
+ * NestInstanceCommand — draw a box inside another on its view, or take it out
6
+ * (Archi's nesting): the instance's `archi.parent` becomes the parent's
7
+ * visual id, so it moves with the parent and an Archi file nests it there. A
8
+ * box nested under one drawn above it is raised just above its parent, so it
9
+ * stays in sight. Undo restores both.
10
+ */
11
+ export class NestInstanceCommand extends Command {
12
+ /**
13
+ * @param {ElementInstance} instance - The box
14
+ * @param {ElementInstance|null} parent - The box it goes in; null takes it out
15
+ */
16
+ constructor(instance, parent, label = parent ? 'Nest' : 'Take out') {
17
+ super(label);
18
+ this.instance = instance;
19
+ this.parent = parent;
20
+ this._before = { archi: instance.archi ? structuredCopy(instance.archi) : null, zIndex: instance.zIndex };
21
+ }
22
+
23
+ execute() {
24
+ const { instance, parent } = this;
25
+ const { parent: _was, ...rest } = instance.archi ?? {};
26
+ instance.archi = parent ? { ...rest, parent: parent.visualId } : (Object.keys(rest).length ? rest : null);
27
+ if (parent && (instance.zIndex ?? 0) <= (parent.zIndex ?? 0)) instance.zIndex = (parent.zIndex ?? 0) + 1;
28
+ }
29
+
30
+ undo() {
31
+ this.instance.archi = this._before.archi ? structuredCopy(this._before.archi) : null;
32
+ this.instance.zIndex = this._before.zIndex;
33
+ }
34
+ }