mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-10-30 18:34:09 +01:00 
			
		
		
		
	Added support for valueFormat directive
This commit is contained in:
		| @@ -113,7 +113,7 @@ classDef secondary fill:#6cf,stroke:#333,stroke-dasharray:5 5; | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('8: should handle value formatting', () => { | ||||
|   it('8: should handle dollar value formatting with thousands separator', () => { | ||||
|     imgSnapshotTest( | ||||
|       `%%{init: {'treemap': {'valueFormat': '$0,0'}}}%% | ||||
| treemap | ||||
| @@ -130,6 +130,103 @@ treemap | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('8a: should handle percentage formatting', () => { | ||||
|     imgSnapshotTest( | ||||
|       `%%{init: {'treemap': {'valueFormat': '.1%'}}}%% | ||||
| treemap | ||||
| "Market Share" | ||||
|     "Company A": 0.35 | ||||
|     "Company B": 0.25 | ||||
|     "Company C": 0.15 | ||||
|     "Others": 0.25 | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('8b: should handle decimal formatting', () => { | ||||
|     imgSnapshotTest( | ||||
|       `%%{init: {'treemap': {'valueFormat': '.2f'}}}%% | ||||
| treemap | ||||
| "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( | ||||
|       `%%{init: {'treemap': {'valueFormat': '$.2f'}}}%% | ||||
| treemap | ||||
| "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( | ||||
|       `%%{init: {'treemap': {'valueFormat': '$,.2f'}}}%% | ||||
| treemap | ||||
| "Revenue" | ||||
|     "Q1": 1250345.75 | ||||
|     "Q2": 1645789.25 | ||||
|     "Q3": 1845123.50 | ||||
|     "Q4": 2145678.75 | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('8e: should handle simple thousands separator', () => { | ||||
|     imgSnapshotTest( | ||||
|       `%%{init: {'treemap': {'valueFormat': ','}}}%% | ||||
| treemap | ||||
| "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( | ||||
|       `%%{init: {'treemap': {'valueFormat': '$,.0f'}}}%% | ||||
| treemap | ||||
| "Sales by Region" | ||||
|     "North": 1234567 | ||||
|     "South": 7654321 | ||||
|     "East": 4567890 | ||||
|     "West": 9876543 | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('8g: should handle scientific notation format', () => { | ||||
|     imgSnapshotTest( | ||||
|       `%%{init: {'treemap': {'valueFormat': '.2e'}}}%% | ||||
| treemap | ||||
| "Scientific Values" | ||||
|     "Value 1": 1234567 | ||||
|     "Value 2": 0.0000123 | ||||
|     "Value 3": 1000000000 | ||||
|       `, | ||||
|       {} | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('9: should handle a complex example with multiple features', () => { | ||||
|     imgSnapshotTest( | ||||
|       `%%{init: {'theme': 'dark', 'treemap': {'valueFormat': '$0,0'}}}%% | ||||
|   | ||||
| @@ -130,7 +130,7 @@ | ||||
|   </head> | ||||
|  | ||||
|   <body> | ||||
|     <pre id="diagram4" class="mermaid"> | ||||
|     <pre id="diagram4" class="mermaid2"> | ||||
| treemap | ||||
| "Section 1" | ||||
|     "Leaf 1.1": 12 | ||||
| @@ -151,12 +151,12 @@ classDef class1   fill:red,color:blue,stroke:#FFD600; | ||||
| treemap | ||||
| "Budget" | ||||
|     "Operations" | ||||
|         "Salaries": 700000 | ||||
|         "Equipment": 200000 | ||||
|         "Supplies": 100000 | ||||
|         "Salaries": 7000 | ||||
|         "Equipment": 2000 | ||||
|         "Supplies": 1000 | ||||
|     "Marketing" | ||||
|         "Advertising": 400000 | ||||
|         "Events": 100000 | ||||
|         "Advertising": 4000 | ||||
|         "Events": 1000 | ||||
|  | ||||
| </pre | ||||
|     > | ||||
|   | ||||
| @@ -91,7 +91,8 @@ mermaid.initialize({ | ||||
|     nodeHeight: 40, | ||||
|     borderWidth: 1, | ||||
|     valueFontSize: 12, | ||||
|     labelFontSize: 14 | ||||
|     labelFontSize: 14, | ||||
|     valueFormat: ',' | ||||
|   } | ||||
| }); | ||||
| ``` | ||||
| @@ -108,6 +109,48 @@ Key configuration options: | ||||
| | borderWidth  | Width of node borders                      | 1       | | ||||
| | valueFontSize| Font size for values                       | 12      | | ||||
| | labelFontSize| Font size for node labels                  | 14      | | ||||
| | valueFormat  | Format string for values (D3 format)       | ','     | | ||||
|  | ||||
| ## Value Formatting | ||||
|  | ||||
| You can customize how values are displayed in the treemap using the `valueFormat` configuration option. This option primarily uses [D3's format specifiers](https://github.com/d3/d3-format#locale_format) to control how numbers are displayed, with some additional special cases for common formats. | ||||
|  | ||||
| Common format patterns: | ||||
| - `,` - Thousands separator (default) | ||||
| - `$` - Add dollar sign | ||||
| - `.1f` - Show one decimal place | ||||
| - `.1%` - Show as percentage with one decimal place | ||||
| - `$0,0` - Dollar sign with thousands separator | ||||
| - `$.2f` - Dollar sign with 2 decimal places | ||||
| - `$,.2f` - Dollar sign with thousands separator and 2 decimal places | ||||
|  | ||||
| The treemap diagram supports both standard D3 format specifiers and some common currency formats that combine the dollar sign with other formatting options. | ||||
|  | ||||
| Example with currency formatting: | ||||
|  | ||||
| ```mermaid | ||||
| %%{init: {'treemap': {'valueFormat': '$0,0'}}}%% | ||||
| treemap | ||||
|     Budget | ||||
|         Development | ||||
|             Frontend: 250000 | ||||
|             Backend: 350000 | ||||
|         Marketing | ||||
|             Digital: 150000 | ||||
|             Print: 50000 | ||||
| ``` | ||||
|  | ||||
| Example with percentage formatting: | ||||
|  | ||||
| ```mermaid | ||||
| %%{init: {'treemap': {'valueFormat': '.1%'}}}%% | ||||
| treemap | ||||
|     Market Share | ||||
|         Company A: 0.35 | ||||
|         Company B: 0.25 | ||||
|         Company C: 0.15 | ||||
|         Others: 0.25 | ||||
| ``` | ||||
|  | ||||
| ## Notes and Limitations | ||||
|  | ||||
|   | ||||
| @@ -267,6 +267,7 @@ const config: RequiredDeep<MermaidConfig> = { | ||||
|     borderWidth: 1, | ||||
|     valueFontSize: 12, | ||||
|     labelFontSize: 14, | ||||
|     valueFormat: ',', | ||||
|   }, | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -47,7 +47,33 @@ const draw: DrawDefinition = (_text, id, _version, diagram: Diagram) => { | ||||
|   configureSvgSize(svg, svgHeight, svgWidth, config.useMaxWidth); | ||||
|  | ||||
|   // Format for displaying values | ||||
|   const valueFormat = format(','); | ||||
|   let valueFormat; | ||||
|   try { | ||||
|     // Handle special format patterns | ||||
|     const formatStr = config.valueFormat || ','; | ||||
|  | ||||
|     // Handle special cases that aren't directly supported by D3 format | ||||
|     if (formatStr === '$0,0') { | ||||
|       // Currency with thousands separator | ||||
|       valueFormat = (value: number) => '$' + format(',')(value); | ||||
|     } else if (formatStr.startsWith('$') && formatStr.includes(',')) { | ||||
|       // Other dollar formats with commas | ||||
|       const precision = formatStr.match(/\.\d+/); | ||||
|       const precisionStr = precision ? precision[0] : ''; | ||||
|       valueFormat = (value: number) => '$' + format(',' + precisionStr)(value); | ||||
|     } else if (formatStr.startsWith('$')) { | ||||
|       // Simple dollar sign prefix | ||||
|       const restOfFormat = formatStr.substring(1); | ||||
|       valueFormat = (value: number) => '$' + format(restOfFormat || '')(value); | ||||
|     } else { | ||||
|       // Standard D3 format | ||||
|       valueFormat = format(formatStr); | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.error('Error creating format function:', error); | ||||
|     // Fallback to default format | ||||
|     valueFormat = format(','); | ||||
|   } | ||||
|  | ||||
|   // Create color scale | ||||
|   const colorScale = scaleOrdinal<string>().range([ | ||||
|   | ||||
| @@ -1,52 +1,50 @@ | ||||
| import type { DiagramStylesProvider } from '../../diagram-api/types.js'; | ||||
| import { cleanAndMerge } from '../../utils.js'; | ||||
| import type { PacketStyleOptions } from './types.js'; | ||||
| import type { TreemapStyleOptions } from './types.js'; | ||||
|  | ||||
| const defaultPacketStyleOptions: PacketStyleOptions = { | ||||
|   byteFontSize: '10px', | ||||
|   startByteColor: 'black', | ||||
|   endByteColor: 'black', | ||||
| const defaultTreemapStyleOptions: TreemapStyleOptions = { | ||||
|   sectionStrokeColor: 'black', | ||||
|   sectionStrokeWidth: '1', | ||||
|   sectionFillColor: '#efefef', | ||||
|   leafStrokeColor: 'black', | ||||
|   leafStrokeWidth: '1', | ||||
|   leafFillColor: '#efefef', | ||||
|   labelColor: 'black', | ||||
|   labelFontSize: '12px', | ||||
|   valueFontSize: '10px', | ||||
|   valueColor: 'black', | ||||
|   titleColor: 'black', | ||||
|   titleFontSize: '14px', | ||||
|   blockStrokeColor: 'black', | ||||
|   blockStrokeWidth: '1', | ||||
|   blockFillColor: '#efefef', | ||||
| }; | ||||
|  | ||||
| export const getStyles: DiagramStylesProvider = ({ | ||||
|   packet, | ||||
| }: { packet?: PacketStyleOptions } = {}) => { | ||||
|   const options = cleanAndMerge(defaultPacketStyleOptions, packet); | ||||
|   treemap, | ||||
| }: { treemap?: TreemapStyleOptions } = {}) => { | ||||
|   const options = cleanAndMerge(defaultTreemapStyleOptions, treemap); | ||||
|  | ||||
|   return ` | ||||
|   .treemapNode { | ||||
|     // stroke: black; | ||||
|     // stroke-width: 1; | ||||
|   .treemapNode.section { | ||||
|     stroke: ${options.sectionStrokeColor}; | ||||
|     stroke-width: ${options.sectionStrokeWidth}; | ||||
|     fill: ${options.sectionFillColor}; | ||||
|   } | ||||
| 	.packetByte { | ||||
| 		font-size: ${options.byteFontSize}; | ||||
|   .treemapNode.leaf { | ||||
|     stroke: ${options.leafStrokeColor}; | ||||
|     stroke-width: ${options.leafStrokeWidth}; | ||||
|     fill: ${options.leafFillColor}; | ||||
|   } | ||||
| 	.packetByte.start { | ||||
| 		fill: ${options.startByteColor}; | ||||
| 	} | ||||
| 	.packetByte.end { | ||||
| 		fill: ${options.endByteColor}; | ||||
| 	} | ||||
| 	.packetLabel { | ||||
|   .treemapLabel { | ||||
|     fill: ${options.labelColor}; | ||||
|     font-size: ${options.labelFontSize}; | ||||
|   } | ||||
| 	.packetTitle { | ||||
|   .treemapValue { | ||||
|     fill: ${options.valueColor}; | ||||
|     font-size: ${options.valueFontSize}; | ||||
|   } | ||||
|   .treemapTitle { | ||||
|     fill: ${options.titleColor}; | ||||
|     font-size: ${options.titleFontSize}; | ||||
|   } | ||||
| 	.packetBlock { | ||||
| 		stroke: ${options.blockStrokeColor}; | ||||
| 		stroke-width: ${options.blockStrokeWidth}; | ||||
| 		fill: ${options.blockFillColor}; | ||||
| 	} | ||||
|   `; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -49,4 +49,5 @@ export interface TreemapDiagramConfig extends BaseDiagramConfig { | ||||
|   borderWidth?: number; | ||||
|   valueFontSize?: number; | ||||
|   labelFontSize?: number; | ||||
|   valueFormat?: string; | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,14 @@ import type { TreemapNode } from './types.js'; | ||||
|  * @returns A hierarchical tree structure | ||||
|  */ | ||||
| export function buildHierarchy( | ||||
|   items: { level: number; name: string; type: string; value?: number; classSelector?: string }[] | ||||
|   items: { | ||||
|     level: number; | ||||
|     name: string; | ||||
|     type: string; | ||||
|     value?: number; | ||||
|     classSelector?: string; | ||||
|     cssCompiledStyles?: string; | ||||
|   }[] | ||||
| ): TreemapNode[] { | ||||
|   if (!items.length) { | ||||
|     return []; | ||||
| @@ -21,7 +28,9 @@ export function buildHierarchy( | ||||
|       children: item.type === 'Leaf' ? undefined : [], | ||||
|     }; | ||||
|     node.classSelector = item?.classSelector; | ||||
|     node.cssCompiledStyles = item?.cssCompiledStyles; | ||||
|     if (item?.cssCompiledStyles) { | ||||
|       node.cssCompiledStyles = [item.cssCompiledStyles]; | ||||
|     } | ||||
|  | ||||
|     if (item.type === 'Leaf' && item.value !== undefined) { | ||||
|       node.value = item.value; | ||||
|   | ||||
| @@ -141,7 +141,20 @@ treemap | ||||
|  | ||||
| ### Value Formatting | ||||
|  | ||||
| Values in treemap diagrams can be formatted to display in different ways: | ||||
| Values in treemap diagrams can be formatted to display in different ways using the `valueFormat` configuration option. This option primarily uses [D3's format specifiers](https://github.com/d3/d3-format#locale_format) to control how numbers are displayed, with some additional special cases for common formats. | ||||
|  | ||||
| Some common format patterns: | ||||
| - `,` - Thousands separator (default) | ||||
| - `$` - Add dollar sign | ||||
| - `.1f` - Show one decimal place | ||||
| - `.1%` - Show as percentage with one decimal place | ||||
| - `$0,0` - Dollar sign with thousands separator | ||||
| - `$.2f` - Dollar sign with 2 decimal places | ||||
| - `$,.2f` - Dollar sign with thousands separator and 2 decimal places | ||||
|  | ||||
| The treemap diagram supports both standard D3 format specifiers and some common currency formats that combine the dollar sign with other formatting options. | ||||
|  | ||||
| Example with currency formatting: | ||||
|  | ||||
| ```mermaid-example | ||||
| %%{init: {'treemap': {'valueFormat': '$0,0'}}}%% | ||||
| @@ -156,6 +169,18 @@ treemap | ||||
|         "Events": 100000 | ||||
| ``` | ||||
|  | ||||
| Example with percentage formatting: | ||||
|  | ||||
| ```mermaid-example | ||||
| %%{init: {'treemap': {'valueFormat': '.1%'}}}%% | ||||
| treemap | ||||
| "Market Share" | ||||
|     "Company A": 0.35 | ||||
|     "Company B": 0.25 | ||||
|     "Company C": 0.15 | ||||
|     "Others": 0.25 | ||||
| ``` | ||||
|  | ||||
| ## Common Use Cases | ||||
|  | ||||
| Treemap diagrams are commonly used for: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Knut Sveidqvist
					Knut Sveidqvist