@peter.prib/renderengine 0.0.0-stage → 0.1.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 (436) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -2
  3. package/REFERENCE.md +2159 -0
  4. package/dist/renderengine-workspace.umd.js +45944 -0
  5. package/dist/renderengine.umd.js +41262 -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 +544 -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 +52 -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/AreaChart.js +71 -0
  132. package/src/charting/charts/BarChart.js +80 -0
  133. package/src/charting/charts/BarChart3D.js +56 -0
  134. package/src/charting/charts/BarChart3DOrbit.js +53 -0
  135. package/src/charting/charts/BarChartBase.js +70 -0
  136. package/src/charting/charts/BarGauge.js +21 -0
  137. package/src/charting/charts/BoxPlotChart.js +41 -0
  138. package/src/charting/charts/BubbleChart.js +99 -0
  139. package/src/charting/charts/BubbleChart3D.js +78 -0
  140. package/src/charting/charts/BulletGauge.js +91 -0
  141. package/src/charting/charts/CalendarHeatmapChart.js +204 -0
  142. package/src/charting/charts/CandlestickChart.js +54 -0
  143. package/src/charting/charts/ChordDiagram.js +130 -0
  144. package/src/charting/charts/DensityChart.js +73 -0
  145. package/src/charting/charts/DialGauge.js +37 -0
  146. package/src/charting/charts/DonutChart.js +15 -0
  147. package/src/charting/charts/FunnelChart.js +47 -0
  148. package/src/charting/charts/GanttChart.js +201 -0
  149. package/src/charting/charts/GaugeChart.js +47 -0
  150. package/src/charting/charts/GeoMapChart.js +146 -0
  151. package/src/charting/charts/GroupedBarChart.js +88 -0
  152. package/src/charting/charts/GroupedDistributionChart.js +70 -0
  153. package/src/charting/charts/HeatmapChart.js +80 -0
  154. package/src/charting/charts/HierarchyChart.js +39 -0
  155. package/src/charting/charts/HistogramChart.js +45 -0
  156. package/src/charting/charts/LagPlotChart.js +41 -0
  157. package/src/charting/charts/LineChart.js +124 -0
  158. package/src/charting/charts/OutlineChart.js +95 -0
  159. package/src/charting/charts/ParallelCoordinatesChart.js +130 -0
  160. package/src/charting/charts/PieChart.js +56 -0
  161. package/src/charting/charts/PipeChart.js +88 -0
  162. package/src/charting/charts/PopulationPyramidChart.js +106 -0
  163. package/src/charting/charts/QQPlotChart.js +64 -0
  164. package/src/charting/charts/RadarChart.js +76 -0
  165. package/src/charting/charts/RadialBarChart.js +96 -0
  166. package/src/charting/charts/SankeyDiagram.js +174 -0
  167. package/src/charting/charts/ScatterChart.js +104 -0
  168. package/src/charting/charts/StackedAreaChart.js +15 -0
  169. package/src/charting/charts/StackedBarChart.js +33 -0
  170. package/src/charting/charts/StackedBarChart3DOrbit.js +58 -0
  171. package/src/charting/charts/StreamGraphChart.js +131 -0
  172. package/src/charting/charts/SunburstChart.js +57 -0
  173. package/src/charting/charts/TreemapChart.js +54 -0
  174. package/src/charting/charts/ViolinChart.js +37 -0
  175. package/src/charting/charts/WaterfallChart.js +66 -0
  176. package/src/charting/charts/WordCloudChart.js +104 -0
  177. package/src/charting/diagramModel/AddViewCommand.js +33 -0
  178. package/src/charting/diagramModel/DiagramModel.js +39 -0
  179. package/src/charting/diagramModel/DiagramModelSearch.js +22 -0
  180. package/src/charting/diagramModel/DiagramView.js +50 -0
  181. package/src/charting/diagramModel/ModelHistory.js +43 -0
  182. package/src/charting/diagramModel/ModelReport.js +153 -0
  183. package/src/charting/diagramModel/ModelSearch.js +223 -0
  184. package/src/charting/diagramModel/RemoveViewCommand.js +25 -0
  185. package/src/charting/diagramModel/RenameViewCommand.js +21 -0
  186. package/src/charting/diagramModel/ReplaceTextCommand.js +25 -0
  187. package/src/charting/diagramModel/ViewSetChecker.js +34 -0
  188. package/src/charting/diagramModel/ViewSetModel.js +243 -0
  189. package/src/charting/diagramModel/index.js +6 -0
  190. package/src/charting/diagramModel/nameTransforms.js +29 -0
  191. package/src/charting/diagrams/ArchimateCommands.js +141 -0
  192. package/src/charting/diagrams/ArchimateDiagram.js +263 -0
  193. package/src/charting/diagrams/ArchimateModel.js +1155 -0
  194. package/src/charting/diagrams/ArchimateModelChecker.js +125 -0
  195. package/src/charting/diagrams/ArchimateModelReport.js +128 -0
  196. package/src/charting/diagrams/ArchimateModelSearch.js +41 -0
  197. package/src/charting/diagrams/ArchimateValidator.js +357 -0
  198. package/src/charting/diagrams/CanvasView.js +112 -0
  199. package/src/charting/diagrams/ContextMenu.js +37 -0
  200. package/src/charting/diagrams/DataModelDiagram.js +86 -0
  201. package/src/charting/diagrams/DataModelRelationshipStrategy.js +38 -0
  202. package/src/charting/diagrams/DerivedRelationships.js +102 -0
  203. package/src/charting/diagrams/EbnfDiagram.js +39 -0
  204. package/src/charting/diagrams/EdgeGeometry.js +553 -0
  205. package/src/charting/diagrams/EditViewItemCommand.js +128 -0
  206. package/src/charting/diagrams/ElementInstance.js +157 -0
  207. package/src/charting/diagrams/GraphDiagram.js +1340 -0
  208. package/src/charting/diagrams/GraphDiagram3D.js +152 -0
  209. package/src/charting/diagrams/GraphMetrics.js +81 -0
  210. package/src/charting/diagrams/GridOverlay.js +137 -0
  211. package/src/charting/diagrams/ImportRowsCommand.js +62 -0
  212. package/src/charting/diagrams/LabelHelper.js +108 -0
  213. package/src/charting/diagrams/MergeElementsCommand.js +101 -0
  214. package/src/charting/diagrams/NestInstanceCommand.js +34 -0
  215. package/src/charting/diagrams/NodeGeometry.js +158 -0
  216. package/src/charting/diagrams/PlaceItemsCommand.js +77 -0
  217. package/src/charting/diagrams/RadialLayout.js +101 -0
  218. package/src/charting/diagrams/RelationshipInstance.js +93 -0
  219. package/src/charting/diagrams/RemoveGroupFromViewCommand.js +28 -0
  220. package/src/charting/diagrams/RemoveLineCommand.js +27 -0
  221. package/src/charting/diagrams/ShowElementCommand.js +43 -0
  222. package/src/charting/diagrams/SvgCoordinate.js +17 -0
  223. package/src/charting/diagrams/SvgZoom.js +127 -0
  224. package/src/charting/diagrams/Tooltip.js +62 -0
  225. package/src/charting/diagrams/ViewConnectionInstance.js +102 -0
  226. package/src/charting/diagrams/ViewObjectInstance.js +56 -0
  227. package/src/charting/diagrams/commands/AddEdgeCommand.js +34 -0
  228. package/src/charting/diagrams/commands/AddNodeCommand.js +28 -0
  229. package/src/charting/diagrams/commands/AddWaypointCommand.js +27 -0
  230. package/src/charting/diagrams/commands/CreateFolderCommand.js +27 -0
  231. package/src/charting/diagrams/commands/DeleteEdgeCommand.js +30 -0
  232. package/src/charting/diagrams/commands/DeleteFolderCommand.js +47 -0
  233. package/src/charting/diagrams/commands/DeleteNodeCommand.js +35 -0
  234. package/src/charting/diagrams/commands/DeleteWaypointCommand.js +24 -0
  235. package/src/charting/diagrams/commands/GraphCommand.js +65 -0
  236. package/src/charting/diagrams/commands/InvertEdgeCommand.js +24 -0
  237. package/src/charting/diagrams/commands/MoveNodeCommand.js +44 -0
  238. package/src/charting/diagrams/commands/MoveWaypointCommand.js +27 -0
  239. package/src/charting/diagrams/commands/RenameEdgeCommand.js +23 -0
  240. package/src/charting/diagrams/commands/RenameFolderCommand.js +31 -0
  241. package/src/charting/diagrams/commands/RenameNodeCommand.js +27 -0
  242. package/src/charting/diagrams/commands/ResizeNodeCommand.js +46 -0
  243. package/src/charting/diagrams/commands/UpdateEdgeSideCommand.js +40 -0
  244. package/src/charting/diagrams/commands/index.js +17 -0
  245. package/src/charting/diagrams/duplicates.js +49 -0
  246. package/src/charting/diagrams/nesting.js +30 -0
  247. package/src/charting/diagrams/roadmap.js +77 -0
  248. package/src/charting/edgeMarkers/ArrowMarker.js +15 -0
  249. package/src/charting/edgeMarkers/CircleMarker.js +13 -0
  250. package/src/charting/edgeMarkers/CrowsFootMarker.js +16 -0
  251. package/src/charting/edgeMarkers/DiamondMarker.js +15 -0
  252. package/src/charting/edgeMarkers/EdgeMarker.js +34 -0
  253. package/src/charting/edgeMarkers/HalfArrowMarker.js +8 -0
  254. package/src/charting/edgeMarkers/HollowDiamondMarker.js +18 -0
  255. package/src/charting/edgeMarkers/HollowTriangleMarker.js +18 -0
  256. package/src/charting/edgeMarkers/OpenArrowMarker.js +17 -0
  257. package/src/charting/edgeMarkers/index.js +27 -0
  258. package/src/charting/edgeStyle/EdgeStyleCascade.js +22 -0
  259. package/src/charting/edgeStyle/EdgeStyleDialog.js +51 -0
  260. package/src/charting/edgeStyle/EdgeStyleSchema.js +43 -0
  261. package/src/charting/edgeStyle/SetStyleCommand.js +12 -0
  262. package/src/charting/edgeStyle/index.js +4 -0
  263. package/src/charting/emphasis/EmphasisRule.js +42 -0
  264. package/src/charting/emphasis/HighlightRule.js +24 -0
  265. package/src/charting/glyphs/ArrowGlyph.js +21 -0
  266. package/src/charting/glyphs/BatteryGlyph.js +18 -0
  267. package/src/charting/glyphs/ChevronGlyph.js +18 -0
  268. package/src/charting/glyphs/CircleGlyph.js +15 -0
  269. package/src/charting/glyphs/CloudGlyph.js +19 -0
  270. package/src/charting/glyphs/ComponentGlyph.js +18 -0
  271. package/src/charting/glyphs/ConstraintGlyph.js +24 -0
  272. package/src/charting/glyphs/ContractBoxGlyph.js +10 -0
  273. package/src/charting/glyphs/CubeGlyph.js +19 -0
  274. package/src/charting/glyphs/CylinderGlyph.js +19 -0
  275. package/src/charting/glyphs/DashedDoubleArrowGlyph.js +11 -0
  276. package/src/charting/glyphs/DeviceGlyph.js +17 -0
  277. package/src/charting/glyphs/DiamondGlyph.js +17 -0
  278. package/src/charting/glyphs/DocumentGlyph.js +17 -0
  279. package/src/charting/glyphs/DoubleArrowGlyph.js +23 -0
  280. package/src/charting/glyphs/DoubleCircleGlyph.js +24 -0
  281. package/src/charting/glyphs/EllipseGlyph.js +18 -0
  282. package/src/charting/glyphs/FactoryGlyph.js +20 -0
  283. package/src/charting/glyphs/FlagGlyph.js +16 -0
  284. package/src/charting/glyphs/GapCircleGlyph.js +17 -0
  285. package/src/charting/glyphs/GearGlyph.js +37 -0
  286. package/src/charting/glyphs/Glyph.js +98 -0
  287. package/src/charting/glyphs/GroupingBoxGlyph.js +13 -0
  288. package/src/charting/glyphs/HalfCircleGlyph.js +22 -0
  289. package/src/charting/glyphs/HexagonGlyph.js +28 -0
  290. package/src/charting/glyphs/IconGlyph.js +22 -0
  291. package/src/charting/glyphs/ImageGlyph.js +16 -0
  292. package/src/charting/glyphs/JunctionGlyph.js +17 -0
  293. package/src/charting/glyphs/LollipopGlyph.js +22 -0
  294. package/src/charting/glyphs/MagnifierGlyph.js +17 -0
  295. package/src/charting/glyphs/NoteGlyph.js +33 -0
  296. package/src/charting/glyphs/ObjectBoxGlyph.js +21 -0
  297. package/src/charting/glyphs/OrJunctionGlyph.js +17 -0
  298. package/src/charting/glyphs/ParallelogramGlyph.js +20 -0
  299. package/src/charting/glyphs/PersonGlyph.js +23 -0
  300. package/src/charting/glyphs/PillGlyph.js +23 -0
  301. package/src/charting/glyphs/PinGlyph.js +18 -0
  302. package/src/charting/glyphs/PrincipleGlyph.js +23 -0
  303. package/src/charting/glyphs/ProductBoxGlyph.js +16 -0
  304. package/src/charting/glyphs/RectGlyph.js +15 -0
  305. package/src/charting/glyphs/RoundedBoxGlyph.js +13 -0
  306. package/src/charting/glyphs/StackGlyph.js +14 -0
  307. package/src/charting/glyphs/StepsGlyph.js +20 -0
  308. package/src/charting/glyphs/StickFigureGlyph.js +32 -0
  309. package/src/charting/glyphs/SystemSoftwareBoxGlyph.js +16 -0
  310. package/src/charting/glyphs/TabbedBoxGlyph.js +37 -0
  311. package/src/charting/glyphs/TargetGlyph.js +23 -0
  312. package/src/charting/glyphs/WavyBoxGlyph.js +17 -0
  313. package/src/charting/glyphs/WheelGlyph.js +28 -0
  314. package/src/charting/glyphs/drawGlyph.js +28 -0
  315. package/src/charting/glyphs/glyphSvg.js +55 -0
  316. package/src/charting/glyphs/index.js +109 -0
  317. package/src/charting/modelTree/AnalysisPanel.js +159 -0
  318. package/src/charting/modelTree/DiagramTabs.js +217 -0
  319. package/src/charting/modelTree/ModelTree.js +164 -0
  320. package/src/charting/modelTree/ModelTreePanel.js +914 -0
  321. package/src/charting/modelTree/TreeBuilder.js +238 -0
  322. package/src/charting/modelTree/TreeModeRegistry.js +51 -0
  323. package/src/charting/modelTree/TreeViewMode.js +110 -0
  324. package/src/charting/modelTree/buildFilterTrees.js +138 -0
  325. package/src/charting/modelTree/modes/FlatTreeMode.js +46 -0
  326. package/src/charting/modelTree/modes/LayerGroupedTreeMode.js +62 -0
  327. package/src/charting/modelTree/modes/TypeGroupedTreeMode.js +60 -0
  328. package/src/charting/modelTree/treeLayers.js +11 -0
  329. package/src/charting/report/reportHtml.js +82 -0
  330. package/src/charting/report/reportViewer.js +118 -0
  331. package/src/charting/shapes/CircleShape.js +19 -0
  332. package/src/charting/shapes/PathShape.js +17 -0
  333. package/src/charting/shapes/RectShape.js +20 -0
  334. package/src/charting/shapes/Shape.js +20 -0
  335. package/src/charting/shapes/ShapeFactory.js +23 -0
  336. package/src/charting/storage/LocalJsonStore.js +43 -0
  337. package/src/charting/templates/ActorTemplate.js +36 -0
  338. package/src/charting/templates/BoxTemplate.js +27 -0
  339. package/src/charting/templates/CircleTemplate.js +18 -0
  340. package/src/charting/templates/ClassTemplate.js +20 -0
  341. package/src/charting/templates/CloudTemplate.js +43 -0
  342. package/src/charting/templates/ComponentTemplate.js +19 -0
  343. package/src/charting/templates/CylinderTemplate.js +30 -0
  344. package/src/charting/templates/DataStoreTemplate.js +16 -0
  345. package/src/charting/templates/DiamondTemplate.js +10 -0
  346. package/src/charting/templates/DocumentTemplate.js +32 -0
  347. package/src/charting/templates/EllipseTemplate.js +15 -0
  348. package/src/charting/templates/FinalStateTemplate.js +12 -0
  349. package/src/charting/templates/GlyphTemplate.js +47 -0
  350. package/src/charting/templates/HexagonTemplate.js +17 -0
  351. package/src/charting/templates/LifelineTemplate.js +20 -0
  352. package/src/charting/templates/ManualInputTemplate.js +12 -0
  353. package/src/charting/templates/NoteTemplate.js +23 -0
  354. package/src/charting/templates/OctagonTemplate.js +7 -0
  355. package/src/charting/templates/PackageTemplate.js +25 -0
  356. package/src/charting/templates/ParallelogramTemplate.js +11 -0
  357. package/src/charting/templates/PentagonTemplate.js +5 -0
  358. package/src/charting/templates/PolygonTemplate.js +18 -0
  359. package/src/charting/templates/PredefinedProcessTemplate.js +13 -0
  360. package/src/charting/templates/RectangleTemplate.js +28 -0
  361. package/src/charting/templates/RegularPolygonTemplate.js +21 -0
  362. package/src/charting/templates/RoundedRectangleTemplate.js +5 -0
  363. package/src/charting/templates/StadiumTemplate.js +8 -0
  364. package/src/charting/templates/StarTemplate.js +17 -0
  365. package/src/charting/templates/SwimlaneTemplate.js +18 -0
  366. package/src/charting/templates/Template.js +208 -0
  367. package/src/charting/templates/TrapezoidTemplate.js +11 -0
  368. package/src/charting/templates/TriangleTemplate.js +12 -0
  369. package/src/charting/templates/index.js +31 -0
  370. package/src/charting/templates/outline.js +59 -0
  371. package/src/charting/templates/svg.js +19 -0
  372. package/src/charting/textToShapes.js +61 -0
  373. package/src/charting/toolbar/ToolbarButton.js +38 -0
  374. package/src/charting/toolbar/ToolbarCheckbox.js +31 -0
  375. package/src/charting/toolbar/ToolbarItem.js +19 -0
  376. package/src/charting/toolbar/ToolbarMenu.js +36 -0
  377. package/src/charting/toolbar/ToolbarSelect.js +38 -0
  378. package/src/charting/toolbar/ToolbarSeparator.js +7 -0
  379. package/src/charting/toolbar/ToolbarText.js +22 -0
  380. package/src/charting/toolbar/index.js +8 -0
  381. package/src/charting/toolbar/pickFile.js +14 -0
  382. package/src/charting/viewDecorations.js +85 -0
  383. package/src/charting/zOrder.js +57 -0
  384. package/src/csvTable.js +61 -0
  385. package/src/datamodel.js +122 -0
  386. package/src/datawindow/BoundedWindow.js +36 -0
  387. package/src/datawindow/FlatDataWindow.js +34 -0
  388. package/src/datawindow/GraphDataWindow.js +40 -0
  389. package/src/datawindow/GroupedSampleDataWindow.js +16 -0
  390. package/src/datawindow/SeriesDataWindow.js +42 -0
  391. package/src/datawindow/index.js +31 -0
  392. package/src/diagramCatalog.js +30 -0
  393. package/src/ebnfDiagram.js +57 -0
  394. package/src/ebnfParser.js +129 -0
  395. package/src/exportImage.js +233 -0
  396. package/src/index.js +2564 -0
  397. package/src/itIcons.js +84 -0
  398. package/src/kernelExpr.js +243 -0
  399. package/src/propertiesDialog.js +463 -0
  400. package/src/railroadDiagram.js +571 -0
  401. package/src/treeModeCatalog.js +16 -0
  402. package/src/workspace/ContextBus.js +79 -0
  403. package/src/workspace/EditorShell.js +67 -0
  404. package/src/workspace/Part.js +163 -0
  405. package/src/workspace/PartFactory.js +49 -0
  406. package/src/workspace/PartRegistry.js +86 -0
  407. package/src/workspace/Workspace.js +321 -0
  408. package/src/workspace/archimateServices.js +33 -0
  409. package/src/workspace/dom.js +120 -0
  410. package/src/workspace/index.js +75 -0
  411. package/src/workspace/layout/GridNode.js +280 -0
  412. package/src/workspace/layout/LayoutNode.js +89 -0
  413. package/src/workspace/layout/PartNode.js +77 -0
  414. package/src/workspace/layout/SplitNode.js +114 -0
  415. package/src/workspace/layout/TabsNode.js +191 -0
  416. package/src/workspace/layout/index.js +24 -0
  417. package/src/workspace/parts/AdapterPart.js +33 -0
  418. package/src/workspace/parts/ArchimateCanvasPart.js +345 -0
  419. package/src/workspace/parts/ArchimateEditorPart.js +79 -0
  420. package/src/workspace/parts/ChartPart.js +115 -0
  421. package/src/workspace/parts/ContentPart.js +34 -0
  422. package/src/workspace/parts/DetailPart.js +46 -0
  423. package/src/workspace/parts/DiagramEditorPart.js +135 -0
  424. package/src/workspace/parts/EditorPart.js +388 -0
  425. package/src/workspace/parts/HtmlPart.js +25 -0
  426. package/src/workspace/parts/ListPart.js +57 -0
  427. package/src/workspace/parts/ModelFile.js +187 -0
  428. package/src/workspace/parts/ModelsPart.js +135 -0
  429. package/src/workspace/styles.js +258 -0
  430. package/src/workspace/themes.js +96 -0
  431. package/src/workspace/workArea.js +413 -0
  432. package/src/workspace/workAreaModel.js +197 -0
  433. package/src/workspace.js +16 -0
  434. package/src/zip/ZipArchive.js +160 -0
  435. package/src/zip/crc32.js +25 -0
  436. package/src/zip/inflate.js +159 -0
