diff --git a/.changeset/better-days-bow.md b/.changeset/better-days-bow.md new file mode 100644 index 000000000..b1baf994b --- /dev/null +++ b/.changeset/better-days-bow.md @@ -0,0 +1,6 @@ +--- +'mermaid': minor +'@mermaid-js/parser': minor +--- + +Adding support for the new diagram type nested treemap diff --git a/.cspell/code-terms.txt b/.cspell/code-terms.txt index e28e9d735..8b549f888 100644 --- a/.cspell/code-terms.txt +++ b/.cspell/code-terms.txt @@ -88,6 +88,7 @@ NODIR NSTR outdir Qcontrolx +QSTR reinit rels reqs diff --git a/.github/workflows/validate-lockfile.yml b/.github/workflows/validate-lockfile.yml index 38c71adaa..6eb0a63ca 100644 --- a/.github/workflows/validate-lockfile.yml +++ b/.github/workflows/validate-lockfile.yml @@ -21,6 +21,8 @@ jobs: with: node-version: 20 + - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0 + - name: Validate pnpm-lock.yaml entries id: validate # give this step an ID so we can reference its outputs run: | diff --git a/cypress/integration/rendering/treemap.spec.ts b/cypress/integration/rendering/treemap.spec.ts new file mode 100644 index 000000000..92fcb5808 --- /dev/null +++ b/cypress/integration/rendering/treemap.spec.ts @@ -0,0 +1,382 @@ +import { imgSnapshotTest } from '../../helpers/util.ts'; + +describe('Treemap Diagram', () => { + it('1: should render a basic treemap', () => { + imgSnapshotTest( + `treemap-beta +"Category A" + "Item A1": 10 + "Item A2": 20 +"Category B" + "Item B1": 15 + "Item B2": 25 + `, + {} + ); + }); + + it('2: should render a hierarchical treemap', () => { + imgSnapshotTest( + `treemap-beta +"Products" + "Electronics" + "Phones": 50 + "Computers": 30 + "Accessories": 20 + "Clothing" + "Men's" + "Shirts": 10 + "Pants": 15 + "Women's" + "Dresses": 20 + "Skirts": 10 + `, + {} + ); + }); + + it('3: should render a treemap with styling using classDef', () => { + imgSnapshotTest( + `treemap-beta +"Section 1" + "Leaf 1.1": 12 + "Section 1.2":::class1 + "Leaf 1.2.1": 12 +"Section 2" + "Leaf 2.1": 20:::class1 + "Leaf 2.2": 25 + "Leaf 2.3": 12 + +classDef class1 fill:red,color:blue,stroke:#FFD600; + `, + {} + ); + }); + + it('4: should handle long text that wraps', () => { + imgSnapshotTest( + `treemap-beta +"Main Category" + "This is a very long item name that should wrap to the next line when rendered in the treemap diagram": 50 + "Short item": 20 + `, + {} + ); + }); + + it('5: should render with a forest theme', () => { + imgSnapshotTest( + `--- +config: + theme: forest +--- +treemap-beta +"Category A" + "Item A1": 10 + "Item A2": 20 +"Category B" + "Item B1": 15 + "Item B2": 25 + `, + {} + ); + }); + + it('6: should handle multiple levels of nesting', () => { + imgSnapshotTest( + `treemap-beta +"Level 1" + "Level 2A" + "Level 3A": 10 + "Level 3B": 15 + "Level 2B" + "Level 3C": 20 + "Level 3D" + "Level 4A": 5 + "Level 4B": 5 + `, + {} + ); + }); + + it('7: should handle classDef with multiple styles', () => { + imgSnapshotTest( + `treemap-beta +"Main" + "A": 20 + "B":::important + "B1": 10 + "B2": 15 + "C": 5:::secondary + +classDef important fill:#f96,stroke:#333,stroke-width:2px; +classDef secondary fill:#6cf,stroke:#333,stroke-dasharray:5 5; + `, + {} + ); + }); + + it('8: should handle dollar value formatting with thousands separator', () => { + imgSnapshotTest( + `--- +config: + treemap: + valueFormat: "$0,0" +--- +treemap +"Budget" + "Operations" + "Salaries": 700000 + "Equipment": 200000 + "Supplies": 100000 + "Marketing" + "Advertising": 400000 + "Events": 100000 + `, + {} + ); + }); + + it('8a: should handle percentage formatting', () => { + imgSnapshotTest( + `--- +config: + treemap: + valueFormat: ".1%" +--- +treemap-beta +"Market Share" + "Company A": 0.35 + "Company B": 0.25 + "Company C": 0.15 + "Others": 0.25 + `, + {} + ); + }); + + it('8b: should handle decimal formatting', () => { + imgSnapshotTest( + `--- +config: + treemap: + valueFormat: ".2f" +--- +treemap-beta +"Metrics" + "Conversion Rate": 0.0567 + "Bounce Rate": 0.6723 + "Click-through Rate": 0.1289 + "Engagement": 0.4521 + `, + {} + ); + }); + + it('8c: should handle dollar sign with decimal places', () => { + imgSnapshotTest( + `--- +config: + treemap: + valueFormat: "$.2f" +--- +treemap-beta +"Product Prices" + "Basic": 19.99 + "Standard": 49.99 + "Premium": 99.99 + "Enterprise": 199.99 + `, + {} + ); + }); + + it('8d: should handle dollar sign with thousands separator and decimal places', () => { + imgSnapshotTest( + `--- +config: + treemap: + valueFormat: "$,.2f" +--- +treemap-beta +"Revenue" + "Q1": 1250345.75 + "Q2": 1645789.25 + "Q3": 1845123.50 + "Q4": 2145678.75 + `, + {} + ); + }); + + it('8e: should handle simple thousands separator', () => { + imgSnapshotTest( + `--- +config: + treemap: + valueFormat: "," +--- +treemap-beta +"User Counts" + "Active Users": 1250345 + "New Signups": 45789 + "Churned": 12350 + "Converted": 78975 + `, + {} + ); + }); + + it('8f: should handle valueFormat set via directive with dollar and thousands separator', () => { + imgSnapshotTest( + `--- +config: + treemap: + valueFormat: "$,.0f" +--- +treemap-beta +"Sales by Region" + "North": 1234567 + "South": 7654321 + "East": 4567890 + "West": 9876543 + `, + {} + ); + }); + + it('8g: should handle scientific notation format', () => { + imgSnapshotTest( + `--- +config: + treemap: + valueFormat: ".2e" +--- +treemap-beta +"Scientific Values" + "Value 1": 1234567 + "Value 2": 0.0000123 + "Value 3": 1000000000 + `, + {} + ); + }); + + it('9: should handle a complex example with multiple features', () => { + imgSnapshotTest( + `--- +config: + theme: dark + treemap: + valueFormat: "$0,0" +--- +treemap-beta +"Company Budget" + "Engineering":::engineering + "Frontend": 300000 + "Backend": 400000 + "DevOps": 200000 + "Marketing":::marketing + "Digital": 250000 + "Print": 100000 + "Events": 150000 + "Sales":::sales + "Direct": 500000 + "Channel": 300000 + +classDef engineering fill:#6b9bc3,stroke:#333; +classDef marketing fill:#c36b9b,stroke:#333; +classDef sales fill:#c3a66b,stroke:#333; + `, + {} + ); + }); + + it('10: should render the example from documentation', () => { + imgSnapshotTest( + ` + treemap-beta + "Section 1" + "Leaf 1.1": 12 + "Section 1.2":::class1 + "Leaf 1.2.1": 12 + "Section 2" + "Leaf 2.1": 20:::class1 + "Leaf 2.2": 25 + "Leaf 2.3": 12 + + classDef class1 fill:red,color:blue,stroke:#FFD600; + `, + {} + ); + }); + + it('11: should handle comments', () => { + imgSnapshotTest( + ` + treemap-beta + %% This is a comment + "Category A" + "Item A1": 10 + "Item A2": 20 + %% Another comment + "Category B" + "Item B1": 15 + "Item B2": 25 + `, + {} + ); + }); + /* + it.skip('12: should render a treemap with title', () => { + imgSnapshotTest( + ` + treemap-beta + title Treemap with Title + "Category A" + "Item A1": 10 + "Item A2": 20 + "Category B" + "Item B1": 15 + "Item B2": 25 + `, + {} + ); + }); + + it.skip('13: should render a treemap with accessibility attributes', () => { + imgSnapshotTest( + ` + treemap-beta + accTitle: Accessible Treemap Title + accDescr: This is a description of the treemap for accessibility purposes + "Category A" + "Item A1": 10 + "Item A2": 20 + "Category B" + "Item B1": 15 + "Item B2": 25 + `, + {} + ); + }); + + it.skip('14: should render a treemap with title and accessibility attributes', () => { + imgSnapshotTest( + ` + treemap + title Treemap with Title and Accessibility + accTitle: Accessible Treemap Title + accDescr: This is a description of the treemap for accessibility purposes + "Category A" + "Item A1": 10 + "Item A2": 20 + "Category B" + "Item B1": 15 + "Item B2": 25 + `, + {} + ); + }); + */ +}); diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 934d6f44c..ab7ded0c2 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -32,8 +32,26 @@ href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap" rel="stylesheet" /> + + + + +
+This is a demo of the new treemap diagram type in Mermaid.
+ ++treemap + "Root" + "Branch 1" + "Leaf 1.1": 10 + "Leaf 1.2": 15 + "Branch 2" + "Branch 2.1" + "Leaf 2.1.1": 20 + "Leaf 2.1.2": 25 + "Leaf 2.2": 25 + "Leaf 2.3": 30 ++ +
+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 ++ + + +