@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,60 @@
|
|
|
1
|
+
import { TreeViewMode } from '../TreeViewMode.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tree mode: groups elements by ArchiMate type, then relationships.
|
|
5
|
+
*/
|
|
6
|
+
export class TypeGroupedTreeMode extends TreeViewMode {
|
|
7
|
+
static key = 'byType';
|
|
8
|
+
static label = 'By Type';
|
|
9
|
+
|
|
10
|
+
buildGroups(model, { filterText = '', typeIds = null, specializationIds = null, propertyIds = null } = {}) {
|
|
11
|
+
// Build element items (include specialization and properties for filtering)
|
|
12
|
+
const elementItems = this._getElements(model).map(el => ({
|
|
13
|
+
id: el.id,
|
|
14
|
+
kind: 'element',
|
|
15
|
+
label: el.name || '(unnamed)',
|
|
16
|
+
type: el.type,
|
|
17
|
+
icon: el.icon,
|
|
18
|
+
specialization: el.specialization,
|
|
19
|
+
properties: el.properties,
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
// Filter elements with all criteria
|
|
23
|
+
const filtered = elementItems.filter(item => this._matchesFilter(item, { text: filterText, typeIds, specializationIds, propertyIds }));
|
|
24
|
+
|
|
25
|
+
// Group by type
|
|
26
|
+
const typeGroups = this._group(
|
|
27
|
+
filtered,
|
|
28
|
+
item => item.type,
|
|
29
|
+
type => type || 'Other'
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// Sort alphabetically within each group
|
|
33
|
+
typeGroups.forEach(group => {
|
|
34
|
+
group.items.sort((a, b) => a.label.localeCompare(b.label));
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Sort groups alphabetically
|
|
38
|
+
typeGroups.sort((a, b) => a.label.localeCompare(b.label));
|
|
39
|
+
|
|
40
|
+
// Add relationships group
|
|
41
|
+
const relationshipItems = this._getRelationships(model).map(rel => ({
|
|
42
|
+
id: rel.id,
|
|
43
|
+
kind: 'relationship',
|
|
44
|
+
label: rel.label || `${rel.source} → ${rel.target}`,
|
|
45
|
+
type: rel.kind,
|
|
46
|
+
properties: rel.properties,
|
|
47
|
+
}));
|
|
48
|
+
|
|
49
|
+
const filtered_rels = relationshipItems.filter(item => this._matchesFilter(item, { text: filterText, typeIds, specializationIds, propertyIds }));
|
|
50
|
+
|
|
51
|
+
if (filtered_rels.length > 0) {
|
|
52
|
+
typeGroups.push({
|
|
53
|
+
label: 'Relationships',
|
|
54
|
+
items: filtered_rels.sort((a, b) => a.label.localeCompare(b.label)),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return typeGroups;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ArchimateDiagram } from '../diagrams/ArchimateDiagram.js';
|
|
2
|
+
|
|
3
|
+
/** The Layers folder's sub-folders, in order; an element of any other layer (junction, grouping, location,
|
|
4
|
+
* an ArchiMate 4 common type, ...) is under Other, as in Archi. */
|
|
5
|
+
export const TREE_LAYERS = Object.freeze(['business', 'application', 'technology', 'implementation', 'motivation', 'strategy', 'physical', 'other']);
|
|
6
|
+
|
|
7
|
+
/** The Layers sub-folder an element is in: its layer as the diagram draws it (ArchimateDiagram.elementLayer). */
|
|
8
|
+
export function treeLayerOf(element) {
|
|
9
|
+
const layer = ArchimateDiagram.elementLayer(element);
|
|
10
|
+
return TREE_LAYERS.includes(layer) ? layer : 'other';
|
|
11
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { toHtml } from '../../workspace/dom.js';
|
|
2
|
+
import { reportViewer } from './reportViewer.js';
|
|
3
|
+
|
|
4
|
+
/** The report page's look: a tree on the left, the item's page on the right. */
|
|
5
|
+
export const REPORT_CSS = `
|
|
6
|
+
* { box-sizing: border-box; }
|
|
7
|
+
body { margin: 0; font: 14px/1.45 system-ui, -apple-system, "Segoe UI", sans-serif; color: #222; background: #fff; height: 100vh; display: flex; flex-direction: column; }
|
|
8
|
+
header { display: flex; gap: 16px; align-items: center; padding: 8px 16px; border-bottom: 1px solid #ddd; background: #f6f7f9; }
|
|
9
|
+
header .title { font-weight: 600; font-size: 16px; color: inherit; text-decoration: none; }
|
|
10
|
+
header input { flex: 0 1 320px; margin-left: auto; padding: 5px 8px; border: 1px solid #bbb; border-radius: 4px; font: inherit; }
|
|
11
|
+
.columns { flex: 1; display: flex; min-height: 0; }
|
|
12
|
+
nav { width: 300px; flex: none; overflow: auto; padding: 8px 12px; border-right: 1px solid #ddd; font-size: 13px; }
|
|
13
|
+
nav h2 { font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: #666; margin: 12px 0 4px; }
|
|
14
|
+
nav summary { cursor: pointer; font-weight: 500; margin: 4px 0; }
|
|
15
|
+
nav ul { list-style: none; margin: 0 0 4px; padding-left: 14px; }
|
|
16
|
+
nav li { padding: 1px 4px; border-radius: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
17
|
+
nav li.current { background: #dde8f7; }
|
|
18
|
+
a { color: #1a5fb4; text-decoration: none; }
|
|
19
|
+
a:hover { text-decoration: underline; }
|
|
20
|
+
main { flex: 1; overflow: auto; padding: 16px 24px; }
|
|
21
|
+
main h1 { font-size: 22px; margin: 0 0 2px; }
|
|
22
|
+
main h2 { font-size: 15px; margin: 20px 0 6px; }
|
|
23
|
+
main ul { padding-left: 20px; }
|
|
24
|
+
.type { color: #666; margin: 0 0 12px; }
|
|
25
|
+
.note { color: #666; }
|
|
26
|
+
.documentation { white-space: pre-wrap; max-width: 80ch; }
|
|
27
|
+
table { border-collapse: collapse; margin: 8px 0; }
|
|
28
|
+
th, td { text-align: left; vertical-align: top; padding: 3px 12px 3px 0; border-bottom: 1px solid #eee; }
|
|
29
|
+
th { color: #555; font-weight: 500; }
|
|
30
|
+
.swatch { display: inline-block; width: 10px; height: 10px; margin-right: 6px; border: 1px solid rgba(0,0,0,.3); border-radius: 2px; }
|
|
31
|
+
.picture { position: relative; display: inline-block; max-width: 100%; margin: 12px 0; border: 1px solid #ddd; }
|
|
32
|
+
.picture img { display: block; max-width: 100%; height: auto; }
|
|
33
|
+
.picture .area { position: absolute; border-radius: 3px; }
|
|
34
|
+
.picture .area:hover { outline: 2px solid #1a5fb4; background: rgba(26,95,180,.08); }
|
|
35
|
+
@media (prefers-color-scheme: dark) {
|
|
36
|
+
body { background: #1e1f22; color: #ddd; }
|
|
37
|
+
header { background: #26282c; border-color: #3a3c40; }
|
|
38
|
+
nav, .picture { border-color: #3a3c40; }
|
|
39
|
+
nav li.current { background: #2f3f57; }
|
|
40
|
+
a { color: #8ab4f8; }
|
|
41
|
+
th, td { border-color: #333; }
|
|
42
|
+
th, .type, .note, nav h2 { color: #aaa; }
|
|
43
|
+
header input { background: #1e1f22; color: inherit; border-color: #555; }
|
|
44
|
+
.picture { background: #fff; }
|
|
45
|
+
}
|
|
46
|
+
@media (max-width: 700px) {
|
|
47
|
+
.columns { flex-direction: column; }
|
|
48
|
+
nav { width: auto; max-height: 40vh; border-right: none; border-bottom: 1px solid #ddd; }
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* A report as one HTML file that opens anywhere (no server, nothing else to
|
|
54
|
+
* load): the report's data as JSON, and the viewer (reportViewer) that builds
|
|
55
|
+
* the browsable page from it in the reader's browser.
|
|
56
|
+
* @param {Object} data - ModelReport#data()
|
|
57
|
+
* @returns {string}
|
|
58
|
+
*/
|
|
59
|
+
export function reportHtml(data) {
|
|
60
|
+
const page = {
|
|
61
|
+
tag: 'html', attrs: { lang: 'en' }, children: [
|
|
62
|
+
{ tag: 'head', children: [
|
|
63
|
+
{ tag: 'meta', attrs: { charset: 'utf-8' } },
|
|
64
|
+
{ tag: 'meta', attrs: { name: 'viewport', content: 'width=device-width, initial-scale=1' } },
|
|
65
|
+
{ tag: 'meta', attrs: { name: 'generator', content: 'RenderEngine' } },
|
|
66
|
+
{ tag: 'title', text: data.title },
|
|
67
|
+
{ tag: 'style', script: REPORT_CSS },
|
|
68
|
+
] },
|
|
69
|
+
{ tag: 'body', children: [
|
|
70
|
+
{ tag: 'script', attrs: { type: 'application/json', id: 'report-data' }, script: JSON.stringify(data).replace(/</g, '\\u003c') },
|
|
71
|
+
{ tag: 'script', script: `(${reportViewer.toString()})(document, JSON.parse(document.getElementById('report-data').textContent));` },
|
|
72
|
+
] },
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
return `<!doctype html>\n${toHtml(page)}\n`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** A report's file name: `Shop` → `shop-report.html`. */
|
|
79
|
+
export function reportFileName(title) {
|
|
80
|
+
const stem = String(title ?? '').trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'model';
|
|
81
|
+
return `${stem}-report.html`;
|
|
82
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* reportViewer — the script inside a saved report (reportHtml): it builds the
|
|
3
|
+
* page from the report's data (ModelReport#data) in the reader's browser: the
|
|
4
|
+
* tree of items on the left, with a search box that keeps what matches by
|
|
5
|
+
* name, type or documentation; the chosen item's page on the right (its
|
|
6
|
+
* facts, documentation, properties, picture with clickable shapes, and
|
|
7
|
+
* lists); the address (#key) says which page, so Back and links work.
|
|
8
|
+
*
|
|
9
|
+
* It is written into the report as its source text, so it uses nothing from
|
|
10
|
+
* outside itself: no imports, no names from this module.
|
|
11
|
+
*
|
|
12
|
+
* @param {Document} doc
|
|
13
|
+
* @param {Object} data - ModelReport#data()
|
|
14
|
+
* @param {Window} [win] - For the address (location.hash, hashchange)
|
|
15
|
+
*/
|
|
16
|
+
export function reportViewer(doc, data, win = doc.defaultView) {
|
|
17
|
+
const h = (tag, props = {}, children = []) => {
|
|
18
|
+
const node = doc.createElement(tag);
|
|
19
|
+
for (const [k, v] of Object.entries(props)) {
|
|
20
|
+
if (v == null) continue;
|
|
21
|
+
if (k === 'text') node.textContent = String(v);
|
|
22
|
+
else if (k === 'cls') node.className = v;
|
|
23
|
+
else if (k === 'style') Object.assign(node.style, v);
|
|
24
|
+
else if (k.startsWith('on')) node.addEventListener(k.slice(2), v);
|
|
25
|
+
else node.setAttribute(k, String(v));
|
|
26
|
+
}
|
|
27
|
+
for (const child of children) if (child) node.appendChild(typeof child === 'string' ? doc.createTextNode(child) : child);
|
|
28
|
+
return node;
|
|
29
|
+
};
|
|
30
|
+
const clear = (node) => { node.textContent = ''; };
|
|
31
|
+
const items = data.items;
|
|
32
|
+
const href = (key) => `#${encodeURIComponent(key)}`;
|
|
33
|
+
const link = (key, text) => (items[key] ? h('a', { href: href(key), text: text ?? items[key].name }) : h('span', { text: text ?? key }));
|
|
34
|
+
const swatch = (item) => (item.color ? h('span', { cls: 'swatch', style: { background: item.color } }) : null);
|
|
35
|
+
|
|
36
|
+
const search = h('input', { type: 'search', placeholder: 'Search names, types, documentation', 'aria-label': 'Search' });
|
|
37
|
+
const nav = h('nav');
|
|
38
|
+
const main = h('main');
|
|
39
|
+
const body = doc.body;
|
|
40
|
+
body.appendChild(h('header', {}, [h('a', { href: href(data.home), cls: 'title', text: data.title }), search]));
|
|
41
|
+
body.appendChild(h('div', { cls: 'columns' }, [nav, main]));
|
|
42
|
+
|
|
43
|
+
// The tree: a section per kind, a group per layer (or kind), a link per item.
|
|
44
|
+
const entries = [];
|
|
45
|
+
for (const section of data.sections) {
|
|
46
|
+
const groups = section.groups.map((group) => {
|
|
47
|
+
const links = group.keys.filter(key => items[key]).map((key) => {
|
|
48
|
+
const item = items[key];
|
|
49
|
+
const row = h('li', {}, [swatch(item), link(key)]);
|
|
50
|
+
entries.push({ key, row, text: `${item.name} ${item.type ?? ''} ${item.documentation ?? ''}`.toLowerCase() });
|
|
51
|
+
return row;
|
|
52
|
+
});
|
|
53
|
+
const list = h('ul', {}, links);
|
|
54
|
+
return { node: group.title ? h('details', { open: '' }, [h('summary', { text: group.title }), list]) : list, links };
|
|
55
|
+
});
|
|
56
|
+
const node = h('section', {}, [h('h2', { text: section.title }), ...groups.map(g => g.node)]);
|
|
57
|
+
nav.appendChild(node);
|
|
58
|
+
entries.push({ section: node, groups });
|
|
59
|
+
}
|
|
60
|
+
const filter = () => {
|
|
61
|
+
const words = search.value.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
62
|
+
for (const entry of entries) {
|
|
63
|
+
if (entry.row) entry.row.style.display = words.every(w => entry.text.includes(w)) ? '' : 'none';
|
|
64
|
+
}
|
|
65
|
+
for (const entry of entries.filter(e => e.section)) {
|
|
66
|
+
let shown = 0;
|
|
67
|
+
for (const group of entry.groups) {
|
|
68
|
+
const n = group.links.filter(row => row.style.display !== 'none').length;
|
|
69
|
+
group.node.style.display = n ? '' : 'none';
|
|
70
|
+
if (words.length && n && group.node.tagName.toLowerCase() === 'details') group.node.setAttribute('open', '');
|
|
71
|
+
shown += n;
|
|
72
|
+
}
|
|
73
|
+
entry.section.style.display = shown ? '' : 'none';
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
search.addEventListener('input', filter);
|
|
77
|
+
|
|
78
|
+
// A picture: the view as an image, a link over each shape that has a page.
|
|
79
|
+
const picture = ({ svg, viewBox, areas }) => {
|
|
80
|
+
const pct = (v, total) => `${(v / total) * 100}%`;
|
|
81
|
+
const frame = h('div', { cls: 'picture' }, [h('img', { src: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`, alt: 'View' })]);
|
|
82
|
+
for (const area of areas) {
|
|
83
|
+
frame.appendChild(h('a', {
|
|
84
|
+
href: href(area.key), title: items[area.key]?.name ?? '', cls: 'area',
|
|
85
|
+
style: {
|
|
86
|
+
left: pct(area.x - viewBox.x, viewBox.width), top: pct(area.y - viewBox.y, viewBox.height),
|
|
87
|
+
width: pct(area.width, viewBox.width), height: pct(area.height, viewBox.height),
|
|
88
|
+
},
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
return frame;
|
|
92
|
+
};
|
|
93
|
+
const table = (rows) => h('table', {}, rows.map(([label, value]) => h('tr', {}, [h('th', { text: label }), h('td', {}, [value])])));
|
|
94
|
+
|
|
95
|
+
const show = (key) => {
|
|
96
|
+
const item = items[key] ?? items[data.home];
|
|
97
|
+
clear(main);
|
|
98
|
+
main.appendChild(h('h1', {}, [swatch(item), item.name]));
|
|
99
|
+
if (item.type) main.appendChild(h('p', { cls: 'type', text: item.type }));
|
|
100
|
+
if (item.facts) main.appendChild(table(item.facts.map(f => [f.label, f.key ? link(f.key) : doc.createTextNode(f.text ?? '')])));
|
|
101
|
+
if (item.documentation) main.appendChild(h('p', { cls: 'documentation', text: item.documentation }));
|
|
102
|
+
if (item.picture) main.appendChild(picture(item.picture));
|
|
103
|
+
if (item.properties) {
|
|
104
|
+
main.appendChild(h('h2', { text: 'Properties' }));
|
|
105
|
+
main.appendChild(table(item.properties.map(p => [p.name, doc.createTextNode(p.value)])));
|
|
106
|
+
}
|
|
107
|
+
for (const list of item.lists ?? []) {
|
|
108
|
+
main.appendChild(h('h2', { text: `${list.title} (${list.rows.length})` }));
|
|
109
|
+
main.appendChild(h('ul', {}, list.rows.map(row => h('li', {}, [swatch(items[row.key] ?? {}), link(row.key), row.note ? h('span', { cls: 'note', text: ` ${row.note}` }) : null]))));
|
|
110
|
+
}
|
|
111
|
+
for (const entry of entries) if (entry.row) entry.row.className = entry.key === item.key ? 'current' : '';
|
|
112
|
+
doc.title = `${item.name} — ${data.title}`;
|
|
113
|
+
};
|
|
114
|
+
const current = () => decodeURIComponent(String(win?.location?.hash ?? '').slice(1)) || data.home;
|
|
115
|
+
win?.addEventListener?.('hashchange', () => show(current()));
|
|
116
|
+
show(current());
|
|
117
|
+
return { show, filter, search };
|
|
118
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Shape } from './Shape.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CircleShape — circle primitive.
|
|
5
|
+
*/
|
|
6
|
+
export class CircleShape extends Shape {
|
|
7
|
+
constructor({ cx, cy, r, fill, stroke }) {
|
|
8
|
+
super('circle');
|
|
9
|
+
this.cx = cx;
|
|
10
|
+
this.cy = cy;
|
|
11
|
+
this.r = r;
|
|
12
|
+
this.fill = fill;
|
|
13
|
+
this.stroke = stroke;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
render(renderer) {
|
|
17
|
+
renderer.circle(this.cx, this.cy, this.r, this.fill, this.stroke);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Shape } from './Shape.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PathShape — path primitive.
|
|
5
|
+
*/
|
|
6
|
+
export class PathShape extends Shape {
|
|
7
|
+
constructor({ d, fill, stroke }) {
|
|
8
|
+
super('path');
|
|
9
|
+
this.d = d;
|
|
10
|
+
this.fill = fill;
|
|
11
|
+
this.stroke = stroke;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
render(renderer) {
|
|
15
|
+
renderer.path(this.d, this.fill, this.stroke);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Shape } from './Shape.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* RectShape — rectangle primitive.
|
|
5
|
+
*/
|
|
6
|
+
export class RectShape extends Shape {
|
|
7
|
+
constructor({ x, y, width, height, fill, stroke }) {
|
|
8
|
+
super('rect');
|
|
9
|
+
this.x = x;
|
|
10
|
+
this.y = y;
|
|
11
|
+
this.width = width;
|
|
12
|
+
this.height = height;
|
|
13
|
+
this.fill = fill;
|
|
14
|
+
this.stroke = stroke;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
render(renderer) {
|
|
18
|
+
renderer.rect(this.x, this.y, this.width, this.height, this.fill, this.stroke);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shape — abstract base for renderer-agnostic geometric primitives.
|
|
3
|
+
*
|
|
4
|
+
* Concrete shapes live alongside this file (RectShape, CircleShape, PathShape)
|
|
5
|
+
* and are assembled by ShapeFactory so that this module stays free of circular
|
|
6
|
+
* subclass imports.
|
|
7
|
+
*/
|
|
8
|
+
export class Shape {
|
|
9
|
+
constructor(type) {
|
|
10
|
+
if (new.target === Shape) {
|
|
11
|
+
throw new TypeError('Shape is abstract — subclass it');
|
|
12
|
+
}
|
|
13
|
+
this.type = type;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Render this shape through the given renderer. Subclasses implement. */
|
|
17
|
+
render(renderer) {
|
|
18
|
+
throw new Error(`${this.constructor.name} must implement render()`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Shape } from './Shape.js';
|
|
2
|
+
import { RectShape } from './RectShape.js';
|
|
3
|
+
import { CircleShape } from './CircleShape.js';
|
|
4
|
+
import { PathShape } from './PathShape.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ShapeFactory — converts plain {type, ...} descriptors into concrete Shape
|
|
8
|
+
* instances. Kept separate from Shape.js to avoid circular imports between
|
|
9
|
+
* the base class and its subclasses.
|
|
10
|
+
*/
|
|
11
|
+
export class ShapeFactory {
|
|
12
|
+
/** Convert a plain shape descriptor into a concrete Shape instance. */
|
|
13
|
+
static fromObject(obj) {
|
|
14
|
+
if (obj instanceof Shape) return obj;
|
|
15
|
+
switch (obj.type) {
|
|
16
|
+
case 'rect': return new RectShape(obj);
|
|
17
|
+
case 'circle': return new CircleShape(obj);
|
|
18
|
+
case 'path': return new PathShape(obj);
|
|
19
|
+
default:
|
|
20
|
+
throw new Error(`Unknown shape type: ${obj.type}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LocalJsonStore — one JSON value under one key of a Storage (localStorage by
|
|
3
|
+
* default). Storage can be missing or throw (private windows, blocked site
|
|
4
|
+
* data), so every read and write degrades to the fallback / a no-op.
|
|
5
|
+
*/
|
|
6
|
+
export class LocalJsonStore {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} key
|
|
9
|
+
* @param {Storage} [storage] - Defaults to globalThis.localStorage when available
|
|
10
|
+
*/
|
|
11
|
+
constructor(key, storage = LocalJsonStore._defaultStorage()) {
|
|
12
|
+
this.key = key;
|
|
13
|
+
this.storage = storage;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** The stored value, or `fallback` if nothing valid is stored. */
|
|
17
|
+
load(fallback) {
|
|
18
|
+
try {
|
|
19
|
+
const raw = this.storage?.getItem(this.key);
|
|
20
|
+
return raw == null ? fallback : JSON.parse(raw);
|
|
21
|
+
} catch {
|
|
22
|
+
return fallback;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** @returns {boolean} whether the value was written */
|
|
27
|
+
save(value) {
|
|
28
|
+
try {
|
|
29
|
+
this.storage?.setItem(this.key, JSON.stringify(value));
|
|
30
|
+
return !!this.storage;
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static _defaultStorage() {
|
|
37
|
+
try {
|
|
38
|
+
return globalThis.localStorage ?? null;
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Template } from './Template.js';
|
|
2
|
+
import { svgEl } from './svg.js';
|
|
3
|
+
|
|
4
|
+
/** ActorTemplate — stick figure; the label sits underneath. */
|
|
5
|
+
export class ActorTemplate extends Template {
|
|
6
|
+
static defaults = { width: 40, height: 80, fillColor: '#ffffff' };
|
|
7
|
+
|
|
8
|
+
get labelAnchor() { return { x: this.x, y: this.bottom + 12 }; }
|
|
9
|
+
|
|
10
|
+
/** Key heights and widths of the figure, shared by drawing and outline. */
|
|
11
|
+
_figure() {
|
|
12
|
+
const r = Math.min(this.width / 2, this.height * 0.14);
|
|
13
|
+
const neck = this.top + r * 2;
|
|
14
|
+
const hip = this.top + this.height * 0.62;
|
|
15
|
+
return { r, neck, hip, arms: neck + (hip - neck) * 0.3, foot: this.width * 0.4 };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Convex hull of head, arms and feet, so edges stop at the figure rather than empty space. */
|
|
19
|
+
outline() {
|
|
20
|
+
const { x, left: L, right: R, top: T, bottom: B } = this;
|
|
21
|
+
const { r, arms, foot } = this._figure();
|
|
22
|
+
return [[x - r, T], [x + r, T], [R, arms], [x + foot, B], [x - foot, B], [L, arms]];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
shapeElements(doc) {
|
|
26
|
+
const { x, left: L, right: R, top: T, bottom: B } = this;
|
|
27
|
+
const { r, neck, hip, arms, foot } = this._figure();
|
|
28
|
+
const stroke = this.line({ 'stroke-width': this.strokeWidth, 'stroke-linecap': 'round' });
|
|
29
|
+
return [
|
|
30
|
+
// The figure is mostly thin lines; a transparent box keeps the whole area clickable.
|
|
31
|
+
svgEl('rect', { x: L, y: T, width: this.width, height: this.height, fill: 'transparent' }, doc),
|
|
32
|
+
svgEl('circle', this.paint({ cx: x, cy: T + r, r }), doc),
|
|
33
|
+
svgEl('path', { ...stroke, d: `M ${x} ${neck} V ${hip} M ${L} ${arms} H ${R} M ${x - foot} ${B} L ${x} ${hip} L ${x + foot} ${B}` }, doc),
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Template } from './Template.js';
|
|
2
|
+
import { svgEl, pointsAttr } from './svg.js';
|
|
3
|
+
|
|
4
|
+
/** BoxTemplate — 3D box (UML deployment node, server, device). */
|
|
5
|
+
export class BoxTemplate extends Template {
|
|
6
|
+
static defaults = { width: 140, height: 90 };
|
|
7
|
+
|
|
8
|
+
get depth() { return Math.min(14, this.width * 0.15, this.height * 0.15); }
|
|
9
|
+
|
|
10
|
+
get labelAnchor() { return { x: this.x - this.depth / 2, y: this.y + this.depth / 2 - 8 }; }
|
|
11
|
+
|
|
12
|
+
outline() {
|
|
13
|
+
const { left: L, right: R, top: T, bottom: B, depth: d } = this;
|
|
14
|
+
return [[L, T + d], [L + d, T], [R, T], [R, B - d], [R - d, B], [L, B]];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
shapeElements(doc) {
|
|
18
|
+
const { left: L, right: R, top: T, bottom: B } = this;
|
|
19
|
+
const d = this.depth;
|
|
20
|
+
const face = (pts, shade) => svgEl('polygon', this.paint({ points: pointsAttr(pts), 'fill-opacity': shade }), doc);
|
|
21
|
+
return [
|
|
22
|
+
face([[L, T + d], [L + d, T], [R, T], [R - d, T + d]], 0.7),
|
|
23
|
+
face([[R - d, T + d], [R, T], [R, B - d], [R - d, B]], 0.5),
|
|
24
|
+
svgEl('rect', this.paint({ x: L, y: T + d, width: this.width - d, height: this.height - d }), doc),
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Template } from './Template.js';
|
|
2
|
+
import { svgEl } from './svg.js';
|
|
3
|
+
import { sampleArc } from './outline.js';
|
|
4
|
+
|
|
5
|
+
/** CircleTemplate — diameter is the smaller of width/height. */
|
|
6
|
+
export class CircleTemplate extends Template {
|
|
7
|
+
static defaults = { width: 80, height: 80 };
|
|
8
|
+
|
|
9
|
+
get radius() { return Math.min(this.width, this.height) / 2; }
|
|
10
|
+
|
|
11
|
+
outline() {
|
|
12
|
+
return sampleArc(this.x, this.y, this.radius, this.radius, 0, 2 * Math.PI, 72);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
shapeElements(doc) {
|
|
16
|
+
return [svgEl('circle', this.paint({ cx: this.x, cy: this.y, r: this.radius }), doc)];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RectangleTemplate } from './RectangleTemplate.js';
|
|
2
|
+
import { svgEl } from './svg.js';
|
|
3
|
+
|
|
4
|
+
/** ClassTemplate — UML classifier box: name, attribute and operation compartments. */
|
|
5
|
+
export class ClassTemplate extends RectangleTemplate {
|
|
6
|
+
static defaults = { width: 160, height: 110, fillColor: '#ffffff' };
|
|
7
|
+
|
|
8
|
+
get cornerRadius() { return 0; }
|
|
9
|
+
|
|
10
|
+
get headerHeight() { return Math.min(28, this.height / 3); }
|
|
11
|
+
|
|
12
|
+
get labelAnchor() { return { x: this.x, y: this.top + this.headerHeight / 2 }; }
|
|
13
|
+
|
|
14
|
+
shapeElements(doc) {
|
|
15
|
+
const h = this.headerHeight;
|
|
16
|
+
const mid = this.top + h + (this.height - h) / 2;
|
|
17
|
+
const divider = (y) => svgEl('line', this.line({ x1: this.left, y1: y, x2: this.right, y2: y }), doc);
|
|
18
|
+
return [...super.shapeElements(doc), divider(this.top + h), divider(mid)];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Template } from './Template.js';
|
|
2
|
+
import { svgEl } from './svg.js';
|
|
3
|
+
import { sampleCubic } from './outline.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Outline in a 100 x 60 unit box: a start point, cubic segments
|
|
7
|
+
* [control1, control2, end], then a straight closing edge back to the start.
|
|
8
|
+
* Drawn and sampled from the same data so edges meet the visible bumps.
|
|
9
|
+
*/
|
|
10
|
+
const START = [25, 56];
|
|
11
|
+
const CURVES = [
|
|
12
|
+
[[8, 56], [2, 44], [10, 36]],
|
|
13
|
+
[[2, 28], [10, 14], [24, 18]],
|
|
14
|
+
[[28, 4], [48, 2], [54, 13]],
|
|
15
|
+
[[62, 3], [82, 6], [82, 20]],
|
|
16
|
+
[[96, 18], [100, 36], [90, 42]],
|
|
17
|
+
[[98, 52], [86, 60], [75, 56]],
|
|
18
|
+
];
|
|
19
|
+
const PATH = `M ${START.join(' ')} ${CURVES.map(c => `C ${c.flat().join(' ')}`).join(' ')} Z`;
|
|
20
|
+
|
|
21
|
+
export class CloudTemplate extends Template {
|
|
22
|
+
static defaults = { width: 140, height: 84 };
|
|
23
|
+
|
|
24
|
+
outline() {
|
|
25
|
+
const sx = this.width / 100, sy = this.height / 60;
|
|
26
|
+
const toCanvas = ([u, v]) => [this.left + u * sx, this.top + v * sy];
|
|
27
|
+
const pts = [toCanvas(START)];
|
|
28
|
+
let from = START;
|
|
29
|
+
for (const [c1, c2, end] of CURVES) {
|
|
30
|
+
pts.push(...sampleCubic(from, c1, c2, end).map(toCanvas));
|
|
31
|
+
from = end;
|
|
32
|
+
}
|
|
33
|
+
return pts;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
shapeElements(doc) {
|
|
37
|
+
return [svgEl('path', this.paint({
|
|
38
|
+
d: PATH,
|
|
39
|
+
transform: `translate(${this.left} ${this.top}) scale(${this.width / 100} ${this.height / 60})`,
|
|
40
|
+
'vector-effect': 'non-scaling-stroke',
|
|
41
|
+
}), doc)];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { RectangleTemplate } from './RectangleTemplate.js';
|
|
2
|
+
import { svgEl } from './svg.js';
|
|
3
|
+
|
|
4
|
+
/** ComponentTemplate — UML 2 component: box with the component icon top-right. */
|
|
5
|
+
export class ComponentTemplate extends RectangleTemplate {
|
|
6
|
+
static defaults = { width: 150, height: 80 };
|
|
7
|
+
|
|
8
|
+
get cornerRadius() { return 0; }
|
|
9
|
+
|
|
10
|
+
shapeElements(doc) {
|
|
11
|
+
const ix = this.right - 22, iy = this.top + 8;
|
|
12
|
+
const icon = [
|
|
13
|
+
svgEl('rect', this.paint({ x: ix, y: iy, width: 14, height: 16, 'stroke-width': 1 }), doc),
|
|
14
|
+
svgEl('rect', this.paint({ x: ix - 4, y: iy + 3, width: 8, height: 4, 'stroke-width': 1 }), doc),
|
|
15
|
+
svgEl('rect', this.paint({ x: ix - 4, y: iy + 9, width: 8, height: 4, 'stroke-width': 1 }), doc),
|
|
16
|
+
];
|
|
17
|
+
return [...super.shapeElements(doc), ...icon];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Template } from './Template.js';
|
|
2
|
+
import { svgEl } from './svg.js';
|
|
3
|
+
import { sampleArc } from './outline.js';
|
|
4
|
+
|
|
5
|
+
/** CylinderTemplate — database / stored data. */
|
|
6
|
+
export class CylinderTemplate extends Template {
|
|
7
|
+
static defaults = { width: 90, height: 100 };
|
|
8
|
+
|
|
9
|
+
get capHeight() { return Math.min(this.height * 0.15, 14); }
|
|
10
|
+
|
|
11
|
+
get labelAnchor() { return { x: this.x, y: this.y + this.capHeight / 2 - 8 }; }
|
|
12
|
+
|
|
13
|
+
outline() {
|
|
14
|
+
const rx = this.width / 2, ry = this.capHeight;
|
|
15
|
+
return [
|
|
16
|
+
...sampleArc(this.x, this.top + ry, rx, ry, Math.PI, 2 * Math.PI, 24),
|
|
17
|
+
...sampleArc(this.x, this.bottom - ry, rx, ry, 0, Math.PI, 24),
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
shapeElements(doc) {
|
|
22
|
+
const { left: L, right: R, top: T, bottom: B } = this;
|
|
23
|
+
const rx = this.width / 2, ry = this.capHeight;
|
|
24
|
+
const body = `M ${L} ${T + ry} A ${rx} ${ry} 0 0 1 ${R} ${T + ry} V ${B - ry} A ${rx} ${ry} 0 0 1 ${L} ${B - ry} Z`;
|
|
25
|
+
return [
|
|
26
|
+
svgEl('path', this.paint({ d: body }), doc),
|
|
27
|
+
svgEl('ellipse', this.paint({ cx: this.x, cy: T + ry, rx, ry }), doc),
|
|
28
|
+
];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Template } from './Template.js';
|
|
2
|
+
import { svgEl } from './svg.js';
|
|
3
|
+
|
|
4
|
+
/** DataStoreTemplate — DFD data store: open-ended box with an ID bay on the left. */
|
|
5
|
+
export class DataStoreTemplate extends Template {
|
|
6
|
+
static defaults = { width: 150, height: 44 };
|
|
7
|
+
|
|
8
|
+
shapeElements(doc) {
|
|
9
|
+
const { left: L, right: R, top: T, bottom: B } = this;
|
|
10
|
+
const bay = Math.min(24, this.width * 0.15);
|
|
11
|
+
return [
|
|
12
|
+
svgEl('rect', { x: L, y: T, width: this.width, height: this.height, fill: this.fillColor, stroke: 'none' }, doc),
|
|
13
|
+
svgEl('path', this.line({ 'stroke-width': this.strokeWidth, d: `M ${R} ${T} H ${L} V ${B} H ${R} M ${L + bay} ${T} V ${B}` }), doc),
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PolygonTemplate } from './PolygonTemplate.js';
|
|
2
|
+
|
|
3
|
+
/** DiamondTemplate — decision / gateway / relationship. */
|
|
4
|
+
export class DiamondTemplate extends PolygonTemplate {
|
|
5
|
+
static defaults = { width: 100, height: 100 };
|
|
6
|
+
|
|
7
|
+
points() {
|
|
8
|
+
return [[this.x, this.top], [this.right, this.y], [this.x, this.bottom], [this.left, this.y]];
|
|
9
|
+
}
|
|
10
|
+
}
|