From a381ab6c418dfbc093d85b6a829a0cc22d2e560a Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Wed, 30 Oct 2024 18:34:52 +0900 Subject: [PATCH] refactor(types): separate `ClusterNode`s Fixes: 7401cb8f6aec0c7dccae820824eb2bb3e6a3e12d --- .../mermaid/src/diagrams/flowchart/flowDb.ts | 19 +++++++++--- .../rendering-elements/clusters.js | 7 +++++ .../rendering-elements/nodes.ts | 8 +++-- packages/mermaid/src/rendering-util/types.ts | 31 +++++++++++++------ 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts index 9e3f64a6c..1dbc789c9 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts +++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts @@ -893,7 +893,7 @@ const addNodeFromVertex = ( node.cssCompiledStyles = getCompiledStyles(vertex.classes); node.cssClasses = vertex.classes.join(' '); } else { - nodes.push({ + const baseNode = { id: vertex.id, label: vertex.text, labelStyle: '', @@ -902,10 +902,8 @@ const addNodeFromVertex = ( cssStyles: vertex.styles, cssCompiledStyles: getCompiledStyles(['default', 'node', ...vertex.classes]), cssClasses: 'default ' + vertex.classes.join(' '), - shape: getTypeFromVertex(vertex), dir: vertex.dir, domId: vertex.domId, - isGroup, look, link: vertex.link, linkTarget: vertex.linkTarget, @@ -916,7 +914,20 @@ const addNodeFromVertex = ( assetWidth: vertex.assetWidth, assetHeight: vertex.assetHeight, constraint: vertex.constraint, - }); + }; + if (isGroup) { + nodes.push({ + ...baseNode, + isGroup: true, + shape: 'rect', + }); + } else { + nodes.push({ + ...baseNode, + isGroup: false, + shape: getTypeFromVertex(vertex), + }); + } } }; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js index 3bd9c9dc7..1dd87d438 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js @@ -471,6 +471,13 @@ const shapes = { let clusterElems = new Map(); +/** + * @typedef {keyof typeof shapes} ClusterShapeID + */ + +/** + * @param {import('../types.js').ClusterNode} node - Shape defaults to 'rect' + */ export const insertCluster = async (elem, node) => { const shape = node.shape || 'rect'; const cluster = await shapes[shape](elem, node); diff --git a/packages/mermaid/src/rendering-util/rendering-elements/nodes.ts b/packages/mermaid/src/rendering-util/rendering-elements/nodes.ts index e2eea5e19..5af6cd17a 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/nodes.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/nodes.ts @@ -1,6 +1,6 @@ import { log } from '../../logger.js'; import { shapes } from './shapes.js'; -import type { Node, ShapeRenderOptions } from '../types.js'; +import type { Node, NonClusterNode, ShapeRenderOptions } from '../types.js'; import type { SVGGroup } from '../../mermaid.js'; import type { D3Selection } from '../../types.js'; import type { graphlib } from 'dagre-d3-es'; @@ -10,7 +10,11 @@ type NodeElement = D3Selection | Awaited>; const nodeElems = new Map(); -export async function insertNode(elem: SVGGroup, node: Node, renderOptions: ShapeRenderOptions) { +export async function insertNode( + elem: SVGGroup, + node: NonClusterNode, + renderOptions: ShapeRenderOptions +) { let newEl: NodeElement | undefined; let el; diff --git a/packages/mermaid/src/rendering-util/types.ts b/packages/mermaid/src/rendering-util/types.ts index f8e9c31b5..86cfd50b3 100644 --- a/packages/mermaid/src/rendering-util/types.ts +++ b/packages/mermaid/src/rendering-util/types.ts @@ -1,5 +1,6 @@ export type MarkdownWordType = 'normal' | 'strong' | 'em'; import type { MermaidConfig } from '../config.type.js'; +import type { ClusterShapeID } from './rendering-elements/clusters.js'; import type { ShapeID } from './rendering-elements/shapes.js'; export interface MarkdownWord { content: string; @@ -9,8 +10,7 @@ export type MarkdownLine = MarkdownWord[]; /** Returns `true` if the line fits a constraint (e.g. it's under 𝑛 chars) */ export type CheckFitFunction = (text: MarkdownLine) => boolean; -// Common properties for any node in the system -export interface Node { +interface BaseNode { id: string; label?: string; description?: string[]; @@ -38,7 +38,6 @@ export interface Node { linkTarget?: string; tooltip?: string; padding?: number; //REMOVE?, use from LayoutData.config - Keep, this could be shape specific - shape?: ShapeID; isGroup: boolean; width?: number; height?: number; @@ -75,6 +74,22 @@ export interface Node { constraint?: 'on' | 'off'; } +/** + * Group/cluster nodes, e.g. nodes that contain other nodes. + */ +export interface ClusterNode extends BaseNode { + shape?: ClusterShapeID; + isGroup: true; +} + +export interface NonClusterNode extends BaseNode { + shape?: ShapeID; + isGroup: false; +} + +// Common properties for any node in the system +export type Node = ClusterNode | NonClusterNode; + // Common properties for any edge in the system export interface Edge { id: string; @@ -118,9 +133,9 @@ export interface RectOptions { } // Extending the Node interface for specific types if needed -export interface ClassDiagramNode extends Node { +export type ClassDiagramNode = Node & { memberData: any; // Specific property for class diagram nodes -} +}; // Specific interfaces for layout and render data export interface LayoutData { @@ -154,13 +169,11 @@ export interface ShapeRenderOptions { dir?: Node['dir']; } -export interface KanbanNode extends Node { +export type KanbanNode = Node & { // Kanban specif data priority?: 'Very High' | 'High' | 'Medium' | 'Low' | 'Very Low'; ticket?: string; assigned?: string; icon?: string; level: number; - rx: number; - ry: number; -} +};