From fc0c7936d145b3bcecca7a39e1a7629b72327016 Mon Sep 17 00:00:00 2001 From: kairi003 Date: Tue, 3 Sep 2024 03:54:12 +0900 Subject: [PATCH] feat: Add support for adding notes to namespaces in class diagrams --- .../mermaid/src/diagrams/class/classDb.ts | 18 ++- .../src/diagrams/class/classRenderer-v2.ts | 108 ++++++++++-------- .../mermaid/src/diagrams/class/classTypes.ts | 1 + .../diagrams/class/parser/classDiagram.jison | 17 +-- 4 files changed, 83 insertions(+), 61 deletions(-) diff --git a/packages/mermaid/src/diagrams/class/classDb.ts b/packages/mermaid/src/diagrams/class/classDb.ts index 490671e76..2548d2a72 100644 --- a/packages/mermaid/src/diagrams/class/classDb.ts +++ b/packages/mermaid/src/diagrams/class/classDb.ts @@ -132,7 +132,7 @@ export const getRelations = function (): ClassRelation[] { export const getNote = function (id: string | number) { const key = typeof id === 'number' ? `note${id}` : id; return notes.get(key)!; -} +}; export const getNotes = function () { return notes; @@ -458,14 +458,24 @@ const getNamespaces = function (): NamespaceMap { * @param classNames - Ids of the class to add * @public */ -export const addClassesToNamespace = function (id: string, classNames: string[]) { +export const addClassesToNamespace = function ( + id: string, + classNames: string[], + noteNames: string[] +) { if (!namespaces.has(id)) { return; } for (const name of classNames) { const { className } = splitClassNameAndType(name); - classes.get(className)!.parent = id; - namespaces.get(id)!.classes.set(className, classes.get(className)!); + const classNode = getClass(className); + classNode.parent = id; + namespaces.get(id)!.classes.set(className, classNode); + } + for (const noteName of noteNames) { + const noteNode = getNote(noteName); + noteNode.parent = id; + namespaces.get(id)!.notes.set(noteName, noteNode); } }; diff --git a/packages/mermaid/src/diagrams/class/classRenderer-v2.ts b/packages/mermaid/src/diagrams/class/classRenderer-v2.ts index f27a144ef..f273e58a7 100644 --- a/packages/mermaid/src/diagrams/class/classRenderer-v2.ts +++ b/packages/mermaid/src/diagrams/class/classRenderer-v2.ts @@ -65,6 +65,9 @@ export const addNamespaces = function ( g.setNode(vertex.id, node); addClasses(vertex.classes, g, _id, diagObj, vertex.id); + const classes: ClassMap = diagObj.db.getClasses(); + const relations: ClassRelation[] = diagObj.db.getRelations(); + addNotes(vertex.notes, g, relations.length + 1, classes, vertex.id); log.info('setNode', node); }); @@ -147,66 +150,71 @@ export const addNotes = function ( notes: ClassNoteMap, g: graphlib.Graph, startEdgeId: number, - classes: ClassMap + classes: ClassMap, + parent?: string ) { log.info(notes); - notes.forEach(function (note, i) { - const vertex = note; + [...notes.values()] + .filter((note) => note.parent === parent) + .forEach(function (vertex) { + const cssNoteStr = ''; - const cssNoteStr = ''; + const styles = { labelStyle: '', style: '' }; - const styles = { labelStyle: '', style: '' }; + const vertexText = vertex.text; - const vertexText = vertex.text; + const radius = 0; + const shape = 'note'; + const node = { + labelStyle: styles.labelStyle, + shape: shape, + labelText: sanitizeText(vertexText), + noteData: vertex, + rx: radius, + ry: radius, + class: cssNoteStr, + style: styles.style, + id: vertex.id, + domId: vertex.id, + tooltip: '', + type: 'note', + // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release + padding: getConfig().flowchart?.padding ?? getConfig().class?.padding, + }; + g.setNode(vertex.id, node); + log.info('setNode', node); - const radius = 0; - const shape = 'note'; - const node = { - labelStyle: styles.labelStyle, - shape: shape, - labelText: sanitizeText(vertexText), - noteData: vertex, - rx: radius, - ry: radius, - class: cssNoteStr, - style: styles.style, - id: vertex.id, - domId: vertex.id, - tooltip: '', - type: 'note', - // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release - padding: getConfig().flowchart?.padding ?? getConfig().class?.padding, - }; - g.setNode(vertex.id, node); - log.info('setNode', node); + if (parent) { + g.setParent(vertex.id, parent); + } - if (!vertex.class || !classes.has(vertex.class)) { - return; - } - const edgeId = startEdgeId + i; + if (!vertex.class || !classes.has(vertex.class)) { + return; + } + const edgeId = startEdgeId + vertex.index; - const edgeData: EdgeData = { - id: `edgeNote${edgeId}`, - //Set relationship style and line type - classes: 'relation', - pattern: 'dotted', - // Set link type for rendering - arrowhead: 'none', - //Set edge extra labels - startLabelRight: '', - endLabelLeft: '', - //Set relation arrow types - arrowTypeStart: 'none', - arrowTypeEnd: 'none', - style: 'fill:none', - labelStyle: '', - curve: interpolateToCurve(conf.curve, curveLinear), - }; + const edgeData: EdgeData = { + id: `edgeNote${edgeId}`, + //Set relationship style and line type + classes: 'relation', + pattern: 'dotted', + // Set link type for rendering + arrowhead: 'none', + //Set edge extra labels + startLabelRight: '', + endLabelLeft: '', + //Set relation arrow types + arrowTypeStart: 'none', + arrowTypeEnd: 'none', + style: 'fill:none', + labelStyle: '', + curve: interpolateToCurve(conf.curve, curveLinear), + }; - // Add the edge to the graph - g.setEdge(vertex.id, vertex.class, edgeData, edgeId); - }); + // Add the edge to the graph + g.setEdge(vertex.id, vertex.class, edgeData, edgeId); + }); }; /** diff --git a/packages/mermaid/src/diagrams/class/classTypes.ts b/packages/mermaid/src/diagrams/class/classTypes.ts index 563c6ec4b..fe352d863 100644 --- a/packages/mermaid/src/diagrams/class/classTypes.ts +++ b/packages/mermaid/src/diagrams/class/classTypes.ts @@ -137,6 +137,7 @@ export interface ClassNote { class: string; text: string; index: number; + parent?: string; } export interface ClassRelation { diff --git a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison index ed4e72027..230bbfcb7 100644 --- a/packages/mermaid/src/diagrams/class/parser/classDiagram.jison +++ b/packages/mermaid/src/diagrams/class/parser/classDiagram.jison @@ -270,8 +270,8 @@ statement ; namespaceStatement - : namespaceIdentifier STRUCT_START classStatements STRUCT_STOP {yy.addClassesToNamespace($1, $3);} - | namespaceIdentifier STRUCT_START NEWLINE classStatements STRUCT_STOP {yy.addClassesToNamespace($1, $4);} + : namespaceIdentifier STRUCT_START classStatements STRUCT_STOP {yy.addClassesToNamespace($1, $3[0], $3[1]);} + | namespaceIdentifier STRUCT_START NEWLINE classStatements STRUCT_STOP {yy.addClassesToNamespace($1, $4[0], $4[1]);} ; namespaceIdentifier @@ -279,9 +279,12 @@ namespaceIdentifier ; classStatements - : classStatement {$$=[$1]} - | classStatement NEWLINE {$$=[$1]} - | classStatement NEWLINE classStatements {$3.unshift($1); $$=$3} + : classStatement {$$=[[$1], []]} + | classStatement NEWLINE {$$=[[$1], []]} + | classStatement NEWLINE classStatements {$3[0].unshift($1); $$=$3} + | noteStatement {$$=[[], [$1]]} + | noteStatement NEWLINE {$$=[[], [$1]]} + | noteStatement NEWLINE classStatements {$3[1].unshift($1); $$=$3} ; classStatement @@ -320,8 +323,8 @@ relationStatement ; noteStatement - : NOTE_FOR className noteText { yy.addNote($3, $2); } - | NOTE noteText { yy.addNote($2); } + : NOTE_FOR className noteText { $$=yy.addNote($3, $2); } + | NOTE noteText { $$=yy.addNote($2); } ; direction