Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

convert diagrams/common/svgDrawCommon.js to ts #4724

Merged
58 changes: 58 additions & 0 deletions packages/mermaid/src/diagrams/common/commonTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export interface RectData {
x?: number;
y?: number;
fill?: string;
width?: number;
height?: number;
stroke?: string;
class?: string;
color?: string | number;
rx?: number;
ry?: number;
attrs?: Record<string, string | number>;
anchor?: string;
Yokozuna59 marked this conversation as resolved.
Show resolved Hide resolved
}

export interface Bound {
startx: number;
stopx: number;
starty: number;
stopy: number;
fill: string;
stroke: string;
}

export interface TextData {
x: number;
y: number;
anchor: string;
text: string;
textMargin: number;
class?: string;
}

export interface TextObject {
x: number;
y: number;
width: number;
height: number;
fill?: string;
anchor?: string;
'text-anchor': string;
style: string;
textMargin: number;
rx: number;
ry: number;
tspan: boolean;
valign: unknown;
}

export type D3RectElement = d3.Selection<SVGRectElement, unknown, Element | null, unknown>;

export type D3UseElement = d3.Selection<SVGUseElement, unknown, Element | null, unknown>;

export type D3ImageElement = d3.Selection<SVGImageElement, unknown, Element | null, unknown>;

export type D3TextElement = d3.Selection<SVGTextElement, unknown, Element | null, unknown>;

export type D3TSpanElement = d3.Selection<SVGTSpanElement, unknown, Element | null, unknown>;
Yokozuna59 marked this conversation as resolved.
Show resolved Hide resolved
110 changes: 63 additions & 47 deletions packages/mermaid/src/diagrams/common/svgDrawCommon.ts
Original file line number Diff line number Diff line change
@@ -1,89 +1,103 @@
// @ts-nocheck - ignore to convert to TS
import { sanitizeUrl } from '@braintree/sanitize-url';
import type { Group, SVG } from '../../diagram-api/types.js';
import type {
Bound,
D3ImageElement,
D3RectElement,
D3TSpanElement,
D3TextElement,
D3UseElement,
RectData,
TextData,
TextObject,
} from './commonTypes.js';

export const drawRect = function (elem, rectData) {
const rectElem = elem.append('rect');
rectElem.attr('x', rectData.x);
rectElem.attr('y', rectData.y);
rectElem.attr('fill', rectData.fill);
rectElem.attr('stroke', rectData.stroke);
rectElem.attr('width', rectData.width);
rectElem.attr('height', rectData.height);
rectElem.attr('rx', rectData.rx);
rectElem.attr('ry', rectData.ry);
export const drawRect = (element: SVG | Group, rectData: RectData): D3RectElement => {
const rectElement: D3RectElement = element.append('rect');
rectData.x !== undefined && rectElement.attr('x', rectData.x);
rectData.y !== undefined && rectElement.attr('y', rectData.y);
rectData.fill !== undefined && rectElement.attr('fill', rectData.fill);
rectData.stroke !== undefined && rectElement.attr('stroke', rectData.stroke);
rectData.width !== undefined && rectElement.attr('width', rectData.width);
rectData.height !== undefined && rectElement.attr('height', rectData.height);
rectData.rx !== undefined && rectElement.attr('rx', rectData.rx);
rectData.ry !== undefined && rectElement.attr('ry', rectData.ry);

if (rectData.attrs !== 'undefined' && rectData.attrs !== null) {
if (rectData.attrs !== undefined && rectData.attrs !== null) {
for (const attrKey in rectData.attrs) {
rectElem.attr(attrKey, rectData.attrs[attrKey]);
rectElement.attr(attrKey, rectData.attrs[attrKey]);
}
}

if (rectData.class !== 'undefined') {
rectElem.attr('class', rectData.class);
if (rectData.class !== undefined) {
Yokozuna59 marked this conversation as resolved.
Show resolved Hide resolved
rectElement.attr('class', rectData.class);
}

return rectElem;
return rectElement;
};

/**
* Draws a background rectangle
*
* @param elem - Diagram (reference for bounds)
* @param element - Diagram (reference for bounds)
* @param bounds - Shape of the rectangle
*/
export const drawBackgroundRect = function (elem, bounds) {
const rectElem = drawRect(elem, {
export const drawBackgroundRect = (element: SVG | Group, bounds: Bound): void => {
const rectData: RectData = {
x: bounds.startx,
y: bounds.starty,
width: bounds.stopx - bounds.startx,
height: bounds.stopy - bounds.starty,
fill: bounds.fill,
stroke: bounds.stroke,
class: 'rect',
});
rectElem.lower();
};
const rectElement: D3RectElement = drawRect(element, rectData);
rectElement.lower();
};

export const drawText = function (elem, textData) {
export const drawText = (element: SVG | Group, textData: TextData): D3TextElement => {
// Remove and ignore br:s
const nText = textData.text.replace(/<br\s*\/?>/gi, ' ');
const nText: string = textData.text.replace(/<br\s*\/?>/gi, ' ');

const textElem = elem.append('text');
const textElem: D3TextElement = element.append('text');
textElem.attr('x', textData.x);
textElem.attr('y', textData.y);
textElem.attr('class', 'legend');

textElem.style('text-anchor', textData.anchor);
textData.class !== undefined && textElem.attr('class', textData.class);

if (textData.class !== undefined) {
textElem.attr('class', textData.class);
}

const span = textElem.append('tspan');
span.attr('x', textData.x + textData.textMargin * 2);
span.text(nText);
const tspan: D3TSpanElement = textElem.append('tspan');
tspan.attr('x', textData.x + textData.textMargin * 2);
tspan.text(nText);

return textElem;
};

export const drawImage = function (elem, x, y, link) {
const imageElem = elem.append('image');
imageElem.attr('x', x);
imageElem.attr('y', y);
const sanitizedLink = sanitizeUrl(link);
imageElem.attr('xlink:href', sanitizedLink);
export const drawImage = (elem: SVG | Group, x: number, y: number, link: string): void => {
const imageElement: D3ImageElement = elem.append('image');
imageElement.attr('x', x);
imageElement.attr('y', y);
const sanitizedLink: string = sanitizeUrl(link);
imageElement.attr('xlink:href', sanitizedLink);
};

export const drawEmbeddedImage = function (elem, x, y, link) {
const imageElem = elem.append('use');
imageElem.attr('x', x);
imageElem.attr('y', y);
const sanitizedLink = sanitizeUrl(link);
imageElem.attr('xlink:href', '#' + sanitizedLink);
export const drawEmbeddedImage = (
element: SVG | Group,
x: number,
y: number,
link: string
): void => {
const imageElement: D3UseElement = element.append('use');
imageElement.attr('x', x);
imageElement.attr('y', y);
const sanitizedLink: string = sanitizeUrl(link);
imageElement.attr('xlink:href', `#${sanitizedLink}`);
};

export const getNoteRect = function () {
return {
export const getNoteRect = (): RectData => {
const noteRectData: RectData = {
x: 0,
y: 0,
width: 100,
Expand All @@ -94,10 +108,11 @@ export const getNoteRect = function () {
rx: 0,
ry: 0,
};
return noteRectData;
};

export const getTextObj = function () {
return {
export const getTextObj = (): TextObject => {
const testObject: TextObject = {
x: 0,
y: 0,
width: 100,
Expand All @@ -112,4 +127,5 @@ export const getTextObj = function () {
tspan: true,
valign: undefined,
};
return testObject;
};