@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.
- package/LICENSE +21 -0
- package/README.md +203 -2
- package/REFERENCE.md +2198 -0
- package/dist/renderengine-workspace.umd.js +46905 -0
- package/dist/renderengine.umd.js +42223 -0
- package/examples/archimate.html +66 -0
- package/examples/diagram-editor.html +51 -0
- package/package.json +65 -4
- package/src/BaseRenderer.js +57 -0
- package/src/CanvasRenderer.js +194 -0
- package/src/Mat4.js +111 -0
- package/src/OrbitCamera.js +57 -0
- package/src/RendererFactory.js +50 -0
- package/src/SVGRenderer.js +439 -0
- package/src/archimate.js +723 -0
- package/src/archimateArchiFormat.js +1693 -0
- package/src/archimateArchiTypes.js +72 -0
- package/src/archimateArchive.js +140 -0
- package/src/archimateCSV.js +127 -0
- package/src/archimateDrawio.js +182 -0
- package/src/archimateExchangeFormat.js +546 -0
- package/src/archimateRelationshipTable.js +93 -0
- package/src/archimateSpecializations.js +161 -0
- package/src/chartCatalog.js +589 -0
- package/src/charting/ArchimateDiagramEditor.js +1624 -0
- package/src/charting/ArchimateSpecializationSelector.js +134 -0
- package/src/charting/Axis.js +68 -0
- package/src/charting/CameraSeeder.js +30 -0
- package/src/charting/CatalogDialog.js +92 -0
- package/src/charting/Chart.js +37 -0
- package/src/charting/Chart3D.js +99 -0
- package/src/charting/ChartBox.js +80 -0
- package/src/charting/ChartData.js +27 -0
- package/src/charting/ChartRegistry.js +76 -0
- package/src/charting/CheckboxTreeSelector.js +304 -0
- package/src/charting/ColorField.js +107 -0
- package/src/charting/ColorPalette.js +88 -0
- package/src/charting/CommandHistory.js +176 -0
- package/src/charting/DataFilter.js +52 -0
- package/src/charting/Diagram.js +36 -0
- package/src/charting/Diagram3D.js +29 -0
- package/src/charting/DiagramClipboard.js +31 -0
- package/src/charting/DiagramEditor.js +3330 -0
- package/src/charting/DiagramEditorCommand.js +110 -0
- package/src/charting/DiagramEditorCommands.js +237 -0
- package/src/charting/DiagramEditorEdgeCommands.js +142 -0
- package/src/charting/DiagramEditorState.js +98 -0
- package/src/charting/DiagramRegistry.js +86 -0
- package/src/charting/DiagramTypeRegistry.js +326 -0
- package/src/charting/DiagramViewPropertiesDialog.js +46 -0
- package/src/charting/Edge.js +113 -0
- package/src/charting/ErrorBars.js +37 -0
- package/src/charting/FilterSystem.js +285 -0
- package/src/charting/FindReplaceDialog.js +139 -0
- package/src/charting/FormDialog.js +385 -0
- package/src/charting/Gauge.js +58 -0
- package/src/charting/Hierarchy.js +175 -0
- package/src/charting/HintPanel.js +86 -0
- package/src/charting/ImageSelector.js +148 -0
- package/src/charting/InteractionManager.js +725 -0
- package/src/charting/Legend.js +58 -0
- package/src/charting/MenuBar.js +62 -0
- package/src/charting/ModelFileFormat.js +115 -0
- package/src/charting/OrbitControls.js +77 -0
- package/src/charting/Palette.js +119 -0
- package/src/charting/PopupMenu.js +117 -0
- package/src/charting/PropertiesPanel.js +155 -0
- package/src/charting/PropertyListEditor.js +96 -0
- package/src/charting/PropertyLog.js +92 -0
- package/src/charting/SettingsCascade.js +93 -0
- package/src/charting/SettingsDialog.js +53 -0
- package/src/charting/SettingsManager.js +179 -0
- package/src/charting/SettingsViewPropertiesDialog.js +58 -0
- package/src/charting/ShapePaths.js +27 -0
- package/src/charting/Statistics.js +134 -0
- package/src/charting/TemplateCatalog.js +59 -0
- package/src/charting/TemplateLibrary.js +103 -0
- package/src/charting/TextStyle.js +168 -0
- package/src/charting/ViewFit.js +55 -0
- package/src/charting/ViewMenu.js +70 -0
- package/src/charting/ViewPropertiesDialog.js +77 -0
- package/src/charting/ViewTabStrip.js +81 -0
- package/src/charting/archimate/ArchiFileFormat.js +32 -0
- package/src/charting/archimate/ArchimateCanvasEditor.js +815 -0
- package/src/charting/archimate/ArchimateCsvFileFormat.js +35 -0
- package/src/charting/archimate/ArchimateEdge.js +137 -0
- package/src/charting/archimate/ArchimateElementTemplate.js +195 -0
- package/src/charting/archimate/ArchimatePalette.js +102 -0
- package/src/charting/archimate/CsvImportDialog.js +105 -0
- package/src/charting/archimate/CustomViewpoints.js +74 -0
- package/src/charting/archimate/DerivedEdge.js +29 -0
- package/src/charting/archimate/DrawioFileFormat.js +24 -0
- package/src/charting/archimate/ElementFilterRule.js +21 -0
- package/src/charting/archimate/ExchangeFileFormat.js +28 -0
- package/src/charting/archimate/ViewGroupTemplate.js +137 -0
- package/src/charting/archimate/ViewLineEdge.js +84 -0
- package/src/charting/archimate/ViewpointRule.js +45 -0
- package/src/charting/archimate/archimateFileFormats.js +12 -0
- package/src/charting/archimate/archimateNames.js +5 -0
- package/src/charting/archimate/csvMapping.js +122 -0
- package/src/charting/archimate/elementMenuItems.js +32 -0
- package/src/charting/archimate/elementProperties.js +146 -0
- package/src/charting/archimate/elementTypeChoices.js +7 -0
- package/src/charting/archimate/elementTypeGroups.js +19 -0
- package/src/charting/archimate/index.js +17 -0
- package/src/charting/archimate/specializationCatalogDialog.js +64 -0
- package/src/charting/archimate/typeGlyph.js +29 -0
- package/src/charting/arrangement/Arrangement.js +112 -0
- package/src/charting/arrangement/ArrangementCommand.js +29 -0
- package/src/charting/arrangement/BackgroundCommand.js +41 -0
- package/src/charting/arrangement/BackgroundGroup.js +18 -0
- package/src/charting/arrangement/GroupCommand.js +46 -0
- package/src/charting/arrangement/ItemGroup.js +62 -0
- package/src/charting/arrangement/LockCommand.js +32 -0
- package/src/charting/arrangement/UngroupCommand.js +27 -0
- package/src/charting/arrangement/alignment.js +88 -0
- package/src/charting/arrangement/arrangeMenuItems.js +25 -0
- package/src/charting/arrangement/index.js +11 -0
- package/src/charting/arrangement/layouts.js +233 -0
- package/src/charting/canvas/ArchiHint.js +78 -0
- package/src/charting/canvas/CanvasBoxKind.js +39 -0
- package/src/charting/canvas/CanvasPalette.js +49 -0
- package/src/charting/canvas/CanvasTemplateLibrary.js +61 -0
- package/src/charting/canvas/CanvasTemplateMenu.js +151 -0
- package/src/charting/canvas/EditHintCommand.js +28 -0
- package/src/charting/canvas/canvasBoxKinds.js +27 -0
- package/src/charting/canvas/canvasBoxMenuItems.js +40 -0
- package/src/charting/canvas/defaultCanvasTemplates.js +186 -0
- package/src/charting/canvas/diagramBoxKinds.js +12 -0
- package/src/charting/canvas/hintMenuItems.js +49 -0
- package/src/charting/charts/ArcGauge.js +55 -0
- package/src/charting/charts/AreaChart.js +71 -0
- package/src/charting/charts/BarChart.js +80 -0
- package/src/charting/charts/BarChart3D.js +56 -0
- package/src/charting/charts/BarChart3DOrbit.js +53 -0
- package/src/charting/charts/BarChartBase.js +70 -0
- package/src/charting/charts/BarGauge.js +42 -0
- package/src/charting/charts/BoxPlotChart.js +41 -0
- package/src/charting/charts/BubbleChart.js +99 -0
- package/src/charting/charts/BubbleChart3D.js +78 -0
- package/src/charting/charts/BulletGauge.js +87 -0
- package/src/charting/charts/CalendarHeatmapChart.js +204 -0
- package/src/charting/charts/CandlestickChart.js +54 -0
- package/src/charting/charts/ChordDiagram.js +130 -0
- package/src/charting/charts/DensityChart.js +73 -0
- package/src/charting/charts/DialGauge.js +65 -0
- package/src/charting/charts/DonutChart.js +15 -0
- package/src/charting/charts/FunnelChart.js +47 -0
- package/src/charting/charts/GanttChart.js +201 -0
- package/src/charting/charts/GaugeChart.js +175 -0
- package/src/charting/charts/GeoMapChart.js +146 -0
- package/src/charting/charts/GroupedBarChart.js +88 -0
- package/src/charting/charts/GroupedDistributionChart.js +70 -0
- package/src/charting/charts/HeatmapChart.js +80 -0
- package/src/charting/charts/HierarchyChart.js +39 -0
- package/src/charting/charts/HistogramChart.js +45 -0
- package/src/charting/charts/KpiTile.js +72 -0
- package/src/charting/charts/LagPlotChart.js +41 -0
- package/src/charting/charts/LineChart.js +124 -0
- package/src/charting/charts/MultiRingGauge.js +54 -0
- package/src/charting/charts/OutlineChart.js +95 -0
- package/src/charting/charts/ParallelCoordinatesChart.js +130 -0
- package/src/charting/charts/PieChart.js +56 -0
- package/src/charting/charts/PipeChart.js +88 -0
- package/src/charting/charts/PopulationPyramidChart.js +106 -0
- package/src/charting/charts/QQPlotChart.js +64 -0
- package/src/charting/charts/RadarChart.js +76 -0
- package/src/charting/charts/RadialBarChart.js +96 -0
- package/src/charting/charts/RingGauge.js +23 -0
- package/src/charting/charts/SankeyDiagram.js +174 -0
- package/src/charting/charts/ScatterChart.js +104 -0
- package/src/charting/charts/StackedAreaChart.js +15 -0
- package/src/charting/charts/StackedBarChart.js +33 -0
- package/src/charting/charts/StackedBarChart3DOrbit.js +58 -0
- package/src/charting/charts/StreamGraphChart.js +131 -0
- package/src/charting/charts/SunburstChart.js +57 -0
- package/src/charting/charts/ThermometerGauge.js +43 -0
- package/src/charting/charts/TreemapChart.js +54 -0
- package/src/charting/charts/ViolinChart.js +37 -0
- package/src/charting/charts/WaterfallChart.js +66 -0
- package/src/charting/charts/WordCloudChart.js +104 -0
- package/src/charting/diagramModel/AddViewCommand.js +33 -0
- package/src/charting/diagramModel/DiagramModel.js +39 -0
- package/src/charting/diagramModel/DiagramModelSearch.js +22 -0
- package/src/charting/diagramModel/DiagramView.js +50 -0
- package/src/charting/diagramModel/ModelHistory.js +43 -0
- package/src/charting/diagramModel/ModelReport.js +153 -0
- package/src/charting/diagramModel/ModelSearch.js +223 -0
- package/src/charting/diagramModel/RemoveViewCommand.js +25 -0
- package/src/charting/diagramModel/RenameViewCommand.js +21 -0
- package/src/charting/diagramModel/ReplaceTextCommand.js +25 -0
- package/src/charting/diagramModel/ViewSetChecker.js +34 -0
- package/src/charting/diagramModel/ViewSetModel.js +243 -0
- package/src/charting/diagramModel/index.js +6 -0
- package/src/charting/diagramModel/nameTransforms.js +29 -0
- package/src/charting/diagrams/ArchimateCommands.js +141 -0
- package/src/charting/diagrams/ArchimateDiagram.js +263 -0
- package/src/charting/diagrams/ArchimateModel.js +1155 -0
- package/src/charting/diagrams/ArchimateModelChecker.js +125 -0
- package/src/charting/diagrams/ArchimateModelReport.js +128 -0
- package/src/charting/diagrams/ArchimateModelSearch.js +41 -0
- package/src/charting/diagrams/ArchimateValidator.js +357 -0
- package/src/charting/diagrams/CanvasView.js +112 -0
- package/src/charting/diagrams/ContextMenu.js +37 -0
- package/src/charting/diagrams/DataModelDiagram.js +86 -0
- package/src/charting/diagrams/DataModelRelationshipStrategy.js +38 -0
- package/src/charting/diagrams/DerivedRelationships.js +102 -0
- package/src/charting/diagrams/EbnfDiagram.js +39 -0
- package/src/charting/diagrams/EdgeGeometry.js +553 -0
- package/src/charting/diagrams/EditViewItemCommand.js +128 -0
- package/src/charting/diagrams/ElementInstance.js +157 -0
- package/src/charting/diagrams/GraphDiagram.js +1340 -0
- package/src/charting/diagrams/GraphDiagram3D.js +152 -0
- package/src/charting/diagrams/GraphMetrics.js +81 -0
- package/src/charting/diagrams/GridOverlay.js +137 -0
- package/src/charting/diagrams/ImportRowsCommand.js +62 -0
- package/src/charting/diagrams/LabelHelper.js +108 -0
- package/src/charting/diagrams/MergeElementsCommand.js +101 -0
- package/src/charting/diagrams/NestInstanceCommand.js +34 -0
- package/src/charting/diagrams/NodeGeometry.js +158 -0
- package/src/charting/diagrams/PlaceItemsCommand.js +77 -0
- package/src/charting/diagrams/RadialLayout.js +101 -0
- package/src/charting/diagrams/RelationshipInstance.js +93 -0
- package/src/charting/diagrams/RemoveGroupFromViewCommand.js +28 -0
- package/src/charting/diagrams/RemoveLineCommand.js +27 -0
- package/src/charting/diagrams/ShowElementCommand.js +43 -0
- package/src/charting/diagrams/SvgCoordinate.js +17 -0
- package/src/charting/diagrams/SvgZoom.js +127 -0
- package/src/charting/diagrams/Tooltip.js +62 -0
- package/src/charting/diagrams/ViewConnectionInstance.js +102 -0
- package/src/charting/diagrams/ViewObjectInstance.js +56 -0
- package/src/charting/diagrams/commands/AddEdgeCommand.js +34 -0
- package/src/charting/diagrams/commands/AddNodeCommand.js +28 -0
- package/src/charting/diagrams/commands/AddWaypointCommand.js +27 -0
- package/src/charting/diagrams/commands/CreateFolderCommand.js +27 -0
- package/src/charting/diagrams/commands/DeleteEdgeCommand.js +30 -0
- package/src/charting/diagrams/commands/DeleteFolderCommand.js +47 -0
- package/src/charting/diagrams/commands/DeleteNodeCommand.js +35 -0
- package/src/charting/diagrams/commands/DeleteWaypointCommand.js +24 -0
- package/src/charting/diagrams/commands/GraphCommand.js +65 -0
- package/src/charting/diagrams/commands/InvertEdgeCommand.js +24 -0
- package/src/charting/diagrams/commands/MoveNodeCommand.js +44 -0
- package/src/charting/diagrams/commands/MoveWaypointCommand.js +27 -0
- package/src/charting/diagrams/commands/RenameEdgeCommand.js +23 -0
- package/src/charting/diagrams/commands/RenameFolderCommand.js +31 -0
- package/src/charting/diagrams/commands/RenameNodeCommand.js +27 -0
- package/src/charting/diagrams/commands/ResizeNodeCommand.js +46 -0
- package/src/charting/diagrams/commands/UpdateEdgeSideCommand.js +40 -0
- package/src/charting/diagrams/commands/index.js +17 -0
- package/src/charting/diagrams/duplicates.js +49 -0
- package/src/charting/diagrams/nesting.js +30 -0
- package/src/charting/diagrams/roadmap.js +77 -0
- package/src/charting/edgeMarkers/ArrowMarker.js +15 -0
- package/src/charting/edgeMarkers/CircleMarker.js +13 -0
- package/src/charting/edgeMarkers/CrowsFootMarker.js +16 -0
- package/src/charting/edgeMarkers/DiamondMarker.js +15 -0
- package/src/charting/edgeMarkers/EdgeMarker.js +34 -0
- package/src/charting/edgeMarkers/HalfArrowMarker.js +8 -0
- package/src/charting/edgeMarkers/HollowDiamondMarker.js +18 -0
- package/src/charting/edgeMarkers/HollowTriangleMarker.js +18 -0
- package/src/charting/edgeMarkers/OpenArrowMarker.js +17 -0
- package/src/charting/edgeMarkers/index.js +27 -0
- package/src/charting/edgeStyle/EdgeStyleCascade.js +22 -0
- package/src/charting/edgeStyle/EdgeStyleDialog.js +51 -0
- package/src/charting/edgeStyle/EdgeStyleSchema.js +43 -0
- package/src/charting/edgeStyle/SetStyleCommand.js +12 -0
- package/src/charting/edgeStyle/index.js +4 -0
- package/src/charting/emphasis/EmphasisRule.js +42 -0
- package/src/charting/emphasis/HighlightRule.js +24 -0
- package/src/charting/gauges/ArcTrack.js +51 -0
- package/src/charting/gauges/GaugeAnimation.js +51 -0
- package/src/charting/gauges/GaugeBands.js +48 -0
- package/src/charting/gauges/GaugeScale.js +87 -0
- package/src/charting/gauges/GaugeTrack.js +44 -0
- package/src/charting/gauges/GaugeValue.js +61 -0
- package/src/charting/gauges/HorizontalTrack.js +14 -0
- package/src/charting/gauges/LinearTrack.js +29 -0
- package/src/charting/gauges/Sparkline.js +42 -0
- package/src/charting/gauges/VerticalTrack.js +17 -0
- package/src/charting/glyphs/ArrowGlyph.js +21 -0
- package/src/charting/glyphs/BatteryGlyph.js +18 -0
- package/src/charting/glyphs/ChevronGlyph.js +18 -0
- package/src/charting/glyphs/CircleGlyph.js +15 -0
- package/src/charting/glyphs/CloudGlyph.js +19 -0
- package/src/charting/glyphs/ComponentGlyph.js +18 -0
- package/src/charting/glyphs/ConstraintGlyph.js +24 -0
- package/src/charting/glyphs/ContractBoxGlyph.js +10 -0
- package/src/charting/glyphs/CubeGlyph.js +19 -0
- package/src/charting/glyphs/CylinderGlyph.js +19 -0
- package/src/charting/glyphs/DashedDoubleArrowGlyph.js +11 -0
- package/src/charting/glyphs/DeviceGlyph.js +17 -0
- package/src/charting/glyphs/DiamondGlyph.js +17 -0
- package/src/charting/glyphs/DocumentGlyph.js +17 -0
- package/src/charting/glyphs/DoubleArrowGlyph.js +23 -0
- package/src/charting/glyphs/DoubleCircleGlyph.js +24 -0
- package/src/charting/glyphs/EllipseGlyph.js +18 -0
- package/src/charting/glyphs/FactoryGlyph.js +20 -0
- package/src/charting/glyphs/FlagGlyph.js +16 -0
- package/src/charting/glyphs/GapCircleGlyph.js +17 -0
- package/src/charting/glyphs/GearGlyph.js +37 -0
- package/src/charting/glyphs/Glyph.js +98 -0
- package/src/charting/glyphs/GroupingBoxGlyph.js +13 -0
- package/src/charting/glyphs/HalfCircleGlyph.js +22 -0
- package/src/charting/glyphs/HexagonGlyph.js +28 -0
- package/src/charting/glyphs/IconGlyph.js +22 -0
- package/src/charting/glyphs/ImageGlyph.js +16 -0
- package/src/charting/glyphs/JunctionGlyph.js +17 -0
- package/src/charting/glyphs/LollipopGlyph.js +22 -0
- package/src/charting/glyphs/MagnifierGlyph.js +17 -0
- package/src/charting/glyphs/NoteGlyph.js +33 -0
- package/src/charting/glyphs/ObjectBoxGlyph.js +21 -0
- package/src/charting/glyphs/OrJunctionGlyph.js +17 -0
- package/src/charting/glyphs/ParallelogramGlyph.js +20 -0
- package/src/charting/glyphs/PersonGlyph.js +23 -0
- package/src/charting/glyphs/PillGlyph.js +23 -0
- package/src/charting/glyphs/PinGlyph.js +18 -0
- package/src/charting/glyphs/PrincipleGlyph.js +23 -0
- package/src/charting/glyphs/ProductBoxGlyph.js +16 -0
- package/src/charting/glyphs/RectGlyph.js +15 -0
- package/src/charting/glyphs/RoundedBoxGlyph.js +13 -0
- package/src/charting/glyphs/StackGlyph.js +14 -0
- package/src/charting/glyphs/StepsGlyph.js +20 -0
- package/src/charting/glyphs/StickFigureGlyph.js +32 -0
- package/src/charting/glyphs/SystemSoftwareBoxGlyph.js +16 -0
- package/src/charting/glyphs/TabbedBoxGlyph.js +37 -0
- package/src/charting/glyphs/TargetGlyph.js +23 -0
- package/src/charting/glyphs/WavyBoxGlyph.js +17 -0
- package/src/charting/glyphs/WheelGlyph.js +28 -0
- package/src/charting/glyphs/drawGlyph.js +28 -0
- package/src/charting/glyphs/glyphSvg.js +55 -0
- package/src/charting/glyphs/index.js +109 -0
- package/src/charting/modelTree/AnalysisPanel.js +159 -0
- package/src/charting/modelTree/DiagramTabs.js +217 -0
- package/src/charting/modelTree/ModelTree.js +164 -0
- package/src/charting/modelTree/ModelTreePanel.js +914 -0
- package/src/charting/modelTree/TreeBuilder.js +238 -0
- package/src/charting/modelTree/TreeModeRegistry.js +51 -0
- package/src/charting/modelTree/TreeViewMode.js +110 -0
- package/src/charting/modelTree/buildFilterTrees.js +138 -0
- package/src/charting/modelTree/modes/FlatTreeMode.js +46 -0
- package/src/charting/modelTree/modes/LayerGroupedTreeMode.js +62 -0
- package/src/charting/modelTree/modes/TypeGroupedTreeMode.js +60 -0
- package/src/charting/modelTree/treeLayers.js +11 -0
- package/src/charting/report/reportHtml.js +82 -0
- package/src/charting/report/reportViewer.js +118 -0
- package/src/charting/shapes/CircleShape.js +19 -0
- package/src/charting/shapes/PathShape.js +17 -0
- package/src/charting/shapes/RectShape.js +20 -0
- package/src/charting/shapes/Shape.js +20 -0
- package/src/charting/shapes/ShapeFactory.js +23 -0
- package/src/charting/storage/LocalJsonStore.js +43 -0
- package/src/charting/templates/ActorTemplate.js +36 -0
- package/src/charting/templates/BoxTemplate.js +27 -0
- package/src/charting/templates/CircleTemplate.js +18 -0
- package/src/charting/templates/ClassTemplate.js +20 -0
- package/src/charting/templates/CloudTemplate.js +43 -0
- package/src/charting/templates/ComponentTemplate.js +19 -0
- package/src/charting/templates/CylinderTemplate.js +30 -0
- package/src/charting/templates/DataStoreTemplate.js +16 -0
- package/src/charting/templates/DiamondTemplate.js +10 -0
- package/src/charting/templates/DocumentTemplate.js +32 -0
- package/src/charting/templates/EllipseTemplate.js +15 -0
- package/src/charting/templates/FinalStateTemplate.js +12 -0
- package/src/charting/templates/GlyphTemplate.js +47 -0
- package/src/charting/templates/HexagonTemplate.js +17 -0
- package/src/charting/templates/LifelineTemplate.js +20 -0
- package/src/charting/templates/ManualInputTemplate.js +12 -0
- package/src/charting/templates/NoteTemplate.js +23 -0
- package/src/charting/templates/OctagonTemplate.js +7 -0
- package/src/charting/templates/PackageTemplate.js +25 -0
- package/src/charting/templates/ParallelogramTemplate.js +11 -0
- package/src/charting/templates/PentagonTemplate.js +5 -0
- package/src/charting/templates/PolygonTemplate.js +18 -0
- package/src/charting/templates/PredefinedProcessTemplate.js +13 -0
- package/src/charting/templates/RectangleTemplate.js +28 -0
- package/src/charting/templates/RegularPolygonTemplate.js +21 -0
- package/src/charting/templates/RoundedRectangleTemplate.js +5 -0
- package/src/charting/templates/StadiumTemplate.js +8 -0
- package/src/charting/templates/StarTemplate.js +17 -0
- package/src/charting/templates/SwimlaneTemplate.js +18 -0
- package/src/charting/templates/Template.js +208 -0
- package/src/charting/templates/TrapezoidTemplate.js +11 -0
- package/src/charting/templates/TriangleTemplate.js +12 -0
- package/src/charting/templates/index.js +31 -0
- package/src/charting/templates/outline.js +59 -0
- package/src/charting/templates/svg.js +19 -0
- package/src/charting/textToShapes.js +61 -0
- package/src/charting/toolbar/ToolbarButton.js +38 -0
- package/src/charting/toolbar/ToolbarCheckbox.js +31 -0
- package/src/charting/toolbar/ToolbarItem.js +19 -0
- package/src/charting/toolbar/ToolbarMenu.js +36 -0
- package/src/charting/toolbar/ToolbarSelect.js +38 -0
- package/src/charting/toolbar/ToolbarSeparator.js +7 -0
- package/src/charting/toolbar/ToolbarText.js +22 -0
- package/src/charting/toolbar/index.js +8 -0
- package/src/charting/toolbar/pickFile.js +14 -0
- package/src/charting/viewDecorations.js +85 -0
- package/src/charting/zOrder.js +57 -0
- package/src/csvTable.js +61 -0
- package/src/datamodel.js +122 -0
- package/src/datawindow/BoundedWindow.js +36 -0
- package/src/datawindow/FlatDataWindow.js +34 -0
- package/src/datawindow/GraphDataWindow.js +40 -0
- package/src/datawindow/GroupedSampleDataWindow.js +16 -0
- package/src/datawindow/SeriesDataWindow.js +42 -0
- package/src/datawindow/index.js +31 -0
- package/src/diagramCatalog.js +30 -0
- package/src/ebnfDiagram.js +57 -0
- package/src/ebnfParser.js +129 -0
- package/src/exportImage.js +233 -0
- package/src/index.js +2636 -0
- package/src/itIcons.js +84 -0
- package/src/kernelExpr.js +243 -0
- package/src/propertiesDialog.js +463 -0
- package/src/railroadDiagram.js +571 -0
- package/src/treeModeCatalog.js +16 -0
- package/src/workspace/ContextBus.js +79 -0
- package/src/workspace/EditorShell.js +67 -0
- package/src/workspace/Part.js +163 -0
- package/src/workspace/PartFactory.js +49 -0
- package/src/workspace/PartRegistry.js +86 -0
- package/src/workspace/Workspace.js +321 -0
- package/src/workspace/archimateServices.js +33 -0
- package/src/workspace/dom.js +120 -0
- package/src/workspace/index.js +75 -0
- package/src/workspace/layout/GridNode.js +280 -0
- package/src/workspace/layout/LayoutNode.js +89 -0
- package/src/workspace/layout/PartNode.js +77 -0
- package/src/workspace/layout/SplitNode.js +114 -0
- package/src/workspace/layout/TabsNode.js +191 -0
- package/src/workspace/layout/index.js +24 -0
- package/src/workspace/parts/AdapterPart.js +33 -0
- package/src/workspace/parts/ArchimateCanvasPart.js +345 -0
- package/src/workspace/parts/ArchimateEditorPart.js +79 -0
- package/src/workspace/parts/ChartPart.js +115 -0
- package/src/workspace/parts/ContentPart.js +34 -0
- package/src/workspace/parts/DetailPart.js +46 -0
- package/src/workspace/parts/DiagramEditorPart.js +135 -0
- package/src/workspace/parts/EditorPart.js +388 -0
- package/src/workspace/parts/HtmlPart.js +25 -0
- package/src/workspace/parts/ListPart.js +57 -0
- package/src/workspace/parts/ModelFile.js +187 -0
- package/src/workspace/parts/ModelsPart.js +135 -0
- package/src/workspace/styles.js +258 -0
- package/src/workspace/themes.js +96 -0
- package/src/workspace/workArea.js +413 -0
- package/src/workspace/workAreaModel.js +197 -0
- package/src/workspace.js +16 -0
- package/src/zip/ZipArchive.js +160 -0
- package/src/zip/crc32.js +25 -0
- 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.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
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
|
+
}
|