Skip to content

Commit 69d0314

Browse files
author
knsv
committed
Fix block diagram styles and bounds
1 parent 6ec0df5 commit 69d0314

10 files changed

Lines changed: 67 additions & 18 deletions

File tree

packages/mermaid/src/diagrams/block/blockRenderer.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,14 @@ export const draw = async function (
5353

5454
// Establish svg dimensions and get width and height
5555
// Why, oh why ????
56-
if (bounds) {
57-
const bounds2 = bounds;
56+
const renderedBounds = nodes.node()?.getBBox();
57+
const bounds2 =
58+
renderedBounds &&
59+
Number.isFinite(renderedBounds.width) &&
60+
Number.isFinite(renderedBounds.height)
61+
? renderedBounds
62+
: bounds;
63+
if (bounds2) {
5864
const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height)));
5965
const height = bounds2.height + magicFactor + 10;
6066
const width = bounds2.width + 10;

packages/mermaid/src/diagrams/block/renderHelpers.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
1919
classStr = (vertex?.classes ?? []).join(' ');
2020
}
2121
classStr = classStr + ' flowchart-label';
22+
const cssCompiledStyles = (vertex?.classes ?? []).flatMap(
23+
(className) => db.getClasses().get(className)?.styles ?? []
24+
);
2225

2326
// We create a SVG label, either by delegating to addHtmlLabel or manually
2427
let radius = 0;
@@ -107,13 +110,16 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
107110
rx: radius,
108111
ry: radius,
109112
class: classStr,
113+
cssClasses: classStr,
114+
cssStyles: vertex?.styles ?? [],
115+
cssCompiledStyles,
110116
style: styles.style,
111117
id: vertex.id,
112118
domId: dbDiagramId ? `${dbDiagramId}-${vertex.id}` : vertex.id,
113119
isGroup: false as const,
114120
directions: vertex.directions,
115-
width: bounds.width,
116-
height: bounds.height,
121+
width: bounds.width || undefined,
122+
height: bounds.height || undefined,
117123
x: bounds.x,
118124
y: bounds.y,
119125
positioned,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { describe, expect, it } from 'vitest';
2+
import type { Node } from '../../types.js';
3+
import { styles2String } from './handDrawnShapeStyles.js';
4+
5+
describe('hand drawn shape styles', () => {
6+
it('normalizes string label styles before compiling node styles', () => {
7+
const styles = styles2String({
8+
id: 'styled-node',
9+
isGroup: false,
10+
cssStyles: ['fill:#f9F', 'stroke:#333'],
11+
labelStyle: 'color:#fff;text-align:center;',
12+
} as Node);
13+
14+
expect(styles.nodeStyles).toContain('fill:#f9F !important');
15+
expect(styles.nodeStyles).toContain('stroke:#333 !important');
16+
expect(styles.labelStyles).toContain('color:#fff !important');
17+
expect(styles.labelStyles).toContain('text-align:center !important');
18+
});
19+
});

packages/mermaid/src/rendering-util/rendering-elements/shapes/handDrawnShapeStyles.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ export const solidStateFill = (color: string) => {
1515
};
1616
};
1717

