@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,58 @@
1
+ /**
2
+ * Legend — a simple vertical list of colored marker squares + labels.
3
+ *
4
+ * Supports both per-data-item legends (barChart) and per-series legends
5
+ * (lineChart/areaChart). Items with `hidden: true` render grayed out.
6
+ */
7
+ export class Legend {
8
+ /**
9
+ * @param {object} options
10
+ * @param {Array<{label?:string, name?:string, color:string, hidden?:boolean, dataIndex?:number}>} options.items
11
+ * @param {number} options.x top-left x
12
+ * @param {number} options.y top-left y
13
+ * @param {number} [options.itemHeight=20]
14
+ * @param {number} [options.markerSize=10]
15
+ * @param {string} [options.fontSize='12px']
16
+ */
17
+ constructor({ items, x, y, itemHeight = 20, markerSize = 10, fontSize = '12px' }) {
18
+ this.items = items;
19
+ this.x = x;
20
+ this.y = y;
21
+ this.itemHeight = itemHeight;
22
+ this.markerSize = markerSize;
23
+ this.fontSize = fontSize;
24
+ }
25
+
26
+ /** Label text for an item — uses `label` or `name`. */
27
+ _label(item) {
28
+ return item.label ?? item.name ?? '';
29
+ }
30
+
31
+ /**
32
+ * Render the legend onto `renderer`.
33
+ * @param {*} renderer a renderer implementing .rect() and .text()
34
+ */
35
+ draw(renderer) {
36
+ let currentY = this.y;
37
+ for (const item of this.items) {
38
+ const hidden = !!item.hidden;
39
+ const color = hidden ? '#ccc' : item.color;
40
+ const textColor = hidden ? '#ccc' : '#333';
41
+ const attrs = {};
42
+ if (item.dataIndex !== undefined) {
43
+ attrs.legendItem = true;
44
+ attrs.dataIndex = item.dataIndex;
45
+ }
46
+
47
+ renderer.rect(this.x, currentY, this.markerSize, this.markerSize, color, null, attrs);
48
+ renderer.text(this._label(item), this.x + this.markerSize + 5, currentY + this.markerSize / 2, {
49
+ textAnchor: 'start',
50
+ verticalAlign: 'middle',
51
+ fontSize: this.fontSize,
52
+ fill: textColor,
53
+ ...attrs,
54
+ });
55
+ currentY += this.itemHeight;
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,62 @@
1
+ import { render as renderSpecs } from '../workspace/dom.js';
2
+
3
+ /**
4
+ * MenuBar — renders a row of ToolbarItems (menus, buttons, selects, toggles).
5
+ *
6
+ * It has no controls of its own: each editor contributes its items through
7
+ * `menuBarItems()` (and a host may add more), so the template editor and the
8
+ * ArchiMate editor share one toolbar implementation. After an item acts the bar
9
+ * re-renders, and live items refresh whenever the editor re-renders.
10
+ */
11
+ export class MenuBar {
12
+ /**
13
+ * @param {Object} options
14
+ * @param {HTMLElement} [options.container] - Element to render into
15
+ * @param {string} [options.menuBarId] - Or the id of that element
16
+ * @param {Array<ToolbarItem>} options.items
17
+ * @param {DiagramEditor} [options.editor] - Refresh live items when it renders
18
+ * @param {Document} [options.document]
19
+ */
20
+ constructor({ container = null, menuBarId = 'menu-bar', items = [], editor = null, document: doc = globalThis.document } = {}) {
21
+ this.doc = doc;
22
+ this.container = container;
23
+ this.menuBarId = menuBarId;
24
+ this.items = items;
25
+ this._nodes = [];
26
+ this._unsubscribe = editor?.onRendered?.(() => this.refresh()) ?? null;
27
+ }
28
+
29
+ render() {
30
+ const host = this.container ?? this.doc.getElementById(this.menuBarId);
31
+ if (!host) throw new Error(`MenuBar: no container (#${this.menuBarId})`);
32
+ this.container = host;
33
+ Object.assign(host.style, {
34
+ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: '8px', padding: '6px 12px',
35
+ background: '#f0f0f0', borderBottom: '1px solid #ccc', fontFamily: 'sans-serif', fontSize: '13px',
36
+ });
37
+ host.setAttribute('role', 'toolbar');
38
+ this._nodes = [];
39
+ renderSpecs(host, this.items.map((item) => {
40
+ const spec = item.spec(this);
41
+ const own = spec.ref;
42
+ return { ...spec, ref: (n) => { own?.(n); this._nodes.push([item, n]); } };
43
+ }), this.doc);
44
+ return this;
45
+ }
46
+
47
+ /** Run an item's action, then re-render so labels reflect the new state. */
48
+ run(action) {
49
+ const result = action();
50
+ if (this.container?.isConnected) this.render();
51
+ return result;
52
+ }
53
+
54
+ /** Update live items (e.g. the zoom %) without rebuilding the bar. */
55
+ refresh() {
56
+ for (const [item, node] of this._nodes) item.refresh(node);
57
+ }
58
+
59
+ dispose() {
60
+ this._unsubscribe?.();
61
+ }
62
+ }
@@ -0,0 +1,115 @@
1
+ import { pickFile } from './toolbar/pickFile.js';
2
+ import { downloadBlob } from '../exportImage.js';
3
+
4
+ /**
5
+ * ModelFileFormat — one file format a model is exported to and imported
6
+ * from. A subclass per format says what it is (`label`, `accept`,
7
+ * `fileName`, whether import reads bytes) and does the two conversions;
8
+ * `modelFileMenuItems` makes the File menu's Export and Import items from a
9
+ * list of them, so every editor offers the same formats the same way.
10
+ *
11
+ * `featureName` names the editor `features` flags that switch it on:
12
+ * `export<featureName>` and `import<featureName>`.
13
+ */
14
+ export class ModelFileFormat {
15
+ constructor() {
16
+ if (new.target === ModelFileFormat) throw new TypeError('ModelFileFormat is abstract — subclass it');
17
+ }
18
+
19
+ /** The format's name in menus ('.archimate', 'CSV', ...). @abstract */
20
+ get label() { throw new Error(`${this.constructor.name} must define label`); }
21
+
22
+ /** The file chooser's filter ('.xml', '.archimate,.xml'). */
23
+ get accept() { return ''; }
24
+
25
+ /** The name an exported file is saved under. */
26
+ get fileName() { return 'model'; }
27
+
28
+ /** Whether files in this format can be imported (opened) as well as exported. A subclass that only exports says no. */
29
+ get imports() { return true; }
30
+
31
+ /** True when import takes the file's bytes (a zip archive), else its text. */
32
+ get readsBytes() { return false; }
33
+
34
+ /** The suffix of the editor feature flags for this format (see the class). */
35
+ get featureName() { return this.constructor.name.replace(/FileFormat$/, ''); }
36
+
37
+ /** Whether a file's contents (text or bytes, as `readsBytes` says) are in this format. Yes unless a subclass checks. */
38
+ recognizes(data) {
39
+ return true;
40
+ }
41
+
42
+ /** Whether a file name has one of this format's extensions (`accept`). */
43
+ acceptsName(name) {
44
+ const lower = String(name ?? '').toLowerCase();
45
+ return this.accept.split(',').map(e => e.trim().toLowerCase()).filter(Boolean).some(ext => lower.endsWith(ext));
46
+ }
47
+
48
+ /**
49
+ * The model as a file.
50
+ * @abstract
51
+ * @returns {{data: string|Uint8Array, mimeType: string}}
52
+ */
53
+ export(model) {
54
+ throw new Error(`${this.constructor.name} must implement export()`);
55
+ }
56
+
57
+ /**
58
+ * A new model from a file's text (or bytes, when `readsBytes`).
59
+ * @abstract
60
+ */
61
+ import(data) {
62
+ throw new Error(`${this.constructor.name} must implement import()`);
63
+ }
64
+ }
65
+
66
+ /**
67
+ * The File menu's Export and Import items for some formats, one group per
68
+ * format. Export downloads the file; Import asks for a file, reads it and
69
+ * hands the new model to `onImport` (a failure is reported, the model kept).
70
+ * @param {Array<ModelFileFormat>} formats
71
+ * @param {Object} options
72
+ * @param {() => Object} options.model - The model to export
73
+ * @param {(model) => void} options.onImport - Replace the model with an imported one
74
+ * @param {(format, direction: 'export'|'import') => boolean} [options.enabled] - Which items to offer (default all)
75
+ * @param {() => Document} [options.document]
76
+ * @param {(file: {data, mimeType}, fileName: string) => void} [options.download] - Default: downloadBlob
77
+ * @param {(accept: string) => Promise<File|null>} [options.chooseFile] - Default: pickFile
78
+ * @param {(message: string) => void} [options.report] - Default: alert
79
+ * @param {'export'|'import'} [options.only] - Only the Export items, or only the Import ones (no separators then)
80
+ * @returns {Array<Object>} menu items (with separators between formats)
81
+ */
82
+ export function modelFileMenuItems(formats, {
83
+ model, onImport, enabled = () => true, document: doc = () => globalThis.document,
84
+ download = null, chooseFile = null, report = null, only = null,
85
+ } = {}) {
86
+ const save = download ?? (({ data, mimeType }, fileName) => downloadBlob(new (doc().defaultView ?? globalThis).Blob([data], { type: mimeType }), fileName));
87
+ const choose = chooseFile ?? ((accept) => pickFile(accept, doc()));
88
+ const tell = report ?? ((message) => (doc().defaultView ?? globalThis).alert(message));
89
+ const groups = formats.map(format => [
90
+ only !== 'import' && enabled(format, 'export') && { label: only ? format.label : `Export ${format.label}`, action: () => save(format.export(model()), format.fileName) },
91
+ only !== 'export' && format.imports && enabled(format, 'import') && {
92
+ label: only ? `${format.label}…` : `Import ${format.label}…`,
93
+ action: () => importFile(format, { choose, onImport, report: tell }),
94
+ },
95
+ ].filter(Boolean)).filter(group => group.length);
96
+ if (only) return groups.flat();
97
+ return groups.flatMap((group, i) => (i ? [{ separator: true }, ...group] : group));
98
+ }
99
+
100
+ /**
101
+ * Ask for a file and import it in `format`; resolves to the new model, or
102
+ * null when no file was chosen or it could not be read (reported).
103
+ */
104
+ export async function importFile(format, { choose, onImport, report }) {
105
+ const file = await choose(format.accept);
106
+ if (!file) return null;
107
+ try {
108
+ const model = format.import(format.readsBytes ? new Uint8Array(await file.arrayBuffer()) : await file.text());
109
+ onImport(model);
110
+ return model;
111
+ } catch (err) {
112
+ report(`Import failed: ${err.message}`);
113
+ return null;
114
+ }
115
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * OrbitControls — mouse/wheel controls for an orbit-camera 3D chart.
3
+ *
4
+ * The logic used to live inside RenderEngine._addOrbit3DListeners; it is
5
+ * collected here so 3D chart classes can attach their own camera controls
6
+ * without going through the engine façade.
7
+ */
8
+ export class OrbitControls {
9
+ constructor(container, getCamera, redraw, resetView, isActive = () => true) {
10
+ this.container = container;
11
+ this.getCamera = getCamera;
12
+ this.redraw = redraw;
13
+ this.resetView = resetView;
14
+ this.isActive = isActive;
15
+ this._dragging = false;
16
+ this._last = { x: 0, y: 0 };
17
+
18
+ this.ROTATE_SPEED = 0.006;
19
+ this.PHI_LIMIT = 1.5; // radians — stay short of straight up/down to avoid gimbal flip
20
+ this.DISTANCE_MIN = 0.6;
21
+ this.DISTANCE_MAX = 8;
22
+
23
+ this._onMouseDown = this._onMouseDown.bind(this);
24
+ this._onMouseMove = this._onMouseMove.bind(this);
25
+ this._onMouseUp = this._onMouseUp.bind(this);
26
+ this._onWheel = this._onWheel.bind(this);
27
+ this._onDblClick = this._onDblClick.bind(this);
28
+
29
+ container.addEventListener('mousedown', this._onMouseDown);
30
+ container.addEventListener('mousemove', this._onMouseMove);
31
+ container.addEventListener('mouseup', this._onMouseUp);
32
+ container.addEventListener('mouseleave', this._onMouseUp);
33
+ container.addEventListener('wheel', this._onWheel, { passive: false });
34
+ container.addEventListener('dblclick', this._onDblClick);
35
+ }
36
+
37
+ _onMouseDown(event) {
38
+ const camera = this.getCamera();
39
+ if (!this.isActive() || !camera || event.button !== 0 || event.altKey) return;
40
+ event.preventDefault();
41
+ this._dragging = true;
42
+ this._last = { x: event.clientX, y: event.clientY };
43
+ this.container.style.cursor = 'grabbing';
44
+ }
45
+
46
+ _onMouseMove(event) {
47
+ const camera = this.getCamera();
48
+ if (!this.isActive() || !this._dragging || !camera) return;
49
+ const dx = event.clientX - this._last.x;
50
+ const dy = event.clientY - this._last.y;
51
+ this._last = { x: event.clientX, y: event.clientY };
52
+
53
+ camera.theta += dx * this.ROTATE_SPEED;
54
+ camera.phi = Math.min(this.PHI_LIMIT, Math.max(-this.PHI_LIMIT, camera.phi + dy * this.ROTATE_SPEED));
55
+ this.redraw?.();
56
+ }
57
+
58
+ _onMouseUp() {
59
+ if (!this._dragging) return;
60
+ this._dragging = false;
61
+ this.container.style.cursor = 'default';
62
+ }
63
+
64
+ _onWheel(event) {
65
+ const camera = this.getCamera();
66
+ if (!this.isActive() || !camera) return;
67
+ event.preventDefault();
68
+ const factor = event.deltaY > 0 ? 1.1 : 1 / 1.1;
69
+ camera.distance = Math.min(this.DISTANCE_MAX, Math.max(this.DISTANCE_MIN, camera.distance * factor));
70
+ this.redraw?.();
71
+ }
72
+
73
+ _onDblClick() {
74
+ if (!this.isActive()) return;
75
+ this.resetView?.();
76
+ }
77
+ }
@@ -0,0 +1,119 @@
1
+ import { render } from '../workspace/dom.js';
2
+ import { CreateTemplateCommand } from './DiagramEditorCommands.js';
3
+
4
+ /**
5
+ * Palette — category picker plus a grid of draggable shapes.
6
+ *
7
+ * Previews are drawn by the templates themselves (Template#renderPreview), so a
8
+ * palette tile always matches what lands on the canvas.
9
+ */
10
+ export class Palette {
11
+ /**
12
+ * @param {Object} options
13
+ * @param {HTMLElement} options.container - Element the palette renders into (contents replaced)
14
+ * @param {TemplateCatalog} options.catalog - Shapes offered in the current category
15
+ * @param {DiagramEditor} options.editor - Editor receiving drops
16
+ * @param {Array<{group: string, types: Array<{key: string, name: string, description?: string}>}>} [options.categories]
17
+ * Grouped categories for the picker; omit to hide the picker
18
+ * @param {string} [options.category] - Selected category key
19
+ * @param {(key: string) => void} [options.onCategoryChange]
20
+ */
21
+ constructor(options = {}) {
22
+ this.container = options.container;
23
+ this.catalog = options.catalog;
24
+ this.editor = options.editor;
25
+ this.categories = options.categories ?? [];
26
+ this.category = options.category ?? null;
27
+ this.onCategoryChange = options.onCategoryChange ?? (() => {});
28
+ }
29
+
30
+ render() {
31
+ if (!this.container) return;
32
+ const doc = this.container.ownerDocument;
33
+ render(this.container, [
34
+ this.categories.length ? this._pickerSpec() : '',
35
+ {
36
+ style: { display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: '6px', overflowY: 'auto', flex: '1 1 auto', alignContent: 'start' },
37
+ children: this.catalog.getAll().map(entry => this._tileSpec(entry, doc)),
38
+ },
39
+ ], doc);
40
+ Object.assign(this.container.style, { display: 'flex', flexDirection: 'column', gap: '8px', minHeight: '0' });
41
+ }
42
+
43
+ _pickerSpec() {
44
+ const selected = this.categories.flatMap(g => g.types).find(t => t.key === this.category);
45
+ return {
46
+ tag: 'select',
47
+ attrs: { 'aria-label': 'Diagram type', title: selected?.description },
48
+ style: { width: '100%', padding: '6px', fontSize: '12px', flex: '0 0 auto' },
49
+ on: { change: (e) => this.onCategoryChange(e.target.value) },
50
+ children: this.categories.map(({ group, types }) => ({
51
+ tag: 'optgroup',
52
+ attrs: { label: group },
53
+ children: types.map(t => ({
54
+ tag: 'option',
55
+ attrs: { value: t.key, selected: t.key === this.category, title: t.description },
56
+ text: t.name,
57
+ })),
58
+ })),
59
+ };
60
+ }
61
+
62
+ _tileSpec(entry, doc) {
63
+ return {
64
+ attrs: { draggable: 'true', title: `Drag to add ${entry.name}` },
65
+ style: {
66
+ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px',
67
+ padding: '6px 4px', background: '#fff', border: '1px solid #ddd', borderRadius: '4px',
68
+ cursor: 'grab', userSelect: 'none',
69
+ },
70
+ on: { dragstart: (e) => this._startDrag(e, entry) },
71
+ children: [
72
+ entry.factory('__preview', 0, 0).renderPreview(40, doc),
73
+ {
74
+ text: entry.name,
75
+ style: { fontSize: '11px', color: '#333', textAlign: 'center', lineHeight: '1.2', overflowWrap: 'anywhere' },
76
+ },
77
+ ],
78
+ };
79
+ }
80
+
81
+ _startDrag(e, entry) {
82
+ if (!e.dataTransfer) return;
83
+ e.dataTransfer.effectAllowed = 'copy';
84
+ e.dataTransfer.setData('templateType', entry.type);
85
+ }
86
+
87
+ /**
88
+ * Create the dragged shape at a drop point given in SVG viewBox coordinates,
89
+ * snapping to the grid when it is shown.
90
+ */
91
+ handleDrop(e, x, y) {
92
+ const templateType = e.dataTransfer.getData('templateType');
93
+ if (!templateType) return false;
94
+
95
+ let snapX = x, snapY = y;
96
+ if (this.editor.showGrid && this.editor.gridSize) {
97
+ const gridSize = this.editor.gridSize;
98
+ snapX = Math.round(x / gridSize) * gridSize;
99
+ snapY = Math.round(y / gridSize) * gridSize;
100
+ }
101
+
102
+ const template = this.catalog.create(templateType, this._generateId(templateType), snapX, snapY);
103
+ if (!template) return false;
104
+
105
+ if (this.editor.history) {
106
+ this.editor.history.execute(new CreateTemplateCommand(this.editor, template));
107
+ } else {
108
+ this.editor.addTemplate(template);
109
+ }
110
+ this.editor.render();
111
+ return true;
112
+ }
113
+
114
+ _generateId(templateType) {
115
+ let counter = 1;
116
+ while (this.editor.getTemplate(`${templateType}_${counter}`)) counter++;
117
+ return `${templateType}_${counter}`;
118
+ }
119
+ }
@@ -0,0 +1,117 @@
1
+ import { el } from '../workspace/dom.js';
2
+
3
+ /**
4
+ * PopupMenu — the one popup/context menu: a small menu at a screen position,
5
+ * closed by choosing an item or clicking elsewhere. One is open at a time.
6
+ * Editor menus, the graph engine's ContextMenu and the model tree's menus all
7
+ * render through it.
8
+ *
9
+ * Items: `{ label, action, danger?, checked?, disabled? }`,
10
+ * `{ label, items: [...] }` for a submenu, or `{ separator: true }`.
11
+ */
12
+ export class PopupMenu {
13
+ static _open = null;
14
+
15
+ static show(x, y, items, doc = document) {
16
+ PopupMenu.close();
17
+ if (!items.length) return null;
18
+ const menu = el({
19
+ ...PopupMenu._panel(items, doc),
20
+ style: { ...PopupMenu._panelStyle, position: 'fixed', left: `${x}px`, top: `${y}px` },
21
+ }, doc);
22
+ doc.body.appendChild(menu);
23
+ // Opened near the window's right or bottom edge, it moves back into the window.
24
+ const win = doc.defaultView;
25
+ const box = menu.getBoundingClientRect?.();
26
+ if (win && box?.width) {
27
+ const at = PopupMenu.fit(x, y, box.width, box.height, win.innerWidth, win.innerHeight);
28
+ Object.assign(menu.style, { left: `${at.x}px`, top: `${at.y}px` });
29
+ }
30
+ // Registered after the opening click has finished propagating.
31
+ const dismiss = () => PopupMenu.close();
32
+ setTimeout(() => doc.addEventListener('click', dismiss, { once: true }), 0);
33
+ PopupMenu._open = { menu, dismiss, doc };
34
+ return menu;
35
+ }
36
+
37
+ /**
38
+ * Where a menu of a size goes, asked for at (x, y), to be all inside a
39
+ * window of a size: left of the point when it would pass the right edge,
40
+ * above it when it would pass the bottom, never past the top-left.
41
+ */
42
+ static fit(x, y, width, height, windowWidth, windowHeight, margin = 4) {
43
+ const left = x + width + margin > windowWidth ? x - width : x;
44
+ const top = y + height + margin > windowHeight ? y - height : y;
45
+ return {
46
+ x: Math.max(margin, Math.min(left, windowWidth - width - margin)),
47
+ y: Math.max(margin, Math.min(top, windowHeight - height - margin)),
48
+ };
49
+ }
50
+
51
+ static close() {
52
+ const open = PopupMenu._open;
53
+ if (!open) return;
54
+ open.menu.remove();
55
+ open.doc.removeEventListener('click', open.dismiss);
56
+ PopupMenu._open = null;
57
+ }
58
+
59
+ static get isOpen() {
60
+ return !!PopupMenu._open;
61
+ }
62
+
63
+ static _panelStyle = {
64
+ background: '#fff', border: '1px solid #ccc', borderRadius: '3px', boxShadow: '0 2px 8px rgba(0,0,0,0.2)',
65
+ zIndex: '10000', minWidth: '170px', fontSize: '12px', fontFamily: 'sans-serif', padding: '4px 0',
66
+ };
67
+
68
+ static _panel(items, doc) {
69
+ return { attrs: { role: 'menu' }, children: items.map(item => PopupMenu._item(item, doc)) };
70
+ }
71
+
72
+ static _item(item, doc) {
73
+ if (item.separator) return { attrs: { role: 'separator' }, style: { borderTop: '1px solid #ddd', margin: '4px 0' } };
74
+ const hover = item.danger ? '#ffe8e8' : '#f0f0f0';
75
+ const base = {
76
+ attrs: { role: 'menuitem', 'aria-disabled': item.disabled ? 'true' : null, 'aria-checked': item.checked != null ? String(!!item.checked) : null },
77
+ style: {
78
+ padding: '7px 14px', cursor: item.disabled ? 'default' : 'pointer', position: 'relative', whiteSpace: 'nowrap',
79
+ color: item.disabled ? '#aaa' : item.danger ? '#cc3333' : '', background: item.checked ? '#e3f2fd' : '',
80
+ },
81
+ };
82
+ if (item.items) {
83
+ let sub;
84
+ return {
85
+ ...base,
86
+ attrs: { ...base.attrs, 'aria-haspopup': 'menu' },
87
+ on: {
88
+ mouseenter: (e) => { e.currentTarget.style.background = hover; sub.style.display = 'block'; },
89
+ mouseleave: (e) => { e.currentTarget.style.background = ''; sub.style.display = 'none'; },
90
+ click: (e) => e.stopPropagation(),
91
+ },
92
+ children: [
93
+ `${item.label} ▸`,
94
+ {
95
+ ...PopupMenu._panel(item.items, doc),
96
+ style: { ...PopupMenu._panelStyle, position: 'absolute', left: '100%', top: '-4px', display: 'none' },
97
+ ref: (n) => { sub = n; },
98
+ },
99
+ ],
100
+ };
101
+ }
102
+ return {
103
+ ...base,
104
+ text: item.label,
105
+ on: {
106
+ mouseenter: (e) => { if (!item.disabled) e.currentTarget.style.background = hover; },
107
+ mouseleave: (e) => { e.currentTarget.style.background = item.checked ? '#e3f2fd' : ''; },
108
+ click: (e) => {
109
+ e.stopPropagation();
110
+ if (item.disabled) return;
111
+ PopupMenu.close();
112
+ item.action();
113
+ },
114
+ },
115
+ };
116
+ }
117
+ }