Merge branch 'knsv/new-shapes' of https://github.com/mermaid-js/mermaid into knsv/new-shapes

This commit is contained in:
saurabhg772244
2024-08-27 16:01:02 +05:30
3 changed files with 94 additions and 90 deletions

View File

@@ -40,7 +40,28 @@ const newShapesSet5 = [
'card', 'card',
'shadedProcess', 'shadedProcess',
] as const; ] as const;
const newShapesSet6 = ['curlyBraces'];
const newShapesSet6 = ['roundedRect', 'squareRect', 'stateStart', 'stateEnd', 'labelRect'] as const;
const newShapesSet7 = ['forkJoin', 'choice', 'note', 'stadium'] as const;
const newShapesSet8 = [
'question',
'hexagon',
'curlyBraces',
'multiRect',
'waveEdgedRectangle',
] as const;
const newShapesSet9 = ['anchor', 'lean_right', 'lean_left', 'trapezoid', 'inv_trapezoid'] as const;
const newShapesSet10 = [
'subroutine',
'cylinder',
'circle',
'doublecircle',
'rect_left_inv_arrow',
] as const;
// Aggregate all shape sets into a single array // Aggregate all shape sets into a single array
const newShapesSets = [ const newShapesSets = [
@@ -50,6 +71,10 @@ const newShapesSets = [
newShapesSet4, newShapesSet4,
newShapesSet5, newShapesSet5,
newShapesSet6, newShapesSet6,
newShapesSet7,
newShapesSet8,
newShapesSet9,
newShapesSet10,
] as const; ] as const;
looks.forEach((look) => { looks.forEach((look) => {
@@ -67,7 +92,7 @@ looks.forEach((look) => {
it(`with label`, () => { it(`with label`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a label' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }@\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -75,7 +100,7 @@ looks.forEach((look) => {
it(`connect all shapes with each other`, () => { it(`connect all shapes with each other`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index}${index}@{ shape: ${newShape}, label: 'This is a label' }@\n`; flowchartCode += ` n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }@\n`;
}); });
for (let i = 0; i < newShapesSet.length; i++) { for (let i = 0; i < newShapesSet.length; i++) {
for (let j = i + 1; j < newShapesSet.length; j++) { for (let j = i + 1; j < newShapesSet.length; j++) {
@@ -88,7 +113,7 @@ looks.forEach((look) => {
it(`with very long label`, () => { it(`with very long label`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a very very very very very long long long label' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a very very very very very long long long label for ${newShape} shape' }@\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -96,7 +121,7 @@ looks.forEach((look) => {
it(`with markdown htmlLabels:true`, () => { it(`with markdown htmlLabels:true`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong>' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }@\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
}); });
@@ -104,7 +129,7 @@ looks.forEach((look) => {
it(`with markdown htmlLabels:false`, () => { it(`with markdown htmlLabels:false`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong>' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** </br>and <strong>strong</strong> for ${newShape} shape' }@\n`;
}); });
imgSnapshotTest(flowchartCode, { imgSnapshotTest(flowchartCode, {
look, look,
@@ -116,7 +141,7 @@ looks.forEach((look) => {
it(`with styles`, () => { it(`with styles`, () => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }@\n`;
flowchartCode += ` style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`; flowchartCode += ` style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });
@@ -126,7 +151,7 @@ looks.forEach((look) => {
let flowchartCode = `flowchart ${direction}\n`; let flowchartCode = `flowchart ${direction}\n`;
flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`; flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`;
newShapesSet.forEach((newShape, index) => { newShapesSet.forEach((newShape, index) => {
flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new shape' }@\n`; flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }@\n`;
flowchartCode += ` n${index}${index}:::customClazz\n`; flowchartCode += ` n${index}${index}:::customClazz\n`;
}); });
imgSnapshotTest(flowchartCode, { look }); imgSnapshotTest(flowchartCode, { look });

View File

@@ -3,20 +3,17 @@ import type { Node } from '$root/rendering-util/types.d.ts';
import type { SVG } from '$root/diagram-api/types.js'; import type { SVG } from '$root/diagram-api/types.js';
// @ts-ignore TODO: Fix rough typings // @ts-ignore TODO: Fix rough typings
import rough from 'roughjs'; import rough from 'roughjs';
import { solidStateFill, styles2String } from './handDrawnShapeStyles.js'; import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
import { getConfig } from '$root/diagram-api/diagramAPI.js'; import { createPathFromPoints, getNodeClasses, labelHelper } from './util.js';
export const choice = (parent: SVG, node: Node) => { export const choice = async (parent: SVG, node: Node) => {
const { labelStyles, nodeStyles } = styles2String(node); const { nodeStyles } = styles2String(node);
node.labelStyle = labelStyles; node.label = '';
const { themeVariables } = getConfig(); const { shapeSvg } = await labelHelper(parent, node, getNodeClasses(node));
const { lineColor } = themeVariables; const { cssStyles } = node;
const shapeSvg = parent
.insert('g') const s = Math.max(28, node.width ?? 0);
.attr('class', 'node default')
.attr('id', node.domId || node.id);
const s = 28;
const points = [ const points = [
{ x: 0, y: s / 2 }, { x: 0, y: s / 2 },
{ x: s / 2, y: 0 }, { x: s / 2, y: 0 },
@@ -24,40 +21,34 @@ export const choice = (parent: SVG, node: Node) => {
{ x: -s / 2, y: 0 }, { x: -s / 2, y: 0 },
]; ];
let choice; // @ts-ignore TODO: Fix rough typings
if (node.look === 'handDrawn') { const rc = rough.svg(shapeSvg);
// @ts-ignore TODO: Fix rough typings const options = userNodeOverrides(node, {});
const rc = rough.svg(shapeSvg);
const pointArr = points.map(function (d) { if (node.look !== 'handDrawn') {
return [d.x, d.y]; options.roughness = 0;
}); options.fillStyle = 'solid';
const roughNode = rc.polygon(pointArr, solidStateFill(lineColor));
choice = shapeSvg.insert(() => roughNode);
} else {
choice = shapeSvg.insert('polygon', ':first-child').attr(
'points',
points
.map(function (d) {
return d.x + ',' + d.y;
})
.join(' ')
);
} }
// center the circle around its coordinate const choicePath = createPathFromPoints(points);
choice const roughNode = rc.path(choicePath, options);
.attr('class', 'state-start') const choiceShape = shapeSvg.insert(() => roughNode, ':first-child');
// @ts-ignore TODO: Fix rough typings
.attr('r', 7) choiceShape.attr('class', 'basic label-container');
.attr('width', 28)
.attr('height', 28) if (cssStyles && node.look !== 'handDrawn') {
.attr('style', nodeStyles); choiceShape.selectAll('path').attr('style', cssStyles);
}
if (nodeStyles && node.look !== 'handDrawn') {
choiceShape.selectAll('path').attr('style', nodeStyles);
}
node.width = 28; node.width = 28;
node.height = 28; node.height = 28;
node.intersect = function (point) { node.intersect = function (point) {
return intersect.circle(node, 14, point); return intersect.polygon(node, points, point);
}; };
return shapeSvg; return shapeSvg;

View File

@@ -1,62 +1,50 @@
import { updateNodeBounds } from './util.js'; import { getNodeClasses, labelHelper, updateNodeBounds } from './util.js';
import intersect from '../intersect/index.js'; import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts'; import type { Node } from '$root/rendering-util/types.d.ts';
import type { SVG } from '$root/diagram-api/types.js'; import type { SVG } from '$root/diagram-api/types.js';
import rough from 'roughjs'; import rough from 'roughjs';
import { solidStateFill } from './handDrawnShapeStyles.js'; import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
import { getConfig } from '$root/diagram-api/diagramAPI.js';
export const forkJoin = (parent: SVG, node: Node, dir: string) => { export const forkJoin = async (parent: SVG, node: Node, dir: string) => {
const { themeVariables } = getConfig(); const { nodeStyles } = styles2String(node);
const { lineColor } = themeVariables; node.label = '';
const shapeSvg = parent const { shapeSvg } = await labelHelper(parent, node, getNodeClasses(node));
.insert('g')
.attr('class', 'node default')
.attr('id', node.domId || node.id);
let width = 70; const { cssStyles } = node;
let height = 10; let width = Math.max(70, node?.width ?? 0);
let height = Math.max(10, node?.height ?? 0);
if (dir === 'LR') { if (dir === 'LR') {
width = 10; width = Math.max(10, node?.width ?? 0);
height = 70; height = Math.max(70, node?.height ?? 0);
} }
const x = (-1 * width) / 2; const x = (-1 * width) / 2;
const y = (-1 * height) / 2; const y = (-1 * height) / 2;
let shape; // @ts-ignore TODO: Fix rough typings
if (node.look === 'handDrawn') { const rc = rough.svg(shapeSvg);
// @ts-ignore TODO: Fix rough typings const options = userNodeOverrides(node, {});
const rc = rough.svg(shapeSvg);
const roughNode = rc.rectangle(x, y, width, height, solidStateFill(lineColor)); if (node.look !== 'handDrawn') {
shape = shapeSvg.insert(() => roughNode); options.roughness = 0;
} else { options.fillStyle = 'solid';
shape = shapeSvg }
.append('rect')
.attr('x', x) const roughNode = rc.rectangle(x, y, width, height, options);
.attr('y', y)
.attr('width', width) const shape = shapeSvg.insert(() => roughNode, ':first-child');
.attr('height', height)
.attr('class', 'fork-join'); if (cssStyles && node.look !== 'handDrawn') {
shape.selectAll('path').attr('style', cssStyles);
}
if (nodeStyles && node.look !== 'handDrawn') {
shape.selectAll('path').attr('style', nodeStyles);
} }
updateNodeBounds(node, shape); updateNodeBounds(node, shape);
let nodeHeight = 0;
let nodeWidth = 0;
let nodePadding = 10;
if (node.height) {
nodeHeight = node.height;
}
if (node.width) {
nodeWidth = node.width;
}
if (node.padding) {
nodePadding = node.padding;
}
node.height = nodeHeight + nodePadding / 2;
node.width = nodeWidth + nodePadding / 2;
node.intersect = function (point) { node.intersect = function (point) {
return intersect.rect(node, point); return intersect.rect(node, point);
}; };