@@ -0,0 +1,58 @@
1
+ import { ViewPropertiesDialog } from './ViewPropertiesDialog.js';
2
+ import { inheritableFields, readInheritableFields } from './SettingsCascade.js';
3
+ import { MODEL_SETTINGS_PROPERTIES } from './SettingsManager.js';
4
+
5
+ const byKey = (keys) => MODEL_SETTINGS_PROPERTIES.filter(p => keys.includes(p.key));
6
+ /** Diagram settings a view may override (routing, grid, how invalid relationships show). */
7
+ const DIAGRAM = byKey(['edgeRouting', 'gridSize', 'showGrid', 'invalidRelationships']);
8
+ /** Watermark settings a view may override. */
9
+ const WATERMARK = byKey(['watermark', 'watermarkRotation', 'watermarkRepeat', 'watermarkOpacity']);
10
+ const TITLE_POSITIONS = [['none', 'None'], ['top', 'Top'], ['bottom', 'Bottom']];
11
+
12
+ /**
13
+ * SettingsViewPropertiesDialog — a view's properties plus its level of the
14
+ * settings cascade (SettingsManager): routing and grid under Diagram;
15
+ * background, title band and watermark under Appearance. A cascading setting
16
+ * may inherit, showing the value and the level it would come from; settings
17
+ * only a view has (background, title band) are set outright. Used by the
18
+ * ArchiMate editor.
19
+ */
20
+ export class SettingsViewPropertiesDialog extends ViewPropertiesDialog {
21
+ /**
22
+ * @param {Object} options - As ViewPropertiesDialog, plus:
23
+ * @param {SettingsManager} options.settingsManager
24
+ * @param {string} [options.modelId] - Settings key of the model level
25
+ */
26
+ constructor({ settingsManager, modelId = 'default', ...rest }) {
27
+ super(rest);
28
+ this.settings = settingsManager;
29
+ this.modelId = modelId;
30
+ }
31
+
32
+ sections() {
33
+ const own = this.settings.getViewSettings(this.view);
34
+ const inherited = this.settings.cascade(this.view, this.modelId).inheritedBy('view');
35
+ return [
36
+ { type: 'heading', label: 'Diagram' },
37
+ ...inheritableFields(DIAGRAM, own, inherited),
38
+ { type: 'heading', label: 'Appearance' },
39
+ { key: 'background', label: 'Background', type: 'color', value: own.background || '#ffffff' },
40
+ { key: 'backgroundImage', label: 'Background image', type: 'text', value: own.backgroundImage ?? '', placeholder: 'URL (optional)' },
41
+ // The band's text is the "title" setting; it is not the view's name.
42
+ { key: 'bandTitle', label: 'Title band', type: 'text', value: own.title ?? '', placeholder: 'Text shown above or below the diagram' },
43
+ { key: 'titlePosition', label: 'Title position', type: 'select', value: own.titlePosition ?? 'none', choices: TITLE_POSITIONS },
44
+ ...inheritableFields(WATERMARK, own, inherited),
45
+ ];
46
+ }
47
+
48
+ applySections(values) {
49
+ this.settings.saveViewSettings(this.view, {
50
+ // undefined inherits from the model level (SettingsCascade).
51
+ ...readInheritableFields([...DIAGRAM, ...WATERMARK], values),
52
+ background: values.background,
53
+ backgroundImage: values.backgroundImage?.trim() ?? '',
54
+ title: values.bandTitle?.trim() ?? '',
55
+ titlePosition: values.titlePosition || 'none',
56
+ });
57
+ }
58
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * ShapePaths — pure geometry-to-SVG-path helpers used by several chart types.
3
+ */
4
+ export class ShapePaths {
5
+ /**
6
+ * Build an SVG path for an annular pie/doughnut slice.
7
+ * @param {number} cx center x
8
+ * @param {number} cy center y
9
+ * @param {number} rOuter outer radius
10
+ * @param {number} rInner inner radius (0 for a pie wedge)
11
+ * @param {number} startAngle radians
12
+ * @param {number} endAngle radians
13
+ * @returns {string}
14
+ */
15
+ static donutSlicePath(cx, cy, rOuter, rInner, startAngle, endAngle) {
16
+ const largeArc = (endAngle - startAngle) > Math.PI ? 1 : 0;
17
+ const outerStart = { x: cx + rOuter * Math.cos(startAngle), y: cy + rOuter * Math.sin(startAngle) };
18
+ const outerEnd = { x: cx + rOuter * Math.cos(endAngle), y: cy + rOuter * Math.sin(endAngle) };
19
+ if (rInner <= 0) {
20
+ return `M${cx},${cy} L${outerStart.x},${outerStart.y} A${rOuter},${rOuter} 0 ${largeArc} 1 ${outerEnd.x},${outerEnd.y} Z`;
21
+ }
22
+ const innerStart = { x: cx + rInner * Math.cos(endAngle), y: cy + rInner * Math.sin(endAngle) };
23
+ const innerEnd = { x: cx + rInner * Math.cos(startAngle), y: cy + rInner * Math.sin(startAngle) };
24
+ return `M${outerStart.x},${outerStart.y} A${rOuter},${rOuter} 0 ${largeArc} 1 ${outerEnd.x},${outerEnd.y} `
25
+ + `L${innerStart.x},${innerStart.y} A${rInner},${rInner} 0 ${largeArc} 0 ${innerEnd.x},${innerEnd.y} Z`;
26
+ }
27
+ }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Statistics — pure, DOM-free helpers for statistical chart types.
3
+ *
4
+ * These used to live as private methods on RenderEngine. Moving them to a
5
+ * shared module lets HistogramChart, BoxPlotChart, DensityChart, ViolinChart,
6
+ * QQPlotChart, and LagPlotChart stay self-contained and testable without the
7
+ * full engine instance.
8
+ */
9
+ export class Statistics {
10
+ /** Computes evenly-spaced bin edges/counts for a raw numeric sample. */
11
+ static histogramBins(values, binCount) {
12
+ const min = Math.min(...values);
13
+ const max = Math.max(...values);
14
+ const range = (max - min) || 1;
15
+ const n = Math.max(1, binCount);
16
+ const width = range / n;
17
+ const bins = Array.from({ length: n }, (_, i) => ({ from: min + i * width, to: min + (i + 1) * width, count: 0 }));
18
+ for (const v of values) {
19
+ let idx = Math.floor((v - min) / width);
20
+ if (idx >= n) idx = n - 1;
21
+ if (idx < 0) idx = 0;
22
+ bins[idx].count++;
23
+ }
24
+ return bins;
25
+ }
26
+
27
+ /**
28
+ * Inverse standard-normal CDF (probit function) via Peter Acklam's
29
+ * rational approximation.
30
+ */
31
+ static normalQuantile(p) {
32
+ if (p <= 0) return -Infinity;
33
+ if (p >= 1) return Infinity;
34
+ const a = [-3.969683028665376e+01, 2.209460984245205e+02, -2.759285104469687e+02, 1.383577518672690e+02, -3.066479806614716e+01, 2.506628277459239e+00];
35
+ const b = [-5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02, 6.680131188771972e+01, -1.328068155288572e+01];
36
+ const c = [-7.784894002430293e-03, -3.223964580411365e-01, -2.400758277161838e+00, -2.549732539343734e+00, 4.374664141464968e+00, 2.938163982698783e+00];
37
+ const d = [7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00];
38
+ const pLow = 0.02425, pHigh = 1 - pLow;
39
+
40
+ if (p < pLow) {
41
+ const q = Math.sqrt(-2 * Math.log(p));
42
+ return (((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5])
43
+ / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);
44
+ }
45
+ if (p <= pHigh) {
46
+ const q = p - 0.5, r = q * q;
47
+ return (((((a[0] * r + a[1]) * r + a[2]) * r + a[3]) * r + a[4]) * r + a[5]) * q
48
+ / (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1);
49
+ }
50
+ const q = Math.sqrt(-2 * Math.log(1 - p));
51
+ return -(((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5])
52
+ / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);
53
+ }
54
+
55
+ /** Pairs each sorted sample value with a theoretical normal quantile. */
56
+ static qqPoints(values) {
57
+ const n = values.length;
58
+ if (n === 0) return [];
59
+ const sorted = [...values].sort((a, b) => a - b);
60
+ return sorted.map((sample, i) => ({ theoretical: Statistics.normalQuantile((i + 0.5) / n), sample }));
61
+ }
62
+
63
+ /** `[{x: values[i-lag], y: values[i]}]` for i = lag..length-1. */
64
+ static lagPairs(values, lag = 1) {
65
+ if (lag < 1 || values.length <= lag) return [];
66
+ const pairs = [];
67
+ for (let i = lag; i < values.length; i++) pairs.push({ x: values[i - lag], y: values[i] });
68
+ return pairs;
69
+ }
70
+
71
+ /** Linear-interpolation quantile (R-7 / PERCENTILE.INC) over a sorted array. */
72
+ static quantile(sorted, p) {
73
+ if (sorted.length === 0) return 0;
74
+ if (sorted.length === 1) return sorted[0];
75
+ const idx = p * (sorted.length - 1);
76
+ const lo = Math.floor(idx), hi = Math.ceil(idx);
77
+ if (lo === hi) return sorted[lo];
78
+ return sorted[lo] + (sorted[hi] - sorted[lo]) * (idx - lo);
79
+ }
80
+
81
+ /** Computes box-and-whisker summary stats for a raw numeric sample. */
82
+ static boxPlotStats(values) {
83
+ const sorted = [...values].sort((a, b) => a - b);
84
+ const q1 = Statistics.quantile(sorted, 0.25);
85
+ const median = Statistics.quantile(sorted, 0.5);
86
+ const q3 = Statistics.quantile(sorted, 0.75);
87
+ const iqr = q3 - q1;
88
+ const lowFence = q1 - 1.5 * iqr;
89
+ const highFence = q3 + 1.5 * iqr;
90
+ const within = sorted.filter(v => v >= lowFence && v <= highFence);
91
+ const outliers = sorted.filter(v => v < lowFence || v > highFence);
92
+ return {
93
+ min: within.length ? within[0] : sorted[0],
94
+ q1, median, q3,
95
+ max: within.length ? within[within.length - 1] : sorted[sorted.length - 1],
96
+ outliers,
97
+ };
98
+ }
99
+
100
+ /** Population standard deviation. */
101
+ static stdev(values) {
102
+ const n = values.length;
103
+ if (n < 2) return 0;
104
+ const mean = values.reduce((s, v) => s + v, 0) / n;
105
+ const variance = values.reduce((s, v) => s + (v - mean) ** 2, 0) / n;
106
+ return Math.sqrt(variance);
107
+ }
108
+
109
+ /**
110
+ * Gaussian-kernel density estimate — a smoothed distribution curve from
111
+ * a raw numeric sample. `bandwidth` defaults via Silverman's rule of thumb.
112
+ * @returns {Array<{x: number, density: number}>}
113
+ */
114
+ static kernelDensityEstimate(values, options = {}) {
115
+ const n = values.length;
116
+ const dataMin = Math.min(...values), dataMax = Math.max(...values);
117
+ const fallbackBandwidth = (dataMax - dataMin) * 0.1 || 1;
118
+ const silverman = n >= 2 ? 1.06 * Statistics.stdev(values) * Math.pow(n, -1 / 5) : 0;
119
+ const bandwidth = options.bandwidth ?? (silverman || fallbackBandwidth);
120
+ const sampleCount = options.sampleCount ?? 60;
121
+ const min = options.min ?? (dataMin - 3 * bandwidth);
122
+ const max = options.max ?? (dataMax + 3 * bandwidth);
123
+ const step = (max - min) / Math.max(1, sampleCount - 1);
124
+ const gaussian = (u) => Math.exp(-0.5 * u * u) / Math.sqrt(2 * Math.PI);
125
+
126
+ const points = [];
127
+ for (let i = 0; i < sampleCount; i++) {
128
+ const x = min + i * step;
129
+ const density = n === 0 ? 0 : values.reduce((s, v) => s + gaussian((x - v) / bandwidth), 0) / (n * bandwidth);
130
+ points.push({ x, density });
131
+ }
132
+ return points;
133
+ }
134
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * TemplateCatalog — registry of template types that can be added to a diagram.
3
+ * Each entry describes a template type and how to create instances.
4
+ */
5
+ export class TemplateCatalog {
6
+ constructor() {
7
+ this.entries = new Map(); // type -> { name, icon, factory, properties }
8
+ }
9
+
10
+ /**
11
+ * Register a template type.
12
+ * @param {string} type - Unique type identifier
13
+ * @param {Object} spec - Template specification
14
+ * @param {string} spec.name - Display name
15
+ * @param {string} spec.icon - Icon/emoji (e.g., "📦")
16
+ * @param {Function} spec.factory - Factory function: (id, x, y) => Template instance
17
+ * @param {Object} spec.properties - Default properties for this type
18
+ */
19
+ register(type, spec) {
20
+ if (!spec.factory) {
21
+ throw new Error(`TemplateCatalog.register: factory required for type '${type}'`);
22
+ }
23
+ this.entries.set(type, {
24
+ type,
25
+ name: spec.name || type,
26
+ icon: spec.icon || '■',
27
+ factory: spec.factory,
28
+ properties: spec.properties || {},
29
+ });
30
+ }
31
+
32
+ /**
33
+ * Get a template type entry.
34
+ */
35
+ get(type) {
36
+ return this.entries.get(type);
37
+ }
38
+
39
+ /**
40
+ * Get all entries.
41
+ */
42
+ getAll() {
43
+ return Array.from(this.entries.values());
44
+ }
45
+
46
+ /**
47
+ * Create a template instance of given type.
48
+ * @param {string} type
49
+ * @param {string} id - Instance id
50
+ * @param {number} x - X position
51
+ * @param {number} y - Y position
52
+ * @returns {Template|null}
53
+ */
54
+ create(type, id, x, y) {
55
+ const entry = this.get(type);
56
+ if (!entry) return null;
57
+ return entry.factory(id, x, y);
58
+ }
59
+ }
@@ -0,0 +1,103 @@
1
+ import { LocalJsonStore } from './storage/LocalJsonStore.js';
2
+
3
+ /**
4
+ * TemplateLibrary — view templates kept across models: a tool's own library,
5
+ * beside each model's templates. What every such library does: keep entries,
6
+ * offer built-in ones, give ids, and tell listeners after a change. A kind of
7
+ * view subclasses it for its own entries and imports (CanvasTemplateLibrary).
8
+ *
9
+ * An entry is plain JSON: `{ id, name, description, thumbnail, view }`, where
10
+ * `view` is the view's JSON form and `thumbnail` a `data:` URL or null.
11
+ *
12
+ * Entries are kept in a store (LocalJsonStore under the class's STORAGE_KEY by
13
+ * default, so the library lives in the browser); pass another store with
14
+ * `load(fallback)` and `save(value)` to keep them elsewhere. Built-in entries
15
+ * (`defaults`, the class's DEFAULTS unless given others) come first, are marked
16
+ * `builtIn`, are not stored, and cannot be renamed or removed.
17
+ */
18
+ export class TemplateLibrary {
19
+ /** The storage key the default store uses; a subclass names its own. */
20
+ static STORAGE_KEY = 'renderengine.templates';
21
+
22
+ /** Built-in entries; a subclass names its own. */
23
+ static DEFAULTS = Object.freeze([]);
24
+
25
+ /**
26
+ * @param {Object} [options]
27
+ * @param {{load: Function, save: Function}} [options.store] - Where entries are kept
28
+ * @param {Array<Object>} [options.defaults] - Built-in entries
29
+ */
30
+ constructor({ store = new LocalJsonStore(this.constructor.STORAGE_KEY), defaults = this.constructor.DEFAULTS } = {}) {
31
+ this.store = store;
32
+ this.defaults = defaults.map(entry => ({ ...entry, builtIn: true }));
33
+ const saved = store.load([]);
34
+ this._entries = Array.isArray(saved) ? saved.filter(e => e && e.id && e.view) : [];
35
+ this._listeners = new Set();
36
+ }
37
+
38
+ /** Every entry: the built-in ones, then those added, in the order added. @returns {Array<Object>} */
39
+ list() {
40
+ return [...this.defaults, ...this._entries];
41
+ }
42
+
43
+ /** The entry with `id`, or null. */
44
+ get(id) {
45
+ return this.list().find(e => e.id === id) ?? null;
46
+ }
47
+
48
+ /**
49
+ * Keep a template.
50
+ * @param {Object} entry
51
+ * @param {Object} entry.view - The view's JSON form
52
+ * @param {string} [entry.name] - Defaults to the view's name
53
+ * @param {string} [entry.description]
54
+ * @param {string|null} [entry.thumbnail] - A `data:` URL
55
+ * @returns {Object} the entry as kept, with its id
56
+ */
57
+ add({ view, name = view?.name ?? 'Template', description = '', thumbnail = null }) {
58
+ if (!view) throw new Error('A template needs a view');
59
+ const entry = { id: this._newId(), name, description, thumbnail, view: JSON.parse(JSON.stringify(view)) };
60
+ this._entries.push(entry);
61
+ this._changed();
62
+ return entry;
63
+ }
64
+
65
+ /** Rename or re-describe an entry (not a built-in one). @returns {boolean} whether it was changed */
66
+ update(id, { name, description } = {}) {
67
+ const entry = this._entries.find(e => e.id === id);
68
+ if (!entry) return false;
69
+ if (name !== undefined) entry.name = name;
70
+ if (description !== undefined) entry.description = description;
71
+ this._changed();
72
+ return true;
73
+ }
74
+
75
+ /** Forget an entry (not a built-in one). @returns {boolean} whether it was removed */
76
+ remove(id) {
77
+ const before = this._entries.length;
78
+ this._entries = this._entries.filter(e => e.id !== id);
79
+ if (this._entries.length === before) return false;
80
+ this._changed();
81
+ return true;
82
+ }
83
+
84
+ /** Call `fn(entries)` after every change. @returns {Function} stops it */
85
+ onChange(fn) {
86
+ this._listeners.add(fn);
87
+ return () => this._listeners.delete(fn);
88
+ }
89
+
90
+ /** @private */
91
+ _newId() {
92
+ const taken = new Set(this.list().map(e => e.id));
93
+ let n = this._entries.length + 1;
94
+ while (taken.has(`template-${n}`)) n++;
95
+ return `template-${n}`;
96
+ }
97
+
98
+ /** @protected */
99
+ _changed() {
100
+ this.store.save(this._entries);
101
+ for (const fn of this._listeners) fn(this.list());
102
+ }
103
+ }
@@ -0,0 +1,168 @@
1
+ /**
2
+ * TextStyle — how a shape's text is set: font, size, bold, italic, underline,
3
+ * and where it sits in the shape (alignment across, position down). One
4
+ * definition for every editor that lets text be styled (the template editor's
5
+ * shapes, the ArchiMate canvas shapes, the ArchiMate properties dialog), so the
6
+ * choices, how a size is written, the dialog fields and the drawing agree.
7
+ *
8
+ * A style is plain data, in the names a view instance's `appearance` uses:
9
+ * `{ fontFamily?, fontSize?, fontWeight?: 'bold', fontStyle?: 'italic',
10
+ * textDecoration?: 'underline', textAlign?: 'left'|'center'|'right', textPosition?: 'top'|'middle'|'bottom' }`.
11
+ * A size is kept as written; a bare number is points ("10" → "10pt"), as Archi keeps it.
12
+ * The graph renderer calls the position `verticalAlign` (fromNode / toNode convert).
13
+ */
14
+
15
+ /** Fonts offered (any other may be typed). */
16
+ export const FONT_FAMILY_CHOICES = Object.freeze(['Segoe UI', 'Arial', 'Helvetica', 'Verdana', 'Tahoma', 'Calibri', 'Times New Roman', 'Georgia', 'Courier New']);
17
+
18
+ /** Sizes offered, in points. */
19
+ export const FONT_SIZE_CHOICES = Object.freeze(['8pt', '9pt', '10pt', '11pt', '12pt', '14pt', '16pt', '18pt', '20pt', '24pt', '28pt', '36pt']);
20
+
21
+ /** Where text sits across a shape, and down it. */
22
+ export const TEXT_ALIGN_CHOICES = Object.freeze(['left', 'center', 'right']);
23
+ export const TEXT_POSITION_CHOICES = Object.freeze(['top', 'middle', 'bottom']);
24
+
25
+ /** The style keys. */
26
+ export const TEXT_STYLE_KEYS = Object.freeze(['fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'textDecoration', 'textAlign', 'textPosition']);
27
+
28
+ /** A style key's name on a graph-renderer node, where it differs. */
29
+ const NODE_NAMES = Object.freeze({ textPosition: 'verticalAlign' });
30
+
31
+ const isUnset = (v) => v === undefined || v === null || v === '';
32
+
33
+ export class TextStyle {
34
+ /**
35
+ * A size as stored: a bare number is points.
36
+ * @param {string|number} size
37
+ * @returns {string|undefined}
38
+ */
39
+ static normaliseSize(size) {
40
+ if (isUnset(size)) return undefined;
41
+ const text = String(size).trim();
42
+ return /^\d+(\.\d+)?$/.test(text) ? `${text}pt` : text;
43
+ }
44
+
45
+ /**
46
+ * A size in pixels, for drawing: points are 4/3 of a pixel, a bare number or
47
+ * "px" is pixels as given. Undefined when there is no usable size.
48
+ */
49
+ static pixels(size) {
50
+ if (isUnset(size)) return undefined;
51
+ const value = parseFloat(size);
52
+ if (!(value > 0)) return undefined;
53
+ return String(size).trim().endsWith('pt') ? value * 4 / 3 : value;
54
+ }
55
+
56
+ /**
57
+ * FormDialog fields for a style: font, size, bold, italic, underline (unless
58
+ * `underline: false`), alignment and position (unless `placement: false`).
59
+ * Their keys are prefixed with `prefix`.
60
+ * @param {Object} style - The current style
61
+ * @param {Object} [options]
62
+ * @param {boolean} [options.underline] - Offer underline (default true)
63
+ * @param {boolean} [options.placement] - Offer alignment and position (default true)
64
+ * @param {string} [options.prefix] - Key prefix (default 'text-')
65
+ */
66
+ static fields(style = {}, { underline = true, placement = true, prefix = 'text-' } = {}) {
67
+ const choices = (list) => list.map(v => [v, v === 'center' ? 'centre' : v]);
68
+ return [
69
+ { key: `${prefix}fontFamily`, label: 'Font', type: 'text', value: style.fontFamily ?? '', suggestions: [...FONT_FAMILY_CHOICES], placeholder: 'default' },
70
+ { key: `${prefix}fontSize`, label: 'Text size', type: 'text', value: style.fontSize ?? '', suggestions: [...FONT_SIZE_CHOICES], placeholder: 'default' },
71
+ { key: `${prefix}bold`, label: 'Bold', type: 'checkbox', value: style.fontWeight === 'bold' },
72
+ { key: `${prefix}italic`, label: 'Italic', type: 'checkbox', value: style.fontStyle === 'italic' },
73
+ ...(underline ? [{ key: `${prefix}underline`, label: 'Underline', type: 'checkbox', value: style.textDecoration === 'underline' }] : []),
74
+ ...(placement ? [
75
+ { key: `${prefix}textAlign`, label: 'Alignment', type: 'select', value: style.textAlign ?? '', choices: choices(TEXT_ALIGN_CHOICES), allowEmpty: true },
76
+ { key: `${prefix}textPosition`, label: 'Position', type: 'select', value: style.textPosition ?? '', choices: choices(TEXT_POSITION_CHOICES), allowEmpty: true },
77
+ ] : []),
78
+ ];
79
+ }
80
+
81
+ /**
82
+ * The style a dialog's values describe (fields made by `fields()`); an
83
+ * unset value is undefined. Fields not offered are left out.
84
+ */
85
+ static fromValues(values, { prefix = 'text-' } = {}) {
86
+ const has = (key) => `${prefix}${key}` in values;
87
+ const v = (key) => values[`${prefix}${key}`];
88
+ const text = (key) => String(v(key) ?? '').trim() || undefined;
89
+ return {
90
+ ...(has('fontFamily') && { fontFamily: text('fontFamily') }),
91
+ ...(has('fontSize') && { fontSize: TextStyle.normaliseSize(v('fontSize')) }),
92
+ ...(has('bold') && { fontWeight: v('bold') ? 'bold' : undefined }),
93
+ ...(has('italic') && { fontStyle: v('italic') ? 'italic' : undefined }),
94
+ ...(has('underline') && { textDecoration: v('underline') ? 'underline' : undefined }),
95
+ ...(has('textAlign') && { textAlign: text('textAlign') }),
96
+ ...(has('textPosition') && { textPosition: text('textPosition') }),
97
+ };
98
+ }
99
+
100
+ /** The style a graph-renderer node is drawn with (its own names read back; the size normalised). */
101
+ static fromNode(node = {}) {
102
+ return Object.fromEntries(TEXT_STYLE_KEYS
103
+ .map(key => [key, node[NODE_NAMES[key] ?? key]])
104
+ .map(([key, value]) => [key, key === 'fontSize' ? TextStyle.normaliseSize(value) : (isUnset(value) ? undefined : value)])
105
+ .filter(([, value]) => value !== undefined));
106
+ }
107
+
108
+ /** A style in a graph-renderer node's names (unset values as undefined, to clear them). */
109
+ static toNode(style = {}) {
110
+ return Object.fromEntries(Object.entries(style).map(([key, value]) => [NODE_NAMES[key] ?? key, value]));
111
+ }
112
+
113
+ /** The keys of `next` whose value differs from `current`'s (unset counts as one value). */
114
+ static changes(current = {}, next = {}) {
115
+ return Object.fromEntries(Object.entries(next).filter(([k, value]) => {
116
+ const was = current[k];
117
+ return !((isUnset(was) && isUnset(value)) || was === value);
118
+ }));
119
+ }
120
+
121
+ /**
122
+ * SVG text attributes for a style; `defaultPixels` when it has no size.
123
+ * (Alignment and position place the text; see `placement`.)
124
+ * @returns {Object} attributes (unset ones left out)
125
+ */
126
+ static svgAttributes(style = {}, { defaultPixels = 12 } = {}) {
127
+ return {
128
+ 'font-size': TextStyle.pixels(style.fontSize) ?? defaultPixels,
129
+ ...(style.fontFamily && { 'font-family': style.fontFamily }),
130
+ ...(style.fontWeight && { 'font-weight': style.fontWeight }),
131
+ ...(style.fontStyle && { 'font-style': style.fontStyle }),
132
+ ...(style.textDecoration && { 'text-decoration': style.textDecoration }),
133
+ };
134
+ }
135
+
136
+ /**
137
+ * Where a block of text lines goes in a box, from the style's alignment and
138
+ * position (or `defaults` where the style sets none): the x and SVG
139
+ * text-anchor of every line, and the baseline of the first (each next line
140
+ * is `lineHeight` lower).
141
+ * @param {Object} style
142
+ * @param {{left, top, right, bottom}} box - Where the text may go
143
+ * @param {number} lineCount
144
+ * @param {Object} [options]
145
+ * @param {number} [options.pixels] - The text's size
146
+ * @param {number} [options.lineHeight] - Defaults to 1.2 × pixels
147
+ * @param {number} [options.pad] - Space from the box's sides
148
+ * @param {{textAlign?, textPosition?}} [options.defaults] - Default 'left', 'top'
149
+ * @returns {{x: number, textAnchor: 'start'|'middle'|'end', baseline: number}}
150
+ */
151
+ static block(style, box, lineCount, { pixels = 12, lineHeight = Math.round(pixels * 1.2), pad = 6, defaults = {} } = {}) {
152
+ const align = style.textAlign ?? defaults.textAlign ?? 'left';
153
+ const position = style.textPosition ?? defaults.textPosition ?? 'top';
154
+ const across = align === 'right' ? { x: box.right - pad, textAnchor: 'end' }
155
+ : align === 'center' ? { x: (box.left + box.right) / 2, textAnchor: 'middle' }
156
+ : { x: box.left + pad, textAnchor: 'start' };
157
+ const height = box.bottom - box.top;
158
+ const baseline = position === 'bottom' ? box.bottom - pad - (lineCount - 1) * lineHeight
159
+ : position === 'middle' ? box.top + (height - lineCount * lineHeight) / 2 + pixels
160
+ : box.top + pad + pixels;
161
+ return { ...across, baseline };
162
+ }
163
+
164
+ /** Whether the style places its text (sets alignment or position). */
165
+ static placesText(style = {}) {
166
+ return !isUnset(style.textAlign) || !isUnset(style.textPosition);
167
+ }
168
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * ViewFit — how to show a drawing's bounds whole in a viewport: centred, with
3
+ * a margin, in the viewport's shape. One calculation for every way a view is
4
+ * zoomed: a viewBox (the graph engine's SvgZoom) or a scale and pan (the
5
+ * template editor's transform).
6
+ */
7
+ export class ViewFit {
8
+ /**
9
+ * The viewBox that shows `bounds` whole.
10
+ * @param {{x, y, width, height}} bounds - Drawing coordinates
11
+ * @param {{width, height}} viewport - The drawing's size on screen (none: the bounds' own shape)
12
+ * @param {number} [margin] - Space around, in drawing units
13
+ * @returns {{x, y, width, height}}
14
+ */
15
+ static viewBox(bounds, viewport, margin = 20) {
16
+ const width = Math.max(1, bounds.width + margin * 2);
17
+ const height = Math.max(1, bounds.height + margin * 2);
18
+ const aspect = viewport.width > 0 && viewport.height > 0 ? viewport.width / viewport.height : width / height;
19
+ const fitted = width / height > aspect ? { width, height: width / aspect } : { width: height * aspect, height };
20
+ return {
21
+ x: bounds.x + bounds.width / 2 - fitted.width / 2,
22
+ y: bounds.y + bounds.height / 2 - fitted.height / 2,
23
+ ...fitted,
24
+ };
25
+ }
26
+
27
+ /**
28
+ * The scale and pan that show `bounds` whole in the visible area:
29
+ * shown = drawing * scale + pan.
30
+ * @param {{x, y, width, height}} bounds
31
+ * @param {{x?, y?, width, height}} viewport - The visible area, in the units the pan is in (origin 0, 0 unless given)
32
+ * @param {number} [margin] - Drawing units
33
+ * @param {{minScale?: number, maxScale?: number}} [limits]
34
+ * @returns {{scale: number, panX: number, panY: number}}
35
+ */
36
+ static transform(bounds, viewport, margin = 20, { minScale = 0.1, maxScale = 5 } = {}) {
37
+ if (!(viewport.width > 0 && viewport.height > 0)) return { scale: 1, panX: 0, panY: 0 };
38
+ const box = ViewFit.viewBox(bounds, viewport, margin);
39
+ const scale = Math.min(maxScale, Math.max(minScale, viewport.width / box.width));
40
+ const cx = bounds.x + bounds.width / 2, cy = bounds.y + bounds.height / 2;
41
+ const { x = 0, y = 0 } = viewport;
42
+ return { scale, panX: x + viewport.width / 2 - cx * scale, panY: y + viewport.height / 2 - cy * scale };
43
+ }
44
+
45
+ /** The box around boxes ({left, top, right, bottom} or {x, y, width, height}); null for none. */
46
+ static union(boxes) {
47
+ const edges = boxes.filter(Boolean).map(b => ('left' in b
48
+ ? b
49
+ : { left: b.x, top: b.y, right: b.x + b.width, bottom: b.y + b.height }));
50
+ if (!edges.length) return null;
51
+ const left = Math.min(...edges.map(e => e.left)), top = Math.min(...edges.map(e => e.top));
52
+ const right = Math.max(...edges.map(e => e.right)), bottom = Math.max(...edges.map(e => e.bottom));
53
+ return { x: left, y: top, width: right - left, height: bottom - top };
54
+ }
55
+ }