From e0a075ecca8ab9bc8e0136e94d1af23bf638a413 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Wed, 7 May 2025 18:16:00 +0200 Subject: [PATCH] Adding treemap --- cypress/platform/knsv2.html | 17 +- demos/treemap.html | 86 ++++++++++ docs/syntax/treemap.md | 128 ++++++++++++++ packages/mermaid/src/defaultConfig.ts | 10 ++ .../src/diagram-api/diagram-orchestration.ts | 4 +- packages/mermaid/src/diagrams/treemap/db.ts | 60 +++++++ .../mermaid/src/diagrams/treemap/detector.ts | 23 +++ .../mermaid/src/diagrams/treemap/diagram.ts | 12 ++ .../mermaid/src/diagrams/treemap/parser.ts | 103 ++++++++++++ .../mermaid/src/diagrams/treemap/renderer.ts | 159 ++++++++++++++++++ .../mermaid/src/diagrams/treemap/styles.ts | 49 ++++++ .../mermaid/src/diagrams/treemap/types.ts | 47 ++++++ packages/parser/src/language/index.ts | 4 + packages/parser/src/parse.ts | 8 +- 14 files changed, 705 insertions(+), 5 deletions(-) create mode 100644 demos/treemap.html create mode 100644 docs/syntax/treemap.md create mode 100644 packages/mermaid/src/diagrams/treemap/db.ts create mode 100644 packages/mermaid/src/diagrams/treemap/detector.ts create mode 100644 packages/mermaid/src/diagrams/treemap/diagram.ts create mode 100644 packages/mermaid/src/diagrams/treemap/parser.ts create mode 100644 packages/mermaid/src/diagrams/treemap/renderer.ts create mode 100644 packages/mermaid/src/diagrams/treemap/styles.ts create mode 100644 packages/mermaid/src/diagrams/treemap/types.ts diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 934d6f44c..a48350690 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -106,19 +106,30 @@
+treemap
+    "Root"
+        "Branch 1"
+            "Leaf 1.1": 10
+            "Leaf 1.2": 15
+        "Branch 2"
+            "Leaf 2.1": 20
+            "Leaf 2.2": 25
+            "Leaf 2.3": 30
+    
+
       flowchart LR
         AB["apa@apa@"] --> B(("`apa@apa`"))
     
-
+    
       flowchart
         D(("for D"))
     
-
+    
       flowchart LR
         A e1@==> B
         e1@{ animate: true}
     
-
+    
 flowchart LR
   A e1@--> B
   classDef animate stroke-width:2,stroke-dasharray:10\,8,stroke-dashoffset:-180,animation: edge-animation-frame 6s linear infinite, stroke-linecap: round
diff --git a/demos/treemap.html b/demos/treemap.html
new file mode 100644
index 000000000..5d51dbe37
--- /dev/null
+++ b/demos/treemap.html
@@ -0,0 +1,86 @@
+
+
+  
+    
+    
+    Mermaid Treemap Diagram Demo
+    
+    
+  
+  
+    

Treemap Diagram Demo

+

This is a demo of the new treemap diagram type in Mermaid.

+ +

Basic Treemap Example

+

+treemap
+    "Root"
+        "Branch 1"
+            "Leaf 1.1": 10
+            "Leaf 1.2": 15
+        "Branch 2"
+            "Leaf 2.1": 20
+            "Leaf 2.2": 25
+            "Leaf 2.3": 30
+    
+
+ treemap Root Branch 1 Leaf 1.1: 10 Leaf 1.2: 15 Branch 2 Leaf 2.1: 20 Leaf 2.2: 25 Leaf 2.3: + 30 +
+ +

Technology Stack Treemap Example

+

