Skip to content

Commit

Permalink
Adding new-shapes and picking up node data from node data statement
Browse files Browse the repository at this point in the history
  • Loading branch information
knsv committed Jul 22, 2024
1 parent 958204e commit 4d8e519
Show file tree
Hide file tree
Showing 10 changed files with 417 additions and 7 deletions.
29 changes: 25 additions & 4 deletions packages/mermaid/src/diagrams/flowchart/flowDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,31 @@ export const addVertex = function (
}

if (shapeData !== undefined) {
console.log('HERE - shapeData: ', shapeData);
// const doc = yaml.load(shapeData);
// console.log('doc', doc);
// vertex.type = shapeData?.shape || 'roundedRect';
let yamlData;
// detect if shapeData contains a newline character

if (!shapeData.includes('\n')) {
console.log('yamlData shapeData has no new lines', shapeData);
yamlData = '{\n' + shapeData + '\n';
} else {
console.log('yamlData shapeData has new lines', shapeData);
yamlData = shapeData + '\n';
// Find the position of the last } and replace it with a newline
const lastPos = yamlData.lastIndexOf('}');
if (lastPos !== -1) {
yamlData = yamlData.substring(0, lastPos) + '\n';
}
}

console.log('yamlData', yamlData);
const doc = yaml.load(yamlData, { schema: yaml.JSON_SCHEMA });
console.log('yamlData doc', doc);
if (doc?.shape) {
vertex.type = doc?.shape;
}
if (doc?.label) {
vertex.text = doc?.label;
}
}
};

Expand Down
14 changes: 13 additions & 1 deletion packages/mermaid/src/diagrams/flowchart/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,20 @@ const getStyles = (options: FlowChartStyleOptions) =>
stroke-width: 1px;
}
.node .label {
.rough-node .label,.node .label {
text-align: center;
}
.node.clickable {
cursor: pointer;
}
.root .anchor path {
fill: ${options.lineColor} !important;
stroke-width: 0;
stroke: ${options.lineColor};
}
.arrowheadPath {
fill: ${options.arrowheadColor};
}
Expand Down Expand Up @@ -151,6 +158,11 @@ const getStyles = (options: FlowChartStyleOptions) =>
font-size: 18px;
fill: ${options.textColor};
}
rect.text {
fill: none;
stroke-width: 0;
}
`;

export default getStyles;
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import { doublecircle } from './shapes/doubleCircle.js';
import { rect_left_inv_arrow } from './shapes/rectLeftInvArrow.js';
import { question } from './shapes/question.js';
import { hexagon } from './shapes/hexagon.js';
import { text } from './shapes/text.js';
import { card } from './shapes/card.js';
import { shadedProcess } from './shapes/shadedProcess.js';
import { anchor } from './shapes/anchor.js';
import { lean_right } from './shapes/leanRight.js';
import { lean_left } from './shapes/leanLeft.js';
import { trapezoid } from './shapes/trapezoid.js';
Expand Down Expand Up @@ -47,6 +51,10 @@ const shapes = {
trapezoid,
inv_trapezoid,
labelRect,
text,
card,
shadedProcess,
anchor,
};

const nodeElems = new Map();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { log } from '$root/logger.js';
import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js';
import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
import rough from 'roughjs';

export const anchor = async (parent: SVGAElement, node: Node): Promise<SVGAElement> => {
const { labelStyles, nodeStyles } = styles2String(node);
node.labelStyle = labelStyles;
// const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, getNodeClasses(node));
const classes = getNodeClasses(node);
let cssClasses = classes;
if (!classes) {
cssClasses = 'anchor';
}
const shapeSvg = parent
.insert('g')
.attr('class', cssClasses)
.attr('id', node.domId || node.id);

const radius = 1;
let circleElem;
const { cssStyles } = node;

// if (node.look === 'handdrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, { fill: 'black', stroke: 'none', fillStyle: 'solid' });

if (node.look !== 'handdrawn') {
options.roughness = 0;
}
const roughNode = rc.circle(0, 0, radius * 2, options);

console.log('IPI roughNode:', options);

circleElem = shapeSvg.insert(() => roughNode, ':first-child');
circleElem.attr('class', 'anchor').attr('style', cssStyles);
// } else {
// circleElem = shapeSvg
// .insert('circle', ':first-child')
// .attr('class', 'basic label-container')
// .attr('style', nodeStyles)
// .attr('r', radius)
// .attr('cx', 0)
// .attr('cy', 0);
// }

updateNodeBounds(node, circleElem);

node.intersect = function (point) {
log.info('Circle intersect', node, radius, point);
return intersect.circle(node, radius, point);
};

return shapeSvg;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js';
import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
import rough from 'roughjs';

import { insertPolygonShape } from './insertPolygonShape.js';
import { createPathFromPoints } from './util.js';

// const createPathFromPoints = (points: { x: number; y: number }[]): string => {
// const pointStrings = points.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x},${p.y}`);
// pointStrings.push('Z');
// return pointStrings.join(' ');
// };

export async function card(parent: SVGAElement, node: Node): Promise<SVGAElement> {
const { labelStyles, nodeStyles } = styles2String(node);
node.labelStyle = labelStyles;
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));

