@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,146 @@
|
|
|
1
|
+
import { ArchimateNotation } from '../../archimate.js';
|
|
2
|
+
import { ArchimateSpecializationRegistry } from '../../archimateSpecializations.js';
|
|
3
|
+
import { PropertyListEditor } from '../PropertyListEditor.js';
|
|
4
|
+
import { EditViewItemCommand } from '../diagrams/EditViewItemCommand.js';
|
|
5
|
+
import { FormDialog } from '../FormDialog.js';
|
|
6
|
+
import { typeTitle } from './archimateNames.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* What a model element is, as dialog fields and an edit: its own name, type,
|
|
10
|
+
* specialization (those registered for its type, and its own), icon (its
|
|
11
|
+
* type's choices), documentation and typed properties, the same on every
|
|
12
|
+
* view. One definition for the canvas editor's shape dialog (its Element
|
|
13
|
+
* section) and the model tree's Properties….
|
|
14
|
+
*
|
|
15
|
+
* Field keys are `element.<key>`, so they sit beside other fields in one form.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The fields for an element.
|
|
20
|
+
* @param {Object} element - A model element
|
|
21
|
+
* @param {Object} [options]
|
|
22
|
+
* @param {string} [options.version] - Whose types and icons to offer
|
|
23
|
+
* @param {Document} [options.document]
|
|
24
|
+
* @returns {Array<Object>} FormDialog fields (headings included)
|
|
25
|
+
*/
|
|
26
|
+
export function elementPropertyFields(element, { version = '4', document: doc = globalThis.document } = {}) {
|
|
27
|
+
return [
|
|
28
|
+
{ key: 'element.name', label: 'Name', type: 'text', value: element.name ?? '' },
|
|
29
|
+
...elementKindFields(element, { version }),
|
|
30
|
+
{
|
|
31
|
+
key: 'element.icon', label: 'Icon', type: 'select', value: element.icon ?? '',
|
|
32
|
+
choices: [['', '(the type default)'], ...[...new Set([...ArchimateNotation.iconChoices(element.type, version), element.icon].filter(Boolean))].map(i => [i, i])],
|
|
33
|
+
},
|
|
34
|
+
{ key: 'element.documentation', label: 'Documentation', type: 'textarea', rows: 4, value: element.documentation ?? '' },
|
|
35
|
+
{ type: 'heading', label: 'Properties' },
|
|
36
|
+
PropertyListEditor.field(element.properties, { key: 'element.properties', document: doc }),
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** An element's type and specialization (those registered for its type, and its own), as fields. */
|
|
41
|
+
export function elementKindFields(element, { version = '4' } = {}) {
|
|
42
|
+
const types = [...new Set([...ArchimateNotation.elementTypeNames(version), element.type].filter(Boolean))];
|
|
43
|
+
return [
|
|
44
|
+
{ key: 'element.type', label: 'Type', type: 'select', value: element.type, choices: types.map(t => [t, typeTitle(t)]) },
|
|
45
|
+
{
|
|
46
|
+
key: 'element.specialization', label: 'Specialization', type: 'select', value: element.specialization ?? '',
|
|
47
|
+
choices: [['', '(none)'], ...[...new Set([...ArchimateSpecializationRegistry.forBaseType(element.type).map(s => s.name), element.specialization].filter(Boolean))].map(n => [n, n])],
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The fields for several elements edited together (see FormDialog.many):
|
|
54
|
+
* their type, their specialization when they share a type (each type has its
|
|
55
|
+
* own), and one property to give them all (set where they have it, added where
|
|
56
|
+
* they don't).
|
|
57
|
+
*/
|
|
58
|
+
export function manyElementsFields(elements, { version = '4' } = {}) {
|
|
59
|
+
const oneType = new Set(elements.map(e => e.type)).size === 1;
|
|
60
|
+
return [
|
|
61
|
+
{ type: 'heading', label: `Elements (${elements.length}, on every view)` },
|
|
62
|
+
...FormDialog.many(elements.map(e => elementKindFields(e, { version }).filter(f => oneType || f.key === 'element.type'))),
|
|
63
|
+
{ key: 'element.property.name', label: 'Set property', type: 'text', value: '', placeholder: 'name (empty: none)' },
|
|
64
|
+
{ key: 'element.property.value', label: 'To', type: 'text', value: '' },
|
|
65
|
+
...(() => {
|
|
66
|
+
const names = [...new Set(elements.flatMap(e => (e.properties ?? []).map(p => p.name ?? p.key)).filter(Boolean))].sort();
|
|
67
|
+
return names.length ? [{ key: 'element.property.remove', label: 'Remove property', type: 'select', value: '', choices: [['', '(none)'], ...names.map(n => [n, n])] }] : [];
|
|
68
|
+
})(),
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* `manyElementsFields`' values as each element's edit (fields left on Keep are
|
|
74
|
+
* undefined): EditViewItemCommands, only for the elements that change.
|
|
75
|
+
* `instanceOf(element)` is the occurrence edited with it, if any.
|
|
76
|
+
*/
|
|
77
|
+
export function manyElementsEditCommands(elements, values, { instanceOf = () => null } = {}) {
|
|
78
|
+
const name = String(values['element.property.name'] ?? '').trim();
|
|
79
|
+
const kind = Object.fromEntries(['element.type', 'element.specialization'].filter(k => values[k] !== undefined).map(k => [k, values[k]]));
|
|
80
|
+
return elements.map(element => {
|
|
81
|
+
const own = element.properties ?? [];
|
|
82
|
+
const property = { name, type: own.find(p => p.name === name)?.type ?? 'string', value: String(values['element.property.value'] ?? '') };
|
|
83
|
+
const remove = String(values['element.property.remove'] ?? '');
|
|
84
|
+
let list = !name ? own : own.some(p => p.name === name) ? own.map(p => (p.name === name ? property : p)) : [...own, property];
|
|
85
|
+
if (remove) list = list.filter(p => (p.name ?? p.key) !== remove);
|
|
86
|
+
const properties = list === own ? {} : { 'element.properties': list };
|
|
87
|
+
return elementEditCommand(element, { ...kind, ...properties }, { instance: instanceOf(element) });
|
|
88
|
+
}).filter(Boolean);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The changed `<prefix>.<key>` values as an edit of a concept (an element or
|
|
93
|
+
* relationship): one EditViewItemCommand, or null when nothing changed. An
|
|
94
|
+
* empty text or list is unset. `instance` is the occurrence edited with it
|
|
95
|
+
* (none from the model tree).
|
|
96
|
+
*/
|
|
97
|
+
export function conceptEditCommand(concept, values, { prefix, instance = null, adjust = () => {} }) {
|
|
98
|
+
const unset = (v) => v === undefined || v === null || v === '' || (Array.isArray(v) && !v.length);
|
|
99
|
+
const changes = {};
|
|
100
|
+
for (const [field, value] of Object.entries(values)) {
|
|
101
|
+
if (!field.startsWith(`${prefix}.`)) continue;
|
|
102
|
+
const key = field.slice(prefix.length + 1);
|
|
103
|
+
const before = concept[key];
|
|
104
|
+
if ((unset(before) && unset(value)) || JSON.stringify(before) === JSON.stringify(value)) continue;
|
|
105
|
+
changes[key] = unset(value) ? undefined : value;
|
|
106
|
+
}
|
|
107
|
+
if (!Object.keys(changes).length) return null;
|
|
108
|
+
adjust(changes);
|
|
109
|
+
return new EditViewItemCommand({ concept, instance }, { concept: changes, appearance: {} }, `Edit ${concept.name || concept.label || concept.id}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** An element's edit (elementPropertyFields' values): a new type drops a stored layer, which then follows the type. */
|
|
113
|
+
export function elementEditCommand(element, values, { instance = null } = {}) {
|
|
114
|
+
return conceptEditCommand(element, values, {
|
|
115
|
+
prefix: 'element', instance,
|
|
116
|
+
adjust: (changes) => { if ('type' in changes && element.layer) changes.layer = undefined; },
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Edit a model element in its own dialog (from the model tree): its
|
|
122
|
+
* properties, saved as one undo step on `history`.
|
|
123
|
+
* @param {Object} element
|
|
124
|
+
* @param {Object} options
|
|
125
|
+
* @param {CommandHistory} options.history - Where the edit goes (the current view's)
|
|
126
|
+
* @param {() => void} [options.onSaved] - After a change (redraw, refresh the tree)
|
|
127
|
+
* @param {string} [options.version]
|
|
128
|
+
* @param {Document} [options.document]
|
|
129
|
+
*/
|
|
130
|
+
export function editElementProperties(element, { history, onSaved = () => {}, version = '4', document: doc = globalThis.document }) {
|
|
131
|
+
return new FormDialog({
|
|
132
|
+
title: `Properties: ${element.name || element.id}`,
|
|
133
|
+
description: 'The element itself: these show on every view it is on.',
|
|
134
|
+
fields: elementPropertyFields(element, { version, document: doc }),
|
|
135
|
+
submitLabel: 'Save',
|
|
136
|
+
idPrefix: 'element-props-',
|
|
137
|
+
document: doc,
|
|
138
|
+
onApply: (values) => {
|
|
139
|
+
const cmd = elementEditCommand(element, values);
|
|
140
|
+
if (!cmd) return;
|
|
141
|
+
if (history) history.execute(cmd);
|
|
142
|
+
else cmd.execute();
|
|
143
|
+
onSaved(cmd);
|
|
144
|
+
},
|
|
145
|
+
}).open();
|
|
146
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { elementTypeGroups } from './elementTypeGroups.js';
|
|
2
|
+
import { typeTitle } from './archimateNames.js';
|
|
3
|
+
|
|
4
|
+
/** Every element type of a version as checklist choices, grouped by layer as the palette groups them. */
|
|
5
|
+
export function elementTypeChoices(version = '4') {
|
|
6
|
+
return elementTypeGroups(version).flatMap(group => group.types.map(type => [type.name, typeTitle(type.name), group.label]));
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ArchimateNotation } from '../../archimate.js';
|
|
2
|
+
import { typeTitle } from './archimateNames.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The element types of a version, grouped as people look for them: each layer
|
|
6
|
+
* that has types (the notation's order), then ArchiMate 4's common behaviour
|
|
7
|
+
* types (no layer of their own). The palette's groups, and the type lists of
|
|
8
|
+
* the specialization and viewpoint dialogs.
|
|
9
|
+
* @returns {Array<{key: string, label: string, types: ArchimateElementType[]}>}
|
|
10
|
+
*/
|
|
11
|
+
export function elementTypeGroups(version = '4') {
|
|
12
|
+
const groups = ArchimateNotation.layers()
|
|
13
|
+
.map(layer => ({ key: layer.name, label: typeTitle(layer.name), types: ArchimateNotation.typesInLayer(layer.name, version) }))
|
|
14
|
+
.filter(g => g.types.length);
|
|
15
|
+
const grouped = new Set(groups.flatMap(g => g.types.map(t => t.name)));
|
|
16
|
+
const common = ArchimateNotation.elementTypeNames(version).filter(n => !grouped.has(n)).map(n => ArchimateNotation.elementType(n, version));
|
|
17
|
+
if (common.length) groups.push({ key: 'common', label: 'Common behaviour', types: common });
|
|
18
|
+
return groups;
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export { ArchimateElementTemplate } from './ArchimateElementTemplate.js';
|
|
2
|
+
export { ArchimateEdge } from './ArchimateEdge.js';
|
|
3
|
+
export { ViewLineEdge } from './ViewLineEdge.js';
|
|
4
|
+
export { ArchimateCanvasEditor, ARCHIMATE_TYPE_MIME, KIND_PREFERENCE, typeTitle } from './ArchimateCanvasEditor.js';
|
|
5
|
+
export { ArchimatePalette } from './ArchimatePalette.js';
|
|
6
|
+
export { ArchiFileFormat } from './ArchiFileFormat.js';
|
|
7
|
+
export { ExchangeFileFormat } from './ExchangeFileFormat.js';
|
|
8
|
+
export { ArchimateCsvFileFormat } from './ArchimateCsvFileFormat.js';
|
|
9
|
+
export { ARCHIMATE_FILE_FORMATS } from './archimateFileFormats.js';
|
|
10
|
+
export { DrawioFileFormat } from './DrawioFileFormat.js';
|
|
11
|
+
export { ViewpointRule } from './ViewpointRule.js';
|
|
12
|
+
export { ElementFilterRule } from './ElementFilterRule.js';
|
|
13
|
+
export { DerivedEdge } from './DerivedEdge.js';
|
|
14
|
+
export { ViewGroupTemplate, GROUP_FILL } from './ViewGroupTemplate.js';
|
|
15
|
+
export { CustomViewpoints, CUSTOM_VIEWPOINTS_STORE } from './CustomViewpoints.js';
|
|
16
|
+
export { specializationCatalogDialog } from './specializationCatalogDialog.js';
|
|
17
|
+
export { elementTypeChoices } from './elementTypeChoices.js';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { CatalogDialog } from '../CatalogDialog.js';
|
|
2
|
+
import { ArchimateSpecializationRegistry, SPECIALIZATIONS_STORE } from '../../archimateSpecializations.js';
|
|
3
|
+
import { elementTypeChoices } from './elementTypeChoices.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Edit the specialization catalog (ArchimateSpecializationRegistry): name,
|
|
7
|
+
* the element types it applies to, its icon, colour and description. Every
|
|
8
|
+
* change is saved to `store` (this browser's catalog), which both editors
|
|
9
|
+
* load.
|
|
10
|
+
* @param {Object} [options]
|
|
11
|
+
* @param {string} [options.version] - Whose element types to offer
|
|
12
|
+
* @param {LocalJsonStore} [options.store]
|
|
13
|
+
* @param {() => void} [options.onChange] - After a change (redraw)
|
|
14
|
+
* @param {Document} [options.document]
|
|
15
|
+
* @returns {CatalogDialog}
|
|
16
|
+
*/
|
|
17
|
+
export function specializationCatalogDialog({ version = '4', store = SPECIALIZATIONS_STORE, onChange = () => {}, document: doc = globalThis.document } = {}) {
|
|
18
|
+
const R = ArchimateSpecializationRegistry;
|
|
19
|
+
const keep = () => store.save(R.serialize());
|
|
20
|
+
return new CatalogDialog({
|
|
21
|
+
title: 'Specializations',
|
|
22
|
+
description: 'Kinds of element of your own (a Firewall is a Node): their icon and colour show on every element given one.',
|
|
23
|
+
noun: 'specialization',
|
|
24
|
+
items: () => R.list().sort((a, b) => a.name.localeCompare(b.name)),
|
|
25
|
+
label: (spec) => `${spec.icon ? `${spec.icon} ` : ''}${spec.name}`,
|
|
26
|
+
fields: (spec) => [
|
|
27
|
+
{ key: 'name', label: 'Name', type: 'text', value: spec?.name ?? '' },
|
|
28
|
+
{ key: 'icon', label: 'Icon', type: 'text', value: spec?.icon ?? '', hint: 'An emoji or a short text, drawn in the corner' },
|
|
29
|
+
{ key: 'color', label: 'Colour', type: 'color', value: spec?.color ?? '' },
|
|
30
|
+
{ key: 'description', label: 'Description', type: 'textarea', rows: 2, value: spec?.description ?? '' },
|
|
31
|
+
{ key: 'baseTypes', label: 'For types', type: 'checklist', value: spec?.baseTypes ?? [], choices: elementTypeChoices(version), hint: 'None chosen: every type' },
|
|
32
|
+
],
|
|
33
|
+
validate: (spec, { name }) => {
|
|
34
|
+
const wanted = String(name ?? '').trim();
|
|
35
|
+
if (!wanted) return 'A specialization needs a name.';
|
|
36
|
+
const other = R.resolve(wanted);
|
|
37
|
+
if (other && other.id !== spec?.id) return `There is already a specialization called "${wanted}".`;
|
|
38
|
+
return null;
|
|
39
|
+
},
|
|
40
|
+
save: (spec, { name, icon, color, description, baseTypes }) => {
|
|
41
|
+
R.register({
|
|
42
|
+
id: spec?.id ?? uniqueId(name.trim(), (id) => !!R.get(id)),
|
|
43
|
+
name: name.trim(),
|
|
44
|
+
baseTypes,
|
|
45
|
+
icon: icon?.trim() || undefined,
|
|
46
|
+
iconUrl: spec?.iconUrl,
|
|
47
|
+
color: color && color !== 'none' ? color : undefined,
|
|
48
|
+
description: description?.trim() || undefined,
|
|
49
|
+
});
|
|
50
|
+
keep();
|
|
51
|
+
},
|
|
52
|
+
remove: (spec) => { R.unregister(spec.id); keep(); },
|
|
53
|
+
onChange,
|
|
54
|
+
document: doc,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** An id made from a name, not yet `taken`. */
|
|
59
|
+
export function uniqueId(name, taken) {
|
|
60
|
+
const base = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') || 'item';
|
|
61
|
+
let id = base;
|
|
62
|
+
for (let n = 2; taken(id); n++) id = `${base}-${n}`;
|
|
63
|
+
return id;
|
|
64
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ArchimateDiagram } from '../diagrams/ArchimateDiagram.js';
|
|
2
|
+
import { ArchimateNotation } from '../../archimate.js';
|
|
3
|
+
import { Glyph } from '../glyphs/Glyph.js';
|
|
4
|
+
import { glyphFor } from '../glyphs/index.js';
|
|
5
|
+
import { glyphToSvg } from '../glyphs/glyphSvg.js';
|
|
6
|
+
import { svgEl } from '../templates/svg.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A small picture of an element type: its notation glyph in its layer
|
|
10
|
+
* colour, as an <svg> (a type of the other ArchiMate version as that version draws it). One drawing for every place a type is shown small:
|
|
11
|
+
* the palette's tiles and the model tree's elements and type folders.
|
|
12
|
+
* @param {string} typeName - An element type ('business-actor', ...)
|
|
13
|
+
* @param {Object} [options]
|
|
14
|
+
* @param {number} [options.size] - Its height in pixels (it is 1.4 times as wide)
|
|
15
|
+
* @param {string} [options.version] - ArchiMate version
|
|
16
|
+
* @param {Document} [options.document]
|
|
17
|
+
* @returns {SVGElement}
|
|
18
|
+
*/
|
|
19
|
+
export function typeGlyph(typeName, { size = 22, version = '4', document: doc = globalThis.document } = {}) {
|
|
20
|
+
// A type of the other version (3.2's business-process under 4) is drawn as that version draws it.
|
|
21
|
+
const own = ArchimateNotation.elementType(typeName, version) ? version : (ArchimateNotation.elementType(typeName, '3.2') ? '3.2' : version);
|
|
22
|
+
const type = ArchimateNotation.elementType(typeName, own);
|
|
23
|
+
const node = ArchimateDiagram.buildNode({ id: typeName, name: '', type: typeName }, { archimateVersion: own });
|
|
24
|
+
const glyph = glyphFor(type?.notationShape ?? 'rect');
|
|
25
|
+
const ctx = Glyph.context({ R: size / 2, size: { w: size * 1.3, h: size }, color: node.color, cornerStyle: node.cornerStyle, strokeColor: '#333', strokeWidth: 1 });
|
|
26
|
+
const svg = svgEl('svg', { width: size * 1.4, height: size + 4, viewBox: `${-size * 0.7} ${-size / 2 - 2} ${size * 1.4} ${size + 4}` }, doc);
|
|
27
|
+
svg.appendChild(glyphToSvg(glyph.parts(ctx), doc));
|
|
28
|
+
return svg;
|
|
29
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { ItemGroup } from './ItemGroup.js';
|
|
2
|
+
import './BackgroundGroup.js'; // registers its kind, so fromJSON makes it
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Arrangement — how the items on one view hold together: which are grouped
|
|
6
|
+
* (an ItemGroup moves as one) and which are locked (fixed in place: not moved,
|
|
7
|
+
* resized or rotated). An item or a whole group can be locked; a locked group
|
|
8
|
+
* locks every member. Items are known by id only, so the same arrangement
|
|
9
|
+
* serves a template diagram's templates and an ArchiMate view's instances.
|
|
10
|
+
*
|
|
11
|
+
* A group may be pinned to the back (a BackgroundGroup, what a canvas takes
|
|
12
|
+
* from its template): its members stack behind every other item.
|
|
13
|
+
*
|
|
14
|
+
* Change it through the commands (GroupCommand, UngroupCommand, LockCommand,
|
|
15
|
+
* BackgroundCommand), so each change is one undo step on the view's history.
|
|
16
|
+
*/
|
|
17
|
+
export class Arrangement {
|
|
18
|
+
/**
|
|
19
|
+
* @param {Object} [spec]
|
|
20
|
+
* @param {Array<ItemGroup|Object>} [spec.groups]
|
|
21
|
+
* @param {Iterable<string>} [spec.locked] - Ids of locked items and groups
|
|
22
|
+
*/
|
|
23
|
+
constructor({ groups = [], locked = [] } = {}) {
|
|
24
|
+
/** @type {Map<string, ItemGroup>} */
|
|
25
|
+
this.groups = new Map(groups.map(g => {
|
|
26
|
+
const group = g instanceof ItemGroup ? g : ItemGroup.fromJSON(g);
|
|
27
|
+
return [group.id, group];
|
|
28
|
+
}));
|
|
29
|
+
/** @type {Set<string>} ids of locked items and groups */
|
|
30
|
+
this.locked = new Set(locked);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The group an item belongs to, or null. */
|
|
34
|
+
groupOf(itemId) {
|
|
35
|
+
for (const group of this.groups.values()) if (group.has(itemId)) return group;
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** The ids that move when `itemId` moves: its group's members, or itself. */
|
|
40
|
+
movingWith(itemId) {
|
|
41
|
+
const group = this.groupOf(itemId);
|
|
42
|
+
return group ? new Set(group.memberIds) : new Set([itemId]);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Everything that moves when these items move, groups included. */
|
|
46
|
+
movers(itemIds) {
|
|
47
|
+
const all = new Set();
|
|
48
|
+
for (const id of itemIds) for (const m of this.movingWith(id)) all.add(m);
|
|
49
|
+
return all;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Whether an item is fixed in place: locked itself, or in a locked group. */
|
|
53
|
+
isLocked(itemId) {
|
|
54
|
+
if (this.locked.has(itemId)) return true;
|
|
55
|
+
const group = this.groupOf(itemId);
|
|
56
|
+
return !!group && this.locked.has(group.id);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Whether these items (with their groups) may move: none of them is locked. */
|
|
60
|
+
canMove(itemIds) {
|
|
61
|
+
return [...this.movers(itemIds)].every(id => !this.isLocked(id));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Whether an item stays behind every item not pinned (it is in a BackgroundGroup). */
|
|
65
|
+
isPinnedToBack(itemId) {
|
|
66
|
+
return !!this.groupOf(itemId)?.pinnedToBack;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** What locking `itemId` locks: its group if it has one, else the item. */
|
|
70
|
+
lockTargetOf(itemId) {
|
|
71
|
+
return this.groupOf(itemId)?.id ?? itemId;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The arrangement of some of the items only (what a part of a view takes
|
|
76
|
+
* with it): groups keep the members among them (a group left with none
|
|
77
|
+
* goes), and their locks.
|
|
78
|
+
* @param {Iterable<string>} itemIds
|
|
79
|
+
* @returns {Arrangement}
|
|
80
|
+
*/
|
|
81
|
+
only(itemIds) {
|
|
82
|
+
const keep = new Set(itemIds);
|
|
83
|
+
const groups = [...this.groups.values()]
|
|
84
|
+
.map(g => g.withMembers([...g.memberIds].filter(id => keep.has(id))))
|
|
85
|
+
.filter(g => g.memberIds.size > 0);
|
|
86
|
+
const groupIds = new Set(groups.map(g => g.id));
|
|
87
|
+
return new Arrangement({ groups, locked: [...this.locked].filter(id => keep.has(id) || groupIds.has(id)) });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** A copy with item ids mapped (for a copied view whose items have new ids). */
|
|
91
|
+
copy(mapId = (id) => id) {
|
|
92
|
+
return new Arrangement({
|
|
93
|
+
groups: [...this.groups.values()].map(g => g.withMembers([...g.memberIds].map(mapId))),
|
|
94
|
+
locked: [...this.locked].map(id => (this.groups.has(id) ? id : mapId(id))),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
toJSON() {
|
|
99
|
+
return { groups: [...this.groups.values()].map(g => g.toJSON()), locked: [...this.locked] };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static fromJSON(data) {
|
|
103
|
+
return new Arrangement(data ?? {});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Replace this arrangement's state with a snapshot (toJSON). Used by undo. @protected */
|
|
107
|
+
restore(snapshot) {
|
|
108
|
+
const again = Arrangement.fromJSON(snapshot);
|
|
109
|
+
this.groups = again.groups;
|
|
110
|
+
this.locked = again.locked;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Command } from '../CommandHistory.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ArrangementCommand — one undoable change to an Arrangement. Undo puts back
|
|
5
|
+
* the arrangement exactly as it was (a snapshot taken when first applied);
|
|
6
|
+
* redo applies the change again. Subclasses implement apply().
|
|
7
|
+
*/
|
|
8
|
+
export class ArrangementCommand extends Command {
|
|
9
|
+
constructor(arrangement, label) {
|
|
10
|
+
super(label);
|
|
11
|
+
if (new.target === ArrangementCommand) throw new TypeError('ArrangementCommand is abstract — subclass it');
|
|
12
|
+
this.arrangement = arrangement;
|
|
13
|
+
this._before = null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
execute() {
|
|
17
|
+
this._before ??= this.arrangement.toJSON();
|
|
18
|
+
this.apply();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
undo() {
|
|
22
|
+
this.arrangement.restore(this._before);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Change the arrangement. @abstract */
|
|
26
|
+
apply() {
|
|
27
|
+
throw new Error(`${this.constructor.name} must implement apply()`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ArrangementCommand } from './ArrangementCommand.js';
|
|
2
|
+
import { BackgroundGroup } from './BackgroundGroup.js';
|
|
3
|
+
|
|
4
|
+
let nextBackground = 1;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* BackgroundCommand — make items the view's background: one BackgroundGroup
|
|
8
|
+
* (their old groups dissolved into it), locked. Their stacking is the view's
|
|
9
|
+
* to settle (DiagramEditorState#arrangeAsBackground puts them behind).
|
|
10
|
+
*/
|
|
11
|
+
export class BackgroundCommand extends ArrangementCommand {
|
|
12
|
+
/**
|
|
13
|
+
* @param {Arrangement} arrangement
|
|
14
|
+
* @param {Iterable<string>} itemIds
|
|
15
|
+
* @param {Object} [options]
|
|
16
|
+
* @param {string} [options.id] - The group's id (default: generated)
|
|
17
|
+
* @param {string} [options.name]
|
|
18
|
+
* @param {boolean} [options.locked] - Lock it (default true)
|
|
19
|
+
*/
|
|
20
|
+
constructor(arrangement, itemIds, { id = `background-${Date.now().toString(36)}-${nextBackground++}`, name = 'Background', locked = true } = {}) {
|
|
21
|
+
super(arrangement, 'Make background');
|
|
22
|
+
this.itemIds = [...itemIds];
|
|
23
|
+
this.groupId = id;
|
|
24
|
+
this.name = name;
|
|
25
|
+
this.lockedValue = locked;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
apply() {
|
|
29
|
+
const arrangement = this.arrangement;
|
|
30
|
+
const members = arrangement.movers(this.itemIds);
|
|
31
|
+
for (const id of this.itemIds) {
|
|
32
|
+
const old = arrangement.groupOf(id);
|
|
33
|
+
if (!old) continue;
|
|
34
|
+
arrangement.locked.delete(old.id);
|
|
35
|
+
arrangement.groups.delete(old.id);
|
|
36
|
+
}
|
|
37
|
+
for (const id of members) arrangement.locked.delete(id);
|
|
38
|
+
arrangement.groups.set(this.groupId, new BackgroundGroup({ id: this.groupId, name: this.name, memberIds: members }));
|
|
39
|
+
if (this.lockedValue) arrangement.locked.add(this.groupId);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ItemGroup } from './ItemGroup.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BackgroundGroup — a group pinned behind everything else on its view: what a
|
|
5
|
+
* canvas takes from its template. Its members always stack below every other
|
|
6
|
+
* item, whatever is sent to the back; it is made locked (BackgroundCommand),
|
|
7
|
+
* so it is neither moved nor changed until unlocked. Unlocked, it moves as
|
|
8
|
+
* one like any group; ungrouped, its items are ordinary items again.
|
|
9
|
+
*/
|
|
10
|
+
export class BackgroundGroup extends ItemGroup {
|
|
11
|
+
static kind = 'background';
|
|
12
|
+
|
|
13
|
+
get pinnedToBack() {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
ItemGroup.register(BackgroundGroup);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ArrangementCommand } from './ArrangementCommand.js';
|
|
2
|
+
import { ItemGroup } from './ItemGroup.js';
|
|
3
|
+
|
|
4
|
+
let nextGroup = 1;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* GroupCommand — group items so they move as one. Groups do not nest: an item
|
|
8
|
+
* already in a group brings its whole group into the new one, and the old
|
|
9
|
+
* group goes. A locked group's lock passes to the new group, and so does a
|
|
10
|
+
* background group's kind (the new group is pinned to the back too).
|
|
11
|
+
*/
|
|
12
|
+
export class GroupCommand extends ArrangementCommand {
|
|
13
|
+
/**
|
|
14
|
+
* @param {Arrangement} arrangement
|
|
15
|
+
* @param {Iterable<string>} itemIds - At least two items (with their groups)
|
|
16
|
+
* @param {Object} [options]
|
|
17
|
+
* @param {string} [options.id] - The new group's id (default: generated)
|
|
18
|
+
* @param {string} [options.name]
|
|
19
|
+
*/
|
|
20
|
+
constructor(arrangement, itemIds, { id = `group-${Date.now().toString(36)}-${nextGroup++}`, name = '' } = {}) {
|
|
21
|
+
super(arrangement, 'Group');
|
|
22
|
+
this.itemIds = [...itemIds];
|
|
23
|
+
this.groupId = id;
|
|
24
|
+
this.name = name;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
apply() {
|
|
28
|
+
const arrangement = this.arrangement;
|
|
29
|
+
const members = arrangement.movers(this.itemIds);
|
|
30
|
+
let locked = false;
|
|
31
|
+
let kindOf = null;
|
|
32
|
+
for (const id of this.itemIds) {
|
|
33
|
+
const old = arrangement.groupOf(id);
|
|
34
|
+
if (!old) continue;
|
|
35
|
+
locked ||= arrangement.locked.has(old.id);
|
|
36
|
+
if (old.pinnedToBack) kindOf = old;
|
|
37
|
+
arrangement.locked.delete(old.id);
|
|
38
|
+
arrangement.groups.delete(old.id);
|
|
39
|
+
}
|
|
40
|
+
const group = kindOf
|
|
41
|
+
? new kindOf.constructor({ id: this.groupId, name: this.name || kindOf.name, memberIds: members })
|
|
42
|
+
: new ItemGroup({ id: this.groupId, name: this.name, memberIds: members });
|
|
43
|
+
arrangement.groups.set(this.groupId, group);
|
|
44
|
+
if (locked) arrangement.locked.add(this.groupId);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ItemGroup — items on a view grouped logically: they move as one. It draws
|
|
3
|
+
* nothing of its own (not a container); a dashed outline shows it while one of
|
|
4
|
+
* its members is selected.
|
|
5
|
+
*
|
|
6
|
+
* A kind of group is a subclass (BackgroundGroup: pinned behind everything);
|
|
7
|
+
* each names its `kind`, which its JSON carries, and registers itself so
|
|
8
|
+
* `ItemGroup.fromJSON` makes the right class.
|
|
9
|
+
*/
|
|
10
|
+
export class ItemGroup {
|
|
11
|
+
/** The kind of group, as its JSON names it. */
|
|
12
|
+
static kind = 'group';
|
|
13
|
+
|
|
14
|
+
/** Group classes by kind (see register). */
|
|
15
|
+
static TYPES = new Map();
|
|
16
|
+
|
|
17
|
+
/** Make `GroupClass` the class for its `kind` when read from JSON. */
|
|
18
|
+
static register(GroupClass) {
|
|
19
|
+
ItemGroup.TYPES.set(GroupClass.kind, GroupClass);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {Object} spec
|
|
24
|
+
* @param {string} spec.id
|
|
25
|
+
* @param {Iterable<string>} spec.memberIds - Ids of the items in the group
|
|
26
|
+
* @param {string} [spec.name]
|
|
27
|
+
*/
|
|
28
|
+
constructor({ id, memberIds, name = '' }) {
|
|
29
|
+
if (!id) throw new TypeError('ItemGroup needs an id');
|
|
30
|
+
this.id = id;
|
|
31
|
+
this.name = name;
|
|
32
|
+
/** @type {Set<string>} */
|
|
33
|
+
this.memberIds = new Set(memberIds);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Whether its members stay behind every other item (a BackgroundGroup's do). */
|
|
37
|
+
get pinnedToBack() {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
has(itemId) {
|
|
42
|
+
return this.memberIds.has(itemId);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The same kind of group, with other members (a copied view's, say). */
|
|
46
|
+
withMembers(memberIds) {
|
|
47
|
+
return new this.constructor({ id: this.id, name: this.name, memberIds });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
toJSON() {
|
|
51
|
+
const kind = this.constructor.kind;
|
|
52
|
+
return { id: this.id, ...(kind !== ItemGroup.kind && { kind }), ...(this.name && { name: this.name }), memberIds: [...this.memberIds] };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** The group its JSON describes, of the class registered for its `kind`. */
|
|
56
|
+
static fromJSON(data) {
|
|
57
|
+
const GroupClass = ItemGroup.TYPES.get(data.kind) ?? ItemGroup;
|
|
58
|
+
return new GroupClass(data);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
ItemGroup.register(ItemGroup);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ArrangementCommand } from './ArrangementCommand.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* LockCommand — fix items in place, or free them. An item in a group locks or
|
|
5
|
+
* frees its whole group. Freeing also frees any member locked on its own, so
|
|
6
|
+
* after "Unlock" the group moves.
|
|
7
|
+
*/
|
|
8
|
+
export class LockCommand extends ArrangementCommand {
|
|
9
|
+
/**
|
|
10
|
+
* @param {Arrangement} arrangement
|
|
11
|
+
* @param {Iterable<string>} itemIds
|
|
12
|
+
* @param {boolean} locked - true to fix in place, false to free
|
|
13
|
+
*/
|
|
14
|
+
constructor(arrangement, itemIds, locked) {
|
|
15
|
+
super(arrangement, locked ? 'Lock' : 'Unlock');
|
|
16
|
+
this.itemIds = [...itemIds];
|
|
17
|
+
this.lockedValue = !!locked;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
apply() {
|
|
21
|
+
const arrangement = this.arrangement;
|
|
22
|
+
for (const id of this.itemIds) {
|
|
23
|
+
const target = arrangement.lockTargetOf(id);
|
|
24
|
+
if (this.lockedValue) {
|
|
25
|
+
arrangement.locked.add(target);
|
|
26
|
+
} else {
|
|
27
|
+
arrangement.locked.delete(target);
|
|
28
|
+
for (const member of arrangement.movingWith(id)) arrangement.locked.delete(member);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ArrangementCommand } from './ArrangementCommand.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* UngroupCommand — dissolve the group an item is in: its members move on
|
|
5
|
+
* their own again. A locked group's lock passes to each member, so nothing
|
|
6
|
+
* that was fixed comes loose.
|
|
7
|
+
*/
|
|
8
|
+
export class UngroupCommand extends ArrangementCommand {
|
|
9
|
+
/**
|
|
10
|
+
* @param {Arrangement} arrangement
|
|
11
|
+
* @param {string} itemId - A member of the group (or the group's id)
|
|
12
|
+
*/
|
|
13
|
+
constructor(arrangement, itemId) {
|
|
14
|
+
super(arrangement, 'Ungroup');
|
|
15
|
+
this.itemId = itemId;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
apply() {
|
|
19
|
+
const arrangement = this.arrangement;
|
|
20
|
+
const group = arrangement.groups.get(this.itemId) ?? arrangement.groupOf(this.itemId);
|
|
21
|
+
if (!group) return;
|
|
22
|
+
if (arrangement.locked.delete(group.id)) {
|
|
23
|
+
for (const id of group.memberIds) arrangement.locked.add(id);
|
|
24
|
+
}
|
|
25
|
+
arrangement.groups.delete(group.id);
|
|
26
|
+
}
|
|
27
|
+
}
|