Files
mermaid/packages/mermaid/src/rendering-util/rendering-elements/shapes/circle.ts
2025-08-29 12:52:01 +05:30

53 lines
1.9 KiB
TypeScript

import rough from 'roughjs';
import { log } from '../../../logger.js';
import type { Bounds, D3Selection, Point } from '../../../types.js';
import { handleUndefinedAttr } from '../../../utils.js';
import type { MindmapOptions, Node, ShapeRenderOptions } from '../../types.js';
import intersect from '../intersect/index.js';
import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
import { getNodeClasses, labelHelper, updateNodeBounds } from './util.js';
export async function circle<T extends SVGGraphicsElement>(
parent: D3Selection<T>,
node: Node,
options?: MindmapOptions | ShapeRenderOptions
) {
const { labelStyles, nodeStyles } = styles2String(node);
node.labelStyle = labelStyles;
const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, getNodeClasses(node));
const padding = options?.padding ?? halfPadding;
const radius = bbox.width / 2 + padding;
let circleElem;
const { cssStyles } = node;
if (node.look === 'handDrawn') {
// @ts-expect-error -- Passing a D3.Selection seems to work for some reason
const rc = rough.svg(shapeSvg);
const options = userNodeOverrides(node, {});
const roughNode = rc.circle(0, 0, radius * 2, options);
circleElem = shapeSvg.insert(() => roughNode, ':first-child');
circleElem.attr('class', 'basic label-container').attr('style', handleUndefinedAttr(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.calcIntersect = function (bounds: Bounds, point: Point) {
const radius = bounds.width / 2;
return intersect.circle(bounds, radius, point);
};
node.intersect = function (point) {
log.info('Circle intersect', node, radius, point);
return intersect.circle(node, radius, point);
};
return shapeSvg;
}