From 9cf562476a4f41c947b4cf5e55be05d549b3856f Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Mon, 26 Aug 2024 15:34:14 +0200 Subject: [PATCH] Tweaking the elk config and exposing elk.layered.cycleBreaking.strategy to mermaid configuration --- .cspell/mermaid-terms.txt | 1 + .cspell/misc-terms.txt | 1 + cypress/platform/knsv2.html | 203 +++++++++++++++++- packages/mermaid-layout-elk/src/render.ts | 36 +++- packages/mermaid/src/config.type.ts | 10 + .../mermaid/src/schemas/config.schema.yaml | 11 + 6 files changed, 246 insertions(+), 16 deletions(-) diff --git a/.cspell/mermaid-terms.txt b/.cspell/mermaid-terms.txt index 46ad6dddb..59a3d108f 100644 --- a/.cspell/mermaid-terms.txt +++ b/.cspell/mermaid-terms.txt @@ -1,5 +1,6 @@ Adamiecki arrowend +Bendpoints bmatrix braintree catmull diff --git a/.cspell/misc-terms.txt b/.cspell/misc-terms.txt index 3fc094309..1820e3c86 100644 --- a/.cspell/misc-terms.txt +++ b/.cspell/misc-terms.txt @@ -4,3 +4,4 @@ handDrawn KOEPF neato newbranch +validify diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 8808a3c9d..a3cbf60bf 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -73,7 +73,9 @@ font-family: monospace; font-size: 72px; } - + pre { + width: 100%; + } /* tspan { font-size: 6px !important; } */ @@ -88,17 +90,202 @@ config: look: handDrawn layout: elk + elk: + + +--- +stateDiagram-v2 + direction LR + accTitle: An idealized Open Source supply-chain graph + + %% + state "šŸŸ¦ Importer" as author_importer + state "šŸŸ„ Supplier, Owner" as author_owner + state "šŸŸØšŸŸ„ Maintainer, Author\nšŸŸØ Custodian" as author + state "šŸŸ© Distributor" as repository_distributor + state "šŸŸ¦ Importer" as language_importer + state "šŸŸ¦šŸŸØ Packager" as language_packager + state "šŸŸ¦šŸŸØ OSS Steward" as language_steward + state "šŸŸØ Curator" as language_curator + state "šŸŸ© Distributor" as language_distributor + state "šŸŸ¦ Contributor" as contributor + state "šŸŸ¦ Importer" as package_importer + state "šŸŸØ Patcher" as package_patcher + state "šŸŸØšŸŸ¦ Builder\nšŸŸØšŸŸ¦ Packager\nšŸŸØšŸŸ¦ Containerizer" as package_packager + state "šŸŸØ Curator" as package_curator + state "šŸŸ© Distributor" as package_distributor + state "šŸŸ¦ Importer" as integrator_importer + state "šŸŸ„ Supplier, Manufacturer, Owner" as integrator_owner + state "šŸŸ¦šŸŸØšŸŸ„ Integrator, Developer" as integrator_developer + state "šŸŸ©šŸŸØ SBOM Redactor\nšŸŸ© Publisher" as integrator_publisher + state "šŸŸ¦šŸŸØ Builder" as integrator_builder + state "šŸŸØ Deployer" as deployer + state "šŸŸ¦ Vuln. Checker" as integrator_checker + state "šŸŸ©šŸŸØ SBOM Redactor" as redactor + state "šŸŸ¦ Consumer\nšŸŸ¦ User" as consumer + state "šŸŸ¦ Auditor" as auditor_internal + state "šŸŸ¦ Auditor" as auditor_external + + %% + classDef createsSBOM stroke:red,stroke-width:3px; + classDef updatesSBOM stroke:yellow,stroke-width:3px; + classDef assemblesSBOM stroke:yellow,stroke-width:3px; + classDef distributesSBOM stroke:green,stroke-width:3px; + classDef verifiesSBOM stroke:#07f,stroke-width:3px; + + %% + class author_importer verifiesSBOM + class author_owner createsSBOM + class manufacturer_owner createsSBOM + class author assemblesSBOM + class package_importer verifiesSBOM + class package_patcher updatesSBOM + class package_packager assemblesSBOM + class package_curator distributesSBOM + class package_distributor distributesSBOM + class language_importer verifiesSBOM + class language_packager assemblesSBOM + class language_steward updatesSBOM + class language_curator distributesSBOM + class language_distributor distributesSBOM + class repository_distributor distributesSBOM + class integrator_importer verifiesSBOM + class integrator_owner createsSBOM + class integrator_developer assemblesSBOM + class integrator_publisher distributesSBOM + class integrator_builder assemblesSBOM + class integrator_checker verifiesSBOM + class deployer assemblesSBOM + class redactor distributesSBOM + class auditor_internal verifiesSBOM + class auditor_external verifiesSBOM + + state "Maintainer Environment" as environment_maintainer { + [*] --> author_importer + [*] --> author + author_importer --> author + author_owner --> author + author --> language_packager + } + + [*] --> environment_maintainer + + state "Language Ecosystem" as ecosystem_lang { + [*] --> language_importer + [*] --> language_steward + [*] --> language_curator + [*] --> language_distributor + language_importer --> language_distributor + language_importer --> language_curator + language_steward --> language_curator + language_curator --> language_distributor + } + + language_packager --> ecosystem_lang + ecosystem_lang --> ecosystem_lang + + state "Public Collaboration Ecosystem" as ecosystem_repo { + [*] --> repository_distributor + } + + author --> ecosystem_repo + ecosystem_repo --> author + + repository_distributor --> contributor + contributor --> repository_distributor + + state "Package Ecosystem" as ecosystem_package { + [*] --> package_importer + [*] --> package_packager + [*] --> package_patcher + package_importer --> package_patcher + package_importer --> package_packager + package_patcher --> package_packager + package_packager --> package_curator + package_packager --> package_distributor + package_curator --> package_distributor + } + + repository_distributor --> ecosystem_package + language_distributor --> ecosystem_package + ecosystem_package --> ecosystem_package + + state "Integrator Environment" as environment_integrator { + [*] --> integrator_developer + [*] --> integrator_importer + integrator_importer --> integrator_developer + integrator_owner --> integrator_developer + integrator_builder --> integrator_publisher + integrator_developer --> integrator_checker + integrator_checker --> integrator_developer + auditor_internal --> integrator_developer + integrator_developer --> integrator_builder + integrator_developer --> auditor_internal + } + + repository_distributor --> environment_integrator + language_distributor --> environment_integrator + package_distributor --> environment_integrator + + state "Production Environment" as environment_prod { + [*] --> deployer + deployer --> redactor + } + + integrator_publisher --> [*] + integrator_developer --> environment_prod + integrator_builder --> environment_prod + integrator_publisher --> environment_prod + + deployer --> auditor_external + deployer --> consumer + redactor --> consumer + + + + +
+---
+  title: hello2
+  config:
+    look: handDrawn
+    layout: dagre
     elk:
         nodePlacementStrategy: BRANDES_KOEPF
 ---
