mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-08 06:44:12 +01:00
Add support for new renderer
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
import type { Selection } from 'd3';
|
||||
import { select } from 'd3';
|
||||
import { select, type Selection } from 'd3';
|
||||
import { log } from '../../logger.js';
|
||||
import { getConfig } from '../../diagram-api/diagramAPI.js';
|
||||
import common from '../common/common.js';
|
||||
import utils from '../../utils.js';
|
||||
import utils, { getEdgeId } from '../../utils.js';
|
||||
import {
|
||||
setAccTitle,
|
||||
getAccTitle,
|
||||
@@ -21,12 +20,15 @@ import type {
|
||||
ClassMap,
|
||||
NamespaceMap,
|
||||
NamespaceNode,
|
||||
StyleClass,
|
||||
} from './classTypes.js';
|
||||
import type { Node, Edge } from '../../rendering-util/types.js';
|
||||
|
||||
const MERMAID_DOM_ID_PREFIX = 'classId-';
|
||||
|
||||
let relations: ClassRelation[] = [];
|
||||
let classes = new Map<string, ClassNode>();
|
||||
const styleClasses = new Map<string, StyleClass>();
|
||||
let notes: ClassNote[] = [];
|
||||
let classCounter = 0;
|
||||
let namespaces = new Map<string, NamespaceNode>();
|
||||
@@ -59,7 +61,7 @@ export const setClassLabel = function (_id: string, label: string) {
|
||||
const { className } = splitClassNameAndType(id);
|
||||
classes.get(className)!.label = label;
|
||||
classes.get(className)!.text =
|
||||
`<strong>${label}${classes.get(className)!.type ? `<${classes.get(className)!.type}>` : ''}</strong>`;
|
||||
`${label}${classes.get(className)!.type ? `<${classes.get(className)!.type}>` : ''}`;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -82,7 +84,7 @@ export const addClass = function (_id: string) {
|
||||
id: name,
|
||||
type: type,
|
||||
label: name,
|
||||
text: `<strong>${name}${type ? `<${type}>` : ''}</strong>`,
|
||||
text: `${name}${type ? `<${type}>` : ''}`,
|
||||
shape: 'classBox',
|
||||
cssClasses: [],
|
||||
methods: [],
|
||||
@@ -238,6 +240,36 @@ export const setCssClass = function (ids: string, className: string) {
|
||||
});
|
||||
};
|
||||
|
||||
export const defineClass = function (ids: string[], style: string[]) {
|
||||
for (const id of ids) {
|
||||
let styleClass = styleClasses.get(id);
|
||||
if (styleClass === undefined) {
|
||||
styleClass = { id, styles: [], textStyles: [] };
|
||||
styleClasses.set(id, styleClass);
|
||||
}
|
||||
|
||||
if (style !== undefined && style !== null) {
|
||||
style.forEach(function (s) {
|
||||
if (/color/.exec(s)) {
|
||||
const newStyle = s.replace('fill', 'bgFill'); // .replace('color', 'fill');
|
||||
styleClass.textStyles.push(newStyle);
|
||||
}
|
||||
styleClass.styles.push(s);
|
||||
});
|
||||
}
|
||||
|
||||
for (const [, value] of classes) {
|
||||
if (value.cssClasses.includes(id)) {
|
||||
for (const s of style) {
|
||||
for (const k of s.split(',')) {
|
||||
value.styles.push(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by parser when a tooltip is found, e.g. a clickable element.
|
||||
*
|
||||
@@ -476,9 +508,131 @@ export const setCssStyle = function (id: string, styles: string[]) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the arrow marker for a type index
|
||||
*
|
||||
* @param type - The type to look for
|
||||
* @returns The arrow marker
|
||||
*/
|
||||
function getArrowMarker(type: number) {
|
||||
let marker;
|
||||
switch (type) {
|
||||
case 0:
|
||||
marker = 'aggregation';
|
||||
break;
|
||||
case 1:
|
||||
marker = 'extension';
|
||||
break;
|
||||
case 2:
|
||||
marker = 'composition';
|
||||
break;
|
||||
case 3:
|
||||
marker = 'dependency';
|
||||
break;
|
||||
case 4:
|
||||
marker = 'lollipop';
|
||||
break;
|
||||
default:
|
||||
marker = 'none';
|
||||
}
|
||||
return marker;
|
||||
}
|
||||
|
||||
export const getData = () => {
|
||||
const nodes: Node[] = [];
|
||||
const edges: Edge[] = [];
|
||||
const config = getConfig();
|
||||
return { nodes: classes, edges: relations, other: {}, config, direction: getDirection() };
|
||||
|
||||
for (const namespaceKey of namespaces.keys()) {
|
||||
const namespace = namespaces.get(namespaceKey);
|
||||
if (namespace) {
|
||||
const node: Node = {
|
||||
id: namespace.id,
|
||||
label: namespace.id,
|
||||
isGroup: false,
|
||||
// parent node must be one of [rect, roundedWithTitle, noteGroup, divider]
|
||||
shape: 'rect',
|
||||
cssStyles: ['fill: none', 'stroke: black'],
|
||||
look: config.look,
|
||||
};
|
||||
nodes.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
for (const classKey of classes.keys()) {
|
||||
const classNode = classes.get(classKey);
|
||||
if (classNode) {
|
||||
const node = classNode as unknown as Node;
|
||||
node.parentId = classNode.parent;
|
||||
nodes.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
let cnt = 0;
|
||||
for (const note of notes) {
|
||||
cnt++;
|
||||
const noteNode: Node = {
|
||||
id: note.id,
|
||||
label: note.text.replaceAll('\\n', '<br>'), // 'rect' shape label sanitizes these newlines so must change to <br> manually
|
||||
isGroup: false,
|
||||
shape: 'rect',
|
||||
padding: config.class!.padding ?? 6,
|
||||
cssStyles: ['text-align: left'],
|
||||
look: config.look,
|
||||
};
|
||||
nodes.push(noteNode);
|
||||
|
||||
const noteClassId = classes.get(note.class)?.id ?? '';
|
||||
|
||||
if (noteClassId) {
|
||||
const edge: Edge = {
|
||||
id: `edgeNote${cnt}`,
|
||||
start: note.id,
|
||||
end: noteClassId,
|
||||
type: 'normal',
|
||||
thickness: 'normal',
|
||||
classes: 'relation',
|
||||
arrowTypeStart: 'none',
|
||||
arrowTypeEnd: 'none',
|
||||
arrowheadStyle: '',
|
||||
labelStyle: [''],
|
||||
style: ['fill: none'],
|
||||
pattern: 'dotted',
|
||||
look: config.look,
|
||||
};
|
||||
edges.push(edge);
|
||||
}
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
for (const relation of relations) {
|
||||
cnt++;
|
||||
const edge: Edge = {
|
||||
id: getEdgeId(relation.id1, relation.id2, {
|
||||
prefix: 'id',
|
||||
counter: cnt,
|
||||
}),
|
||||
start: relation.id1,
|
||||
end: relation.id2,
|
||||
type: 'normal',
|
||||
label: relation.title,
|
||||
labelpos: 'c',
|
||||
thickness: 'normal',
|
||||
classes: 'relation',
|
||||
arrowTypeStart: getArrowMarker(relation.relation.type1),
|
||||
arrowTypeEnd: getArrowMarker(relation.relation.type2),
|
||||
startLabelRight: relation.relationTitle1 === 'none' ? '' : relation.relationTitle1,
|
||||
endLabelLeft: relation.relationTitle2 === 'none' ? '' : relation.relationTitle2,
|
||||
arrowheadStyle: '',
|
||||
labelStyle: ['display: inline-block'],
|
||||
style: relation.style || '',
|
||||
pattern: relation.relation.lineType == 1 ? 'dashed' : 'solid',
|
||||
look: config.look,
|
||||
};
|
||||
edges.push(edge);
|
||||
}
|
||||
|
||||
return { nodes, edges, other: {}, config, direction: getDirection() };
|
||||
};
|
||||
|
||||
export default {
|
||||
@@ -506,6 +660,7 @@ export default {
|
||||
relationType,
|
||||
setClickEvent,
|
||||
setCssClass,
|
||||
defineClass,
|
||||
setLink,
|
||||
getTooltip,
|
||||
setTooltip,
|
||||
|
||||
Reference in New Issue
Block a user