@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,58 @@
|
|
|
1
|
+
import { ViewPropertiesDialog } from './ViewPropertiesDialog.js';
|
|
2
|
+
import { inheritableFields, readInheritableFields } from './SettingsCascade.js';
|
|
3
|
+
import { MODEL_SETTINGS_PROPERTIES } from './SettingsManager.js';
|
|
4
|
+
|
|
5
|
+
const byKey = (keys) => MODEL_SETTINGS_PROPERTIES.filter(p => keys.includes(p.key));
|
|
6
|
+
/** Diagram settings a view may override (routing, grid, how invalid relationships show). */
|
|
7
|
+
const DIAGRAM = byKey(['edgeRouting', 'gridSize', 'showGrid', 'invalidRelationships']);
|
|
8
|
+
/** Watermark settings a view may override. */
|
|
9
|
+
const WATERMARK = byKey(['watermark', 'watermarkRotation', 'watermarkRepeat', 'watermarkOpacity']);
|
|
10
|
+
const TITLE_POSITIONS = [['none', 'None'], ['top', 'Top'], ['bottom', 'Bottom']];
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* SettingsViewPropertiesDialog — a view's properties plus its level of the
|
|
14
|
+
* settings cascade (SettingsManager): routing and grid under Diagram;
|
|
15
|
+
* background, title band and watermark under Appearance. A cascading setting
|
|
16
|
+
* may inherit, showing the value and the level it would come from; settings
|
|
17
|
+
* only a view has (background, title band) are set outright. Used by the
|
|
18
|
+
* ArchiMate editor.
|
|
19
|
+
*/
|
|
20
|
+
export class SettingsViewPropertiesDialog extends ViewPropertiesDialog {
|
|
21
|
+
/**
|
|
22
|
+
* @param {Object} options - As ViewPropertiesDialog, plus:
|
|
23
|
+
* @param {SettingsManager} options.settingsManager
|
|
24
|
+
* @param {string} [options.modelId] - Settings key of the model level
|
|
25
|
+
*/
|
|
26
|
+
constructor({ settingsManager, modelId = 'default', ...rest }) {
|
|
27
|
+
super(rest);
|
|
28
|
+
this.settings = settingsManager;
|
|
29
|
+
this.modelId = modelId;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
sections() {
|
|
33
|
+
const own = this.settings.getViewSettings(this.view);
|
|
34
|
+
const inherited = this.settings.cascade(this.view, this.modelId).inheritedBy('view');
|
|
35
|
+
return [
|
|
36
|
+
{ type: 'heading', label: 'Diagram' },
|
|
37
|
+
...inheritableFields(DIAGRAM, own, inherited),
|
|
38
|
+
{ type: 'heading', label: 'Appearance' },
|
|
39
|
+
{ key: 'background', label: 'Background', type: 'color', value: own.background || '#ffffff' },
|
|
40
|
+
{ key: 'backgroundImage', label: 'Background image', type: 'text', value: own.backgroundImage ?? '', placeholder: 'URL (optional)' },
|
|
41
|
+
// The band's text is the "title" setting; it is not the view's name.
|
|
42
|
+
{ key: 'bandTitle', label: 'Title band', type: 'text', value: own.title ?? '', placeholder: 'Text shown above or below the diagram' },
|
|
43
|
+
{ key: 'titlePosition', label: 'Title position', type: 'select', value: own.titlePosition ?? 'none', choices: TITLE_POSITIONS },
|
|
44
|
+
...inheritableFields(WATERMARK, own, inherited),
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
applySections(values) {
|
|
49
|
+
this.settings.saveViewSettings(this.view, {
|
|
50
|
+
// undefined inherits from the model level (SettingsCascade).
|
|
51
|
+
...readInheritableFields([...DIAGRAM, ...WATERMARK], values),
|
|
52
|
+
background: values.background,
|
|
53
|
+
backgroundImage: values.backgroundImage?.trim() ?? '',
|
|
54
|
+
title: values.bandTitle?.trim() ?? '',
|
|
55
|
+
titlePosition: values.titlePosition || 'none',
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShapePaths — pure geometry-to-SVG-path helpers used by several chart types.
|
|
3
|
+
*/
|
|
4
|
+
export class ShapePaths {
|
|
5
|
+
/**
|
|
6
|
+
* Build an SVG path for an annular pie/doughnut slice.
|
|
7
|
+
* @param {number} cx center x
|
|
8
|
+
* @param {number} cy center y
|
|
9
|
+
* @param {number} rOuter outer radius
|
|
10
|
+
* @param {number} rInner inner radius (0 for a pie wedge)
|
|
11
|
+
* @param {number} startAngle radians
|
|
12
|
+
* @param {number} endAngle radians
|
|
13
|
+
* @returns {string}
|
|
14
|
+
*/
|
|
15
|
+
static donutSlicePath(cx, cy, rOuter, rInner, startAngle, endAngle) {
|
|
16
|
+
const largeArc = (endAngle - startAngle) > Math.PI ? 1 : 0;
|
|
17
|
+
const outerStart = { x: cx + rOuter * Math.cos(startAngle), y: cy + rOuter * Math.sin(startAngle) };
|
|
18
|
+
const outerEnd = { x: cx + rOuter * Math.cos(endAngle), y: cy + rOuter * Math.sin(endAngle) };
|
|
19
|
+
if (rInner <= 0) {
|
|
20
|
+
return `M${cx},${cy} L${outerStart.x},${outerStart.y} A${rOuter},${rOuter} 0 ${largeArc} 1 ${outerEnd.x},${outerEnd.y} Z`;
|
|
21
|
+
}
|
|
22
|
+
const innerStart = { x: cx + rInner * Math.cos(endAngle), y: cy + rInner * Math.sin(endAngle) };
|
|
23
|
+
const innerEnd = { x: cx + rInner * Math.cos(startAngle), y: cy + rInner * Math.sin(startAngle) };
|
|
24
|
+
return `M${outerStart.x},${outerStart.y} A${rOuter},${rOuter} 0 ${largeArc} 1 ${outerEnd.x},${outerEnd.y} `
|
|
25
|
+
+ `L${innerStart.x},${innerStart.y} A${rInner},${rInner} 0 ${largeArc} 0 ${innerEnd.x},${innerEnd.y} Z`;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statistics — pure, DOM-free helpers for statistical chart types.
|
|
3
|
+
*
|
|
4
|
+
* These used to live as private methods on RenderEngine. Moving them to a
|
|
5
|
+
* shared module lets HistogramChart, BoxPlotChart, DensityChart, ViolinChart,
|
|
6
|
+
* QQPlotChart, and LagPlotChart stay self-contained and testable without the
|
|
7
|
+
* full engine instance.
|
|
8
|
+
*/
|
|
9
|
+
export class Statistics {
|
|
10
|
+
/** Computes evenly-spaced bin edges/counts for a raw numeric sample. */
|
|
11
|
+
static histogramBins(values, binCount) {
|
|
12
|
+
const min = Math.min(...values);
|
|
13
|
+
const max = Math.max(...values);
|
|
14
|
+
const range = (max - min) || 1;
|
|
15
|
+
const n = Math.max(1, binCount);
|
|
16
|
+
const width = range / n;
|
|
17
|
+
const bins = Array.from({ length: n }, (_, i) => ({ from: min + i * width, to: min + (i + 1) * width, count: 0 }));
|
|
18
|
+
for (const v of values) {
|
|
19
|
+
let idx = Math.floor((v - min) / width);
|
|
20
|
+
if (idx >= n) idx = n - 1;
|
|
21
|
+
if (idx < 0) idx = 0;
|
|
22
|
+
bins[idx].count++;
|
|
23
|
+
}
|
|
24
|
+
return bins;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Inverse standard-normal CDF (probit function) via Peter Acklam's
|
|
29
|
+
* rational approximation.
|
|
30
|
+
*/
|
|
31
|
+
static normalQuantile(p) {
|
|
32
|
+
if (p <= 0) return -Infinity;
|
|
33
|
+
if (p >= 1) return Infinity;
|
|
34
|
+
const a = [-3.969683028665376e+01, 2.209460984245205e+02, -2.759285104469687e+02, 1.383577518672690e+02, -3.066479806614716e+01, 2.506628277459239e+00];
|
|
35
|
+
const b = [-5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02, 6.680131188771972e+01, -1.328068155288572e+01];
|
|
36
|
+
const c = [-7.784894002430293e-03, -3.223964580411365e-01, -2.400758277161838e+00, -2.549732539343734e+00, 4.374664141464968e+00, 2.938163982698783e+00];
|
|
37
|
+
const d = [7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00];
|
|
38
|
+
const pLow = 0.02425, pHigh = 1 - pLow;
|
|
39
|
+
|
|
40
|
+
if (p < pLow) {
|
|
41
|
+
const q = Math.sqrt(-2 * Math.log(p));
|
|
42
|
+
return (((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5])
|
|
43
|
+
/ ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);
|
|
44
|
+
}
|
|
45
|
+
if (p <= pHigh) {
|
|
46
|
+
const q = p - 0.5, r = q * q;
|
|
47
|
+
return (((((a[0] * r + a[1]) * r + a[2]) * r + a[3]) * r + a[4]) * r + a[5]) * q
|
|
48
|
+
/ (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1);
|
|
49
|
+
}
|
|
50
|
+
const q = Math.sqrt(-2 * Math.log(1 - p));
|
|
51
|
+
return -(((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5])
|
|
52
|
+
/ ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Pairs each sorted sample value with a theoretical normal quantile. */
|
|
56
|
+
static qqPoints(values) {
|
|
57
|
+
const n = values.length;
|
|
58
|
+
if (n === 0) return [];
|
|
59
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
60
|
+
return sorted.map((sample, i) => ({ theoretical: Statistics.normalQuantile((i + 0.5) / n), sample }));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** `[{x: values[i-lag], y: values[i]}]` for i = lag..length-1. */
|
|
64
|
+
static lagPairs(values, lag = 1) {
|
|
65
|
+
if (lag < 1 || values.length <= lag) return [];
|
|
66
|
+
const pairs = [];
|
|
67
|
+
for (let i = lag; i < values.length; i++) pairs.push({ x: values[i - lag], y: values[i] });
|
|
68
|
+
return pairs;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Linear-interpolation quantile (R-7 / PERCENTILE.INC) over a sorted array. */
|
|
72
|
+
static quantile(sorted, p) {
|
|
73
|
+
if (sorted.length === 0) return 0;
|
|
74
|
+
if (sorted.length === 1) return sorted[0];
|
|
75
|
+
const idx = p * (sorted.length - 1);
|
|
76
|
+
const lo = Math.floor(idx), hi = Math.ceil(idx);
|
|
77
|
+
if (lo === hi) return sorted[lo];
|
|
78
|
+
return sorted[lo] + (sorted[hi] - sorted[lo]) * (idx - lo);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Computes box-and-whisker summary stats for a raw numeric sample. */
|
|
82
|
+
static boxPlotStats(values) {
|
|
83
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
84
|
+
const q1 = Statistics.quantile(sorted, 0.25);
|
|
85
|
+
const median = Statistics.quantile(sorted, 0.5);
|
|
86
|
+
const q3 = Statistics.quantile(sorted, 0.75);
|
|
87
|
+
const iqr = q3 - q1;
|
|
88
|
+
const lowFence = q1 - 1.5 * iqr;
|
|
89
|
+
const highFence = q3 + 1.5 * iqr;
|
|
90
|
+
const within = sorted.filter(v => v >= lowFence && v <= highFence);
|
|
91
|
+
const outliers = sorted.filter(v => v < lowFence || v > highFence);
|
|
92
|
+
return {
|
|
93
|
+
min: within.length ? within[0] : sorted[0],
|
|
94
|
+
q1, median, q3,
|
|
95
|
+
max: within.length ? within[within.length - 1] : sorted[sorted.length - 1],
|
|
96
|
+
outliers,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Population standard deviation. */
|
|
101
|
+
static stdev(values) {
|
|
102
|
+
const n = values.length;
|
|
103
|
+
if (n < 2) return 0;
|
|
104
|
+
const mean = values.reduce((s, v) => s + v, 0) / n;
|
|
105
|
+
const variance = values.reduce((s, v) => s + (v - mean) ** 2, 0) / n;
|
|
106
|
+
return Math.sqrt(variance);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Gaussian-kernel density estimate — a smoothed distribution curve from
|
|
111
|
+
* a raw numeric sample. `bandwidth` defaults via Silverman's rule of thumb.
|
|
112
|
+
* @returns {Array<{x: number, density: number}>}
|
|
113
|
+
*/
|
|
114
|
+
static kernelDensityEstimate(values, options = {}) {
|
|
115
|
+
const n = values.length;
|
|
116
|
+
const dataMin = Math.min(...values), dataMax = Math.max(...values);
|
|
117
|
+
const fallbackBandwidth = (dataMax - dataMin) * 0.1 || 1;
|
|
118
|
+
const silverman = n >= 2 ? 1.06 * Statistics.stdev(values) * Math.pow(n, -1 / 5) : 0;
|
|
119
|
+
const bandwidth = options.bandwidth ?? (silverman || fallbackBandwidth);
|
|
120
|
+
const sampleCount = options.sampleCount ?? 60;
|
|
121
|
+
const min = options.min ?? (dataMin - 3 * bandwidth);
|
|
122
|
+
const max = options.max ?? (dataMax + 3 * bandwidth);
|
|
123
|
+
const step = (max - min) / Math.max(1, sampleCount - 1);
|
|
124
|
+
const gaussian = (u) => Math.exp(-0.5 * u * u) / Math.sqrt(2 * Math.PI);
|
|
125
|
+
|
|
126
|
+
const points = [];
|
|
127
|
+
for (let i = 0; i < sampleCount; i++) {
|
|
128
|
+
const x = min + i * step;
|
|
129
|
+
const density = n === 0 ? 0 : values.reduce((s, v) => s + gaussian((x - v) / bandwidth), 0) / (n * bandwidth);
|
|
130
|
+
points.push({ x, density });
|
|
131
|
+
}
|
|
132
|
+
return points;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TemplateCatalog — registry of template types that can be added to a diagram.
|
|
3
|
+
* Each entry describes a template type and how to create instances.
|
|
4
|
+
*/
|
|
5
|
+
export class TemplateCatalog {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.entries = new Map(); // type -> { name, icon, factory, properties }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Register a template type.
|
|
12
|
+
* @param {string} type - Unique type identifier
|
|
13
|
+
* @param {Object} spec - Template specification
|
|
14
|
+
* @param {string} spec.name - Display name
|
|
15
|
+
* @param {string} spec.icon - Icon/emoji (e.g., "📦")
|
|
16
|
+
* @param {Function} spec.factory - Factory function: (id, x, y) => Template instance
|
|
17
|
+
* @param {Object} spec.properties - Default properties for this type
|
|
18
|
+
*/
|
|
19
|
+
register(type, spec) {
|
|
20
|
+
if (!spec.factory) {
|
|
21
|
+
throw new Error(`TemplateCatalog.register: factory required for type '${type}'`);
|
|
22
|
+
}
|
|
23
|
+
this.entries.set(type, {
|
|
24
|
+
type,
|
|
25
|
+
name: spec.name || type,
|
|
26
|
+
icon: spec.icon || '■',
|
|
27
|
+
factory: spec.factory,
|
|
28
|
+
properties: spec.properties || {},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get a template type entry.
|
|
34
|
+
*/
|
|
35
|
+
get(type) {
|
|
36
|
+
return this.entries.get(type);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get all entries.
|
|
41
|
+
*/
|
|
42
|
+
getAll() {
|
|
43
|
+
return Array.from(this.entries.values());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create a template instance of given type.
|
|
48
|
+
* @param {string} type
|
|
49
|
+
* @param {string} id - Instance id
|
|
50
|
+
* @param {number} x - X position
|
|
51
|
+
* @param {number} y - Y position
|
|
52
|
+
* @returns {Template|null}
|
|
53
|
+
*/
|
|
54
|
+
create(type, id, x, y) {
|
|
55
|
+
const entry = this.get(type);
|
|
56
|
+
if (!entry) return null;
|
|
57
|
+
return entry.factory(id, x, y);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { LocalJsonStore } from './storage/LocalJsonStore.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TemplateLibrary — view templates kept across models: a tool's own library,
|
|
5
|
+
* beside each model's templates. What every such library does: keep entries,
|
|
6
|
+
* offer built-in ones, give ids, and tell listeners after a change. A kind of
|
|
7
|
+
* view subclasses it for its own entries and imports (CanvasTemplateLibrary).
|
|
8
|
+
*
|
|
9
|
+
* An entry is plain JSON: `{ id, name, description, thumbnail, view }`, where
|
|
10
|
+
* `view` is the view's JSON form and `thumbnail` a `data:` URL or null.
|
|
11
|
+
*
|
|
12
|
+
* Entries are kept in a store (LocalJsonStore under the class's STORAGE_KEY by
|
|
13
|
+
* default, so the library lives in the browser); pass another store with
|
|
14
|
+
* `load(fallback)` and `save(value)` to keep them elsewhere. Built-in entries
|
|
15
|
+
* (`defaults`, the class's DEFAULTS unless given others) come first, are marked
|
|
16
|
+
* `builtIn`, are not stored, and cannot be renamed or removed.
|
|
17
|
+
*/
|
|
18
|
+
export class TemplateLibrary {
|
|
19
|
+
/** The storage key the default store uses; a subclass names its own. */
|
|
20
|
+
static STORAGE_KEY = 'renderengine.templates';
|
|
21
|
+
|
|
22
|
+
/** Built-in entries; a subclass names its own. */
|
|
23
|
+
static DEFAULTS = Object.freeze([]);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param {Object} [options]
|
|
27
|
+
* @param {{load: Function, save: Function}} [options.store] - Where entries are kept
|
|
28
|
+
* @param {Array<Object>} [options.defaults] - Built-in entries
|
|
29
|
+
*/
|
|
30
|
+
constructor({ store = new LocalJsonStore(this.constructor.STORAGE_KEY), defaults = this.constructor.DEFAULTS } = {}) {
|
|
31
|
+
this.store = store;
|
|
32
|
+
this.defaults = defaults.map(entry => ({ ...entry, builtIn: true }));
|
|
33
|
+
const saved = store.load([]);
|
|
34
|
+
this._entries = Array.isArray(saved) ? saved.filter(e => e && e.id && e.view) : [];
|
|
35
|
+
this._listeners = new Set();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Every entry: the built-in ones, then those added, in the order added. @returns {Array<Object>} */
|
|
39
|
+
list() {
|
|
40
|
+
return [...this.defaults, ...this._entries];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** The entry with `id`, or null. */
|
|
44
|
+
get(id) {
|
|
45
|
+
return this.list().find(e => e.id === id) ?? null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Keep a template.
|
|
50
|
+
* @param {Object} entry
|
|
51
|
+
* @param {Object} entry.view - The view's JSON form
|
|
52
|
+
* @param {string} [entry.name] - Defaults to the view's name
|
|
53
|
+
* @param {string} [entry.description]
|
|
54
|
+
* @param {string|null} [entry.thumbnail] - A `data:` URL
|
|
55
|
+
* @returns {Object} the entry as kept, with its id
|
|
56
|
+
*/
|
|
57
|
+
add({ view, name = view?.name ?? 'Template', description = '', thumbnail = null }) {
|
|
58
|
+
if (!view) throw new Error('A template needs a view');
|
|
59
|
+
const entry = { id: this._newId(), name, description, thumbnail, view: JSON.parse(JSON.stringify(view)) };
|
|
60
|
+
this._entries.push(entry);
|
|
61
|
+
this._changed();
|
|
62
|
+
return entry;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Rename or re-describe an entry (not a built-in one). @returns {boolean} whether it was changed */
|
|
66
|
+
update(id, { name, description } = {}) {
|
|
67
|
+
const entry = this._entries.find(e => e.id === id);
|
|
68
|
+
if (!entry) return false;
|
|
69
|
+
if (name !== undefined) entry.name = name;
|
|
70
|
+
if (description !== undefined) entry.description = description;
|
|
71
|
+
this._changed();
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Forget an entry (not a built-in one). @returns {boolean} whether it was removed */
|
|
76
|
+
remove(id) {
|
|
77
|
+
const before = this._entries.length;
|
|
78
|
+
this._entries = this._entries.filter(e => e.id !== id);
|
|
79
|
+
if (this._entries.length === before) return false;
|
|
80
|
+
this._changed();
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Call `fn(entries)` after every change. @returns {Function} stops it */
|
|
85
|
+
onChange(fn) {
|
|
86
|
+
this._listeners.add(fn);
|
|
87
|
+
return () => this._listeners.delete(fn);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** @private */
|
|
91
|
+
_newId() {
|
|
92
|
+
const taken = new Set(this.list().map(e => e.id));
|
|
93
|
+
let n = this._entries.length + 1;
|
|
94
|
+
while (taken.has(`template-${n}`)) n++;
|
|
95
|
+
return `template-${n}`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** @protected */
|
|
99
|
+
_changed() {
|
|
100
|
+
this.store.save(this._entries);
|
|
101
|
+
for (const fn of this._listeners) fn(this.list());
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TextStyle — how a shape's text is set: font, size, bold, italic, underline,
|
|
3
|
+
* and where it sits in the shape (alignment across, position down). One
|
|
4
|
+
* definition for every editor that lets text be styled (the template editor's
|
|
5
|
+
* shapes, the ArchiMate canvas shapes, the ArchiMate properties dialog), so the
|
|
6
|
+
* choices, how a size is written, the dialog fields and the drawing agree.
|
|
7
|
+
*
|
|
8
|
+
* A style is plain data, in the names a view instance's `appearance` uses:
|
|
9
|
+
* `{ fontFamily?, fontSize?, fontWeight?: 'bold', fontStyle?: 'italic',
|
|
10
|
+
* textDecoration?: 'underline', textAlign?: 'left'|'center'|'right', textPosition?: 'top'|'middle'|'bottom' }`.
|
|
11
|
+
* A size is kept as written; a bare number is points ("10" → "10pt"), as Archi keeps it.
|
|
12
|
+
* The graph renderer calls the position `verticalAlign` (fromNode / toNode convert).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** Fonts offered (any other may be typed). */
|
|
16
|
+
export const FONT_FAMILY_CHOICES = Object.freeze(['Segoe UI', 'Arial', 'Helvetica', 'Verdana', 'Tahoma', 'Calibri', 'Times New Roman', 'Georgia', 'Courier New']);
|
|
17
|
+
|
|
18
|
+
/** Sizes offered, in points. */
|
|
19
|
+
export const FONT_SIZE_CHOICES = Object.freeze(['8pt', '9pt', '10pt', '11pt', '12pt', '14pt', '16pt', '18pt', '20pt', '24pt', '28pt', '36pt']);
|
|
20
|
+
|
|
21
|
+
/** Where text sits across a shape, and down it. */
|
|
22
|
+
export const TEXT_ALIGN_CHOICES = Object.freeze(['left', 'center', 'right']);
|
|
23
|
+
export const TEXT_POSITION_CHOICES = Object.freeze(['top', 'middle', 'bottom']);
|
|
24
|
+
|
|
25
|
+
/** The style keys. */
|
|
26
|
+
export const TEXT_STYLE_KEYS = Object.freeze(['fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'textDecoration', 'textAlign', 'textPosition']);
|
|
27
|
+
|
|
28
|
+
/** A style key's name on a graph-renderer node, where it differs. */
|
|
29
|
+
const NODE_NAMES = Object.freeze({ textPosition: 'verticalAlign' });
|
|
30
|
+
|
|
31
|
+
const isUnset = (v) => v === undefined || v === null || v === '';
|
|
32
|
+
|
|
33
|
+
export class TextStyle {
|
|
34
|
+
/**
|
|
35
|
+
* A size as stored: a bare number is points.
|
|
36
|
+
* @param {string|number} size
|
|
37
|
+
* @returns {string|undefined}
|
|
38
|
+
*/
|
|
39
|
+
static normaliseSize(size) {
|
|
40
|
+
if (isUnset(size)) return undefined;
|
|
41
|
+
const text = String(size).trim();
|
|
42
|
+
return /^\d+(\.\d+)?$/.test(text) ? `${text}pt` : text;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A size in pixels, for drawing: points are 4/3 of a pixel, a bare number or
|
|
47
|
+
* "px" is pixels as given. Undefined when there is no usable size.
|
|
48
|
+
*/
|
|
49
|
+
static pixels(size) {
|
|
50
|
+
if (isUnset(size)) return undefined;
|
|
51
|
+
const value = parseFloat(size);
|
|
52
|
+
if (!(value > 0)) return undefined;
|
|
53
|
+
return String(size).trim().endsWith('pt') ? value * 4 / 3 : value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* FormDialog fields for a style: font, size, bold, italic, underline (unless
|
|
58
|
+
* `underline: false`), alignment and position (unless `placement: false`).
|
|
59
|
+
* Their keys are prefixed with `prefix`.
|
|
60
|
+
* @param {Object} style - The current style
|
|
61
|
+
* @param {Object} [options]
|
|
62
|
+
* @param {boolean} [options.underline] - Offer underline (default true)
|
|
63
|
+
* @param {boolean} [options.placement] - Offer alignment and position (default true)
|
|
64
|
+
* @param {string} [options.prefix] - Key prefix (default 'text-')
|
|
65
|
+
*/
|
|
66
|
+
static fields(style = {}, { underline = true, placement = true, prefix = 'text-' } = {}) {
|
|
67
|
+
const choices = (list) => list.map(v => [v, v === 'center' ? 'centre' : v]);
|
|
68
|
+
return [
|
|
69
|
+
{ key: `${prefix}fontFamily`, label: 'Font', type: 'text', value: style.fontFamily ?? '', suggestions: [...FONT_FAMILY_CHOICES], placeholder: 'default' },
|
|
70
|
+
{ key: `${prefix}fontSize`, label: 'Text size', type: 'text', value: style.fontSize ?? '', suggestions: [...FONT_SIZE_CHOICES], placeholder: 'default' },
|
|
71
|
+
{ key: `${prefix}bold`, label: 'Bold', type: 'checkbox', value: style.fontWeight === 'bold' },
|
|
72
|
+
{ key: `${prefix}italic`, label: 'Italic', type: 'checkbox', value: style.fontStyle === 'italic' },
|
|
73
|
+
...(underline ? [{ key: `${prefix}underline`, label: 'Underline', type: 'checkbox', value: style.textDecoration === 'underline' }] : []),
|
|
74
|
+
...(placement ? [
|
|
75
|
+
{ key: `${prefix}textAlign`, label: 'Alignment', type: 'select', value: style.textAlign ?? '', choices: choices(TEXT_ALIGN_CHOICES), allowEmpty: true },
|
|
76
|
+
{ key: `${prefix}textPosition`, label: 'Position', type: 'select', value: style.textPosition ?? '', choices: choices(TEXT_POSITION_CHOICES), allowEmpty: true },
|
|
77
|
+
] : []),
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The style a dialog's values describe (fields made by `fields()`); an
|
|
83
|
+
* unset value is undefined. Fields not offered are left out.
|
|
84
|
+
*/
|
|
85
|
+
static fromValues(values, { prefix = 'text-' } = {}) {
|
|
86
|
+
const has = (key) => `${prefix}${key}` in values;
|
|
87
|
+
const v = (key) => values[`${prefix}${key}`];
|
|
88
|
+
const text = (key) => String(v(key) ?? '').trim() || undefined;
|
|
89
|
+
return {
|
|
90
|
+
...(has('fontFamily') && { fontFamily: text('fontFamily') }),
|
|
91
|
+
...(has('fontSize') && { fontSize: TextStyle.normaliseSize(v('fontSize')) }),
|
|
92
|
+
...(has('bold') && { fontWeight: v('bold') ? 'bold' : undefined }),
|
|
93
|
+
...(has('italic') && { fontStyle: v('italic') ? 'italic' : undefined }),
|
|
94
|
+
...(has('underline') && { textDecoration: v('underline') ? 'underline' : undefined }),
|
|
95
|
+
...(has('textAlign') && { textAlign: text('textAlign') }),
|
|
96
|
+
...(has('textPosition') && { textPosition: text('textPosition') }),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** The style a graph-renderer node is drawn with (its own names read back; the size normalised). */
|
|
101
|
+
static fromNode(node = {}) {
|
|
102
|
+
return Object.fromEntries(TEXT_STYLE_KEYS
|
|
103
|
+
.map(key => [key, node[NODE_NAMES[key] ?? key]])
|
|
104
|
+
.map(([key, value]) => [key, key === 'fontSize' ? TextStyle.normaliseSize(value) : (isUnset(value) ? undefined : value)])
|
|
105
|
+
.filter(([, value]) => value !== undefined));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** A style in a graph-renderer node's names (unset values as undefined, to clear them). */
|
|
109
|
+
static toNode(style = {}) {
|
|
110
|
+
return Object.fromEntries(Object.entries(style).map(([key, value]) => [NODE_NAMES[key] ?? key, value]));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The keys of `next` whose value differs from `current`'s (unset counts as one value). */
|
|
114
|
+
static changes(current = {}, next = {}) {
|
|
115
|
+
return Object.fromEntries(Object.entries(next).filter(([k, value]) => {
|
|
116
|
+
const was = current[k];
|
|
117
|
+
return !((isUnset(was) && isUnset(value)) || was === value);
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* SVG text attributes for a style; `defaultPixels` when it has no size.
|
|
123
|
+
* (Alignment and position place the text; see `placement`.)
|
|
124
|
+
* @returns {Object} attributes (unset ones left out)
|
|
125
|
+
*/
|
|
126
|
+
static svgAttributes(style = {}, { defaultPixels = 12 } = {}) {
|
|
127
|
+
return {
|
|
128
|
+
'font-size': TextStyle.pixels(style.fontSize) ?? defaultPixels,
|
|
129
|
+
...(style.fontFamily && { 'font-family': style.fontFamily }),
|
|
130
|
+
...(style.fontWeight && { 'font-weight': style.fontWeight }),
|
|
131
|
+
...(style.fontStyle && { 'font-style': style.fontStyle }),
|
|
132
|
+
...(style.textDecoration && { 'text-decoration': style.textDecoration }),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Where a block of text lines goes in a box, from the style's alignment and
|
|
138
|
+
* position (or `defaults` where the style sets none): the x and SVG
|
|
139
|
+
* text-anchor of every line, and the baseline of the first (each next line
|
|
140
|
+
* is `lineHeight` lower).
|
|
141
|
+
* @param {Object} style
|
|
142
|
+
* @param {{left, top, right, bottom}} box - Where the text may go
|
|
143
|
+
* @param {number} lineCount
|
|
144
|
+
* @param {Object} [options]
|
|
145
|
+
* @param {number} [options.pixels] - The text's size
|
|
146
|
+
* @param {number} [options.lineHeight] - Defaults to 1.2 × pixels
|
|
147
|
+
* @param {number} [options.pad] - Space from the box's sides
|
|
148
|
+
* @param {{textAlign?, textPosition?}} [options.defaults] - Default 'left', 'top'
|
|
149
|
+
* @returns {{x: number, textAnchor: 'start'|'middle'|'end', baseline: number}}
|
|
150
|
+
*/
|
|
151
|
+
static block(style, box, lineCount, { pixels = 12, lineHeight = Math.round(pixels * 1.2), pad = 6, defaults = {} } = {}) {
|
|
152
|
+
const align = style.textAlign ?? defaults.textAlign ?? 'left';
|
|
153
|
+
const position = style.textPosition ?? defaults.textPosition ?? 'top';
|
|
154
|
+
const across = align === 'right' ? { x: box.right - pad, textAnchor: 'end' }
|
|
155
|
+
: align === 'center' ? { x: (box.left + box.right) / 2, textAnchor: 'middle' }
|
|
156
|
+
: { x: box.left + pad, textAnchor: 'start' };
|
|
157
|
+
const height = box.bottom - box.top;
|
|
158
|
+
const baseline = position === 'bottom' ? box.bottom - pad - (lineCount - 1) * lineHeight
|
|
159
|
+
: position === 'middle' ? box.top + (height - lineCount * lineHeight) / 2 + pixels
|
|
160
|
+
: box.top + pad + pixels;
|
|
161
|
+
return { ...across, baseline };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Whether the style places its text (sets alignment or position). */
|
|
165
|
+
static placesText(style = {}) {
|
|
166
|
+
return !isUnset(style.textAlign) || !isUnset(style.textPosition);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ViewFit — how to show a drawing's bounds whole in a viewport: centred, with
|
|
3
|
+
* a margin, in the viewport's shape. One calculation for every way a view is
|
|
4
|
+
* zoomed: a viewBox (the graph engine's SvgZoom) or a scale and pan (the
|
|
5
|
+
* template editor's transform).
|
|
6
|
+
*/
|
|
7
|
+
export class ViewFit {
|
|
8
|
+
/**
|
|
9
|
+
* The viewBox that shows `bounds` whole.
|
|
10
|
+
* @param {{x, y, width, height}} bounds - Drawing coordinates
|
|
11
|
+
* @param {{width, height}} viewport - The drawing's size on screen (none: the bounds' own shape)
|
|
12
|
+
* @param {number} [margin] - Space around, in drawing units
|
|
13
|
+
* @returns {{x, y, width, height}}
|
|
14
|
+
*/
|
|
15
|
+
static viewBox(bounds, viewport, margin = 20) {
|
|
16
|
+
const width = Math.max(1, bounds.width + margin * 2);
|
|
17
|
+
const height = Math.max(1, bounds.height + margin * 2);
|
|
18
|
+
const aspect = viewport.width > 0 && viewport.height > 0 ? viewport.width / viewport.height : width / height;
|
|
19
|
+
const fitted = width / height > aspect ? { width, height: width / aspect } : { width: height * aspect, height };
|
|
20
|
+
return {
|
|
21
|
+
x: bounds.x + bounds.width / 2 - fitted.width / 2,
|
|
22
|
+
y: bounds.y + bounds.height / 2 - fitted.height / 2,
|
|
23
|
+
...fitted,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The scale and pan that show `bounds` whole in the visible area:
|
|
29
|
+
* shown = drawing * scale + pan.
|
|
30
|
+
* @param {{x, y, width, height}} bounds
|
|
31
|
+
* @param {{x?, y?, width, height}} viewport - The visible area, in the units the pan is in (origin 0, 0 unless given)
|
|
32
|
+
* @param {number} [margin] - Drawing units
|
|
33
|
+
* @param {{minScale?: number, maxScale?: number}} [limits]
|
|
34
|
+
* @returns {{scale: number, panX: number, panY: number}}
|
|
35
|
+
*/
|
|
36
|
+
static transform(bounds, viewport, margin = 20, { minScale = 0.1, maxScale = 5 } = {}) {
|
|
37
|
+
if (!(viewport.width > 0 && viewport.height > 0)) return { scale: 1, panX: 0, panY: 0 };
|
|
38
|
+
const box = ViewFit.viewBox(bounds, viewport, margin);
|
|
39
|
+
const scale = Math.min(maxScale, Math.max(minScale, viewport.width / box.width));
|
|
40
|
+
const cx = bounds.x + bounds.width / 2, cy = bounds.y + bounds.height / 2;
|
|
41
|
+
const { x = 0, y = 0 } = viewport;
|
|
42
|
+
return { scale, panX: x + viewport.width / 2 - cx * scale, panY: y + viewport.height / 2 - cy * scale };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The box around boxes ({left, top, right, bottom} or {x, y, width, height}); null for none. */
|
|
46
|
+
static union(boxes) {
|
|
47
|
+
const edges = boxes.filter(Boolean).map(b => ('left' in b
|
|
48
|
+
? b
|
|
49
|
+
: { left: b.x, top: b.y, right: b.x + b.width, bottom: b.y + b.height }));
|
|
50
|
+
if (!edges.length) return null;
|
|
51
|
+
const left = Math.min(...edges.map(e => e.left)), top = Math.min(...edges.map(e => e.top));
|
|
52
|
+
const right = Math.max(...edges.map(e => e.right)), bottom = Math.max(...edges.map(e => e.bottom));
|
|
53
|
+
return { x: left, y: top, width: right - left, height: bottom - top };
|
|
54
|
+
}
|
|
55
|
+
}
|