@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,66 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>ArchiMate Modeller</title>
7
+ </head>
8
+ <body>
9
+ <!-- Deliberately empty: the workbench and the modeller part are built from
10
+ JavaScript and JSON specs. A classic script (not type="module") so the
11
+ page also opens straight off disk. The modeller is the diagram editor's
12
+ canvas (ArchimateCanvasPart), one per model in a ModelsPart, so several
13
+ models can be open at once (File > New model, Open… in a new tab);
14
+ archimate-legacy.html keeps the graph-engine editor for comparison. -->
15
+ <script>
16
+ function runModeller() {
17
+ const { el, registerBuiltinParts, ArchimateCanvasPart } = RenderEngineWorkspace;
18
+
19
+ Object.assign(document.documentElement.style, { height: '100%' });
20
+ Object.assign(document.body.style, { margin: '0', height: '100%', display: 'flex' });
21
+
22
+ const ws = document.body.appendChild(el({
23
+ tag: 'ws-workspace',
24
+ attrs: { label: 'ArchiMate Modeller', theme: 'light' },
25
+ style: { flex: '1 1 auto', minHeight: '0' },
26
+ }));
27
+ registerBuiltinParts(ws);
28
+ ws.registerPart(ArchimateCanvasPart);
29
+
30
+ // The models open at once: a tab each. The first is this sample; New model makes empty ones.
31
+ ws.addParts([{
32
+ id: 'models', type: 'models', editorType: 'archimate-canvas', newModel: { analysis: true },
33
+ models: [{
34
+ id: 'modeller', name: 'Sample model', analysis: true,
35
+ elements: [
36
+ { id: 'customer', name: 'Customer', layer: 'business', type: 'business-actor', icon: '👤' },
37
+ { id: 'order', name: 'Order Process', layer: 'business', type: 'business-process' },
38
+ { id: 'order-svc', name: 'Order Service', layer: 'application', type: 'application-service' },
39
+ { id: 'db', name: 'Database', layer: 'technology', type: 'node', icon: '🗄️' },
40
+ ],
41
+ relationships: [
42
+ { source: 'customer', target: 'order', kind: 'assignment' },
43
+ { source: 'order-svc', target: 'order', kind: 'serving' },
44
+ { source: 'db', target: 'order-svc', kind: 'serving' },
45
+ ],
46
+ views: [{
47
+ id: 'default',
48
+ name: 'Default View',
49
+ elementIds: ['customer', 'order', 'order-svc', 'db'],
50
+ layout: {
51
+ customer: { x: 80, y: 80 },
52
+ order: { x: 300, y: 80 },
53
+ 'order-svc': { x: 300, y: 200 },
54
+ db: { x: 80, y: 200 },
55
+ },
56
+ }],
57
+ }],
58
+ }]);
59
+
60
+ ws.registerPerspective('Modelling', { type: 'part', partId: 'models' });
61
+ ws.activatePerspective('Modelling');
62
+ }
63
+ </script>
64
+ <script src="../dist/renderengine-workspace.umd.js" onload="runModeller()"></script>
65
+ </body>
66
+ </html>
@@ -0,0 +1,51 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Diagram Editor</title>
7
+ <style>
8
+ html, body { margin: 0; height: 100%; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; }
9
+ body { display: flex; flex-direction: column; }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <!-- The base diagram editor (DiagramEditorPart) in the workbench: palettes of
14
+ flowchart, UML and other shapes, several diagrams per model and several
15
+ models at once (File > New model). Classic scripts, so the page opens
16
+ straight off disk; `npm run diagram` opens it. -->
17
+ <script src="../dist/renderengine.umd.js"></script>
18
+ <script src="../dist/renderengine-workspace.umd.js"></script>
19
+ <script>
20
+ const { RectangleTemplate, StadiumTemplate, DiamondTemplate } = window.RenderEngine;
21
+ const { el, registerBuiltinParts, DiagramEditorPart } = window.RenderEngineWorkspace;
22
+
23
+ const ws = document.body.appendChild(el({
24
+ tag: 'ws-workspace',
25
+ attrs: { label: 'Diagram Editor', theme: 'light' },
26
+ style: { flex: '1 1 auto', minHeight: '0' },
27
+ }));
28
+ registerBuiltinParts(ws);
29
+ ws.registerPart(DiagramEditorPart);
30
+ ws.addParts([{
31
+ id: 'models', type: 'models', editorType: 'diagram-editor',
32
+ newModel: { templateType: 'flowchart' },
33
+ models: [{ id: 'editor', name: 'Order flow', templateType: 'flowchart' }],
34
+ }]);
35
+ ws.registerPerspective('Diagrams', { type: 'part', partId: 'models' });
36
+ ws.activatePerspective('Diagrams');
37
+
38
+ // A small flowchart to start from.
39
+ const editorPart = ws.getPart('editor');
40
+ const { templates } = editorPart.model.currentView;
41
+ for (const t of [
42
+ new StadiumTemplate('start', 'Order received', { x: 160, y: 80, fillColor: '#dcfce7' }),
43
+ new RectangleTemplate('check', 'Check stock', { x: 160, y: 200, fillColor: '#dbeafe' }),
44
+ new DiamondTemplate('decide', 'In stock?', { x: 160, y: 330, fillColor: '#fef9c3' }),
45
+ new RectangleTemplate('ship', 'Ship order', { x: 400, y: 330, fillColor: '#dbeafe' }),
46
+ new StadiumTemplate('end', 'Done', { x: 400, y: 460, fillColor: '#dcfce7' }),
47
+ ]) templates.set(t.id, t);
48
+ editorPart.editor.render();
49
+ </script>
50
+ </body>
51
+ </html>
package/package.json CHANGED
@@ -1,6 +1,67 @@
1
1
  {
2
2
  "name": "@peter.prib/renderengine",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "ArchiMate modeller, diagram editor and chart library for the browser, with no runtime dependencies.",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "module": "src/index.js",
8
+ "browser": "dist/renderengine.umd.js",
9
+ "exports": {
10
+ ".": "./src/index.js",
11
+ "./workspace": "./src/workspace/index.js",
12
+ "./src/*": "./src/*",
13
+ "./dist/*": "./dist/*",
14
+ "./package.json": "./package.json"
15
+ },
16
+ "files": [
17
+ "src/",
18
+ "dist/*.umd.js",
19
+ "examples/archimate.html",
20
+ "examples/diagram-editor.html",
21
+ "README.md",
22
+ "REFERENCE.md",
23
+ "LICENSE"
24
+ ],
25
+ "scripts": {
26
+ "start": "node scripts/open.mjs examples/archimate.html",
27
+ "archimate": "node scripts/open.mjs examples/archimate.html",
28
+ "diagram": "node scripts/open.mjs examples/diagram-editor.html",
29
+ "test": "node --test --test-timeout=10000 ./test/*.js ./test/charting/*.js ./test/charting/charts/*.js ./test/charting/diagrams/*.js ./test/charting/shapes/*.js",
30
+ "build": "rollup -c",
31
+ "prepublishOnly": "npm test && npm run build"
32
+ },
33
+ "keywords": [
34
+ "archimate",
35
+ "archi",
36
+ "diagram",
37
+ "diagram-editor",
38
+ "modelling",
39
+ "charts",
40
+ "svg",
41
+ "canvas",
42
+ "render",
43
+ "engine",
44
+ "graphics"
45
+ ],
46
+ "author": "Peter Prib <peter.prib@gmail.com>",
47
+ "license": "MIT",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://gitlab.com/peter.prib/renderengine.git"
51
+ },
52
+ "homepage": "https://gitlab.com/peter.prib/renderengine#readme",
53
+ "bugs": {
54
+ "url": "https://gitlab.com/peter.prib/renderengine/-/issues"
55
+ },
56
+ "engines": {
57
+ "node": ">=18"
58
+ },
59
+ "publishConfig": {
60
+ "access": "public"
61
+ },
62
+ "devDependencies": {
63
+ "@rollup/plugin-commonjs": "^25.0.8",
64
+ "@rollup/plugin-node-resolve": "^15.3.1",
65
+ "rollup": "^3.30.0"
66
+ }
67
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @class BaseRenderer
3
+ * @abstract
4
+ * Defines the common drawing API for all renderers.
5
+ * Methods here are meant to be overridden by concrete implementations.
6
+ */
7
+ export class BaseRenderer {
8
+ constructor(container, width, height) {
9
+ if (this.constructor === BaseRenderer) {
10
+ throw new Error("BaseRenderer is an abstract class and cannot be instantiated directly.");
11
+ }
12
+ this.container = container;
13
+ this.width = width;
14
+ this.height = height;
15
+ }
16
+ clear() { throw new Error("Method 'clear()' must be implemented."); }
17
+ rect(x, y, width, height, fill, stroke) { throw new Error("Method 'rect()' must be implemented."); }
18
+ circle(cx, cy, r, fill, stroke) { throw new Error("Method 'circle()' must be implemented."); }
19
+ path(d, fill, stroke) { throw new Error("Method 'path()' must be implemented."); }
20
+ text(text, x, y, options) { throw new Error("Method 'text()' must be implemented."); }
21
+ image(href, x, y, width, height, options) { throw new Error("Method 'image()' must be implemented."); }
22
+ enterState(shape, stateName) { throw new Error("Method 'enterState()' must be implemented."); }
23
+ leaveState(shape, stateName) { throw new Error("Method 'leaveState()' must be implemented."); }
24
+ renderDiagram(diagram) { throw new Error("Method 'renderDiagram()' must be implemented."); }
25
+
26
+ /**
27
+ * The width of some text in pixels. This estimate (an average character
28
+ * width) serves where nothing can measure; SVGRenderer and CanvasRenderer
29
+ * measure with a 2D canvas context.
30
+ * @param {string} text
31
+ * @param {{fontSize?: string, fontFamily?: string, fontWeight?: string, fontStyle?: string}} [font]
32
+ * @returns {number}
33
+ */
34
+ measureText(text, font = {}) {
35
+ return String(text).length * (parseFloat(font.fontSize) || 12) * 0.55;
36
+ }
37
+
38
+ /** A CSS font string for a 2D context, from text options. @protected */
39
+ static cssFont({ fontSize = '12px', fontFamily = 'sans-serif', fontWeight = '', fontStyle = '' } = {}) {
40
+ return `${fontStyle} ${fontWeight} ${fontSize} ${fontFamily}`.trim().replace(/\s+/g, ' ');
41
+ }
42
+
43
+ /** Renderer type identifier. Subclasses override with 'svg' or 'canvas'. */
44
+ get type() { return 'base'; }
45
+
46
+ /** Normalized center text-anchor value for this renderer. */
47
+ get centerTextAnchor() { return 'middle'; }
48
+
49
+ /** Whether this renderer supports a retained scene graph (groups, events). */
50
+ get supportsSceneGraph() { return false; }
51
+
52
+ _setAttributes(el, attributes) {
53
+ for (const [key, value] of Object.entries(attributes)) {
54
+ el.setAttribute(key, value);
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,194 @@
1
+ import { BaseRenderer } from './BaseRenderer.js';
2
+
3
+ /**
4
+ * @class CanvasRenderer
5
+ * Renders shapes by drawing on a 2D canvas context.
6
+ */
7
+ export class CanvasRenderer extends BaseRenderer {
8
+ get type() { return 'canvas'; }
9
+ get centerTextAnchor() { return 'center'; }
10
+
11
+ constructor(container, width, height) {
12
+ super(container, width, height);
13
+ this.canvas = document.createElement('canvas');
14
+ this.canvas.width = width;
15
+ this.canvas.height = height;
16
+ // Inline elements (the default for <canvas>) leave a few px of baseline
17
+ // whitespace below them inside a block container, making the
18
+ // container's scrollHeight exceed its clientHeight for every chart.
19
+ this.canvas.style.display = 'block';
20
+ this._shapes = [];
21
+ this.container.appendChild(this.canvas);
22
+ this.ctx = this.canvas.getContext('2d');
23
+ }
24
+
25
+ clear() {
26
+ this.ctx.clearRect(0, 0, this.width, this.height);
27
+ this._shapes = [];
28
+ }
29
+
30
+ // Always returns an isolated Path2D — used by hitTest() to test one
31
+ // shape's geometry at a time. Previously rect/circle called this.ctx.rect()/
32
+ // .arc() directly onto the canvas's own current path without resetting it
33
+ // first, so each hitTest() loop iteration kept accumulating geometry from
34
+ // every shape checked before it, corrupting hit results for anything but
35
+ // the very first shape tested (tooltips/clicks/hover on Canvas charts
36
+ // could resolve to the wrong shape).
37
+ _drawPath(shape) {
38
+ const p = new Path2D();
39
+ switch (shape.type) {
40
+ case 'rect':
41
+ p.rect(shape.x, shape.y, shape.width, shape.height);
42
+ return p;
43
+ case 'circle':
44
+ p.arc(shape.cx, shape.cy, shape.r, 0, 2 * Math.PI);
45
+ return p;
46
+ case 'path':
47
+ return new Path2D(shape.d);
48
+ default:
49
+ return p; // empty — no geometry to hit-test
50
+ }
51
+ }
52
+ _setShapeType={
53
+ rect:(shape)=>this.ctx.rect(shape.x, shape.y, shape.width, shape.height),
54
+ circle:(shape)=>this.ctx.arc(shape.cx, shape.cy, shape.r, 0, 2 * Math.PI),
55
+ path:(shape,fill,stroke)=>{
56
+ const p = new Path2D(shape.d);
57
+ if (fill && fill !== 'none') { this.ctx.fillStyle = fill; this.ctx.fill(p); }
58
+ if (stroke && stroke.color !== 'none') {
59
+ this.ctx.strokeStyle = stroke.color;
60
+ this.ctx.lineWidth = stroke.width || 1;
61
+ // Used by the gauge arcs' rounded end-caps ({cap: 'round'}).
62
+ this.ctx.lineCap = stroke.cap || 'butt';
63
+ this.ctx.stroke(p);
64
+ }
65
+ }
66
+ }
67
+ // Shared by text() (initial draw) and _draw()'s 'text' case (redraw on
68
+ // hover enter/leave) so rotation/alignment logic isn't duplicated.
69
+ _paintText(shape) {
70
+ const hoverStyle = shape._hoverStyle;
71
+ const fill = hoverStyle?.fill ?? shape.fill;
72
+ this.ctx.fillStyle = fill || 'black';
73
+ this.ctx.font = `${shape.fontStyle || ''} ${shape.fontWeight || ''} ${shape.fontSize || '12px'} ${shape.fontFamily || 'sans-serif'}`.trim().replace(/\s+/g, ' ');
74
+ let textAlign = shape.textAnchor || 'start';
75
+ if (textAlign === 'middle') textAlign = 'center';
76
+ this.ctx.textAlign = textAlign;
77
+ this.ctx.textBaseline = 'middle';
78
+ if (shape.rotation) {
79
+ this.ctx.save();
80
+ this.ctx.translate(shape.x, shape.y);
81
+ this.ctx.rotate(shape.rotation);
82
+ this.ctx.fillText(shape.text, 0, 0);
83
+ this.ctx.restore();
84
+ } else {
85
+ this.ctx.fillText(shape.text, shape.x, shape.y);
86
+ }
87
+ }
88
+ _draw(shape) {
89
+ if (shape.type === 'text') { this._paintText(shape); return; }
90
+
91
+ const hoverStyle = shape._hoverStyle;
92
+ const fill = hoverStyle?.fill ?? shape.fill;
93
+ const stroke = hoverStyle?.stroke ?? shape.stroke;
94
+
95
+ // For path, we need to handle fill and stroke separately inside the case.
96
+ const isPath = shape.type === 'path';
97
+
98
+ this.ctx.beginPath();
99
+ this._setShapeType[shape.type](shape, fill, stroke);
100
+ if (isPath) return
101
+ if (fill && fill !== 'none') {
102
+ this.ctx.fillStyle = fill;
103
+ this.ctx.fill();
104
+ }
105
+ if (stroke) {
106
+ this.ctx.strokeStyle = stroke.color || 'none';
107
+ this.ctx.lineWidth = stroke.width || 1;
108
+ this.ctx.stroke();
109
+ }
110
+ }
111
+
112
+ _redraw() {
113
+ this.ctx.clearRect(0, 0, this.width, this.height);
114
+ this._shapes.forEach(shape => this._draw(shape));
115
+ }
116
+
117
+ rect(x, y, width, height, fill, stroke, extra = {}) {
118
+ const shape = { type: 'rect', x, y, width, height, fill, stroke, id: `shape_${this._shapes.length}`, ...extra };
119
+ this._shapes.push(shape);
120
+ this._draw(shape);
121
+ }
122
+
123
+ circle(cx, cy, r, fill, stroke, extra = {}) {
124
+ const shape = { type: 'circle', cx, cy, r, fill, stroke, id: `shape_${this._shapes.length}`, ...extra };
125
+ this._shapes.push(shape);
126
+ this._draw(shape);
127
+ }
128
+
129
+ path(d, fill, stroke, extra = {}) {
130
+ const shape = { type: 'path', d, fill, stroke, id: `shape_${this._shapes.length}`, ...extra };
131
+ this._shapes.push(shape);
132
+ this._draw(shape);
133
+ }
134
+
135
+ /** Text width measured by this renderer's own 2D context. */
136
+ measureText(text, font = {}) {
137
+ if (!this.ctx?.measureText) return super.measureText(text, font);
138
+ this.ctx.save();
139
+ this.ctx.font = BaseRenderer.cssFont(font);
140
+ const width = this.ctx.measureText(String(text)).width;
141
+ this.ctx.restore();
142
+ return width;
143
+ }
144
+
145
+ text(text, x, y, options = {}) {
146
+ const shape = { type: 'text', text, x, y, ...options, id: `shape_${this._shapes.length}` };
147
+ this._shapes.push(shape);
148
+ this._paintText(shape);
149
+ }
150
+
151
+ hitTest(x, y) {
152
+ for (let i = this._shapes.length - 1; i >= 0; i--) {
153
+ const shape = this._shapes[i];
154
+ const path2d = this._drawPath(shape);
155
+
156
+ // 1. Check for a fill hit first.
157
+ if (shape.fill && shape.fill !== 'none') {
158
+ if (path2d ? this.ctx.isPointInPath(path2d, x, y) : this.ctx.isPointInPath(x, y)) {
159
+ return shape;
160
+ }
161
+ }
162
+
163
+ // 2. If no fill hit, check for a stroke hit.
164
+ if (shape.stroke && shape.stroke.color !== 'none') {
165
+ this.ctx.lineWidth = shape.stroke.width || 1;
166
+ if (path2d ? this.ctx.isPointInStroke(path2d, x, y) : this.ctx.isPointInStroke(x, y)) {
167
+ return shape;
168
+ }
169
+ }
170
+ }
171
+ return null;
172
+ }
173
+
174
+ enterState(shape, stateName) {
175
+ const targetShape = this._shapes.find(s => s.id === shape.id);
176
+ if (targetShape) {
177
+ targetShape._hoverStyle = { fill: 'orange', stroke: { color: '#333', width: 2 } };
178
+ this._redraw();
179
+ }
180
+ }
181
+
182
+ leaveState(shape, stateName) {
183
+ const targetShape = this._shapes.find(s => s.id === shape.id);
184
+ if (targetShape) {
185
+ delete targetShape._hoverStyle;
186
+ this._redraw();
187
+ }
188
+ }
189
+
190
+ renderDiagram(diagram) {
191
+ // Draw the diagram directly onto the canvas context.
192
+ diagram.drawOn(this.ctx);
193
+ }
194
+ }
package/src/Mat4.js ADDED
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Mat4 — real 4x4 homogeneous matrix math, column-major (matches the
3
+ * standard WebGL/OpenGL convention), backing the orbit-camera 3D pipeline
4
+ * (see OrbitCamera.js). Pure math, no DOM — directly unit-testable.
5
+ *
6
+ * Layout (column-major flat array of 16, columns stored consecutively):
7
+ * m[0] m[4] m[8] m[12]
8
+ * m[1] m[5] m[9] m[13]
9
+ * m[2] m[6] m[10] m[14]
10
+ * m[3] m[7] m[11] m[15]
11
+ */
12
+ export class Mat4 {
13
+ static identity() {
14
+ return new Float64Array([
15
+ 1, 0, 0, 0,
16
+ 0, 1, 0, 0,
17
+ 0, 0, 1, 0,
18
+ 0, 0, 0, 1,
19
+ ]);
20
+ }
21
+
22
+ /** Returns a * b (b is applied first, then a — standard matrix-multiply composition order). */
23
+ static multiply(a, b) {
24
+ const out = new Float64Array(16);
25
+ for (let col = 0; col < 4; col++) {
26
+ for (let row = 0; row < 4; row++) {
27
+ let sum = 0;
28
+ for (let k = 0; k < 4; k++) sum += a[k * 4 + row] * b[col * 4 + k];
29
+ out[col * 4 + row] = sum;
30
+ }
31
+ }
32
+ return out;
33
+ }
34
+
35
+ /** Rotation about the X axis (rotates Y toward Z), right-handed. */
36
+ static rotateX(rad) {
37
+ const c = Math.cos(rad), s = Math.sin(rad);
38
+ return new Float64Array([
39
+ 1, 0, 0, 0,
40
+ 0, c, s, 0,
41
+ 0, -s, c, 0,
42
+ 0, 0, 0, 1,
43
+ ]);
44
+ }
45
+
46
+ /** Rotation about the Y axis (rotates Z toward X), right-handed. */
47
+ static rotateY(rad) {
48
+ const c = Math.cos(rad), s = Math.sin(rad);
49
+ return new Float64Array([
50
+ c, 0, -s, 0,
51
+ 0, 1, 0, 0,
52
+ s, 0, c, 0,
53
+ 0, 0, 0, 1,
54
+ ]);
55
+ }
56
+
57
+ /** Rotation about the Z axis (rotates X toward Y), right-handed. */
58
+ static rotateZ(rad) {
59
+ const c = Math.cos(rad), s = Math.sin(rad);
60
+ return new Float64Array([
61
+ c, s, 0, 0,
62
+ -s, c, 0, 0,
63
+ 0, 0, 1, 0,
64
+ 0, 0, 0, 1,
65
+ ]);
66
+ }
67
+
68
+ static translate(x, y, z) {
69
+ return new Float64Array([
70
+ 1, 0, 0, 0,
71
+ 0, 1, 0, 0,
72
+ 0, 0, 1, 0,
73
+ x, y, z, 1,
74
+ ]);
75
+ }
76
+
77
+ static scale(x, y, z) {
78
+ return new Float64Array([
79
+ x, 0, 0, 0,
80
+ 0, y, 0, 0,
81
+ 0, 0, z, 0,
82
+ 0, 0, 0, 1,
83
+ ]);
84
+ }
85
+
86
+ /**
87
+ * Standard right-handed perspective projection matrix (OpenGL convention —
88
+ * camera looks down -Z in view space). `fovYRadians` is the full vertical
89
+ * field of view; `near`/`far` are positive distances from the camera.
90
+ */
91
+ static perspective(fovYRadians, aspect, near, far) {
92
+ const f = 1 / Math.tan(fovYRadians / 2);
93
+ const rangeInv = 1 / (near - far);
94
+ return new Float64Array([
95
+ f / aspect, 0, 0, 0,
96
+ 0, f, 0, 0,
97
+ 0, 0, (far + near) * rangeInv, -1,
98
+ 0, 0, 2 * far * near * rangeInv, 0,
99
+ ]);
100
+ }
101
+
102
+ /** Applies `m` to the homogeneous point (x,y,z,1); returns {x,y,z,w}. */
103
+ static transformPoint(m, { x, y, z }) {
104
+ return {
105
+ x: m[0] * x + m[4] * y + m[8] * z + m[12],
106
+ y: m[1] * x + m[5] * y + m[9] * z + m[13],
107
+ z: m[2] * x + m[6] * y + m[10] * z + m[14],
108
+ w: m[3] * x + m[7] * y + m[11] * z + m[15],
109
+ };
110
+ }
111
+ }
@@ -0,0 +1,57 @@
1
+ import { Mat4 } from './Mat4.js';
2
+
3
+ /**
4
+ * OrbitCamera — a real view+perspective-projection pipeline for the 3D
5
+ * charts and 3D node-graphs, replacing the old hand-rolled trig in
6
+ * RenderEngine._project3D with actual composed matrices (Mat4.js).
7
+ *
8
+ * State is the same {theta, phi, distance} shape already used by
9
+ * RenderEngine's `_camera3D`/`_addOrbit3DListeners` (drag-to-rotate,
10
+ * wheel-to-zoom) — this class only changes how a point gets projected, not
11
+ * how the camera is driven.
12
+ */
13
+ export class OrbitCamera {
14
+ constructor({ theta = 0, phi = 0, distance = 2.2, fovY = Math.PI / 4, near = 0.1, far = 100 } = {}) {
15
+ this.theta = theta;
16
+ this.phi = phi;
17
+ this.distance = distance;
18
+ this.fovY = fovY;
19
+ this.near = near;
20
+ this.far = far;
21
+ }
22
+
23
+ /**
24
+ * World -> view-space: rotate the world by phi (tilt, X axis) then theta
25
+ * (orbit, Y axis), then push it away from the camera by `distance` along Z
26
+ * (equivalent to the camera itself sitting at (0,0,distance) looking at
27
+ * the origin — standard orbit-camera composition).
28
+ */
29
+ viewMatrix() {
30
+ const rot = Mat4.multiply(Mat4.rotateX(this.phi), Mat4.rotateY(this.theta));
31
+ return Mat4.multiply(Mat4.translate(0, 0, -this.distance), rot);
32
+ }
33
+
34
+ viewProjectionMatrix(aspect = 1) {
35
+ return Mat4.multiply(Mat4.perspective(this.fovY, aspect, this.near, this.far), this.viewMatrix());
36
+ }
37
+
38
+ /**
39
+ * Projects a world-space {x,y,z} point through the orbit camera.
40
+ * @returns {{sx:number, sy:number, depth:number, scale:number}}
41
+ * sx/sy — NDC screen coordinates (roughly [-1,1] across the viewport,
42
+ * same convention _project3D's callers already scale by their
43
+ * own pixel radius).
44
+ * depth — positive camera-space distance from the camera (bigger =
45
+ * farther), for back-to-front z-sorting — same semantics the
46
+ * old _project3D's `depth` had.
47
+ * scale — perspective foreshortening factor (1/w); callers multiply a
48
+ * point/node's base radius by this so nearer things read as
49
+ * visibly bigger, not just drawn on top.
50
+ */
51
+ project(point, aspect = 1) {
52
+ const viewPoint = Mat4.transformPoint(this.viewMatrix(), point);
53
+ const clip = Mat4.transformPoint(Mat4.perspective(this.fovY, aspect, this.near, this.far), viewPoint);
54
+ const w = Math.abs(clip.w) > 1e-6 ? clip.w : 1e-6;
55
+ return { sx: clip.x / w, sy: clip.y / w, depth: -viewPoint.z, scale: 1 / w };
56
+ }
57
+ }
@@ -0,0 +1,50 @@
1
+ import { SVGRenderer } from './SVGRenderer.js';
2
+ import { CanvasRenderer } from './CanvasRenderer.js';
3
+
4
+ /**
5
+ * RendererFactory — centralizes renderer instantiation.
6
+ *
7
+ * Keeps the `RenderEngine` constructor free of type-specific `new` calls and
8
+ * lets new renderer backends be registered in one place.
9
+ */
10
+ export class RendererFactory {
11
+ static _registry = new Map([
12
+ ['svg', SVGRenderer],
13
+ ['canvas', CanvasRenderer],
14
+ ]);
15
+
16
+ /**
17
+ * Create a renderer for the given container.
18
+ * @param {'svg'|'canvas'} type
19
+ * @param {HTMLElement} container
20
+ * @param {number} width
21
+ * @param {number} height
22
+ * @returns {BaseRenderer}
23
+ */
24
+ static create(type, container, width, height) {
25
+ // Tooltip/context-menu elements are appended as children of `container`
26
+ // with position:absolute + left/top computed relative to container's own
27
+ // bounding rect. CSS absolute positioning uses the nearest *positioned*
28
+ // ancestor, so a static container would misalign popups. Force a
29
+ // positioning context here so container's coordinate space matches what
30
+ // the tooltip/context-menu math assumes.
31
+ if (getComputedStyle(container).position === 'static') {
32
+ container.style.position = 'relative';
33
+ }
34
+
35
+ const RendererClass = RendererFactory._registry.get(type);
36
+ if (!RendererClass) {
37
+ throw new Error(`Unknown renderer type: ${type}`);
38
+ }
39
+ return new RendererClass(container, width, height);
40
+ }
41
+
42
+ /**
43
+ * Register a new renderer type. Used for third-party backends.
44
+ * @param {string} type
45
+ * @param {typeof BaseRenderer} RendererClass
46
+ */
47
+ static register(type, RendererClass) {
48
+ RendererFactory._registry.set(type, RendererClass);
49
+ }
50
+ }