18+
const normalizeStyleList = (styles: string | string[] | undefined): string[] => {
19+
if (Array.isArray(styles)) {
20+
return styles;
21+
}
22+
if (!styles) {
23+
return [];
24+
}
25+
return styles
26+
.split(';')
27+
.map((style) => style.trim())
28+
.filter(Boolean);
29+
};
30+
1831
export const compileStyles = (node: Node) => {
1932
// node.cssCompiledStyles is an array of strings in the form of 'key: value' where key is the css property and value is the value
2033
// the array is the styles of node from the classes it is using
@@ -23,7 +36,7 @@ export const compileStyles = (node: Node) => {
2336
const stylesMap = styles2Map([
2437
...(node.cssCompiledStyles || []),
2538
...(node.cssStyles || []),
26-
...(node.labelStyle || []),
39+
...normalizeStyleList(node.labelStyle),
2740
]);
2841
return { stylesMap, stylesArray: [...stylesMap] };
2942
};
@@ -36,6 +49,7 @@ export const styles2Map = (styles: string[]) => {
3649
});
3750
return styleMap;
3851
};
52+
3953
export const isLabelStyle = (key: string) => {
4054
return (
4155
key === 'color' ||

packages/mermaid/src/rendering-util/rendering-elements/shapes/invertedTrapezoid.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export async function inv_trapezoid<T extends SVGGraphicsElement>(
1818
const labelPaddingX = node.look === 'neo' ? nodePadding * 2 : nodePadding;
1919
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
2020

21-
const w = Math.max(bbox.width + (labelPaddingX ?? 0) * 2, node?.width ?? 0);
22-
const h = Math.max(bbox.height + (labelPaddingY ?? 0) * 2, node?.height ?? 0);
21+
const h = Math.max(bbox.height + labelPaddingY * 2, node.height ?? 0);
22+
const w = Math.max(bbox.width + labelPaddingX * 2, (node.width ?? 0) - h);
2323

2424
const points = [
2525
{ x: 0, y: 0 },

packages/mermaid/src/rendering-util/rendering-elements/shapes/leanLeft.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export async function lean_left<T extends SVGGraphicsElement>(parent: D3Selectio
1313
const labelPaddingY = nodePadding;
1414
const labelPaddingX = node.look === 'neo' ? nodePadding * 2 : nodePadding;
1515
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
16-
const h = (node?.height ?? bbox.height) + labelPaddingY;
17-
const w = (node?.width ?? bbox.width) + labelPaddingX;
16+
const h = Math.max(bbox.height + labelPaddingY, node.height ?? 0);
17+
const w = Math.max(bbox.width + labelPaddingX, (node.width ?? 0) - h);
1818
const points = [
1919
{ x: 0, y: 0 },
2020
{ x: w + (3 * h) / 6, y: 0 },

packages/mermaid/src/rendering-util/rendering-elements/shapes/leanRight.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export async function lean_right<T extends SVGGraphicsElement>(parent: D3Selecti
1313
const labelPaddingY = nodePadding;
1414
const labelPaddingX = node.look === 'neo' ? nodePadding * 2 : nodePadding;
1515
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
16-
const h = (node?.height ?? bbox.height) + labelPaddingY;
17-
const w = (node?.width ?? bbox.width) + labelPaddingX;
16+
const h = Math.max(bbox.height + labelPaddingY, node.height ?? 0);
17+
const w = Math.max(bbox.width + labelPaddingX, (node.width ?? 0) - h);
1818

1919
const points = [
2020
{ x: (-3 * h) / 6, y: 0 },

packages/mermaid/src/rendering-util/rendering-elements/shapes/rectLeftInvArrow.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ export async function rect_left_inv_arrow<T extends SVGGraphicsElement>(
1616
const labelPaddingY = node.look === 'neo' ? 12 : (nodePadding ?? 0);
1717
const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node));
1818

19-
const w = (node?.width ?? bbox.width) + (node.look === 'neo' ? labelPaddingX * 2 : labelPaddingX);
20-
const h =
21-
(node?.height ?? bbox.height) + (node.look === 'neo' ? labelPaddingY * 2 : labelPaddingY);
19+
const labelWidth = bbox.width + (node.look === 'neo' ? labelPaddingX * 2 : labelPaddingX);
20+
const h = Math.max(
21+
bbox.height + (node.look === 'neo' ? labelPaddingY * 2 : labelPaddingY),
22+
node.height ?? 0
23+
);
24+
const notchWidth = h / 4;
25+
const w = Math.max(labelWidth, (node.width ?? 0) - notchWidth);
2226

2327
const x = -w / 2;
2428
const y = -h / 2;

packages/mermaid/src/rendering-util/rendering-elements/shapes/subroutine.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ export async function subroutine<T extends SVGGraphicsElement>(parent: D3Selecti
4646

4747
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
4848

49-
const totalWidth = (node?.width ?? bbox.width) + 2 * FRAME_WIDTH + labelPaddingX;
50-
const totalHeight = (node?.height ?? bbox.height) + labelPaddingY;
49+
const totalWidth = Math.max(bbox.width + 2 * FRAME_WIDTH + labelPaddingX, node.width ?? 0);
50+
const totalHeight = Math.max(bbox.height + labelPaddingY, node.height ?? 0);
5151

5252
const w = totalWidth - 2 * FRAME_WIDTH;
5353
const h = totalHeight;

packages/mermaid/src/rendering-util/rendering-elements/shapes/trapezoid.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export async function trapezoid<T extends SVGGraphicsElement>(parent: D3Selectio
1313
const labelPaddingY = node.look === 'neo' ? nodePadding : nodePadding;
1414
const labelPaddingX = node.look === 'neo' ? nodePadding * 2 : nodePadding;
1515
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
16-
const h = (node?.height ?? bbox.height) + labelPaddingY;
17-
const w = (node?.width ?? bbox.width) + labelPaddingX;
16+
const h = Math.max(bbox.height + labelPaddingY, node.height ?? 0);
17+
const w = Math.max(bbox.width + labelPaddingX, (node.width ?? 0) - h);
1818

1919
const points = [
2020
{ x: (-3 * h) / 6, y: 0 },

0 commit comments

Comments
 (0)