-flowchart LR
-  A[Start] --Some text--> B(Continue)
-  B --> C{Evaluate}
-  C -- One --> D[Option 1]
-  C -- Two --> E[Option 2]
-  C -- Three --> F[fa:fa-car Option 3]
+stateDiagram-v2
+  A --> A
+  state A {
+    B --> D
+    state B {
+      C
+    }
+    state D {
+      E
+    }
+  }
 
 
+
+
+---
+  title: hello2
+  config:
+    look: handDrawn
+    layout: dagre
+    elk:
+        nodePlacementStrategy: BRANDES_KOEPF
+---
+flowchart
+  A --> A
+  subgraph A
+    B --> B
+    subgraph B
+      C
+    end
+  end
+
 
 
@@ -195,7 +382,7 @@ flowchart LR messageFontFamily: 'courier', }, fontSize: 12, - logLevel: 0, + logLevel: 3, securityLevel: 'loose', }); function callback() { diff --git a/packages/mermaid-layout-elk/src/render.ts b/packages/mermaid-layout-elk/src/render.ts index 117ca6276..7ac43bb7f 100644 --- a/packages/mermaid-layout-elk/src/render.ts +++ b/packages/mermaid-layout-elk/src/render.ts @@ -752,14 +752,34 @@ export const render = async ( 'nodePlacement.strategy': data4Layout.config.elk.nodePlacementStrategy, 'elk.layered.mergeEdges': data4Layout.config.elk.mergeEdges, 'elk.direction': 'DOWN', - 'spacing.baseValue': 30, - // 'spacing.nodeNode': 40, - // 'spacing.nodeNodeBetweenLayers': 45, - // 'spacing.edgeNode': 40, - // 'spacing.edgeNodeBetweenLayers': 30, - // 'spacing.edgeEdge': 30, - // 'spacing.edgeEdgeBetweenLayers': 40, - // 'spacing.nodeSelfLoop': 50, + 'spacing.baseValue': 35, + 'elk.layered.unnecessaryBendpoints': true, + 'elk.layered.cycleBreaking.strategy': data4Layout.config.elk.cycleBreakingStrategy, + // 'spacing.nodeNode': 20, + // 'spacing.nodeNodeBetweenLayers': 25, + // 'spacing.edgeNode': 20, + // 'spacing.edgeNodeBetweenLayers': 10, + // 'spacing.edgeEdge': 10, + // 'spacing.edgeEdgeBetweenLayers': 20, + // 'spacing.nodeSelfLoop': 20, + + // Tweaking options + // 'elk.layered.nodePlacement.favorStraightEdges': true, + // 'nodePlacement.feedbackEdges': true, + // 'elk.layered.wrapping.multiEdge.improveCuts': true, + // 'elk.layered.wrapping.multiEdge.improveWrappedEdges': true, + // 'elk.layered.wrapping.strategy': 'MULTI_EDGE', + // 'elk.layered.edgeRouting.selfLoopDistribution': 'EQUALLY', + // 'elk.layered.mergeHierarchyEdges': true, + // 'elk.layered.feedbackEdges': true, + // 'elk.layered.crossingMinimization.semiInteractive': true, + // 'elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor': 1, + // 'elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth': 4.0, + // 'elk.layered.wrapping.validify.strategy': 'LOOK_BACK', + // 'elk.insideSelfLoops.activate': true, + // 'elk.alg.layered.options.EdgeStraighteningStrategy': 'NONE', + // 'elk.layered.considerModelOrder.strategy': 'NODES_AND_EDGES', // NODES_AND_EDGES + // 'elk.layered.wrapping.cutting.strategy': 'ARD', // NODES_AND_EDGES }, children: [], edges: [], diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index 972f85bc4..0236de3ae 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -99,6 +99,16 @@ export interface MermaidConfig { * */ nodePlacementStrategy?: 'SIMPLE' | 'NETWORK_SIMPLEX' | 'LINEAR_SEGMENTS' | 'BRANDES_KOEPF'; + /** + * This strategy decides how to find cycles in the graph and deciding which edges need adjustment to break loops. + * + */ + cycleBreakingStrategy?: + | 'GREEDY' + | 'DEPTH_FIRST' + | 'INTERACTIVE' + | 'MODEL_ORDER' + | 'GREEDY_MODEL_ORDER'; }; darkMode?: boolean; htmlLabels?: boolean; diff --git a/packages/mermaid/src/schemas/config.schema.yaml b/packages/mermaid/src/schemas/config.schema.yaml index 11c294ed9..0d2b610ae 100644 --- a/packages/mermaid/src/schemas/config.schema.yaml +++ b/packages/mermaid/src/schemas/config.schema.yaml @@ -119,6 +119,17 @@ properties: - LINEAR_SEGMENTS - BRANDES_KOEPF default: BRANDES_KOEPF + cycleBreakingStrategy: + description: | + This strategy decides how to find cycles in the graph and deciding which edges need adjustment to break loops. + type: string + enum: + - GREEDY + - DEPTH_FIRST + - INTERACTIVE + - MODEL_ORDER + - GREEDY_MODEL_ORDER + default: GREEDY_MODEL_ORDER darkMode: type: boolean default: false