diff --git a/docs/diagrams/flowchart-code-flow.mmd b/docs/diagrams/flowchart-code-flow.mmd new file mode 100644 index 000000000..d306dac7b --- /dev/null +++ b/docs/diagrams/flowchart-code-flow.mmd @@ -0,0 +1,189 @@ +--- +references: + - "File: /packages/mermaid/src/diagrams/flowchart/flowDiagram.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/flowDb.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/flowDetector.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/flowDetector-v2.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/styles.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/types.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/flowChartShapes.js" + - "File: /packages/mermaid/src/diagrams/flowchart/parser/flowParser.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/elk/detector.ts" +generationTime: 2025-07-23T10:31:53.266Z +--- +flowchart TD + %% Entry Points and Detection + Input["User Input Text"] --> Detection{Detection Phase} + + Detection --> flowDetector["flowDetector.ts
detector(txt, config)"] + Detection --> flowDetectorV2["flowDetector-v2.ts
detector(txt, config)"] + Detection --> elkDetector["elk/detector.ts
detector(txt, config)"] + + flowDetector --> |"Checks /^\s*graph/"| DetectLegacy{Legacy Flowchart?} + flowDetectorV2 --> |"Checks /^\s*flowchart/"| DetectNew{New Flowchart?} + elkDetector --> |"Checks /^\s*flowchart-elk/"| DetectElk{ELK Layout?} + + DetectLegacy --> |Yes| LoadDiagram + DetectNew --> |Yes| LoadDiagram + DetectElk --> |Yes| LoadDiagram + + %% Loading Phase + LoadDiagram["loader() function"] --> flowDiagram["flowDiagram.ts
diagram object"] + + flowDiagram --> DiagramStructure{Diagram Components} + DiagramStructure --> Parser["parser: flowParser"] + DiagramStructure --> Database["db: new FlowDB()"] + DiagramStructure --> Renderer["renderer: flowRenderer-v3-unified"] + DiagramStructure --> Styles["styles: flowStyles"] + DiagramStructure --> Init["init: (cnf: MermaidConfig)"] + + %% Parser Phase + Parser --> flowParser["parser/flowParser.ts
newParser.parse(src)"] + flowParser --> |"Preprocesses src"| RemoveWhitespace["Remove trailing whitespace
src.replace(/}\s*\n/g, '}\n')"] + RemoveWhitespace --> flowJison["parser/flow.jison
flowJisonParser.parse(newSrc)"] + + flowJison --> ParseGraph["Parse Graph Structure"] + ParseGraph --> ParseVertices["Parse Vertices"] + ParseGraph --> ParseEdges["Parse Edges"] + ParseGraph --> ParseSubgraphs["Parse Subgraphs"] + ParseGraph --> ParseClasses["Parse Classes"] + ParseGraph --> ParseStyles["Parse Styles"] + + %% Database Phase - FlowDB Class + Database --> FlowDBClass["flowDb.ts
FlowDB class"] + + FlowDBClass --> DBInit["constructor()
- Initialize counters
- Bind methods
- Setup toolTips
- Call clear()"] + + DBInit --> DBMethods{FlowDB Methods} + + DBMethods --> addVertex["addVertex(id, textObj, type, style,
classes, dir, props, metadata)"] + DBMethods --> addLink["addLink(_start[], _end[], linkData)"] + DBMethods --> addSingleLink["addSingleLink(_start, _end, type, id)"] + DBMethods --> setDirection["setDirection(dir)"] + DBMethods --> addSubGraph["addSubGraph(nodes[], id, title)"] + DBMethods --> addClass["addClass(id, style)"] + DBMethods --> setClass["setClass(ids, className)"] + DBMethods --> setTooltip["setTooltip(ids, tooltip)"] + DBMethods --> setClickEvent["setClickEvent(id, functionName, args)"] + DBMethods --> setClickFun["setClickFun(id, functionName, args)"] + + %% Vertex Processing + addVertex --> VertexProcess{Vertex Processing} + VertexProcess --> CreateVertex["Create FlowVertex object
- id, labelType, domId
- styles[], classes[]"] + VertexProcess --> SanitizeText["sanitizeText(textObj.text)"] + VertexProcess --> ParseMetadata["Parse YAML metadata
yaml.load(yamlData)"] + VertexProcess --> SetVertexProps["Set vertex properties
- shape, label, icon, form
- pos, img, constraint, w, h"] + + %% Edge Processing + addSingleLink --> EdgeProcess{Edge Processing} + EdgeProcess --> CreateEdge["Create FlowEdge object
- start, end, type, text
- labelType, classes[]"] + EdgeProcess --> ProcessLinkText["Process link text
- sanitizeText()
- strip quotes"] + EdgeProcess --> SetEdgeProps["Set edge properties
- type, stroke, length"] + EdgeProcess --> GenerateEdgeId["Generate edge ID
getEdgeId(start, end, counter)"] + EdgeProcess --> ValidateEdgeLimit["Validate edge limit
maxEdges check"] + + %% Data Collection + DBMethods --> GetData["getData()"] + GetData --> CollectNodes["Collect nodes[] from vertices"] + GetData --> CollectEdges["Collect edges[] from edges"] + GetData --> ProcessSubGraphs["Process subgraphs
- parentDB Map
- subGraphDB Map"] + GetData --> AddNodeFromVertex["addNodeFromVertex()
for each vertex"] + GetData --> ProcessEdgeTypes["destructEdgeType()
arrowTypeStart, arrowTypeEnd"] + + %% Node Creation + AddNodeFromVertex --> NodeCreation{Node Creation} + NodeCreation --> FindExistingNode["findNode(nodes, vertex.id)"] + NodeCreation --> CreateBaseNode["Create base node
- id, label, parentId
- cssStyles, cssClasses
- shape, domId, tooltip"] + NodeCreation --> GetCompiledStyles["getCompiledStyles(classDefs)"] + NodeCreation --> GetTypeFromVertex["getTypeFromVertex(vertex)"] + + %% Rendering Phase + Renderer --> flowRendererV3["flowRenderer-v3-unified.ts
draw(text, id, version, diag)"] + + flowRendererV3 --> RenderInit["Initialize rendering
- getConfig()
- handle securityLevel
- getDiagramElement()"] + + RenderInit --> GetLayoutData["diag.db.getData()
as LayoutData"] + GetLayoutData --> SetupLayoutData["Setup layout data
- type, layoutAlgorithm
- direction, spacing
- markers, diagramId"] + + SetupLayoutData --> CallRender["render(data4Layout, svg)"] + CallRender --> SetupViewPort["setupViewPortForSVG(svg, padding)"] + SetupViewPort --> ProcessLinks["Process vertex links
- create anchor elements
- handle click events"] + + %% Shape Rendering + CallRender --> ShapeSystem["flowChartShapes.js
Shape Functions"] + + ShapeSystem --> ShapeFunctions{Shape Functions} + ShapeFunctions --> question["question(parent, bbox, node)"] + ShapeFunctions --> hexagon["hexagon(parent, bbox, node)"] + ShapeFunctions --> rect_left_inv_arrow["rect_left_inv_arrow(parent, bbox, node)"] + ShapeFunctions --> lean_right["lean_right(parent, bbox, node)"] + ShapeFunctions --> lean_left["lean_left(parent, bbox, node)"] + + ShapeFunctions --> insertPolygonShape["insertPolygonShape(parent, w, h, points)"] + ShapeFunctions --> intersectPolygon["intersectPolygon(node, points, point)"] + ShapeFunctions --> intersectRect["intersectRect(node, point)"] + + %% Styling System + Styles --> stylesTS["styles.ts
getStyles(options)"] + stylesTS --> StyleOptions["FlowChartStyleOptions
- arrowheadColor, border2
- clusterBkg, mainBkg
- fontFamily, textColor"] + + StyleOptions --> GenerateCSS["Generate CSS styles
- .label, .cluster-label
- .node, .edgePath
- .flowchart-link, .edgeLabel"] + GenerateCSS --> GetIconStyles["getIconStyles()"] + + %% Type System + Parser --> TypeSystem["types.ts
Type Definitions"] + TypeSystem --> FlowVertex["FlowVertex interface"] + TypeSystem --> FlowEdge["FlowEdge interface"] + TypeSystem --> FlowClass["FlowClass interface"] + TypeSystem --> FlowSubGraph["FlowSubGraph interface"] + TypeSystem --> FlowVertexTypeParam["FlowVertexTypeParam
Shape types"] + + %% Utility Functions + DBMethods --> UtilityFunctions{Utility Functions} + UtilityFunctions --> lookUpDomId["lookUpDomId(id)"] + UtilityFunctions --> getClasses["getClasses()"] + UtilityFunctions --> getDirection["getDirection()"] + UtilityFunctions --> getVertices["getVertices()"] + UtilityFunctions --> getEdges["getEdges()"] + UtilityFunctions --> getSubGraphs["getSubGraphs()"] + UtilityFunctions --> clear["clear()"] + UtilityFunctions --> defaultConfig["defaultConfig()"] + + %% Event Handling + ProcessLinks --> EventHandling{Event Handling} + EventHandling --> setupToolTips["setupToolTips(element)"] + EventHandling --> bindFunctions["bindFunctions(element)"] + EventHandling --> runFunc["utils.runFunc(functionName, args)"] + + %% Common Database Functions + DBMethods --> CommonDB["commonDb.js functions"] + CommonDB --> setAccTitle["setAccTitle()"] + CommonDB --> getAccTitle["getAccTitle()"] + CommonDB --> setAccDescription["setAccDescription()"] + CommonDB --> getAccDescription["getAccDescription()"] + CommonDB --> setDiagramTitle["setDiagramTitle()"] + CommonDB --> getDiagramTitle["getDiagramTitle()"] + CommonDB --> commonClear["clear()"] + + %% Final Output + ProcessLinks --> FinalSVG["Final SVG Output"] + + %% Layout Algorithm Selection + SetupLayoutData --> LayoutAlgorithm{Layout Algorithm} + LayoutAlgorithm --> Dagre["dagre
(default)"] + LayoutAlgorithm --> DagreWrapper["dagre-wrapper
(v2 renderer)"] + LayoutAlgorithm --> ELK["elk
(external package)"] + + %% Testing Components + FlowDBClass --> TestFiles["Test Files"] + TestFiles --> flowDbSpec["flowDb.spec.ts"] + TestFiles --> flowChartShapesSpec["flowChartShapes.spec.js"] + TestFiles --> ParserTests["parser/*.spec.js files
- flow-text.spec.js
- flow-edges.spec.js
- flow-style.spec.js
- subgraph.spec.js"] + + %% Configuration + Init --> ConfigSetup["Configuration Setup"] + ConfigSetup --> FlowchartConfig["cnf.flowchart config"] + ConfigSetup --> ArrowMarkers["arrowMarkerAbsolute"] + ConfigSetup --> LayoutConfig["layout config"] + ConfigSetup --> SetConfig["setConfig() calls"] \ No newline at end of file diff --git a/docs/diagrams/mermaid-api-sequence.mmd b/docs/diagrams/mermaid-api-sequence.mmd new file mode 100644 index 000000000..ce7597525 --- /dev/null +++ b/docs/diagrams/mermaid-api-sequence.mmd @@ -0,0 +1,307 @@ +--- +references: + - "File: /packages/mermaid/src/mermaidAPI.ts" + - "File: /packages/mermaid/src/mermaid.ts" +generationTime: 2025-01-28T16:30:00.000Z +--- +sequenceDiagram + participant User as User/Browser + participant Mermaid as mermaid.ts + participant Queue as executionQueue + participant API as mermaidAPI.ts + participant Config as configApi + participant Preprocessor as preprocessDiagram + participant DiagramAPI as diagram-api + participant Diagram as Diagram.fromText + participant Renderer as diagram.renderer + participant Styles as Styling System + participant DOM as DOM/SVG + + Note over User, DOM: Mermaid Complete API Flow + + %% Initialization Phase + User->>+Mermaid: mermaid.initialize(config) + Mermaid->>+API: mermaidAPI.initialize(config) + + API->>API: assignWithDepth({}, userOptions) + API->>API: handle legacy fontFamily config + API->>Config: saveConfigFromInitialize(options) + + alt Theme Configuration Available + API->>API: check if theme in theme object + API->>API: set themeVariables from theme + else Default Theme + API->>API: use default theme variables + end + + API->>Config: setSiteConfig(options) or getSiteConfig() + API->>API: setLogLevel(config.logLevel) + API->>DiagramAPI: addDiagrams() + + API-->>-Mermaid: initialization complete + Mermaid-->>-User: ready to render + + %% Content Loaded Event + User->>DOM: document.load event + DOM->>+Mermaid: contentLoaded() + + opt startOnLoad is true + Mermaid->>Config: getConfig() + Config-->>Mermaid: { startOnLoad: true } + Mermaid->>Mermaid: run() + end + + Mermaid-->>-DOM: event handling complete + + %% Main Run Function + User->>+Mermaid: mermaid.run(options) + + Mermaid->>Mermaid: runThrowsErrors(options) + Mermaid->>Config: getConfig() + Config-->>Mermaid: configuration object + + alt nodes provided + Mermaid->>Mermaid: use provided nodes + else querySelector provided + Mermaid->>DOM: document.querySelectorAll(querySelector) + DOM-->>Mermaid: nodesToProcess + end + + Mermaid->>Mermaid: new InitIDGenerator(deterministicIds, seed) + + loop For each diagram element + Mermaid->>DOM: check element.getAttribute('data-processed') + + opt not processed + Mermaid->>DOM: element.setAttribute('data-processed', 'true') + Mermaid->>Mermaid: generate unique id + Mermaid->>DOM: get element.innerHTML + Mermaid->>Mermaid: entityDecode and clean text + Mermaid->>Mermaid: detectInit(txt) + + Mermaid->>Queue: render(id, txt, element) + end + end + + Mermaid-->>-User: processing initiated + + %% Render Function (Queued) + activate Queue + Queue->>+API: mermaidAPI.render(id, text, container) + + API->>DiagramAPI: addDiagrams() + API->>+Preprocessor: processAndSetConfigs(text) + + Preprocessor->>Preprocessor: preprocessDiagram(text) + Preprocessor->>Config: reset() + Preprocessor->>Config: addDirective(processed.config) + Preprocessor-->>-API: { code, config } + + API->>Config: getConfig() + Config-->>API: current configuration + + opt text length > maxTextSize + API->>API: text = MAX_TEXTLENGTH_EXCEEDED_MSG + end + + API->>API: setup id selectors and element IDs + API->>API: determine security level (sandbox/loose) + + %% DOM Setup + alt svgContainingElement provided + alt isSandboxed + API->>DOM: sandboxedIframe(select(svgContainingElement), iFrameID) + API->>DOM: select iframe contentDocument body + else + API->>DOM: select(svgContainingElement) + end + else no container + API->>API: removeExistingElements(document, id, divId, iFrameId) + alt isSandboxed + API->>DOM: sandboxedIframe(select('body'), iFrameID) + else + API->>DOM: select('body') + end + end + + API->>DOM: appendDivSvgG(root, id, enclosingDivID, fontFamily, XMLNS_XLINK_STD) + + %% Diagram Creation + API->>+Diagram: Diagram.fromText(text, { title: processed.title }) + + Diagram->>DiagramAPI: detect diagram type + Diagram->>DiagramAPI: load appropriate diagram + Diagram-->>-API: diagram instance + + opt parsing error occurred + API->>+Diagram: Diagram.fromText('error') + Diagram-->>-API: error diagram + API->>API: store parseEncounteredException + end + + %% Style Generation + API->>DOM: get svg element and firstChild + API->>Renderer: diag.renderer.getClasses(text, diag) + Renderer-->>API: diagramClassDefs + + API->>+Styles: createUserStyles(config, diagramType, diagramClassDefs, idSelector) + + Styles->>Styles: createCssStyles(config, classDefs) + + opt config.themeCSS defined + Styles->>Styles: append themeCSS + end + + opt fontFamily configured + Styles->>Styles: add CSS variables for fonts + end + + opt classDefs exist + loop For each styleClassDef + opt has styles + Styles->>Styles: cssImportantStyles for each CSS element + end + opt has textStyles + Styles->>Styles: cssImportantStyles for tspan elements + end + end + end + + Styles->>Styles: getStyles(graphType, userCSSstyles, themeVariables) + Styles->>Styles: serialize(compile(svgId{allStyles}), stringify) + Styles-->>-API: compiled CSS rules + + API->>DOM: create style element + API->>DOM: style.innerHTML = rules + API->>DOM: svg.insertBefore(style, firstChild) + + %% Diagram Rendering + API->>+Renderer: diag.renderer.draw(text, id, version, diag) + + Renderer->>Renderer: diagram-specific rendering logic + Renderer->>DOM: create SVG elements + Renderer->>DOM: apply positioning and styling + Renderer-->>-API: rendered diagram + + opt rendering error + alt suppressErrorRendering + API->>API: removeTempElements() + API->>Mermaid: throw error + else + API->>Renderer: errorRenderer.draw(text, id, version) + end + end + + %% Accessibility and Cleanup + API->>DOM: select svg element + API->>Diagram: diag.db.getAccTitle() + API->>Diagram: diag.db.getAccDescription() + API->>API: addA11yInfo(diagramType, svgNode, a11yTitle, a11yDescr) + + API->>DOM: set xmlns for foreignobject elements + API->>DOM: get innerHTML from enclosing div + + API->>+API: cleanUpSvgCode(svgCode, isSandboxed, arrowMarkerAbsolute) + + opt not useArrowMarkerUrls and not sandboxed + API->>API: replace marker-end URLs with anchors + end + + API->>API: decodeEntities(svgCode) + API->>API: replace
with
+ API-->>-API: cleaned SVG code + + alt isSandboxed + API->>+API: putIntoIFrame(svgCode, svgEl) + API->>API: calculate iframe height + API->>API: toBase64 encode SVG content + API->>API: create iframe with sandbox attributes + API-->>-API: iframe HTML + else not loose security + API->>API: DOMPurify.sanitize(svgCode, options) + end + + API->>API: attachFunctions() + API->>API: removeTempElements() + + opt parseEncounteredException + API->>Mermaid: throw parseEncounteredException + end + + API-->>-Queue: { diagramType, svg: svgCode, bindFunctions } + + %% Return to Web Integration + activate Mermaid + Queue-->>Mermaid: render result + Mermaid->>DOM: element.innerHTML = svg + + opt postRenderCallback + Mermaid->>User: postRenderCallback(id) + end + + opt bindFunctions exist + Mermaid->>DOM: bindFunctions(element) + end + deactivate Mermaid + + %% Parse Function Flow + User->>+Mermaid: mermaid.parse(text, parseOptions) + activate Queue + + Queue->>+API: mermaidAPI.parse(text, parseOptions) + + API->>DiagramAPI: addDiagrams() + API->>Preprocessor: processAndSetConfigs(text) + Preprocessor-->>API: { code, config } + API->>Diagram: getDiagramFromText(code) + Diagram-->>API: diagram instance + API-->>-Queue: { diagramType: diagram.type, config } + + Queue-->>-Mermaid: parse result + Mermaid-->>-User: ParseResult or false + + %% External Diagram Registration + User->>+Mermaid: registerExternalDiagrams(diagrams, options) + + Mermaid->>DiagramAPI: addDiagrams() + Mermaid->>DiagramAPI: registerLazyLoadedDiagrams(...diagrams) + + opt lazyLoad is false + Mermaid->>DiagramAPI: loadRegisteredDiagrams() + end + + Mermaid-->>-User: registration complete + + %% Error Handling + Note over Mermaid, API: Error Handling Throughout + alt Error occurs + API->>Mermaid: throw error + Mermaid->>+Mermaid: handleError(error, errors, parseError) + + Mermaid->>Mermaid: log.warn(error) + + alt isDetailedError + Mermaid->>User: parseError(error.str, error.hash) + else + Mermaid->>User: parseError(error) + end + + opt not suppressErrors + Mermaid->>User: throw error + end + + Mermaid-->>-User: error handled + end + + %% Configuration Details + Note over Config: Configuration Functions + Note right of Config: Functions:
- reset()
- getConfig()
- setConfig()
- getSiteConfig()
- updateSiteConfig()
- saveConfigFromInitialize() + + Note over Styles: CSS Generation + Note right of Styles: Features:
- createCssStyles()
- createUserStyles()
- cssImportantStyles()
- Theme integration
- Class definitions + + Note over API: Security Levels + Note right of API: Modes:
- sandbox: iframe isolation
- loose: minimal sanitization
- default: DOMPurify sanitization + + Note over API: Helper Functions + Note right of API: Utilities:
- cleanUpSvgCode()
- putIntoIFrame()
- appendDivSvgG()
- removeExistingElements() \ No newline at end of file diff --git a/docs/diagrams/mindmap-implementation-sequence.mmd b/docs/diagrams/mindmap-implementation-sequence.mmd new file mode 100644 index 000000000..335855380 --- /dev/null +++ b/docs/diagrams/mindmap-implementation-sequence.mmd @@ -0,0 +1,180 @@ +--- +references: + - "File: /packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/mindmapDb.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/detector.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/styles.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/svgDraw.ts" +generationTime: 2025-01-28T16:00:00.000Z +--- +sequenceDiagram + participant User as User Input Text + participant Detector as detector.ts + participant Loader as DiagramLoader + participant Definition as mindmap-definition.ts + participant Parser as parser/mindmap.jison + participant DB as MindmapDB + participant Renderer as mindmapRenderer.ts + participant Cytoscape as cytoscape.js + participant SVGDraw as svgDraw.ts + participant Styles as styles.ts + participant Output as Final SVG + + Note over User, Output: Mindmap Implementation Flow + + %% Detection Phase + User->>Detector: /^\s*mindmap/ text input + activate Detector + Detector->>Detector: detector(txt) validates pattern + Detector->>Loader: loader() function called + deactivate Detector + + activate Loader + Loader->>Definition: import mindmap-definition.js + deactivate Loader + + %% Core Structure Setup + activate Definition + Definition->>DB: get db() → new MindmapDB() + Definition->>Renderer: setup renderer + Definition->>Parser: setup parser + Definition->>Styles: setup styles + deactivate Definition + + %% Database Initialization + activate DB + Note over DB: MindmapDB Constructor + DB->>DB: initialize nodes array + DB->>DB: setup nodeType constants + DB->>DB: bind methods + DB->>DB: clear() state + + %% Parsing Phase + activate Parser + User->>Parser: mindmap syntax text + + loop For each node in hierarchy + Parser->>DB: addNode(level, id, descr, type) + activate DB + DB->>DB: sanitizeText(id, descr) + DB->>DB: getType(startStr, endStr) + Note right of DB: Shape Detection:
[ → RECT
( → ROUNDED_RECT
(( → CIRCLE
)) → BANG
{{ → HEXAGON + DB->>DB: getParent(level) + DB->>DB: create MindmapNode + DB->>DB: add to hierarchy + deactivate DB + end + + opt Icon/Class Decoration + Parser->>DB: decorateNode(decoration) + DB->>DB: set icon/class properties + end + deactivate Parser + + %% Data Preparation + Renderer->>DB: getData() for layout + activate DB + DB->>DB: collect all nodes + DB->>DB: build parent-child relationships + DB-->>Renderer: return node hierarchy + deactivate DB + + %% Rendering Pipeline + activate Renderer + Note over Renderer: Rendering Phase + + Renderer->>Cytoscape: initialize cytoscape + activate Cytoscape + + loop For each node in mindmap + Renderer->>Cytoscape: addNodes(mindmap, cy, conf, level) + Cytoscape->>Cytoscape: create node data + Cytoscape->>Cytoscape: set position (x, y) + end + + loop For parent-child relationships + Renderer->>Cytoscape: add edges + Cytoscape->>Cytoscape: create edge data + end + + Renderer->>Cytoscape: configure cose-bilkent layout + Cytoscape->>Cytoscape: calculate optimal positions + Cytoscape-->>Renderer: return positioned graph + deactivate Cytoscape + + %% SVG Generation + Renderer->>SVGDraw: drawNodes(db, svg, mindmap, section, conf) + activate SVGDraw + + loop For each node recursively + SVGDraw->>SVGDraw: select shape function + + alt Default Shape + SVGDraw->>SVGDraw: defaultBkg() - rounded rectangle + else Rectangle Shape + SVGDraw->>SVGDraw: rectBkg() - sharp corners + else Circle Shape + SVGDraw->>SVGDraw: circleBkg() - perfect circle + else Cloud Shape + SVGDraw->>SVGDraw: cloudBkg() - organic curves + else Bang Shape + SVGDraw->>SVGDraw: bangBkg() - explosion style + else Hexagon Shape + SVGDraw->>SVGDraw: hexagonBkg() - six sides + end + + SVGDraw->>SVGDraw: create SVG elements + SVGDraw->>SVGDraw: add text labels + SVGDraw->>SVGDraw: position node + + opt Node has children + SVGDraw->>SVGDraw: drawNodes() recursive call + end + end + deactivate SVGDraw + + %% Edge Rendering + Renderer->>Renderer: drawEdges(edgesEl, cy) + loop For each edge + Renderer->>Renderer: extract edge bounds + Renderer->>Renderer: draw SVG path + end + + %% Styling Application + Renderer->>Styles: getStyles(options) + activate Styles + + Styles->>Styles: genSections(options) + loop For THEME_COLOR_LIMIT sections + Styles->>Styles: generate color scale + Styles->>Styles: create CSS rules + Note right of Styles: .section-X fills
.edge-depth-X widths
.node-icon-X colors + end + + Styles->>Styles: apply theme integration + Styles-->>Renderer: return compiled CSS + deactivate Styles + + %% Final Assembly + Renderer->>Output: selectSvgElement() + Renderer->>Output: setupGraphViewbox() + Renderer->>Output: apply styles + Renderer->>Output: add interactive elements + deactivate Renderer + + activate Output + Note over Output: Final Mindmap Features + Output->>Output: responsive layout + Output->>Output: accessibility attributes + Output->>Output: hover effects + Output->>Output: click handling + Output-->>User: rendered mindmap + deactivate Output + + %% Configuration Details + Note over DB, Styles: Configuration Options + Note right of DB: Padding Calculations:
Base padding from config
RECT: ×2 padding
ROUNDED_RECT: ×2 padding
HEXAGON: ×2 padding + Note right of Styles: Section Management:
MAX_SECTIONS = 12
Dynamic color generation
Git theme integration + Note right of Renderer: Layout Parameters:
Cytoscape configuration
coseBilkent settings
Node spacing rules \ No newline at end of file diff --git a/packages/mermaid/src/docs/diagrams/flowchart-code-flow.mmd b/packages/mermaid/src/docs/diagrams/flowchart-code-flow.mmd new file mode 100644 index 000000000..d306dac7b --- /dev/null +++ b/packages/mermaid/src/docs/diagrams/flowchart-code-flow.mmd @@ -0,0 +1,189 @@ +--- +references: + - "File: /packages/mermaid/src/diagrams/flowchart/flowDiagram.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/flowDb.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/flowDetector.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/flowDetector-v2.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/styles.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/types.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/flowChartShapes.js" + - "File: /packages/mermaid/src/diagrams/flowchart/parser/flowParser.ts" + - "File: /packages/mermaid/src/diagrams/flowchart/elk/detector.ts" +generationTime: 2025-07-23T10:31:53.266Z +--- +flowchart TD + %% Entry Points and Detection + Input["User Input Text"] --> Detection{Detection Phase} + + Detection --> flowDetector["flowDetector.ts
detector(txt, config)"] + Detection --> flowDetectorV2["flowDetector-v2.ts
detector(txt, config)"] + Detection --> elkDetector["elk/detector.ts
detector(txt, config)"] + + flowDetector --> |"Checks /^\s*graph/"| DetectLegacy{Legacy Flowchart?} + flowDetectorV2 --> |"Checks /^\s*flowchart/"| DetectNew{New Flowchart?} + elkDetector --> |"Checks /^\s*flowchart-elk/"| DetectElk{ELK Layout?} + + DetectLegacy --> |Yes| LoadDiagram + DetectNew --> |Yes| LoadDiagram + DetectElk --> |Yes| LoadDiagram + + %% Loading Phase + LoadDiagram["loader() function"] --> flowDiagram["flowDiagram.ts
diagram object"] + + flowDiagram --> DiagramStructure{Diagram Components} + DiagramStructure --> Parser["parser: flowParser"] + DiagramStructure --> Database["db: new FlowDB()"] + DiagramStructure --> Renderer["renderer: flowRenderer-v3-unified"] + DiagramStructure --> Styles["styles: flowStyles"] + DiagramStructure --> Init["init: (cnf: MermaidConfig)"] + + %% Parser Phase + Parser --> flowParser["parser/flowParser.ts
newParser.parse(src)"] + flowParser --> |"Preprocesses src"| RemoveWhitespace["Remove trailing whitespace
src.replace(/}\s*\n/g, '}\n')"] + RemoveWhitespace --> flowJison["parser/flow.jison
flowJisonParser.parse(newSrc)"] + + flowJison --> ParseGraph["Parse Graph Structure"] + ParseGraph --> ParseVertices["Parse Vertices"] + ParseGraph --> ParseEdges["Parse Edges"] + ParseGraph --> ParseSubgraphs["Parse Subgraphs"] + ParseGraph --> ParseClasses["Parse Classes"] + ParseGraph --> ParseStyles["Parse Styles"] + + %% Database Phase - FlowDB Class + Database --> FlowDBClass["flowDb.ts
FlowDB class"] + + FlowDBClass --> DBInit["constructor()
- Initialize counters
- Bind methods
- Setup toolTips
- Call clear()"] + + DBInit --> DBMethods{FlowDB Methods} + + DBMethods --> addVertex["addVertex(id, textObj, type, style,
classes, dir, props, metadata)"] + DBMethods --> addLink["addLink(_start[], _end[], linkData)"] + DBMethods --> addSingleLink["addSingleLink(_start, _end, type, id)"] + DBMethods --> setDirection["setDirection(dir)"] + DBMethods --> addSubGraph["addSubGraph(nodes[], id, title)"] + DBMethods --> addClass["addClass(id, style)"] + DBMethods --> setClass["setClass(ids, className)"] + DBMethods --> setTooltip["setTooltip(ids, tooltip)"] + DBMethods --> setClickEvent["setClickEvent(id, functionName, args)"] + DBMethods --> setClickFun["setClickFun(id, functionName, args)"] + + %% Vertex Processing + addVertex --> VertexProcess{Vertex Processing} + VertexProcess --> CreateVertex["Create FlowVertex object
- id, labelType, domId
- styles[], classes[]"] + VertexProcess --> SanitizeText["sanitizeText(textObj.text)"] + VertexProcess --> ParseMetadata["Parse YAML metadata
yaml.load(yamlData)"] + VertexProcess --> SetVertexProps["Set vertex properties
- shape, label, icon, form
- pos, img, constraint, w, h"] + + %% Edge Processing + addSingleLink --> EdgeProcess{Edge Processing} + EdgeProcess --> CreateEdge["Create FlowEdge object
- start, end, type, text
- labelType, classes[]"] + EdgeProcess --> ProcessLinkText["Process link text
- sanitizeText()
- strip quotes"] + EdgeProcess --> SetEdgeProps["Set edge properties
- type, stroke, length"] + EdgeProcess --> GenerateEdgeId["Generate edge ID
getEdgeId(start, end, counter)"] + EdgeProcess --> ValidateEdgeLimit["Validate edge limit
maxEdges check"] + + %% Data Collection + DBMethods --> GetData["getData()"] + GetData --> CollectNodes["Collect nodes[] from vertices"] + GetData --> CollectEdges["Collect edges[] from edges"] + GetData --> ProcessSubGraphs["Process subgraphs
- parentDB Map
- subGraphDB Map"] + GetData --> AddNodeFromVertex["addNodeFromVertex()
for each vertex"] + GetData --> ProcessEdgeTypes["destructEdgeType()
arrowTypeStart, arrowTypeEnd"] + + %% Node Creation + AddNodeFromVertex --> NodeCreation{Node Creation} + NodeCreation --> FindExistingNode["findNode(nodes, vertex.id)"] + NodeCreation --> CreateBaseNode["Create base node
- id, label, parentId
- cssStyles, cssClasses
- shape, domId, tooltip"] + NodeCreation --> GetCompiledStyles["getCompiledStyles(classDefs)"] + NodeCreation --> GetTypeFromVertex["getTypeFromVertex(vertex)"] + + %% Rendering Phase + Renderer --> flowRendererV3["flowRenderer-v3-unified.ts
draw(text, id, version, diag)"] + + flowRendererV3 --> RenderInit["Initialize rendering
- getConfig()
- handle securityLevel
- getDiagramElement()"] + + RenderInit --> GetLayoutData["diag.db.getData()
as LayoutData"] + GetLayoutData --> SetupLayoutData["Setup layout data
- type, layoutAlgorithm
- direction, spacing
- markers, diagramId"] + + SetupLayoutData --> CallRender["render(data4Layout, svg)"] + CallRender --> SetupViewPort["setupViewPortForSVG(svg, padding)"] + SetupViewPort --> ProcessLinks["Process vertex links
- create anchor elements
- handle click events"] + + %% Shape Rendering + CallRender --> ShapeSystem["flowChartShapes.js
Shape Functions"] + + ShapeSystem --> ShapeFunctions{Shape Functions} + ShapeFunctions --> question["question(parent, bbox, node)"] + ShapeFunctions --> hexagon["hexagon(parent, bbox, node)"] + ShapeFunctions --> rect_left_inv_arrow["rect_left_inv_arrow(parent, bbox, node)"] + ShapeFunctions --> lean_right["lean_right(parent, bbox, node)"] + ShapeFunctions --> lean_left["lean_left(parent, bbox, node)"] + + ShapeFunctions --> insertPolygonShape["insertPolygonShape(parent, w, h, points)"] + ShapeFunctions --> intersectPolygon["intersectPolygon(node, points, point)"] + ShapeFunctions --> intersectRect["intersectRect(node, point)"] + + %% Styling System + Styles --> stylesTS["styles.ts
getStyles(options)"] + stylesTS --> StyleOptions["FlowChartStyleOptions
- arrowheadColor, border2
- clusterBkg, mainBkg
- fontFamily, textColor"] + + StyleOptions --> GenerateCSS["Generate CSS styles
- .label, .cluster-label
- .node, .edgePath
- .flowchart-link, .edgeLabel"] + GenerateCSS --> GetIconStyles["getIconStyles()"] + + %% Type System + Parser --> TypeSystem["types.ts
Type Definitions"] + TypeSystem --> FlowVertex["FlowVertex interface"] + TypeSystem --> FlowEdge["FlowEdge interface"] + TypeSystem --> FlowClass["FlowClass interface"] + TypeSystem --> FlowSubGraph["FlowSubGraph interface"] + TypeSystem --> FlowVertexTypeParam["FlowVertexTypeParam
Shape types"] + + %% Utility Functions + DBMethods --> UtilityFunctions{Utility Functions} + UtilityFunctions --> lookUpDomId["lookUpDomId(id)"] + UtilityFunctions --> getClasses["getClasses()"] + UtilityFunctions --> getDirection["getDirection()"] + UtilityFunctions --> getVertices["getVertices()"] + UtilityFunctions --> getEdges["getEdges()"] + UtilityFunctions --> getSubGraphs["getSubGraphs()"] + UtilityFunctions --> clear["clear()"] + UtilityFunctions --> defaultConfig["defaultConfig()"] + + %% Event Handling + ProcessLinks --> EventHandling{Event Handling} + EventHandling --> setupToolTips["setupToolTips(element)"] + EventHandling --> bindFunctions["bindFunctions(element)"] + EventHandling --> runFunc["utils.runFunc(functionName, args)"] + + %% Common Database Functions + DBMethods --> CommonDB["commonDb.js functions"] + CommonDB --> setAccTitle["setAccTitle()"] + CommonDB --> getAccTitle["getAccTitle()"] + CommonDB --> setAccDescription["setAccDescription()"] + CommonDB --> getAccDescription["getAccDescription()"] + CommonDB --> setDiagramTitle["setDiagramTitle()"] + CommonDB --> getDiagramTitle["getDiagramTitle()"] + CommonDB --> commonClear["clear()"] + + %% Final Output + ProcessLinks --> FinalSVG["Final SVG Output"] + + %% Layout Algorithm Selection + SetupLayoutData --> LayoutAlgorithm{Layout Algorithm} + LayoutAlgorithm --> Dagre["dagre
(default)"] + LayoutAlgorithm --> DagreWrapper["dagre-wrapper
(v2 renderer)"] + LayoutAlgorithm --> ELK["elk
(external package)"] + + %% Testing Components + FlowDBClass --> TestFiles["Test Files"] + TestFiles --> flowDbSpec["flowDb.spec.ts"] + TestFiles --> flowChartShapesSpec["flowChartShapes.spec.js"] + TestFiles --> ParserTests["parser/*.spec.js files
- flow-text.spec.js
- flow-edges.spec.js
- flow-style.spec.js
- subgraph.spec.js"] + + %% Configuration + Init --> ConfigSetup["Configuration Setup"] + ConfigSetup --> FlowchartConfig["cnf.flowchart config"] + ConfigSetup --> ArrowMarkers["arrowMarkerAbsolute"] + ConfigSetup --> LayoutConfig["layout config"] + ConfigSetup --> SetConfig["setConfig() calls"] \ No newline at end of file diff --git a/packages/mermaid/src/docs/diagrams/mermaid-api-sequence.mmd b/packages/mermaid/src/docs/diagrams/mermaid-api-sequence.mmd new file mode 100644 index 000000000..ce7597525 --- /dev/null +++ b/packages/mermaid/src/docs/diagrams/mermaid-api-sequence.mmd @@ -0,0 +1,307 @@ +--- +references: + - "File: /packages/mermaid/src/mermaidAPI.ts" + - "File: /packages/mermaid/src/mermaid.ts" +generationTime: 2025-01-28T16:30:00.000Z +--- +sequenceDiagram + participant User as User/Browser + participant Mermaid as mermaid.ts + participant Queue as executionQueue + participant API as mermaidAPI.ts + participant Config as configApi + participant Preprocessor as preprocessDiagram + participant DiagramAPI as diagram-api + participant Diagram as Diagram.fromText + participant Renderer as diagram.renderer + participant Styles as Styling System + participant DOM as DOM/SVG + + Note over User, DOM: Mermaid Complete API Flow + + %% Initialization Phase + User->>+Mermaid: mermaid.initialize(config) + Mermaid->>+API: mermaidAPI.initialize(config) + + API->>API: assignWithDepth({}, userOptions) + API->>API: handle legacy fontFamily config + API->>Config: saveConfigFromInitialize(options) + + alt Theme Configuration Available + API->>API: check if theme in theme object + API->>API: set themeVariables from theme + else Default Theme + API->>API: use default theme variables + end + + API->>Config: setSiteConfig(options) or getSiteConfig() + API->>API: setLogLevel(config.logLevel) + API->>DiagramAPI: addDiagrams() + + API-->>-Mermaid: initialization complete + Mermaid-->>-User: ready to render + + %% Content Loaded Event + User->>DOM: document.load event + DOM->>+Mermaid: contentLoaded() + + opt startOnLoad is true + Mermaid->>Config: getConfig() + Config-->>Mermaid: { startOnLoad: true } + Mermaid->>Mermaid: run() + end + + Mermaid-->>-DOM: event handling complete + + %% Main Run Function + User->>+Mermaid: mermaid.run(options) + + Mermaid->>Mermaid: runThrowsErrors(options) + Mermaid->>Config: getConfig() + Config-->>Mermaid: configuration object + + alt nodes provided + Mermaid->>Mermaid: use provided nodes + else querySelector provided + Mermaid->>DOM: document.querySelectorAll(querySelector) + DOM-->>Mermaid: nodesToProcess + end + + Mermaid->>Mermaid: new InitIDGenerator(deterministicIds, seed) + + loop For each diagram element + Mermaid->>DOM: check element.getAttribute('data-processed') + + opt not processed + Mermaid->>DOM: element.setAttribute('data-processed', 'true') + Mermaid->>Mermaid: generate unique id + Mermaid->>DOM: get element.innerHTML + Mermaid->>Mermaid: entityDecode and clean text + Mermaid->>Mermaid: detectInit(txt) + + Mermaid->>Queue: render(id, txt, element) + end + end + + Mermaid-->>-User: processing initiated + + %% Render Function (Queued) + activate Queue + Queue->>+API: mermaidAPI.render(id, text, container) + + API->>DiagramAPI: addDiagrams() + API->>+Preprocessor: processAndSetConfigs(text) + + Preprocessor->>Preprocessor: preprocessDiagram(text) + Preprocessor->>Config: reset() + Preprocessor->>Config: addDirective(processed.config) + Preprocessor-->>-API: { code, config } + + API->>Config: getConfig() + Config-->>API: current configuration + + opt text length > maxTextSize + API->>API: text = MAX_TEXTLENGTH_EXCEEDED_MSG + end + + API->>API: setup id selectors and element IDs + API->>API: determine security level (sandbox/loose) + + %% DOM Setup + alt svgContainingElement provided + alt isSandboxed + API->>DOM: sandboxedIframe(select(svgContainingElement), iFrameID) + API->>DOM: select iframe contentDocument body + else + API->>DOM: select(svgContainingElement) + end + else no container + API->>API: removeExistingElements(document, id, divId, iFrameId) + alt isSandboxed + API->>DOM: sandboxedIframe(select('body'), iFrameID) + else + API->>DOM: select('body') + end + end + + API->>DOM: appendDivSvgG(root, id, enclosingDivID, fontFamily, XMLNS_XLINK_STD) + + %% Diagram Creation + API->>+Diagram: Diagram.fromText(text, { title: processed.title }) + + Diagram->>DiagramAPI: detect diagram type + Diagram->>DiagramAPI: load appropriate diagram + Diagram-->>-API: diagram instance + + opt parsing error occurred + API->>+Diagram: Diagram.fromText('error') + Diagram-->>-API: error diagram + API->>API: store parseEncounteredException + end + + %% Style Generation + API->>DOM: get svg element and firstChild + API->>Renderer: diag.renderer.getClasses(text, diag) + Renderer-->>API: diagramClassDefs + + API->>+Styles: createUserStyles(config, diagramType, diagramClassDefs, idSelector) + + Styles->>Styles: createCssStyles(config, classDefs) + + opt config.themeCSS defined + Styles->>Styles: append themeCSS + end + + opt fontFamily configured + Styles->>Styles: add CSS variables for fonts + end + + opt classDefs exist + loop For each styleClassDef + opt has styles + Styles->>Styles: cssImportantStyles for each CSS element + end + opt has textStyles + Styles->>Styles: cssImportantStyles for tspan elements + end + end + end + + Styles->>Styles: getStyles(graphType, userCSSstyles, themeVariables) + Styles->>Styles: serialize(compile(svgId{allStyles}), stringify) + Styles-->>-API: compiled CSS rules + + API->>DOM: create style element + API->>DOM: style.innerHTML = rules + API->>DOM: svg.insertBefore(style, firstChild) + + %% Diagram Rendering + API->>+Renderer: diag.renderer.draw(text, id, version, diag) + + Renderer->>Renderer: diagram-specific rendering logic + Renderer->>DOM: create SVG elements + Renderer->>DOM: apply positioning and styling + Renderer-->>-API: rendered diagram + + opt rendering error + alt suppressErrorRendering + API->>API: removeTempElements() + API->>Mermaid: throw error + else + API->>Renderer: errorRenderer.draw(text, id, version) + end + end + + %% Accessibility and Cleanup + API->>DOM: select svg element + API->>Diagram: diag.db.getAccTitle() + API->>Diagram: diag.db.getAccDescription() + API->>API: addA11yInfo(diagramType, svgNode, a11yTitle, a11yDescr) + + API->>DOM: set xmlns for foreignobject elements + API->>DOM: get innerHTML from enclosing div + + API->>+API: cleanUpSvgCode(svgCode, isSandboxed, arrowMarkerAbsolute) + + opt not useArrowMarkerUrls and not sandboxed + API->>API: replace marker-end URLs with anchors + end + + API->>API: decodeEntities(svgCode) + API->>API: replace
with
+ API-->>-API: cleaned SVG code + + alt isSandboxed + API->>+API: putIntoIFrame(svgCode, svgEl) + API->>API: calculate iframe height + API->>API: toBase64 encode SVG content + API->>API: create iframe with sandbox attributes + API-->>-API: iframe HTML + else not loose security + API->>API: DOMPurify.sanitize(svgCode, options) + end + + API->>API: attachFunctions() + API->>API: removeTempElements() + + opt parseEncounteredException + API->>Mermaid: throw parseEncounteredException + end + + API-->>-Queue: { diagramType, svg: svgCode, bindFunctions } + + %% Return to Web Integration + activate Mermaid + Queue-->>Mermaid: render result + Mermaid->>DOM: element.innerHTML = svg + + opt postRenderCallback + Mermaid->>User: postRenderCallback(id) + end + + opt bindFunctions exist + Mermaid->>DOM: bindFunctions(element) + end + deactivate Mermaid + + %% Parse Function Flow + User->>+Mermaid: mermaid.parse(text, parseOptions) + activate Queue + + Queue->>+API: mermaidAPI.parse(text, parseOptions) + + API->>DiagramAPI: addDiagrams() + API->>Preprocessor: processAndSetConfigs(text) + Preprocessor-->>API: { code, config } + API->>Diagram: getDiagramFromText(code) + Diagram-->>API: diagram instance + API-->>-Queue: { diagramType: diagram.type, config } + + Queue-->>-Mermaid: parse result + Mermaid-->>-User: ParseResult or false + + %% External Diagram Registration + User->>+Mermaid: registerExternalDiagrams(diagrams, options) + + Mermaid->>DiagramAPI: addDiagrams() + Mermaid->>DiagramAPI: registerLazyLoadedDiagrams(...diagrams) + + opt lazyLoad is false + Mermaid->>DiagramAPI: loadRegisteredDiagrams() + end + + Mermaid-->>-User: registration complete + + %% Error Handling + Note over Mermaid, API: Error Handling Throughout + alt Error occurs + API->>Mermaid: throw error + Mermaid->>+Mermaid: handleError(error, errors, parseError) + + Mermaid->>Mermaid: log.warn(error) + + alt isDetailedError + Mermaid->>User: parseError(error.str, error.hash) + else + Mermaid->>User: parseError(error) + end + + opt not suppressErrors + Mermaid->>User: throw error + end + + Mermaid-->>-User: error handled + end + + %% Configuration Details + Note over Config: Configuration Functions + Note right of Config: Functions:
- reset()
- getConfig()
- setConfig()
- getSiteConfig()
- updateSiteConfig()
- saveConfigFromInitialize() + + Note over Styles: CSS Generation + Note right of Styles: Features:
- createCssStyles()
- createUserStyles()
- cssImportantStyles()
- Theme integration
- Class definitions + + Note over API: Security Levels + Note right of API: Modes:
- sandbox: iframe isolation
- loose: minimal sanitization
- default: DOMPurify sanitization + + Note over API: Helper Functions + Note right of API: Utilities:
- cleanUpSvgCode()
- putIntoIFrame()
- appendDivSvgG()
- removeExistingElements() \ No newline at end of file diff --git a/packages/mermaid/src/docs/diagrams/mindmap-implementation-sequence.mmd b/packages/mermaid/src/docs/diagrams/mindmap-implementation-sequence.mmd new file mode 100644 index 000000000..335855380 --- /dev/null +++ b/packages/mermaid/src/docs/diagrams/mindmap-implementation-sequence.mmd @@ -0,0 +1,180 @@ +--- +references: + - "File: /packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/mindmapDb.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/detector.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/mindmapTypes.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/mindmapRenderer.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/styles.ts" + - "File: /packages/mermaid/src/diagrams/mindmap/svgDraw.ts" +generationTime: 2025-01-28T16:00:00.000Z +--- +sequenceDiagram + participant User as User Input Text + participant Detector as detector.ts + participant Loader as DiagramLoader + participant Definition as mindmap-definition.ts + participant Parser as parser/mindmap.jison + participant DB as MindmapDB + participant Renderer as mindmapRenderer.ts + participant Cytoscape as cytoscape.js + participant SVGDraw as svgDraw.ts + participant Styles as styles.ts + participant Output as Final SVG + + Note over User, Output: Mindmap Implementation Flow + + %% Detection Phase + User->>Detector: /^\s*mindmap/ text input + activate Detector + Detector->>Detector: detector(txt) validates pattern + Detector->>Loader: loader() function called + deactivate Detector + + activate Loader + Loader->>Definition: import mindmap-definition.js + deactivate Loader + + %% Core Structure Setup + activate Definition + Definition->>DB: get db() → new MindmapDB() + Definition->>Renderer: setup renderer + Definition->>Parser: setup parser + Definition->>Styles: setup styles + deactivate Definition + + %% Database Initialization + activate DB + Note over DB: MindmapDB Constructor + DB->>DB: initialize nodes array + DB->>DB: setup nodeType constants + DB->>DB: bind methods + DB->>DB: clear() state + + %% Parsing Phase + activate Parser + User->>Parser: mindmap syntax text + + loop For each node in hierarchy + Parser->>DB: addNode(level, id, descr, type) + activate DB + DB->>DB: sanitizeText(id, descr) + DB->>DB: getType(startStr, endStr) + Note right of DB: Shape Detection:
[ → RECT
( → ROUNDED_RECT
(( → CIRCLE
)) → BANG
{{ → HEXAGON + DB->>DB: getParent(level) + DB->>DB: create MindmapNode + DB->>DB: add to hierarchy + deactivate DB + end + + opt Icon/Class Decoration + Parser->>DB: decorateNode(decoration) + DB->>DB: set icon/class properties + end + deactivate Parser + + %% Data Preparation + Renderer->>DB: getData() for layout + activate DB + DB->>DB: collect all nodes + DB->>DB: build parent-child relationships + DB-->>Renderer: return node hierarchy + deactivate DB + + %% Rendering Pipeline + activate Renderer + Note over Renderer: Rendering Phase + + Renderer->>Cytoscape: initialize cytoscape + activate Cytoscape + + loop For each node in mindmap + Renderer->>Cytoscape: addNodes(mindmap, cy, conf, level) + Cytoscape->>Cytoscape: create node data + Cytoscape->>Cytoscape: set position (x, y) + end + + loop For parent-child relationships + Renderer->>Cytoscape: add edges + Cytoscape->>Cytoscape: create edge data + end + + Renderer->>Cytoscape: configure cose-bilkent layout + Cytoscape->>Cytoscape: calculate optimal positions + Cytoscape-->>Renderer: return positioned graph + deactivate Cytoscape + + %% SVG Generation + Renderer->>SVGDraw: drawNodes(db, svg, mindmap, section, conf) + activate SVGDraw + + loop For each node recursively + SVGDraw->>SVGDraw: select shape function + + alt Default Shape + SVGDraw->>SVGDraw: defaultBkg() - rounded rectangle + else Rectangle Shape + SVGDraw->>SVGDraw: rectBkg() - sharp corners + else Circle Shape + SVGDraw->>SVGDraw: circleBkg() - perfect circle + else Cloud Shape + SVGDraw->>SVGDraw: cloudBkg() - organic curves + else Bang Shape + SVGDraw->>SVGDraw: bangBkg() - explosion style + else Hexagon Shape + SVGDraw->>SVGDraw: hexagonBkg() - six sides + end + + SVGDraw->>SVGDraw: create SVG elements + SVGDraw->>SVGDraw: add text labels + SVGDraw->>SVGDraw: position node + + opt Node has children + SVGDraw->>SVGDraw: drawNodes() recursive call + end + end + deactivate SVGDraw + + %% Edge Rendering + Renderer->>Renderer: drawEdges(edgesEl, cy) + loop For each edge + Renderer->>Renderer: extract edge bounds + Renderer->>Renderer: draw SVG path + end + + %% Styling Application + Renderer->>Styles: getStyles(options) + activate Styles + + Styles->>Styles: genSections(options) + loop For THEME_COLOR_LIMIT sections + Styles->>Styles: generate color scale + Styles->>Styles: create CSS rules + Note right of Styles: .section-X fills
.edge-depth-X widths
.node-icon-X colors + end + + Styles->>Styles: apply theme integration + Styles-->>Renderer: return compiled CSS + deactivate Styles + + %% Final Assembly + Renderer->>Output: selectSvgElement() + Renderer->>Output: setupGraphViewbox() + Renderer->>Output: apply styles + Renderer->>Output: add interactive elements + deactivate Renderer + + activate Output + Note over Output: Final Mindmap Features + Output->>Output: responsive layout + Output->>Output: accessibility attributes + Output->>Output: hover effects + Output->>Output: click handling + Output-->>User: rendered mindmap + deactivate Output + + %% Configuration Details + Note over DB, Styles: Configuration Options + Note right of DB: Padding Calculations:
Base padding from config
RECT: ×2 padding
ROUNDED_RECT: ×2 padding
HEXAGON: ×2 padding + Note right of Styles: Section Management:
MAX_SECTIONS = 12
Dynamic color generation
Git theme integration + Note right of Renderer: Layout Parameters:
Cytoscape configuration
coseBilkent settings
Node spacing rules \ No newline at end of file