mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-26 11:46:42 +02: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(
|
imgSnapshotTest(
|
||||||
`%%{init: {'treemap': {'valueFormat': '$0,0'}}}%%
|
`%%{init: {'treemap': {'valueFormat': '$0,0'}}}%%
|
||||||
treemap
|
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', () => {
|
it('9: should handle a complex example with multiple features', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`%%{init: {'theme': 'dark', 'treemap': {'valueFormat': '$0,0'}}}%%
|
`%%{init: {'theme': 'dark', 'treemap': {'valueFormat': '$0,0'}}}%%
|
||||||
|
@@ -130,7 +130,7 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
treemap
|
treemap
|
||||||
"Section 1"
|
"Section 1"
|
||||||
"Leaf 1.1": 12
|
"Leaf 1.1": 12
|
||||||
@@ -151,12 +151,12 @@ classDef class1 fill:red,color:blue,stroke:#FFD600;
|
|||||||
treemap
|
treemap
|
||||||
"Budget"
|
"Budget"
|
||||||
"Operations"
|
"Operations"
|
||||||
"Salaries": 700000
|
"Salaries": 7000
|
||||||
"Equipment": 200000
|
"Equipment": 2000
|
||||||
"Supplies": 100000
|
"Supplies": 1000
|
||||||
"Marketing"
|
"Marketing"
|
||||||
"Advertising": 400000
|
"Advertising": 4000
|
||||||
"Events": 100000
|
"Events": 1000
|
||||||
|
|
||||||
</pre
|
</pre
|
||||||
>
|
>
|
||||||
|
@@ -91,7 +91,8 @@ mermaid.initialize({
|
|||||||
nodeHeight: 40,
|
nodeHeight: 40,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
valueFontSize: 12,
|
valueFontSize: 12,
|
||||||
labelFontSize: 14
|
labelFontSize: 14,
|
||||||
|
valueFormat: ','
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@@ -108,6 +109,48 @@ Key configuration options:
|
|||||||
| borderWidth | Width of node borders | 1 |
|
| borderWidth | Width of node borders | 1 |
|
||||||
| valueFontSize| Font size for values | 12 |
|
| valueFontSize| Font size for values | 12 |
|
||||||
| labelFontSize| Font size for node labels | 14 |
|
| 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
|
## Notes and Limitations
|
||||||
|
|
||||||
|
@@ -267,6 +267,7 @@ const config: RequiredDeep<MermaidConfig> = {
|
|||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
valueFontSize: 12,
|
valueFontSize: 12,
|
||||||
labelFontSize: 14,
|
labelFontSize: 14,
|
||||||
|
valueFormat: ',',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -47,7 +47,33 @@ const draw: DrawDefinition = (_text, id, _version, diagram: Diagram) => {
|
|||||||
configureSvgSize(svg, svgHeight, svgWidth, config.useMaxWidth);
|
configureSvgSize(svg, svgHeight, svgWidth, config.useMaxWidth);
|
||||||
|
|
||||||
// Format for displaying values
|
// 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
|
// Create color scale
|
||||||
const colorScale = scaleOrdinal<string>().range([
|
const colorScale = scaleOrdinal<string>().range([
|
||||||
|
@@ -1,53 +1,51 @@
|
|||||||
import type { DiagramStylesProvider } from '../../diagram-api/types.js';
|
import type { DiagramStylesProvider } from '../../diagram-api/types.js';
|
||||||
import { cleanAndMerge } from '../../utils.js';
|
import { cleanAndMerge } from '../../utils.js';
|
||||||
import type { PacketStyleOptions } from './types.js';
|
import type { TreemapStyleOptions } from './types.js';
|
||||||
|
|
||||||
const defaultPacketStyleOptions: PacketStyleOptions = {
|
const defaultTreemapStyleOptions: TreemapStyleOptions = {
|
||||||
byteFontSize: '10px',
|
sectionStrokeColor: 'black',
|
||||||
startByteColor: 'black',
|
sectionStrokeWidth: '1',
|
||||||
endByteColor: 'black',
|
sectionFillColor: '#efefef',
|
||||||
|
leafStrokeColor: 'black',
|
||||||
|
leafStrokeWidth: '1',
|
||||||
|
leafFillColor: '#efefef',
|
||||||
labelColor: 'black',
|
labelColor: 'black',
|
||||||
labelFontSize: '12px',
|
labelFontSize: '12px',
|
||||||
|
valueFontSize: '10px',
|
||||||
|
valueColor: 'black',
|
||||||
titleColor: 'black',
|
titleColor: 'black',
|
||||||
titleFontSize: '14px',
|
titleFontSize: '14px',
|
||||||
blockStrokeColor: 'black',
|
|
||||||
blockStrokeWidth: '1',
|
|
||||||
blockFillColor: '#efefef',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getStyles: DiagramStylesProvider = ({
|
export const getStyles: DiagramStylesProvider = ({
|
||||||
packet,
|
treemap,
|
||||||
}: { packet?: PacketStyleOptions } = {}) => {
|
}: { treemap?: TreemapStyleOptions } = {}) => {
|
||||||
const options = cleanAndMerge(defaultPacketStyleOptions, packet);
|
const options = cleanAndMerge(defaultTreemapStyleOptions, treemap);
|
||||||
|
|
||||||
return `
|
return `
|
||||||
.treemapNode {
|
.treemapNode.section {
|
||||||
// stroke: black;
|
stroke: ${options.sectionStrokeColor};
|
||||||
// stroke-width: 1;
|
stroke-width: ${options.sectionStrokeWidth};
|
||||||
|
fill: ${options.sectionFillColor};
|
||||||
}
|
}
|
||||||
.packetByte {
|
.treemapNode.leaf {
|
||||||
font-size: ${options.byteFontSize};
|
stroke: ${options.leafStrokeColor};
|
||||||
}
|
stroke-width: ${options.leafStrokeWidth};
|
||||||
.packetByte.start {
|
fill: ${options.leafFillColor};
|
||||||
fill: ${options.startByteColor};
|
}
|
||||||
}
|
.treemapLabel {
|
||||||
.packetByte.end {
|
fill: ${options.labelColor};
|
||||||
fill: ${options.endByteColor};
|
font-size: ${options.labelFontSize};
|
||||||
}
|
}
|
||||||
.packetLabel {
|
.treemapValue {
|
||||||
fill: ${options.labelColor};
|
fill: ${options.valueColor};
|
||||||
font-size: ${options.labelFontSize};
|
font-size: ${options.valueFontSize};
|
||||||
}
|
}
|
||||||
.packetTitle {
|
.treemapTitle {
|
||||||
fill: ${options.titleColor};
|
fill: ${options.titleColor};
|
||||||
font-size: ${options.titleFontSize};
|
font-size: ${options.titleFontSize};
|
||||||
}
|
}
|
||||||
.packetBlock {
|
`;
|
||||||
stroke: ${options.blockStrokeColor};
|
|
||||||
stroke-width: ${options.blockStrokeWidth};
|
|
||||||
fill: ${options.blockFillColor};
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default getStyles;
|
export default getStyles;
|
||||||
|
@@ -49,4 +49,5 @@ export interface TreemapDiagramConfig extends BaseDiagramConfig {
|
|||||||
borderWidth?: number;
|
borderWidth?: number;
|
||||||
valueFontSize?: number;
|
valueFontSize?: number;
|
||||||
labelFontSize?: number;
|
labelFontSize?: number;
|
||||||
|
valueFormat?: string;
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,14 @@ import type { TreemapNode } from './types.js';
|
|||||||
* @returns A hierarchical tree structure
|
* @returns A hierarchical tree structure
|
||||||
*/
|
*/
|
||||||
export function buildHierarchy(
|
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[] {
|
): TreemapNode[] {
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
return [];
|
return [];
|
||||||
@@ -21,7 +28,9 @@ export function buildHierarchy(
|
|||||||
children: item.type === 'Leaf' ? undefined : [],
|
children: item.type === 'Leaf' ? undefined : [],
|
||||||
};
|
};
|
||||||
node.classSelector = item?.classSelector;
|
node.classSelector = item?.classSelector;
|
||||||
node.cssCompiledStyles = item?.cssCompiledStyles;
|
if (item?.cssCompiledStyles) {
|
||||||
|
node.cssCompiledStyles = [item.cssCompiledStyles];
|
||||||
|
}
|
||||||
|
|
||||||
if (item.type === 'Leaf' && item.value !== undefined) {
|
if (item.type === 'Leaf' && item.value !== undefined) {
|
||||||
node.value = item.value;
|
node.value = item.value;
|
||||||
|
@@ -141,7 +141,20 @@ treemap
|
|||||||
|
|
||||||
### Value Formatting
|
### 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
|
```mermaid-example
|
||||||
%%{init: {'treemap': {'valueFormat': '$0,0'}}}%%
|
%%{init: {'treemap': {'valueFormat': '$0,0'}}}%%
|
||||||
@@ -156,6 +169,18 @@ treemap
|
|||||||
"Events": 100000
|
"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
|
## Common Use Cases
|
||||||
|
|
||||||
Treemap diagrams are commonly used for:
|
Treemap diagrams are commonly used for:
|
||||||
|
Reference in New Issue
Block a user