+treemap
+    Technology Stack
+        Frontend
+            React: 35
+            CSS: 15
+            HTML: 10
+        Backend
+            Node.js: 25
+            Express: 10
+            MongoDB: 15
+        DevOps
+            Docker: 10
+            Kubernetes: 15
+            CI/CD: 5
+    
+
+ treemap Technology Stack Frontend React: 35 CSS: 15 HTML: 10 Backend Node.js: 25 Express: 10 + MongoDB: 15 DevOps Docker: 10 Kubernetes: 15 CI/CD: 5 +
+ + + + diff --git a/docs/syntax/treemap.md b/docs/syntax/treemap.md new file mode 100644 index 000000000..a025536e9 --- /dev/null +++ b/docs/syntax/treemap.md @@ -0,0 +1,128 @@ +# Treemap Diagrams + +> A treemap diagram displays hierarchical data as a set of nested rectangles. + +Treemap diagrams are useful for visualizing hierarchical structures where the size of each rectangle can represent a quantitative value. + +## Syntax + +The syntax for creating a treemap is straightforward. It uses indentation to define the hierarchy and allows you to specify values for the leaf nodes. + +``` +treemap + Root + Branch 1 + Leaf 1.1: 10 + Leaf 1.2: 15 + Branch 2 + Leaf 2.1: 20 + Leaf 2.2: 25 +``` + +In the example above: +- `Root` is the top-level node +- `Branch 1` and `Branch 2` are children of `Root` +- The leaf nodes (`Leaf 1.1`, etc.) have values specified after a colon + +## Examples + +### Basic Treemap + +```mermaid +treemap + Root + Branch 1 + Leaf 1.1: 10 + Leaf 1.2: 15 + Branch 2 + Leaf 2.1: 20 + Leaf 2.2: 25 + Leaf 2.3: 30 +``` + +### Technology Stack Treemap + +```mermaid +treemap + Technology Stack + Frontend + React: 35 + CSS: 15 + HTML: 10 + Backend + Node.js: 25 + Express: 10 + MongoDB: 15 + DevOps + Docker: 10 + Kubernetes: 15 + CI/CD: 5 +``` + +### Project Resource Allocation + +```mermaid +treemap + Project Resources + Development + Frontend: 20 + Backend: 25 + Database: 15 + Testing + Unit Tests: 10 + Integration Tests: 15 + E2E Tests: 10 + Deployment + Staging: 5 + Production: 10 +``` + +## Configuration + +You can configure the appearance of treemap diagrams in your Mermaid configuration: + +```javascript +mermaid.initialize({ + treemap: { + useMaxWidth: true, + padding: 10, + showValues: true, + nodeWidth: 100, + nodeHeight: 40, + borderWidth: 1, + valueFontSize: 12, + labelFontSize: 14 + } +}); +``` + +Key configuration options: + +| Parameter | Description | Default | +|--------------|--------------------------------------------|---------| +| useMaxWidth | Use available width to scale the diagram | true | +| padding | Padding between nodes | 10 | +| showValues | Show values in leaf nodes | true | +| nodeWidth | Default width of nodes | 100 | +| nodeHeight | Default height of nodes | 40 | +| borderWidth | Width of node borders | 1 | +| valueFontSize| Font size for values | 12 | +| labelFontSize| Font size for node labels | 14 | + +## Notes and Limitations + +- The treemap diagram is designed for hierarchical visualization only +- Deep hierarchies may result in very small rectangles that are difficult to read +- For best results, limit your hierarchy to 3-4 levels +- Values should be provided only for leaf nodes + +## Styling + +You can style the different elements of the treemap using CSS. The key classes are: + +- `.treemapNode` - All nodes +- `.treemapSection` - Non-leaf nodes +- `.treemapLeaf` - Leaf nodes +- `.treemapLabel` - Node labels +- `.treemapValue` - Node values +- `.treemapTitle` - Diagram title diff --git a/packages/mermaid/src/defaultConfig.ts b/packages/mermaid/src/defaultConfig.ts index 2e4e20f50..55c63c3c5 100644 --- a/packages/mermaid/src/defaultConfig.ts +++ b/packages/mermaid/src/defaultConfig.ts @@ -258,6 +258,16 @@ const config: RequiredDeep = { radar: { ...defaultConfigJson.radar, }, + treemap: { + useMaxWidth: true, + padding: 10, + showValues: true, + nodeWidth: 100, + nodeHeight: 40, + borderWidth: 1, + valueFontSize: 12, + labelFontSize: 14, + }, }; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/mermaid/src/diagram-api/diagram-orchestration.ts b/packages/mermaid/src/diagram-api/diagram-orchestration.ts index 8f2b76abb..64112e999 100644 --- a/packages/mermaid/src/diagram-api/diagram-orchestration.ts +++ b/packages/mermaid/src/diagram-api/diagram-orchestration.ts @@ -27,6 +27,7 @@ import block from '../diagrams/block/blockDetector.js'; import architecture from '../diagrams/architecture/architectureDetector.js'; import { registerLazyLoadedDiagrams } from './detectType.js'; import { registerDiagram } from './diagramAPI.js'; +import { treemap } from '../diagrams/treemap/detector.js'; let hasLoadedDiagrams = false; export const addDiagrams = () => { @@ -96,6 +97,7 @@ export const addDiagrams = () => { xychart, block, architecture, - radar + radar, + treemap ); }; diff --git a/packages/mermaid/src/diagrams/treemap/db.ts b/packages/mermaid/src/diagrams/treemap/db.ts new file mode 100644 index 000000000..0f8aa8397 --- /dev/null +++ b/packages/mermaid/src/diagrams/treemap/db.ts @@ -0,0 +1,60 @@ +import { getConfig as commonGetConfig } from '../../config.js'; +import DEFAULT_CONFIG from '../../defaultConfig.js'; +import { cleanAndMerge } from '../../utils.js'; +import { + clear as commonClear, + getAccDescription, + getAccTitle, + getDiagramTitle, + setAccDescription, + setAccTitle, + setDiagramTitle, +} from '../common/commonDb.js'; +import type { TreemapDB, TreemapData, TreemapNode } from './types.js'; + +const defaultTreemapData: TreemapData = { + nodes: [], + levels: new Map(), +}; + +let data: TreemapData = structuredClone(defaultTreemapData); + +const getConfig = () => { + return cleanAndMerge({ + ...DEFAULT_CONFIG.treemap, + ...commonGetConfig().treemap, + }); +}; + +const getNodes = (): TreemapNode[] => data.nodes; + +const addNode = (node: TreemapNode, level: number) => { + data.nodes.push(node); + data.levels.set(node, level); + + // Set the root node if this is a level 0 node and we don't have a root yet + if (level === 0 && !data.root) { + data.root = node; + } +}; + +const getRoot = (): TreemapNode | undefined => data.root; + +const clear = () => { + commonClear(); + data = structuredClone(defaultTreemapData); +}; + +export const db: TreemapDB = { + getNodes, + addNode, + getRoot, + getConfig, + clear, + setAccTitle, + getAccTitle, + setDiagramTitle, + getDiagramTitle, + getAccDescription, + setAccDescription, +}; diff --git a/packages/mermaid/src/diagrams/treemap/detector.ts b/packages/mermaid/src/diagrams/treemap/detector.ts new file mode 100644 index 000000000..914571aba --- /dev/null +++ b/packages/mermaid/src/diagrams/treemap/detector.ts @@ -0,0 +1,23 @@ +import type { + DiagramDetector, + DiagramLoader, + ExternalDiagramDefinition, +} from '../../diagram-api/types.js'; + +const id = 'treemap'; + +const detector: DiagramDetector = (txt) => { + console.log('treemap detector', txt); + return /^\s*treemap/.test(txt); +}; + +const loader: DiagramLoader = async () => { + const { diagram } = await import('./diagram.js'); + return { id, diagram }; +}; + +export const treemap: ExternalDiagramDefinition = { + id, + detector, + loader, +}; diff --git a/packages/mermaid/src/diagrams/treemap/diagram.ts b/packages/mermaid/src/diagrams/treemap/diagram.ts new file mode 100644 index 000000000..dd599174e --- /dev/null +++ b/packages/mermaid/src/diagrams/treemap/diagram.ts @@ -0,0 +1,12 @@ +import type { DiagramDefinition } from '../../diagram-api/types.js'; +import { db } from './db.js'; +import { parser } from './parser.js'; +import { renderer } from './renderer.js'; +import styles from './styles.js'; + +export const diagram: DiagramDefinition = { + parser, + db, + renderer, + styles, +}; diff --git a/packages/mermaid/src/diagrams/treemap/parser.ts b/packages/mermaid/src/diagrams/treemap/parser.ts new file mode 100644 index 000000000..943f6622a --- /dev/null +++ b/packages/mermaid/src/diagrams/treemap/parser.ts @@ -0,0 +1,103 @@ +import { parse } from '@mermaid-js/parser'; +import type { ParserDefinition } from '../../diagram-api/types.js'; +import { log } from '../../logger.js'; +import { populateCommonDb } from '../common/populateCommonDb.js'; +import { db } from './db.js'; +import type { TreemapNode } from './types.js'; + +/** + * Populates the database with data from the Treemap AST + * @param ast - The Treemap AST + */ +const populate = (ast: any) => { + populateCommonDb(ast, db); + + // Process rows + let lastLevel = 0; + let lastNode: TreemapNode | undefined; + + // Process each row in the treemap, building the node hierarchy + for (const row of ast.TreemapRows || []) { + const item = row.item; + if (!item) { + continue; + } + + const level = row.indent ? parseInt(row.indent) : 0; + const name = getItemName(item); + + // Create the node + const node: TreemapNode = { + name, + children: [], + }; + + // If it's a leaf node, add the value + if (item.$type === 'Leaf') { + node.value = item.value; + } + + // Add to the right place in hierarchy + if (level === 0) { + // Root node + db.addNode(node, level); + } else if (level > lastLevel) { + // Child of the last node + if (lastNode) { + lastNode.children = lastNode.children || []; + lastNode.children.push(node); + node.parent = lastNode; + } + db.addNode(node, level); + } else if (level === lastLevel) { + // Sibling of the last node + if (lastNode?.parent) { + lastNode.parent.children = lastNode.parent.children || []; + lastNode.parent.children.push(node); + node.parent = lastNode.parent; + } + db.addNode(node, level); + } else if (level < lastLevel) { + // Go up in the hierarchy + let parent = lastNode ? lastNode.parent : undefined; + for (let i = lastLevel; i > level; i--) { + if (parent) { + parent = parent.parent; + } + } + if (parent) { + parent.children = parent.children || []; + parent.children.push(node); + node.parent = parent; + } + db.addNode(node, level); + } + + lastLevel = level; + lastNode = node; + } +}; + +/** + * Gets the name of a treemap item + * @param item - The treemap item + * @returns The name of the item + */ +const getItemName = (item: any): string => { + return item.name ? String(item.name) : ''; +}; + +export const parser: ParserDefinition = { + parse: async (text: string): Promise => { + try { + // Use a generic parse that accepts any diagram type + const parseFunc = parse as (diagramType: string, text: string) => Promise; + const ast = await parseFunc('treemap', text); + log.debug('Treemap AST:', ast); + populate(ast); + } catch (error) { + log.error('Error parsing treemap:', error); + throw error; + } + }, +}; diff --git a/packages/mermaid/src/diagrams/treemap/renderer.ts b/packages/mermaid/src/diagrams/treemap/renderer.ts new file mode 100644 index 000000000..24a512d36 --- /dev/null +++ b/packages/mermaid/src/diagrams/treemap/renderer.ts @@ -0,0 +1,159 @@ +import type { Diagram } from '../../Diagram.js'; +import type { DiagramRenderer, DrawDefinition } from '../../diagram-api/types.js'; +import { selectSvgElement } from '../../rendering-util/selectSvgElement.js'; +import { configureSvgSize } from '../../setupGraphViewbox.js'; +import type { TreemapDB, TreemapNode } from './types.js'; + +const DEFAULT_PADDING = 10; +const DEFAULT_NODE_WIDTH = 100; +const DEFAULT_NODE_HEIGHT = 40; + +/** + * Draws the treemap diagram + */ +const draw: DrawDefinition = (_text, id, _version, diagram: Diagram) => { + const treemapDb = diagram.db as TreemapDB; + const config = treemapDb.getConfig(); + const padding = config.padding || DEFAULT_PADDING; + const title = treemapDb.getDiagramTitle(); + const root = treemapDb.getRoot(); + + if (!root) { + return; + } + + const svg = selectSvgElement(id); + + // Calculate the size of the treemap + const { width, height } = calculateTreemapSize(root, config); + const titleHeight = title ? 30 : 0; + const svgWidth = width + padding * 2; + const svgHeight = height + padding * 2 + titleHeight; + + // Set the SVG size + svg.attr('viewBox', `0 0 ${svgWidth} ${svgHeight}`); + configureSvgSize(svg, svgHeight, svgWidth, config.useMaxWidth); + + // Create a container group to hold all elements + const g = svg.append('g').attr('transform', `translate(${padding}, ${padding + titleHeight})`); + + // Draw the title if it exists + if (title) { + svg + .append('text') + .attr('x', svgWidth / 2) + .attr('y', padding + titleHeight / 2) + .attr('class', 'treemapTitle') + .attr('text-anchor', 'middle') + .attr('dominant-baseline', 'middle') + .text(title); + } + + // Draw the treemap recursively + drawNode(g, root, 0, 0, width, height, config); +}; + +/** + * Calculates the size of the treemap + */ +const calculateTreemapSize = ( + root: TreemapNode, + config: any +): { width: number; height: number } => { + // If we have a value, use it as the size + if (root.value) { + return { + width: config.nodeWidth || DEFAULT_NODE_WIDTH, + height: config.nodeHeight || DEFAULT_NODE_HEIGHT, + }; + } + + // Otherwise, layout the children + if (!root.children || root.children.length === 0) { + return { + width: config.nodeWidth || DEFAULT_NODE_WIDTH, + height: config.nodeHeight || DEFAULT_NODE_HEIGHT, + }; + } + + // Calculate based on children + let totalWidth = 0; + let maxHeight = 0; + + // Arrange in a simple tiled layout + for (const child of root.children) { + const { width, height } = calculateTreemapSize(child, config); + totalWidth += width + (config.padding || DEFAULT_PADDING); + maxHeight = Math.max(maxHeight, height); + } + + // Remove the last padding + totalWidth -= config.padding || DEFAULT_PADDING; + + return { + width: Math.max(totalWidth, config.nodeWidth || DEFAULT_NODE_WIDTH), + height: Math.max( + maxHeight + (config.padding || DEFAULT_PADDING) * 2, + config.nodeHeight || DEFAULT_NODE_HEIGHT + ), + }; +}; + +/** + * Recursively draws a node and its children in the treemap + */ +const drawNode = ( + parent: any, + node: TreemapNode, + x: number, + y: number, + width: number, + height: number, + config: any +) => { + // Add rectangle + parent + .append('rect') + .attr('x', x) + .attr('y', y) + .attr('width', width) + .attr('height', height) + .attr('class', `treemapNode ${node.value ? 'treemapLeaf' : 'treemapSection'}`); + + // Add the label + parent + .append('text') + .attr('x', x + width / 2) + .attr('y', y + 20) // Position the label at the top + .attr('class', 'treemapLabel') + .attr('text-anchor', 'middle') + .text(node.name); + + // Add the value if it exists and should be shown + if (node.value !== undefined && config.showValues !== false) { + parent + .append('text') + .attr('x', x + width / 2) + .attr('y', y + height - 10) // Position the value at the bottom + .attr('class', 'treemapValue') + .attr('text-anchor', 'middle') + .text(node.value); + } + + // If this is a section with children, layout and draw the children + if (!node.value && node.children && node.children.length > 0) { + // Simple tiled layout for children + const padding = config.padding || DEFAULT_PADDING; + let currentX = x + padding; + const innerY = y + 30; // Allow space for the label + const innerHeight = height - 40; // Allow space for label + + for (const child of node.children) { + const childWidth = width / node.children.length - padding; + drawNode(parent, child, currentX, innerY, childWidth, innerHeight, config); + currentX += childWidth + padding; + } + } +}; + +export const renderer: DiagramRenderer = { draw }; diff --git a/packages/mermaid/src/diagrams/treemap/styles.ts b/packages/mermaid/src/diagrams/treemap/styles.ts new file mode 100644 index 000000000..03c6328a8 --- /dev/null +++ b/packages/mermaid/src/diagrams/treemap/styles.ts @@ -0,0 +1,49 @@ +import type { DiagramStylesProvider } from '../../diagram-api/types.js'; +import { cleanAndMerge } from '../../utils.js'; +import type { PacketStyleOptions } from './types.js'; + +const defaultPacketStyleOptions: PacketStyleOptions = { + byteFontSize: '10px', + startByteColor: 'black', + endByteColor: 'black', + labelColor: 'black', + labelFontSize: '12px', + titleColor: 'black', + titleFontSize: '14px', + blockStrokeColor: 'black', + blockStrokeWidth: '1', + blockFillColor: '#efefef', +}; + +export const getStyles: DiagramStylesProvider = ({ + packet, +}: { packet?: PacketStyleOptions } = {}) => { + const options = cleanAndMerge(defaultPacketStyleOptions, packet); + + return ` + .packetByte { + font-size: ${options.byteFontSize}; + } + .packetByte.start { + fill: ${options.startByteColor}; + } + .packetByte.end { + fill: ${options.endByteColor}; + } + .packetLabel { + fill: ${options.labelColor}; + font-size: ${options.labelFontSize}; + } + .packetTitle { + fill: ${options.titleColor}; + font-size: ${options.titleFontSize}; + } + .packetBlock { + stroke: ${options.blockStrokeColor}; + stroke-width: ${options.blockStrokeWidth}; + fill: ${options.blockFillColor}; + } + `; +}; + +export default getStyles; diff --git a/packages/mermaid/src/diagrams/treemap/types.ts b/packages/mermaid/src/diagrams/treemap/types.ts new file mode 100644 index 000000000..c9a2cd087 --- /dev/null +++ b/packages/mermaid/src/diagrams/treemap/types.ts @@ -0,0 +1,47 @@ +import type { DiagramDBBase } from '../../diagram-api/types.js'; +import type { BaseDiagramConfig } from '../../config.type.js'; + +export interface TreemapNode { + name: string; + children?: TreemapNode[]; + value?: number; + parent?: TreemapNode; +} + +export interface TreemapDB extends DiagramDBBase { + getNodes: () => TreemapNode[]; + addNode: (node: TreemapNode, level: number) => void; + getRoot: () => TreemapNode | undefined; +} + +export interface TreemapStyleOptions { + sectionStrokeColor?: string; + sectionStrokeWidth?: string; + sectionFillColor?: string; + leafStrokeColor?: string; + leafStrokeWidth?: string; + leafFillColor?: string; + labelColor?: string; + labelFontSize?: string; + valueFontSize?: string; + valueColor?: string; + titleColor?: string; + titleFontSize?: string; +} + +export interface TreemapData { + nodes: TreemapNode[]; + levels: Map; + root?: TreemapNode; +} + +// Define the TreemapDiagramConfig interface +export interface TreemapDiagramConfig extends BaseDiagramConfig { + padding?: number; + showValues?: boolean; + nodeWidth?: number; + nodeHeight?: number; + borderWidth?: number; + valueFontSize?: number; + labelFontSize?: number; +} diff --git a/packages/parser/src/language/index.ts b/packages/parser/src/language/index.ts index aa0c0f703..c41d7eeb8 100644 --- a/packages/parser/src/language/index.ts +++ b/packages/parser/src/language/index.ts @@ -8,6 +8,7 @@ export { Architecture, GitGraph, Radar, + TreemapDoc, Branch, Commit, Merge, @@ -19,6 +20,7 @@ export { isPieSection, isArchitecture, isGitGraph, + isTreemapDoc, isBranch, isCommit, isMerge, @@ -32,6 +34,7 @@ export { ArchitectureGeneratedModule, GitGraphGeneratedModule, RadarGeneratedModule, + TreemapGeneratedModule, } from './generated/module.js'; export * from './gitGraph/index.js'; @@ -41,3 +44,4 @@ export * from './packet/index.js'; export * from './pie/index.js'; export * from './architecture/index.js'; export * from './radar/index.js'; +export * from './treemap/index.js'; diff --git a/packages/parser/src/parse.ts b/packages/parser/src/parse.ts index 020a86f7b..6f5a94ce6 100644 --- a/packages/parser/src/parse.ts +++ b/packages/parser/src/parse.ts @@ -1,6 +1,6 @@ import type { LangiumParser, ParseResult } from 'langium'; -import type { Info, Packet, Pie, Architecture, GitGraph, Radar } from './index.js'; +import type { Info, Packet, Pie, Architecture, GitGraph, Radar, Treemap } from './index.js'; export type DiagramAST = Info | Packet | Pie | Architecture | GitGraph | Radar; @@ -36,6 +36,11 @@ const initializers = { const parser = createRadarServices().Radar.parser.LangiumParser; parsers.radar = parser; }, + treemap: async () => { + const { createTreemapServices } = await import('./language/treemap/index.js'); + const parser = createTreemapServices().Treemap.parser.LangiumParser; + parsers.treemap = parser; + }, } as const; export async function parse(diagramType: 'info', text: string): Promise; @@ -44,6 +49,7 @@ export async function parse(diagramType: 'pie', text: string): Promise; export async function parse(diagramType: 'architecture', text: string): Promise; export async function parse(diagramType: 'gitGraph', text: string): Promise; export async function parse(diagramType: 'radar', text: string): Promise; +export async function parse(diagramType: 'treemap', text: string): Promise; export async function parse( diagramType: keyof typeof initializers,