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