const f = 4;
const h = bbox.height + node.padding;
// const m = h / f;
const m = 10;
const padding = 12;
const w = bbox.width + node.padding + padding;
const left = 0;
const right = w;
const top = -h;
const bottom = 0;
// const w = bbox.width + 2 * m + node.padding;
const points = [
{ x: left + padding, y: top },
{ x: right, y: top },
{ x: right, y: bottom },
{ x: left, y: bottom },
{ x: left, y: top + padding },
{ x: left + padding, y: top },
];

let polygon: d3.Selection<SVGPolygonElement | SVGGElement, unknown, null, undefined>;
const { cssStyles } = node;

if (node.look === 'handdrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});
const pathData = createPathFromPoints(points);
const roughNode = rc.path(pathData, options);

polygon = shapeSvg
.insert(() => roughNode, ':first-child')
.attr('transform', `translate(${-w / 2}, ${h / 2})`);

if (cssStyles) {
polygon.attr('style', cssStyles);
}
} else {
polygon = insertPolygonShape(shapeSvg, w, h, points);
}

if (nodeStyles) {
polygon.attr('style', nodeStyles);
}

updateNodeBounds(node, polygon);

node.intersect = function (point) {
return intersect.polygon(node, points, point);
};

return shapeSvg;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js';
import intersect from '../intersect/index.js';
import type { Node } from '$root/rendering-util/types.d.ts';
import {
styles2String,
userNodeOverrides,
} from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
import rough from 'roughjs';

export const createCylinderPathD = (
x: number,
y: number,
width: number,
height: number,
rx: number,
ry: number
): string => {
return [
`M${x},${y + ry}`,
`a${rx},${ry} 0,0,0 ${width},0`,
`a${rx},${ry} 0,0,0 ${-width},0`,
`l0,${height}`,
`a${rx},${ry} 0,0,0 ${width},0`,
`l0,${-height}`,
].join(' ');
};
export const createOuterCylinderPathD = (
x: number,
y: number,
width: number,
height: number,
rx: number,
ry: number
): string => {
return [
`M${x},${y + ry}`,
`M${x + width},${y + ry}`,
`a${rx},${ry} 0,0,0 ${-width},0`,
`l0,${height}`,
`a${rx},${ry} 0,0,0 ${width},0`,
`l0,${-height}`,
].join(' ');
};
export const createInnerCylinderPathD = (
x: number,
y: number,
width: number,
height: number,
rx: number,
ry: number
): string => {
return [`M${x - width / 2},${-height / 2}`, `a${rx},${ry} 0,0,0 ${width},0`].join(' ');
};
export const cylinder = async (parent: SVGAElement, node: Node) => {
const { labelStyles, nodeStyles } = styles2String(node);
node.labelStyle = labelStyles;
const { shapeSvg, bbox } = await labelHelper(parent, node, getNodeClasses(node));
const w = bbox.width + node.padding;
const rx = w / 2;
const ry = rx / (2.5 + w / 50);
const h = bbox.height + ry + node.padding;

let cylinder: d3.Selection<SVGPathElement | SVGGElement, unknown, null, undefined>;
const { cssStyles } = node;

if (node.look === 'handdrawn') {
// @ts-ignore - rough is not typed
const rc = rough.svg(shapeSvg);
const outerPathData = createOuterCylinderPathD(0, 0, w, h, rx, ry);
const innerPathData = createInnerCylinderPathD(0, ry, w, h, rx, ry);
const outerNode = rc.path(outerPathData, userNodeOverrides(node, {}));
const innerLine = rc.path(innerPathData, userNodeOverrides(node, { fill: 'none' }));

cylinder = shapeSvg.insert(() => innerLine, ':first-child');
cylinder = shapeSvg.insert(() => outerNode, ':first-child');
cylinder.attr('class', 'basic label-container');
if (cssStyles) {
cylinder.attr('style', cssStyles);
}
} else {
const pathData = createCylinderPathD(0, 0, w, h, rx, ry);
cylinder = shapeSvg
.insert('path', ':first-child')
.attr('d', pathData)
.attr('class', 'basic label-container')
.attr('style', cssStyles)
.attr('style', nodeStyles);
}

cylinder.attr('label-offset-y', ry);
cylinder.attr('transform', `translate(${-w / 2}, ${-(h / 2 + ry)})`);

updateNodeBounds(node, cylinder);

node.intersect = function (point) {
const pos = intersect.rect(node, point);
const x = pos.x - (node.x ?? 0);

if (
rx != 0 &&
(Math.abs(x) < (node.width ?? 0) / 2 ||
(Math.abs(x) == (node.width ?? 0) / 2 &&
Math.abs(pos.y - (node.y ?? 0)) > (node.height ?? 0) / 2 - ry))
) {
let y = ry * ry * (1 - (x * x) / (rx * rx));
if (y != 0) {
y = Math.sqrt(y);
}
y = ry - y;
if (point.y - (node.y ?? 0) > 0) {
y = -y;
}

pos.y += y;
}

return pos;
};

return shapeSvg;
};
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ export const drawRect = async (parent: SVGAElement, node: Node, options: RectOpt
.attr('class', 'basic label-container')
.attr('style', nodeStyles)
.attr('rx', rx)
.attr('data-id', 'abc')
.attr('data-et', 'node')
.attr('ry', ry)
.attr('x', x)
.attr('y', y)
Expand Down
Loading

0 comments on commit 4d8e519

Please sign in to comment.