@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,155 @@
|
|
|
1
|
+
import { EditPropertyCommand } from './DiagramEditorCommands.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PropertiesPanel — side panel for viewing/editing template properties.
|
|
5
|
+
* Shows properties of selected template and allows inline editing.
|
|
6
|
+
*/
|
|
7
|
+
export class PropertiesPanel {
|
|
8
|
+
/**
|
|
9
|
+
* @param {Object} options
|
|
10
|
+
* @param {string} options.panelId - Element id for panel container
|
|
11
|
+
* @param {DiagramEditor} options.editor - Diagram editor instance
|
|
12
|
+
*/
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
this.panelId = options.panelId || 'properties-panel';
|
|
15
|
+
this.editor = options.editor;
|
|
16
|
+
this.currentTemplate = null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Render the properties panel.
|
|
21
|
+
*/
|
|
22
|
+
render() {
|
|
23
|
+
if (typeof document === 'undefined') return;
|
|
24
|
+
|
|
25
|
+
let panel = document.getElementById(this.panelId);
|
|
26
|
+
if (!panel) {
|
|
27
|
+
panel = document.createElement('div');
|
|
28
|
+
panel.id = this.panelId;
|
|
29
|
+
// Place after menu bar
|
|
30
|
+
const menuBar = document.getElementById('menu-bar');
|
|
31
|
+
if (menuBar && menuBar.nextSibling) {
|
|
32
|
+
menuBar.parentNode.insertBefore(panel, menuBar.nextSibling);
|
|
33
|
+
} else {
|
|
34
|
+
document.body.appendChild(panel);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
panel.style.cssText = `
|
|
39
|
+
position: fixed;
|
|
40
|
+
right: 0;
|
|
41
|
+
top: 50px;
|
|
42
|
+
width: 300px;
|
|
43
|
+
max-height: calc(100vh - 50px);
|
|
44
|
+
background: #f9f9f9;
|
|
45
|
+
border-left: 3px solid #0066cc;
|
|
46
|
+
padding: 15px;
|
|
47
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
48
|
+
font-size: 13px;
|
|
49
|
+
overflow-y: auto;
|
|
50
|
+
z-index: 1000;
|
|
51
|
+
box-shadow: -4px 0 12px rgba(0,0,0,0.15);
|
|
52
|
+
pointer-events: auto;
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
this._renderContent(panel);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Render panel content.
|
|
60
|
+
* @private
|
|
61
|
+
*/
|
|
62
|
+
_renderContent(panel) {
|
|
63
|
+
panel.innerHTML = '';
|
|
64
|
+
|
|
65
|
+
if (!this.currentTemplate) {
|
|
66
|
+
const empty = document.createElement('div');
|
|
67
|
+
empty.style.cssText = 'color: #999; padding: 10px;';
|
|
68
|
+
empty.textContent = 'Select an element to edit properties';
|
|
69
|
+
panel.appendChild(empty);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const title = document.createElement('div');
|
|
74
|
+
title.style.cssText = 'font-weight: bold; margin-bottom: 10px; border-bottom: 1px solid #ddd; padding-bottom: 5px;';
|
|
75
|
+
title.textContent = this.currentTemplate.name;
|
|
76
|
+
panel.appendChild(title);
|
|
77
|
+
|
|
78
|
+
const properties = [
|
|
79
|
+
{ name: 'id', label: 'ID', readonly: true },
|
|
80
|
+
{ name: 'name', label: 'Name', type: 'text' },
|
|
81
|
+
{ name: 'x', label: 'X', type: 'number' },
|
|
82
|
+
{ name: 'y', label: 'Y', type: 'number' },
|
|
83
|
+
{ name: 'zIndex', label: 'Z-Index', type: 'number' },
|
|
84
|
+
{ name: 'visible', label: 'Visible', type: 'checkbox' },
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
for (const prop of properties) {
|
|
88
|
+
const row = document.createElement('div');
|
|
89
|
+
row.style.cssText = 'margin-bottom: 8px;';
|
|
90
|
+
|
|
91
|
+
const label = document.createElement('label');
|
|
92
|
+
label.style.cssText = 'display: block; font-weight: bold; margin-bottom: 2px;';
|
|
93
|
+
label.textContent = prop.label;
|
|
94
|
+
row.appendChild(label);
|
|
95
|
+
|
|
96
|
+
let input;
|
|
97
|
+
if (prop.type === 'checkbox') {
|
|
98
|
+
input = document.createElement('input');
|
|
99
|
+
input.type = 'checkbox';
|
|
100
|
+
input.checked = this.currentTemplate[prop.name];
|
|
101
|
+
input.style.cssText = 'cursor: pointer;';
|
|
102
|
+
} else {
|
|
103
|
+
input = document.createElement('input');
|
|
104
|
+
input.type = prop.type || 'text';
|
|
105
|
+
input.value = this.currentTemplate[prop.name];
|
|
106
|
+
input.style.cssText = `
|
|
107
|
+
width: 100%;
|
|
108
|
+
padding: 4px;
|
|
109
|
+
border: 1px solid #ccc;
|
|
110
|
+
border-radius: 3px;
|
|
111
|
+
box-sizing: border-box;
|
|
112
|
+
`;
|
|
113
|
+
if (prop.readonly) {
|
|
114
|
+
input.disabled = true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!prop.readonly) {
|
|
119
|
+
input.addEventListener('change', (e) => {
|
|
120
|
+
const newValue = prop.type === 'checkbox' ? e.target.checked : e.target.value;
|
|
121
|
+
this._editProperty(prop.name, newValue);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
row.appendChild(input);
|
|
126
|
+
panel.appendChild(row);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Edit a property via command.
|
|
132
|
+
* @private
|
|
133
|
+
*/
|
|
134
|
+
_editProperty(propertyName, newValue) {
|
|
135
|
+
if (!this.currentTemplate || !this.editor.history) return;
|
|
136
|
+
|
|
137
|
+
const oldValue = this.currentTemplate[propertyName];
|
|
138
|
+
if (oldValue === newValue) return;
|
|
139
|
+
|
|
140
|
+
if (!EditPropertyCommand) return;
|
|
141
|
+
|
|
142
|
+
const cmd = new EditPropertyCommand(this.editor, this.currentTemplate.id, propertyName, oldValue, newValue);
|
|
143
|
+
this.editor.history.execute(cmd);
|
|
144
|
+
this.editor.render();
|
|
145
|
+
this._renderContent(document.getElementById(this.panelId));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Set the selected template and refresh the panel.
|
|
150
|
+
*/
|
|
151
|
+
setSelected(template) {
|
|
152
|
+
this.currentTemplate = template;
|
|
153
|
+
this.render();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { el } from '../workspace/dom.js';
|
|
2
|
+
|
|
3
|
+
/** Supported types for user-defined properties. */
|
|
4
|
+
export const PROPERTY_TYPES = ['string', 'integer', 'boolean', 'date'];
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Convert a raw string (from a property value input) to the requested type.
|
|
8
|
+
* Invalid integer/boolean/date fall back to the string, preserving user input.
|
|
9
|
+
*/
|
|
10
|
+
export function coercePropertyValue(raw, type) {
|
|
11
|
+
if (type === 'integer') {
|
|
12
|
+
const n = Number(raw);
|
|
13
|
+
return Number.isFinite(n) && raw.trim() !== '' ? Math.trunc(n) : raw;
|
|
14
|
+
}
|
|
15
|
+
if (type === 'boolean') {
|
|
16
|
+
if (/^true$/i.test(raw) || raw === '1') return true;
|
|
17
|
+
if (/^false$/i.test(raw) || raw === '0') return false;
|
|
18
|
+
return raw;
|
|
19
|
+
}
|
|
20
|
+
if (type === 'date') {
|
|
21
|
+
const d = new Date(raw);
|
|
22
|
+
return !isNaN(d.getTime()) ? raw : raw;
|
|
23
|
+
}
|
|
24
|
+
return raw;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Convert a property value to a display/editable string. */
|
|
28
|
+
export function stringifyPropertyValue(value) {
|
|
29
|
+
return value == null ? '' : String(value);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* PropertyListEditor — an editable list of user-defined, typed properties
|
|
34
|
+
* (`[{name, type, value}]`): a row per property (name, type, value, remove) and
|
|
35
|
+
* "+ Add property". `collect()` reads them back typed; rows without a name are
|
|
36
|
+
* dropped. `PropertyListEditor.field(properties)` is the FormDialog field for it.
|
|
37
|
+
*/
|
|
38
|
+
export class PropertyListEditor {
|
|
39
|
+
constructor(properties, doc) {
|
|
40
|
+
this.doc = doc;
|
|
41
|
+
this.rows = [];
|
|
42
|
+
this.list = el({ style: { display: 'flex', flexDirection: 'column', gap: '6px' } }, doc);
|
|
43
|
+
for (const prop of properties) this._addRow(prop);
|
|
44
|
+
this.element = el({
|
|
45
|
+
style: { gridColumn: '1 / -1' },
|
|
46
|
+
children: [
|
|
47
|
+
this.list,
|
|
48
|
+
{
|
|
49
|
+
tag: 'button', attrs: { type: 'button' }, text: '+ Add property',
|
|
50
|
+
style: { marginTop: '6px', padding: '3px 10px', fontSize: '12px' },
|
|
51
|
+
on: { click: () => this._addRow() },
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
}, doc);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
_addRow(prop = { name: '', type: 'string', value: '' }) {
|
|
58
|
+
const entry = {};
|
|
59
|
+
const input = { padding: '3px 6px', border: '1px solid #ccc', borderRadius: '3px' };
|
|
60
|
+
entry.row = el({
|
|
61
|
+
style: { display: 'flex', alignItems: 'center', gap: '6px' },
|
|
62
|
+
children: [
|
|
63
|
+
{ tag: 'input', attrs: { type: 'text', placeholder: 'name', value: prop.name || '' }, style: { ...input, flex: '1 1 auto' }, ref: (n) => { entry.name = n; } },
|
|
64
|
+
{
|
|
65
|
+
tag: 'select', style: { ...input, flex: '0 0 80px' },
|
|
66
|
+
on: { change: () => { entry.value.type = entry.type.value === 'date' ? 'date' : 'text'; } },
|
|
67
|
+
children: PROPERTY_TYPES.map(t => ({ tag: 'option', attrs: { value: t, selected: t === (prop.type || 'string') }, text: t })),
|
|
68
|
+
ref: (n) => { entry.type = n; },
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
tag: 'input', attrs: { type: prop.type === 'date' ? 'date' : 'text', placeholder: 'value', value: stringifyPropertyValue(prop.value) },
|
|
72
|
+
style: { ...input, flex: '1 1 auto' }, ref: (n) => { entry.value = n; },
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
tag: 'button', attrs: { type: 'button', 'aria-label': 'Remove property' }, text: '×',
|
|
76
|
+
style: { flex: '0 0 24px', padding: '2px 4px' },
|
|
77
|
+
on: { click: () => { entry.row.remove(); this.rows = this.rows.filter(r => r !== entry); } },
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
}, this.doc);
|
|
81
|
+
this.list.appendChild(entry.row);
|
|
82
|
+
this.rows.push(entry);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** A FormDialog field (`custom`) editing `properties`; its value is the collected list. */
|
|
86
|
+
static field(properties = [], { key = 'properties', document: doc = globalThis.document } = {}) {
|
|
87
|
+
const editor = new PropertyListEditor(properties ?? [], doc);
|
|
88
|
+
return { key, label: '', type: 'custom', element: editor.element, read: () => editor.collect() };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
collect() {
|
|
92
|
+
return this.rows
|
|
93
|
+
.map(({ name, type, value }) => ({ name: name.value.trim(), type: type.value, value: coercePropertyValue(value.value, type.value) }))
|
|
94
|
+
.filter(p => p.name !== '');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PropertyLog — Universal undo/redo by recording mutations.
|
|
3
|
+
* Two patterns:
|
|
4
|
+
* 1. Property mutation: record(getObj, property, oldValue, newValue)
|
|
5
|
+
* 2. Complex mutation: record(getObj, property, oldState, newState) where oldState/newState are functions
|
|
6
|
+
* Undo applies old. Redo applies new. Flexible handling for both simple and complex changes.
|
|
7
|
+
*/
|
|
8
|
+
export class PropertyLog {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.changes = [];
|
|
11
|
+
this.currentIndex = -1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Record a change.
|
|
16
|
+
* For property mutation: record(getObj, 'property', oldValue, newValue)
|
|
17
|
+
* For complex state: record(getObj, 'complexKey', undoFn, redoFn)
|
|
18
|
+
*
|
|
19
|
+
* @param {object|function} objOrGetter - Object or function that returns it
|
|
20
|
+
* @param {string} key - Property name or operation key
|
|
21
|
+
* @param {*} oldValueOrUndoFn - Value to restore on undo, or function to call
|
|
22
|
+
* @param {*} newValueOrRedoFn - Value to apply on redo, or function to call
|
|
23
|
+
*/
|
|
24
|
+
record(objOrGetter, key, oldValueOrUndoFn, newValueOrRedoFn) {
|
|
25
|
+
if (this.currentIndex < this.changes.length - 1) {
|
|
26
|
+
this.changes = this.changes.slice(0, this.currentIndex + 1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const getObj = typeof objOrGetter === 'function' ? objOrGetter : () => objOrGetter;
|
|
30
|
+
|
|
31
|
+
this.changes.push({
|
|
32
|
+
getObj,
|
|
33
|
+
key,
|
|
34
|
+
old: oldValueOrUndoFn,
|
|
35
|
+
new: newValueOrRedoFn,
|
|
36
|
+
});
|
|
37
|
+
this.currentIndex++;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Undo: apply old value or call undo function.
|
|
42
|
+
*/
|
|
43
|
+
undo() {
|
|
44
|
+
if (this.currentIndex < 0) return false;
|
|
45
|
+
const change = this.changes[this.currentIndex];
|
|
46
|
+
const obj = change.getObj();
|
|
47
|
+
console.log(`[UNDO] key=${change.key}, old=${change.old}, obj=${obj ? 'found' : 'null'}`);
|
|
48
|
+
if (obj) {
|
|
49
|
+
if (typeof change.old === 'function') {
|
|
50
|
+
change.old();
|
|
51
|
+
} else {
|
|
52
|
+
obj[change.key] = change.old;
|
|
53
|
+
console.log(`[UNDO] applied: ${change.key}=${obj[change.key]}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
this.currentIndex--;
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Redo: apply new value or call redo function.
|
|
62
|
+
*/
|
|
63
|
+
redo() {
|
|
64
|
+
if (this.currentIndex >= this.changes.length - 1) return false;
|
|
65
|
+
this.currentIndex++;
|
|
66
|
+
const change = this.changes[this.currentIndex];
|
|
67
|
+
const obj = change.getObj();
|
|
68
|
+
console.log(`[REDO] key=${change.key}, new=${change.new}, obj=${obj ? 'found' : 'null'}`);
|
|
69
|
+
if (obj) {
|
|
70
|
+
if (typeof change.new === 'function') {
|
|
71
|
+
change.new();
|
|
72
|
+
} else {
|
|
73
|
+
obj[change.key] = change.new;
|
|
74
|
+
console.log(`[REDO] applied: ${change.key}=${obj[change.key]}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
canUndo() {
|
|
81
|
+
return this.currentIndex >= 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
canRedo() {
|
|
85
|
+
return this.currentIndex < this.changes.length - 1;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
clear() {
|
|
89
|
+
this.changes = [];
|
|
90
|
+
this.currentIndex = -1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SettingsCascade — resolve values through ordered levels of overrides.
|
|
3
|
+
*
|
|
4
|
+
* Levels are supplied most specific first, each `{ key, label, style }` where
|
|
5
|
+
* `style` holds only the values that level sets. A property's value comes from
|
|
6
|
+
* the first level that sets it (not `undefined`), else the schema default; the
|
|
7
|
+
* resolution also says which level supplied it. Line styles (EdgeStyleCascade)
|
|
8
|
+
* and editor settings (SettingsManager) both resolve through this.
|
|
9
|
+
*/
|
|
10
|
+
export class SettingsCascade {
|
|
11
|
+
/**
|
|
12
|
+
* @param {Array<{key: string, label: string, style: Object}>} levels
|
|
13
|
+
* @param {ReadonlyArray<{key: string, default: *}>} properties
|
|
14
|
+
*/
|
|
15
|
+
constructor(levels = [], properties = []) {
|
|
16
|
+
this.levels = levels;
|
|
17
|
+
this.properties = properties;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
level(key) {
|
|
21
|
+
return this.levels.find(l => l.key === key) ?? null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Resolve over every level, optionally with an extra most-specific one first.
|
|
26
|
+
* @returns {{style: Object, sources: Object<string, string>}} sources hold level labels, or 'Default'
|
|
27
|
+
*/
|
|
28
|
+
resolveWith(first = null) {
|
|
29
|
+
return this._resolve(first ? [first, ...this.levels] : this.levels);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* What a level inherits: the resolution over every level below it.
|
|
34
|
+
* Pass `null` for what something above every level would get.
|
|
35
|
+
*/
|
|
36
|
+
inheritedBy(levelKey) {
|
|
37
|
+
const at = levelKey === null ? -1 : this.levels.findIndex(l => l.key === levelKey);
|
|
38
|
+
if (levelKey !== null && at < 0) throw new Error(`Unknown style level "${levelKey}"`);
|
|
39
|
+
return this._resolve(this.levels.slice(at + 1));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
_resolve(chain) {
|
|
43
|
+
const style = {}, sources = {};
|
|
44
|
+
for (const { key, default: fallback } of this.properties) {
|
|
45
|
+
const from = chain.find(l => l.style?.[key] !== undefined);
|
|
46
|
+
style[key] = from ? from.style[key] : fallback;
|
|
47
|
+
sources[key] = from ? from.label : 'Default';
|
|
48
|
+
}
|
|
49
|
+
return { style, sources };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* FormDialog fields for cascading properties at one level: each shows the
|
|
55
|
+
* level's own value and offers "Inherit", labelled with the value and the
|
|
56
|
+
* level it would come from. A property's `type`, `choices`, `min`/`max` and
|
|
57
|
+
* `label` come from its schema entry; a `boolean` property is a select of
|
|
58
|
+
* `true`/`false` (read back with `readInheritableFields`).
|
|
59
|
+
*
|
|
60
|
+
* @param {ReadonlyArray<Object>} properties - Schema entries ({key, label, type, choices?, ...})
|
|
61
|
+
* @param {Object} own - The level's own values (unset keys inherit)
|
|
62
|
+
* @param {{style: Object, sources: Object}} inherited - What unset values resolve to (`inheritedBy`)
|
|
63
|
+
* @returns {Array<Object>} FormDialog fields
|
|
64
|
+
*/
|
|
65
|
+
export function inheritableFields(properties, own, inherited) {
|
|
66
|
+
return properties.map((p) => {
|
|
67
|
+
const choices = p.type === 'boolean' ? (p.choices ?? [['true', 'Yes'], ['false', 'No']]) : p.choices;
|
|
68
|
+
const shown = (value) => choices?.find(([v]) => v === String(value))?.[1] ?? String(value);
|
|
69
|
+
const value = own[p.key];
|
|
70
|
+
return {
|
|
71
|
+
...p,
|
|
72
|
+
type: p.type === 'boolean' ? 'select' : p.type,
|
|
73
|
+
choices,
|
|
74
|
+
value: p.type === 'boolean' && value !== undefined ? String(value) : value,
|
|
75
|
+
inherit: {
|
|
76
|
+
text: `Inherit: ${shown(inherited.style[p.key])} (${inherited.sources[p.key]})`,
|
|
77
|
+
short: `Inherit (${inherited.sources[p.key]})`,
|
|
78
|
+
value: inherited.style[p.key],
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Values read back from `inheritableFields`, as the schema's types: a
|
|
86
|
+
* boolean select becomes true/false; undefined (inherit) stays undefined.
|
|
87
|
+
*/
|
|
88
|
+
export function readInheritableFields(properties, values) {
|
|
89
|
+
return Object.fromEntries(properties.map(({ key, type }) => {
|
|
90
|
+
const v = values[key];
|
|
91
|
+
return [key, v === undefined ? undefined : type === 'boolean' ? v === 'true' || v === true : v];
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { FormDialog } from './FormDialog.js';
|
|
2
|
+
import { MODEL_SETTINGS_PROPERTIES } from './SettingsManager.js';
|
|
3
|
+
import { inheritableFields, readInheritableFields } from './SettingsCascade.js';
|
|
4
|
+
|
|
5
|
+
/** Settings a model sets or inherits from the tool, and the tool sets for every model. */
|
|
6
|
+
const CHECKING = MODEL_SETTINGS_PROPERTIES.filter(p => p.key === 'invalidRelationships');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* SettingsDialog — app-level settings (theme; a model's edge routing and grid),
|
|
10
|
+
* as a FormDialog. Settings are saved via SettingsManager, which broadcasts
|
|
11
|
+
* changes to observers (e.g. diagram tabs re-render).
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* showGlobalSettingsDialog(document, settingsManager, 'default');
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const ROUTING_CHOICES = [['straight', 'shortest path'], ['curved', 'curved'], ['orthogonal', 'orthogonal'], ['polyline', 'polyline']];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {Document} doc - document to append dialog to
|
|
21
|
+
* @param {SettingsManager} settingsManager - settings manager instance
|
|
22
|
+
* @param {string} modelId - model id to load/save model settings for
|
|
23
|
+
*/
|
|
24
|
+
export function showGlobalSettingsDialog(doc, settingsManager, modelId = 'default') {
|
|
25
|
+
const tool = settingsManager.getToolSettings();
|
|
26
|
+
const model = settingsManager.getModelSettings(modelId);
|
|
27
|
+
const modelOwn = settingsManager.getModelOverrides(modelId);
|
|
28
|
+
const fromTool = settingsManager.cascade(null, modelId).inheritedBy('model');
|
|
29
|
+
const [checking] = CHECKING;
|
|
30
|
+
return new FormDialog({
|
|
31
|
+
title: 'Global Settings',
|
|
32
|
+
fields: [
|
|
33
|
+
{ type: 'heading', label: 'Tool' },
|
|
34
|
+
{ key: 'theme', label: 'Theme', type: 'select', value: tool.theme, choices: [['light', 'light'], ['dark', 'dark']] },
|
|
35
|
+
{ key: 'toolInvalidRelationships', label: checking.label, type: 'select', value: tool.invalidRelationships ?? checking.default, choices: checking.choices },
|
|
36
|
+
{ type: 'heading', label: 'Model' },
|
|
37
|
+
...inheritableFields(CHECKING, modelOwn, fromTool),
|
|
38
|
+
{ key: 'edgeRouting', label: 'Default edge routing', type: 'select', value: model.edgeRouting, choices: ROUTING_CHOICES },
|
|
39
|
+
{ key: 'gridSize', label: 'Default grid size', type: 'number', value: model.gridSize || 16, min: 0 },
|
|
40
|
+
{ key: 'showGrid', label: 'Show grid by default', type: 'checkbox', value: !!model.showGrid },
|
|
41
|
+
],
|
|
42
|
+
submitLabel: 'Save',
|
|
43
|
+
idPrefix: 'global-settings-',
|
|
44
|
+
document: doc,
|
|
45
|
+
onApply: ({ theme, toolInvalidRelationships, edgeRouting, gridSize, showGrid, ...rest }) => {
|
|
46
|
+
settingsManager.saveToolSettings({ theme, invalidRelationships: toolInvalidRelationships });
|
|
47
|
+
// The model's own choice, or undefined to inherit the tool's.
|
|
48
|
+
settingsManager.saveModelSettings(modelId, readInheritableFields(CHECKING, rest));
|
|
49
|
+
// Observers (e.g. DiagramTabs) re-render on these notifications.
|
|
50
|
+
settingsManager.saveModelSettings(modelId, { edgeRouting, gridSize: Number.isFinite(gridSize) ? Math.trunc(gridSize) : 0, showGrid });
|
|
51
|
+
},
|
|
52
|
+
}).open();
|
|
53
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { SettingsCascade } from './SettingsCascade.js';
|
|
2
|
+
import { LocalJsonStore } from './storage/LocalJsonStore.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SettingsManager — editor settings across tool, model and view levels.
|
|
6
|
+
*
|
|
7
|
+
* Hierarchy: Tool (global) ← Model (per model) ← View (per tab, overrides)
|
|
8
|
+
*
|
|
9
|
+
* Tool settings (localStorage): theme, zoom
|
|
10
|
+
* Model settings (localStorage, per model id): edge routing, grid, watermark
|
|
11
|
+
* View settings (on the view object): overrides of model settings, plus title/background
|
|
12
|
+
*
|
|
13
|
+
* Model-level values resolve view → model → default through the shared
|
|
14
|
+
* SettingsCascade, the same resolver line styles use.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Settings a model sets and a view may override; labels and types drive the settings forms. */
|
|
18
|
+
export const MODEL_SETTINGS_PROPERTIES = Object.freeze([
|
|
19
|
+
{
|
|
20
|
+
key: 'edgeRouting', label: 'Routing', type: 'select', default: 'straight',
|
|
21
|
+
choices: [['straight', 'Straight'], ['orthogonal', 'Orthogonal'], ['curved', 'Curved'], ['polyline', 'Around shapes']],
|
|
22
|
+
},
|
|
23
|
+
{ key: 'gridSize', label: 'Grid size', type: 'number', default: 16, min: 0 },
|
|
24
|
+
{ key: 'showGrid', label: 'Show grid', type: 'boolean', default: false, choices: [['true', 'Shown'], ['false', 'Hidden']] },
|
|
25
|
+
{ key: 'watermark', label: 'Watermark', type: 'text', default: '' },
|
|
26
|
+
{
|
|
27
|
+
key: 'watermarkRotation', label: 'Watermark angle', type: 'select', default: '-45°',
|
|
28
|
+
choices: ['0°', '-45°', '45°', '-90°', '90°'].map(r => [r, r]),
|
|
29
|
+
},
|
|
30
|
+
{ key: 'watermarkRepeat', label: 'Watermark repeat', type: 'select', default: 'none', choices: [['none', 'Once'], ['repeat', 'Repeat'], ['tile', 'Tile']] },
|
|
31
|
+
{ key: 'watermarkOpacity', label: 'Watermark opacity %', type: 'number', default: 20, min: 0, max: 100 },
|
|
32
|
+
{
|
|
33
|
+
key: 'invalidRelationships', label: 'Invalid relationships', type: 'select', default: 'highlight',
|
|
34
|
+
choices: [['highlight', 'Highlight (red, dashed)'], ['tooltip', 'Warn in the tooltip only'], ['off', 'Do not check']],
|
|
35
|
+
},
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
/** Settings that only a view has. */
|
|
39
|
+
export const VIEW_SETTINGS_DEFAULTS = Object.freeze({
|
|
40
|
+
title: '',
|
|
41
|
+
titlePosition: 'none',
|
|
42
|
+
background: '#ffffff',
|
|
43
|
+
backgroundImage: '',
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const TOOL_SETTINGS_DEFAULTS = Object.freeze({
|
|
47
|
+
theme: 'light',
|
|
48
|
+
defaultZoom: 1,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export class SettingsManager {
|
|
52
|
+
/**
|
|
53
|
+
* @param {Object} [options]
|
|
54
|
+
* @param {Storage} [options.storage] - Defaults to localStorage when available
|
|
55
|
+
*/
|
|
56
|
+
constructor({ storage } = {}) {
|
|
57
|
+
this._storage = storage;
|
|
58
|
+
this._toolStore = new LocalJsonStore('archimate-tool-settings', ...(storage !== undefined ? [storage] : []));
|
|
59
|
+
this._toolSettings = { ...TOOL_SETTINGS_DEFAULTS, ...this._toolStore.load({}) };
|
|
60
|
+
this._modelSettings = {}; // model id -> settings
|
|
61
|
+
this._listeners = []; // settings change callbacks
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Call `callback(event)` on every settings change. @returns {() => void} unsubscribe */
|
|
65
|
+
onSettingsChange(callback) {
|
|
66
|
+
this._listeners.push(callback);
|
|
67
|
+
return () => { this._listeners = this._listeners.filter(cb => cb !== callback); };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
_notifyListeners(event) {
|
|
71
|
+
this._listeners.forEach(cb => {
|
|
72
|
+
try {
|
|
73
|
+
cb(event);
|
|
74
|
+
} catch (err) {
|
|
75
|
+
console.warn('Settings listener error:', err);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
_modelStore(modelId) {
|
|
81
|
+
return new LocalJsonStore(`archimate-model-settings-${modelId}`, ...(this._storage !== undefined ? [this._storage] : []));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ── Tool Settings (app-wide) ──
|
|
85
|
+
|
|
86
|
+
saveToolSettings(settings) {
|
|
87
|
+
this._toolSettings = { ...this._toolSettings, ...settings };
|
|
88
|
+
this._toolStore.save(this._toolSettings);
|
|
89
|
+
this._notifyListeners({ type: 'tool', settings: this._toolSettings });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getToolSettings() {
|
|
93
|
+
return { ...this._toolSettings };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ── Model Settings (per-model defaults) ──
|
|
97
|
+
|
|
98
|
+
/** The model level holds only what is set on it; unset settings come from the tool level, then defaults. */
|
|
99
|
+
initModelSettings(modelId, initial = {}) {
|
|
100
|
+
this._modelSettings[modelId] = {
|
|
101
|
+
...this._modelStore(modelId).load({}),
|
|
102
|
+
...initial,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** What the model level itself sets (unset keys inherit from the tool level). */
|
|
107
|
+
getModelOverrides(modelId) {
|
|
108
|
+
if (!this._modelSettings[modelId]) {
|
|
109
|
+
this.initModelSettings(modelId);
|
|
110
|
+
}
|
|
111
|
+
return { ...this._modelSettings[modelId] };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** A model's settings resolved: its own, then the tool's, then defaults. */
|
|
115
|
+
getModelSettings(modelId) {
|
|
116
|
+
return { ...this.getModelOverrides(modelId), ...this.cascade(null, modelId).inheritedBy('view').style };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
saveModelSettings(modelId, settings) {
|
|
120
|
+
if (!this._modelSettings[modelId]) {
|
|
121
|
+
this.initModelSettings(modelId);
|
|
122
|
+
}
|
|
123
|
+
this._modelSettings[modelId] = { ...this._modelSettings[modelId], ...settings };
|
|
124
|
+
this._modelStore(modelId).save(this._modelSettings[modelId]);
|
|
125
|
+
this._notifyListeners({ type: 'model', modelId, settings: this._modelSettings[modelId] });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ── View Settings (per-view overrides) ──
|
|
129
|
+
|
|
130
|
+
initViewSettings(view, initial = {}) {
|
|
131
|
+
view._settings = { ...VIEW_SETTINGS_DEFAULTS, ...initial };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
getViewSettings(view) {
|
|
135
|
+
if (!view._settings) {
|
|
136
|
+
this.initViewSettings(view);
|
|
137
|
+
}
|
|
138
|
+
return { ...view._settings };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
saveViewSettings(view, settings) {
|
|
142
|
+
if (!view._settings) {
|
|
143
|
+
this.initViewSettings(view);
|
|
144
|
+
}
|
|
145
|
+
view._settings = { ...view._settings, ...settings };
|
|
146
|
+
this._notifyListeners({ type: 'view', viewId: view.id, settings: view._settings });
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ── Resolve Settings (hierarchy: tool ← model ← view) ──
|
|
150
|
+
|
|
151
|
+
/** The cascade for one view: its own settings, then the model's, then the tool's, then defaults. */
|
|
152
|
+
cascade(view, modelId) {
|
|
153
|
+
return new SettingsCascade([
|
|
154
|
+
{ key: 'view', label: 'View', style: view?._settings ?? {} },
|
|
155
|
+
{ key: 'model', label: 'Model', style: this.getModelOverrides(modelId) },
|
|
156
|
+
{ key: 'tool', label: 'Tool', style: this._toolSettings },
|
|
157
|
+
], MODEL_SETTINGS_PROPERTIES);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Effective settings for rendering a specific view:
|
|
162
|
+
* view overrides > model settings > defaults, plus tool and view-only settings.
|
|
163
|
+
*/
|
|
164
|
+
getEffectiveSettings(view, modelId) {
|
|
165
|
+
const tool = this.getToolSettings();
|
|
166
|
+
const viewSettings = view?._settings ?? {};
|
|
167
|
+
return {
|
|
168
|
+
theme: tool.theme,
|
|
169
|
+
defaultZoom: tool.defaultZoom,
|
|
170
|
+
...this.cascade(view, modelId).resolveWith().style,
|
|
171
|
+
title: viewSettings.title,
|
|
172
|
+
titlePosition: viewSettings.titlePosition,
|
|
173
|
+
background: viewSettings.background,
|
|
174
|
+
backgroundImage: viewSettings.backgroundImage,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export const settingsManager = new SettingsManager();
|