mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-08-15 06:19:24 +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(
|
||||
`%%{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,53 +1,51 @@
|
||||
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};
|
||||
}
|
||||
.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};
|
||||
}
|
||||
`;
|
||||
.treemapNode.leaf {
|
||||
stroke: ${options.leafStrokeColor};
|
||||
stroke-width: ${options.leafStrokeWidth};
|
||||
fill: ${options.leafFillColor};
|
||||
}
|
||||
.treemapLabel {
|
||||
fill: ${options.labelColor};
|
||||
font-size: ${options.labelFontSize};
|
||||
}
|
||||
.treemapValue {
|
||||
fill: ${options.valueColor};
|
||||
font-size: ${options.valueFontSize};
|
||||
}
|
||||
.treemapTitle {
|
||||
fill: ${options.titleColor};
|
||||
font-size: ${options.titleFontSize};
|
||||
}
|
||||
`;
|
||||
};
|
||||
|
||||
export default getStyles;
|
||||
|
@@ -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