mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-06 15:49:44 +02:00
MC-1730 Latest fixes from mermaid
This commit is contained in:
@@ -109,7 +109,7 @@ export const openURLAndVerifyRendering = (
|
||||
}
|
||||
|
||||
cy.visit(url);
|
||||
cy.window().should('have.property', 'rendered', true);
|
||||
// cy.window().should('have.property', 'rendered', true);
|
||||
cy.get('svg').should('be.visible');
|
||||
|
||||
if (validation) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,181 +1,191 @@
|
||||
<html>
|
||||
<head>
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
||||
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
|
||||
/>
|
||||
<link
|
||||
href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Caveat:wght@400..700&family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<head>
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
||||
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap" rel="stylesheet" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Caveat:wght@400..700&family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap"
|
||||
rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&family=Rubik+Mono+One&display=swap"
|
||||
rel="stylesheet" />
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Arial';
|
||||
}
|
||||
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Arial';
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
}
|
||||
th,
|
||||
td {
|
||||
border: 1px solid black;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid black;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.separator {
|
||||
height: 20px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.separator {
|
||||
height: 20px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
.vertical-header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.vertical-header {
|
||||
text-align: center;
|
||||
}
|
||||
.collapsible {
|
||||
background-color: #f9f9f9;
|
||||
color: #444;
|
||||
cursor: pointer;
|
||||
padding: 18px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
text-align: left;
|
||||
outline: none;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.collapsible {
|
||||
background-color: #f9f9f9;
|
||||
color: #444;
|
||||
cursor: pointer;
|
||||
padding: 18px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
text-align: left;
|
||||
outline: none;
|
||||
font-size: 15px;
|
||||
}
|
||||
.active,
|
||||
.collapsible:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.active,
|
||||
.collapsible:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
.collapsible:after {
|
||||
content: '\002B';
|
||||
color: #777;
|
||||
font-weight: bold;
|
||||
float: right;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.collapsible:after {
|
||||
content: '\002B';
|
||||
color: #777;
|
||||
font-weight: bold;
|
||||
float: right;
|
||||
margin-left: 2px;
|
||||
}
|
||||
.active:after {
|
||||
content: '\2212';
|
||||
}
|
||||
|
||||
.active:after {
|
||||
content: "\2212";
|
||||
}
|
||||
.content {
|
||||
padding: 0 5px;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.2s ease-out;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 5px;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.2s ease-out;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
.content .pre-scrollable {
|
||||
max-height: 200px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
.content .pre-scrollable {
|
||||
max-height: 200px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table>
|
||||
<tr>
|
||||
<th></th> <!-- Placeholder for the top left corner -->
|
||||
<th>State rough</th>
|
||||
<th>Flowchart rough</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Stadium shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
<body>
|
||||
<table>
|
||||
<tr>
|
||||
<th></th>
|
||||
<!-- Placeholder for the top left corner -->
|
||||
<th>State rough</th>
|
||||
<th>Flowchart rough</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="vertical-header">
|
||||
<button class="collapsible">Stadium shape</button>
|
||||
<div class="content">
|
||||
<div class="pre-scrollable">
|
||||
<pre>
|
||||
flowchart LR
|
||||
id1([This is the text in the box])
|
||||
|
||||
</pre>
|
||||
</pre
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram1" class="mermaid">
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram1" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
stateDiagram-v2
|
||||
stateA
|
||||
|
||||
</pre>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram2" class="mermaid">
|
||||
</pre
|
||||
>
|
||||
</td>
|
||||
<td>
|
||||
<pre id="diagram2" class="mermaid">
|
||||
%%{init: {"look": "handdrawn"} }%%
|
||||
flowchart LR
|
||||
id1[[This is the text in the box]]
|
||||
|
||||
|
||||
</pre>
|
||||
</td>
|
||||
</pre
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</tr>
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
import { layouts } from './mermaid-layout-elk.esm.mjs';
|
||||
mermaid.registerLayoutLoaders(layouts);
|
||||
mermaid.parseError = function (err, hash) {};
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<script type="module">
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
import { layouts } from './mermaid-layout-elk.esm.mjs';
|
||||
mermaid.registerLayoutLoaders(layouts);
|
||||
mermaid.parseError = function (err, hash) {
|
||||
|
||||
};
|
||||
|
||||
mermaid.initialize({
|
||||
handdrawn: false,
|
||||
mergeEdges: true,
|
||||
layout: 'dagre',
|
||||
flowchart: { titleTopMargin: 10 },
|
||||
// fontFamily: 'Caveat',
|
||||
fontFamily: 'Kalam',
|
||||
sequence: {
|
||||
actorFontFamily: 'courier',
|
||||
noteFontFamily: 'courier',
|
||||
messageFontFamily: 'courier',
|
||||
},
|
||||
fontSize: 16,
|
||||
logLevel: 0,
|
||||
});
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
mermaid.parseError = function (err, hash) {
|
||||
console.error('In parse error:');
|
||||
console.error(err);
|
||||
};
|
||||
|
||||
|
||||
let coll = document.getElementsByClassName("collapsible");
|
||||
for (const element of coll) {
|
||||
element.addEventListener("click", function () {
|
||||
this.classList.toggle("active");
|
||||
let content = this.nextElementSibling;
|
||||
if (content.style.maxHeight) {
|
||||
content.style.maxHeight = null;
|
||||
} else {
|
||||
content.style.maxHeight = content.scrollHeight + "px";
|
||||
}
|
||||
mermaid.initialize({
|
||||
handdrawn: false,
|
||||
mergeEdges: true,
|
||||
layout: 'dagre',
|
||||
flowchart: { titleTopMargin: 10 },
|
||||
// fontFamily: 'Caveat',
|
||||
fontFamily: 'Kalam',
|
||||
sequence: {
|
||||
actorFontFamily: 'courier',
|
||||
noteFontFamily: 'courier',
|
||||
messageFontFamily: 'courier',
|
||||
},
|
||||
fontSize: 16,
|
||||
logLevel: 0,
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
function callback() {
|
||||
alert('It worked');
|
||||
}
|
||||
mermaid.parseError = function (err, hash) {
|
||||
console.error('In parse error:');
|
||||
console.error(err);
|
||||
};
|
||||
|
||||
let coll = document.getElementsByClassName('collapsible');
|
||||
for (const element of coll) {
|
||||
element.addEventListener('click', function () {
|
||||
this.classList.toggle('active');
|
||||
let content = this.nextElementSibling;
|
||||
if (content.style.maxHeight) {
|
||||
content.style.maxHeight = null;
|
||||
} else {
|
||||
content.style.maxHeight = content.scrollHeight + 'px';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -184,7 +184,7 @@ Apa --> C
|
||||
A --> B & C["C"]
|
||||
</pre
|
||||
>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
<pre id="diagram" class="mermaid">
|
||||
stateDiagram
|
||||
direction LR
|
||||
state Gorilla0 {
|
||||
@@ -195,6 +195,7 @@ direction LR
|
||||
}
|
||||
Apa0 --> C0
|
||||
A0 --> C0
|
||||
C1: "`This is C`"
|
||||
</pre
|
||||
>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
@@ -206,6 +207,7 @@ flowchart LR
|
||||
end
|
||||
Apa --- C
|
||||
A --x C
|
||||
</pre>
|
||||
|
||||
<pre id="diagram" class="mermaid2">
|
||||
---
|
||||
@@ -235,14 +237,9 @@ stateDiagram
|
||||
|
||||
</pre
|
||||
>
|
||||
<pre id="diagram" class="mermaid2">
|
||||
<pre id="diagram" class="mermaid">
|
||||
flowchart LR
|
||||
subgraph Apa["Apa"]
|
||||
A["Start"]
|
||||
B["This is B"]
|
||||
end
|
||||
A --> B & C["C"]
|
||||
Apa --> C
|
||||
Apa --Hello--> C
|
||||
|
||||
</pre
|
||||
>
|
||||
|
@@ -106,6 +106,7 @@
|
||||
stateId
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<td>
|
||||
<pre id="diagram1" class="mermaid">
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import mermaid from './mermaid.esm.mjs';
|
||||
import flowchartELK from './mermaid-flowchart-elk.esm.mjs';
|
||||
// import flowchartELK from './mermaid-flowchart-elk.esm.mjs';
|
||||
import externalExample from './mermaid-example-diagram.esm.mjs';
|
||||
import zenUml from './mermaid-zenuml.esm.mjs';
|
||||
|
||||
@@ -9,6 +9,7 @@ function b64ToUtf8(str) {
|
||||
|
||||
// Adds a rendered flag to window when rendering is done, so cypress can wait for it.
|
||||
function markRendered() {
|
||||
console.log('Done rendering');
|
||||
if (window.Cypress) {
|
||||
window.rendered = true;
|
||||
}
|
||||
@@ -46,7 +47,8 @@ const contentLoaded = async function () {
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
|
||||
await mermaid.registerExternalDiagrams([externalExample, zenUml, flowchartELK]);
|
||||
// await mermaid.registerExternalDiagrams([externalExample, zenUml, flowchartELK]);
|
||||
await mermaid.registerExternalDiagrams([externalExample, zenUml]);
|
||||
mermaid.initialize(graphObj.mermaid);
|
||||
await mermaid.run();
|
||||
}
|
||||
|
13
package.json
13
package.json
@@ -25,8 +25,8 @@
|
||||
"dev:vite": "tsx .vite/server.ts",
|
||||
"dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev:vite",
|
||||
"release": "pnpm build",
|
||||
"lint": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content . && pnpm lint:jison && prettier --cache --check .",
|
||||
"lint:fix": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content --fix . && prettier --write . && tsx scripts/fixCSpell.ts",
|
||||
"lint": "cross-env NODE_OPTIONS=--max_old_space_size=48192 eslint --cache --cache-strategy content . && pnpm lint:jison && prettier --cache --check .",
|
||||
"lint:fix": "cross-env NODE_OPTIONS=--max_old_space_size=48192 eslint --cache --cache-strategy content --fix . && prettier --write . && tsx scripts/fixCSpell.ts",
|
||||
"lint:jison": "tsx ./scripts/jison/lint.mts",
|
||||
"contributors": "tsx scripts/updateContributors.ts",
|
||||
"cypress": "cypress run",
|
||||
@@ -61,7 +61,7 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@applitools/eyes-cypress": "^3.42.3",
|
||||
"@applitools/eyes-cypress": "^3.44.4",
|
||||
"@cspell/eslint-plugin": "^8.6.0",
|
||||
"@cypress/code-coverage": "^3.12.30",
|
||||
"@rollup/plugin-typescript": "^11.1.6",
|
||||
@@ -85,7 +85,7 @@
|
||||
"cors": "^2.8.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"cspell": "^8.6.0",
|
||||
"cypress": "^13.7.1",
|
||||
"cypress": "^13.11.0",
|
||||
"cypress-image-snapshot": "^4.0.1",
|
||||
"esbuild": "^0.20.2",
|
||||
"eslint": "^8.57.0",
|
||||
@@ -126,10 +126,5 @@
|
||||
},
|
||||
"nyc": {
|
||||
"report-dir": "coverage/cypress"
|
||||
},
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"cytoscape@3.28.1": "patches/cytoscape@3.28.1.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -725,6 +725,8 @@ export interface StateDiagramConfig extends BaseDiagramConfig {
|
||||
textHeight?: number;
|
||||
titleShift?: number;
|
||||
noteMargin?: number;
|
||||
nodeSpacing?: number;
|
||||
rankSpacing?: number;
|
||||
forkWidth?: number;
|
||||
forkHeight?: number;
|
||||
miniPadding?: number;
|
||||
|
@@ -26,7 +26,7 @@ const detector: DiagramDetector = (txt, config): boolean => {
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// @ts-ignore - TODO: Fix after refactor
|
||||
const loader: DiagramLoader = async () => {
|
||||
const { diagram } = await import('../flowDiagram-v2.js');
|
||||
return { id, diagram };
|
||||
|
@@ -852,7 +852,7 @@ export const getData = () => {
|
||||
|
||||
const n = getVertices();
|
||||
n.forEach((vertex) => {
|
||||
const node = addNodeFromVertex(vertex, nodes, parentDB, subGraphDB, config, config.look);
|
||||
addNodeFromVertex(vertex, nodes, parentDB, subGraphDB, config, config.look || 'classic');
|
||||
});
|
||||
|
||||
const e = getEdges();
|
||||
@@ -874,7 +874,6 @@ export const getData = () => {
|
||||
pattern: rawEdge.stroke,
|
||||
look: config.look,
|
||||
};
|
||||
console.log('rawEdge SPLIT', rawEdge, index);
|
||||
edges.push(edge);
|
||||
});
|
||||
|
||||
|
@@ -18,6 +18,7 @@ const detector: DiagramDetector = (txt, config) => {
|
||||
return /^\s*flowchart/.test(txt);
|
||||
};
|
||||
|
||||
// @ts-ignore - TODO: Fix after refactor
|
||||
const loader: DiagramLoader = async () => {
|
||||
const { diagram } = await import('./flowDiagram-v2.js');
|
||||
return { id, diagram };
|
||||
|
@@ -2,7 +2,7 @@
|
||||
import flowParser from './parser/flow.jison';
|
||||
import flowDb from './flowDb.js';
|
||||
import flowRendererV2 from './flowRenderer-v2.js';
|
||||
import flowRendererV3 from './flowRenderer-v3-unified.js';
|
||||
// import flowRendererV3 from './flowRenderer-v3-unified.js';
|
||||
import flowStyles from './styles.js';
|
||||
import type { MermaidConfig } from '../../config.type.js';
|
||||
import { setConfig } from '../../diagram-api/diagramAPI.js';
|
||||
@@ -10,8 +10,8 @@ import { setConfig } from '../../diagram-api/diagramAPI.js';
|
||||
export const diagram = {
|
||||
parser: flowParser,
|
||||
db: flowDb,
|
||||
// renderer: flowRendererV2,
|
||||
renderer: flowRendererV3,
|
||||
renderer: flowRendererV2,
|
||||
// renderer: flowRendererV3,
|
||||
styles: flowStyles,
|
||||
init: (cnf: MermaidConfig) => {
|
||||
if (!cnf.flowchart) {
|
||||
@@ -20,7 +20,8 @@ export const diagram = {
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
// flowchart-v2 uses dagre-wrapper, which doesn't have access to flowchart cnf
|
||||
setConfig({ flowchart: { arrowMarkerAbsolute: cnf.arrowMarkerAbsolute } });
|
||||
flowRendererV3.setConf(cnf.flowchart);
|
||||
flowRendererV2.setConf(cnf.flowchart);
|
||||
// flowRendererV3.setConf(cnf.flowchart);
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
},
|
||||
|
@@ -324,7 +324,7 @@ export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, alt
|
||||
domId: stateDomId(itemId, graphItemCount, NOTE),
|
||||
type: newNode.type,
|
||||
isGroup: newNode.type === 'group',
|
||||
padding: 0, //getConfig().flowchart.padding
|
||||
padding: getConfig().flowchart.padding,
|
||||
look,
|
||||
position: parsedItem.note.position,
|
||||
};
|
||||
|
@@ -231,6 +231,14 @@ const extract = (_doc) => {
|
||||
const look = config.look;
|
||||
resetDataFetching();
|
||||
dataFetcher(undefined, getRootDocV2(), diagramStates, nodes, edges, true, look);
|
||||
nodes.forEach((node) => {
|
||||
if (Array.isArray(node.label)) {
|
||||
// add the rest as description
|
||||
node.description = node.label.slice(1);
|
||||
// add first description as label
|
||||
node.label = node.label[0];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -76,9 +76,8 @@ export const draw = async function (
|
||||
data4Layout.direction = DIR;
|
||||
|
||||
// TODO: Should we move these two to baseConfig? These types are not there in StateConfig.
|
||||
// @ts-expect-error TODO: Will be fixed after config refactor
|
||||
|
||||
data4Layout.nodeSpacing = conf?.nodeSpacing || 50;
|
||||
// @ts-expect-error TODO: Will be fixed after config refactor
|
||||
data4Layout.rankSpacing = conf?.rankSpacing || 50;
|
||||
const config = getConfig();
|
||||
if (config.look === 'neo') {
|
||||
|
@@ -183,22 +183,11 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
const halfPadding = node?.padding / 2 || 0;
|
||||
const labelHeight = node?.labelBBox?.height || 0;
|
||||
const offsetY = labelHeight - halfPadding || 0;
|
||||
node.y += offsetY + (parent?.offsetY / 2 || 0);
|
||||
// node.y += offsetY + (parent?.offsetY / 2 || 0);
|
||||
// node.offsetY = offsetY;
|
||||
insertCluster(clusters, node);
|
||||
|
||||
// A cluster in the non-recursive way
|
||||
console.log(
|
||||
'A tainted cluster node with children XBX',
|
||||
v,
|
||||
node.id,
|
||||
node.width,
|
||||
node.height,
|
||||
node.x,
|
||||
node.y,
|
||||
'offset',
|
||||
parent?.offsetY
|
||||
);
|
||||
clusterDb[node.id].node = node;
|
||||
} else {
|
||||
const parent = graph.node(node.parentId);
|
||||
@@ -244,7 +233,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
||||
diff = n.diff;
|
||||
}
|
||||
});
|
||||
log.trace('Returning from recursive render XAX', elem, diff);
|
||||
log.warn('Returning from recursive render XAX', elem, diff);
|
||||
return { elem, diff };
|
||||
};
|
||||
/**
|
||||
|
@@ -287,7 +287,7 @@ const roundedWithTitle = (parent, node) => {
|
||||
const rectBox = rect.node().getBBox();
|
||||
node.height = rectBox.height;
|
||||
node.offsetX = 0;
|
||||
// Used by payout engone to position subgraph in parent
|
||||
// Used by layout engine to position subgraph in parent
|
||||
node.offsetY = bbox.height - node.padding / 2;
|
||||
node.labelBBox = bbox;
|
||||
|
||||
|
@@ -8,6 +8,7 @@ import { forkJoin } from './shapes/forkJoin.ts';
|
||||
import { choice } from './shapes/choice.ts';
|
||||
import { note } from './shapes/note.ts';
|
||||
import { stadium } from './shapes/stadium.js';
|
||||
import { rectWithTitle } from './shapes/rectWithTitle.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import { subroutine } from './shapes/subroutine.js';
|
||||
import { cylinder } from './shapes/cylinder.js';
|
||||
@@ -36,7 +37,7 @@ const shapes = {
|
||||
choice,
|
||||
note,
|
||||
roundedRect,
|
||||
rectWithTitle: roundedRect,
|
||||
rectWithTitle,
|
||||
squareRect,
|
||||
stadium,
|
||||
subroutine,
|
||||
@@ -117,8 +118,8 @@ export const positionNode = (node) => {
|
||||
node,
|
||||
'translate(' + (node.x - node.width / 2 - 5) + ', ' + node.width / 2 + ')'
|
||||
);
|
||||
|
||||
const diff = 0;
|
||||
// Handling of the case where teh label grows the cluster
|
||||
const diff = node.diff || 0;
|
||||
if (node.clusterNode) {
|
||||
el.attr(
|
||||
'transform',
|
||||
|
@@ -25,8 +25,8 @@ export const note = async (parent: SVGAElement, node: Node) => {
|
||||
let rect;
|
||||
const totalWidth = bbox.width + node.padding;
|
||||
const totalHeight = bbox.height + node.padding;
|
||||
const x = -bbox.width / 2 - halfPadding;
|
||||
const y = -bbox.height / 2 - halfPadding;
|
||||
const x = -totalWidth / 2;
|
||||
const y = -totalHeight / 2;
|
||||
|
||||
if (node.look === 'handdrawn') {
|
||||
// add the rect
|
||||
|
@@ -1,12 +1,146 @@
|
||||
import type { Node, RectOptions } from '$root/rendering-util/types.d.ts';
|
||||
import { drawRect } from './drawRect.js';
|
||||
import { select } from 'd3';
|
||||
import { evaluate } from '$root/diagrams/common/common.js';
|
||||
import { labelHelper, updateNodeBounds, getNodeClasses } from './util.js';
|
||||
import createLabel from '../createLabel.js';
|
||||
import intersect from '../intersect/index.js';
|
||||
import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
|
||||
import rough from 'roughjs';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
import { createRoundedRectPathD } from './roundedRectPath.js';
|
||||
import { log } from '$root/logger.js';
|
||||
|
||||
export const roundedRect = async (parent: SVGAElement, node: Node) => {
|
||||
const options = {
|
||||
rx: 5,
|
||||
ry: 5,
|
||||
classes: '',
|
||||
} as RectOptions;
|
||||
export const rectWithTitle = async (parent: SVGElement, node: Node) => {
|
||||
let classes;
|
||||
if (!node.cssClasses) {
|
||||
classes = 'node default';
|
||||
} else {
|
||||
classes = 'node ' + node.cssClasses;
|
||||
}
|
||||
|
||||
return drawRect(parent, node, options);
|
||||
// Add outer g element
|
||||
const shapeSvg = parent
|
||||
// @ts-ignore - d3 typings are not correct
|
||||
.insert('g')
|
||||
.attr('class', classes)
|
||||
.attr('id', node.domId || node.id);
|
||||
|
||||
// Create the title label and insert it after the rect
|
||||
const g = shapeSvg.insert('g');
|
||||
|
||||
const label = shapeSvg.insert('g').attr('class', 'label');
|
||||
|
||||
const description = node.description;
|
||||
|
||||
const title = node.label;
|
||||
|
||||
const text = label.node().appendChild(createLabel(title, node.labelStyle, true, true));
|
||||
let bbox = { width: 0, height: 0 };
|
||||
if (evaluate(getConfig()?.flowchart?.htmlLabels)) {
|
||||
const div = text.children[0];
|
||||
const dv = select(text);
|
||||
bbox = div.getBoundingClientRect();
|
||||
dv.attr('width', bbox.width);
|
||||
dv.attr('height', bbox.height);
|
||||
}
|
||||
log.info('Text 2', description);
|
||||
const textRows = description || [];
|
||||
const titleBox = text.getBBox();
|
||||
const descr = label
|
||||
.node()
|
||||
.appendChild(
|
||||
createLabel(textRows.join ? textRows.join('<br/>') : textRows, node.labelStyle, true, true)
|
||||
);
|
||||
|
||||
if (evaluate(getConfig()?.flowchart?.htmlLabels)) {
|
||||
const div = descr.children[0];
|
||||
const dv = select(descr);
|
||||
bbox = div.getBoundingClientRect();
|
||||
dv.attr('width', bbox.width);
|
||||
dv.attr('height', bbox.height);
|
||||
}
|
||||
|
||||
const halfPadding = (node.padding || 0) / 2;
|
||||
select(descr).attr(
|
||||
'transform',
|
||||
'translate( ' +
|
||||
(bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) +
|
||||
', ' +
|
||||
(titleBox.height + halfPadding + 5) +
|
||||
')'
|
||||
);
|
||||
select(text).attr(
|
||||
'transform',
|
||||
'translate( ' +
|
||||
(bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) +
|
||||
', ' +
|
||||
0 +
|
||||
')'
|
||||
);
|
||||
// Get the size of the label
|
||||
|
||||
// Bounding box for title and text
|
||||
bbox = label.node().getBBox();
|
||||
|
||||
// Center the label
|
||||
label.attr(
|
||||
'transform',
|
||||
'translate(' + -bbox.width / 2 + ', ' + (-bbox.height / 2 - halfPadding + 3) + ')'
|
||||
);
|
||||
|
||||
const totalWidth = bbox.width + (node.padding || 0);
|
||||
const totalHeight = bbox.height + (node.padding || 0);
|
||||
const x = -bbox.width / 2 - halfPadding;
|
||||
const y = -bbox.height / 2 - halfPadding;
|
||||
let rect;
|
||||
let innerLine;
|
||||
if (node.look === 'handdrawn') {
|
||||
// @ts-ignore No typings for rough
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {});
|
||||
const roughNode = rc.path(
|
||||
createRoundedRectPathD(x, y, totalWidth, totalHeight, node.rx || 0),
|
||||
options
|
||||
);
|
||||
|
||||
const roughLine = rc.line(
|
||||
-bbox.width / 2 - halfPadding,
|
||||
-bbox.height / 2 - halfPadding + titleBox.height + halfPadding,
|
||||
bbox.width / 2 + halfPadding,
|
||||
-bbox.height / 2 - halfPadding + titleBox.height + halfPadding,
|
||||
options
|
||||
);
|
||||
|
||||
innerLine = shapeSvg.insert(() => {
|
||||
log.debug('Rough node insert CXC', roughNode);
|
||||
return roughLine;
|
||||
}, ':first-child');
|
||||
rect = shapeSvg.insert(() => {
|
||||
log.debug('Rough node insert CXC', roughNode);
|
||||
return roughNode;
|
||||
}, ':first-child');
|
||||
} else {
|
||||
rect = g.insert('rect', ':first-child');
|
||||
innerLine = g.insert('line');
|
||||
rect
|
||||
.attr('class', 'outer title-state')
|
||||
.attr('x', -bbox.width / 2 - halfPadding)
|
||||
.attr('y', -bbox.height / 2 - halfPadding)
|
||||
.attr('width', bbox.width + (node.padding || 0))
|
||||
.attr('height', bbox.height + (node.padding || 0));
|
||||
|
||||
innerLine
|
||||
.attr('class', 'divider')
|
||||
.attr('x1', -bbox.width / 2 - halfPadding)
|
||||
.attr('x2', bbox.width / 2 + halfPadding)
|
||||
.attr('y1', -bbox.height / 2 - halfPadding + titleBox.height + halfPadding)
|
||||
.attr('y2', -bbox.height / 2 - halfPadding + titleBox.height + halfPadding);
|
||||
}
|
||||
updateNodeBounds(node, rect);
|
||||
|
||||
node.intersect = function (point) {
|
||||
return intersect.rect(node, point);
|
||||
};
|
||||
|
||||
return shapeSvg;
|
||||
};
|
||||
|
@@ -12,6 +12,8 @@ export const roundedRect = async (parent: SVGAElement, node: Node) => {
|
||||
labelPaddingX: node.look === 'neo' ? node.padding * 2 : node.padding,
|
||||
labelPaddingY: node.look === 'neo' ? node.padding : node.padding,
|
||||
classes: '',
|
||||
labelPaddingX: (node?.padding || 0) * 1,
|
||||
labelPaddingY: (node?.padding || 0) * 1,
|
||||
} as RectOptions;
|
||||
|
||||
return drawRect(parent, node, options);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import type { Node } from '$root/rendering-util/types.d.ts';
|
||||
import type { Node, RectOptions } from '$root/rendering-util/types.d.ts';
|
||||
import { drawRect } from './drawRect.js';
|
||||
import { getConfig } from '$root/diagram-api/diagramAPI.js';
|
||||
|
||||
@@ -10,6 +10,6 @@ export const state = async (parent: SVGAElement, node: Node) => {
|
||||
rx: node.look === 'neo' ? 3 : 5,
|
||||
ry: node.look === 'neo' ? 3 : 5,
|
||||
classes: 'flowchart-node',
|
||||
};
|
||||
} as RectOptions;
|
||||
return drawRect(parent, node, options);
|
||||
};
|
||||
|
@@ -37,8 +37,7 @@ export const trapezoid = async (parent: SVGAElement, node: Node): Promise<SVGAEl
|
||||
const { cssStyles } = node;
|
||||
|
||||
if (node.look === 'handdrawn') {
|
||||
console.log('Trapezoid: Inside handdrawn block');
|
||||
// @ts-ignore
|
||||
// @ts-ignore - rough is not typed
|
||||
const rc = rough.svg(shapeSvg);
|
||||
const options = userNodeOverrides(node, {});
|
||||
const pathData = createTrapezoidPathD(0, 0, w, h);
|
||||
|
@@ -13,6 +13,7 @@ export type CheckFitFunction = (text: MarkdownLine) => boolean;
|
||||
interface Node {
|
||||
id: string;
|
||||
label?: string;
|
||||
description?: string[];
|
||||
parentId?: string;
|
||||
position?: string; // Keep, this is for notes 'left of', 'right of', etc. Move into nodeNode
|
||||
cssStyles?: string; // Renamed from `styles` to `cssStyles`
|
||||
|
@@ -52,6 +52,7 @@ required:
|
||||
- sankey
|
||||
- packet
|
||||
- block
|
||||
- look
|
||||
properties:
|
||||
theme:
|
||||
description: |
|
||||
@@ -1291,6 +1292,16 @@ $defs: # JSON Schema definition (maybe we should move these to a separate file)
|
||||
noteMargin:
|
||||
type: number
|
||||
default: 10
|
||||
nodeSpacing:
|
||||
type: integer
|
||||
minimum: 0
|
||||
# should the default value be 50?
|
||||
# see https://github.com/mermaid-js/mermaid/blob/7647ae317a7b2130e32777248d25a9c4d24b8f9f/packages/mermaid/src/diagrams/class/classRenderer-v2.ts#L258
|
||||
rankSpacing:
|
||||
type: integer
|
||||
minimum: 0
|
||||
# should the default value be 50?
|
||||
# see https://github.com/mermaid-js/mermaid/blob/7647ae317a7b2130e32777248d25a9c4d24b8f9f/packages/mermaid/src/diagrams/class/classRenderer-v2.ts#L259
|
||||
forkWidth:
|
||||
type: number
|
||||
default: 70
|
||||
|
@@ -34,7 +34,7 @@ class Theme {
|
||||
this.arrowheadColor = '#333333';
|
||||
this.fontFamily = '"trebuchet ms", verdana, arial, sans-serif';
|
||||
this.fontSize = '16px';
|
||||
this.labelBackground = 'rgba(232,232,232,0.6)';
|
||||
this.labelBackground = 'rgba(232,232,232,0.8)';
|
||||
this.textColor = '#333';
|
||||
this.THEME_COLOR_LIMIT = 12;
|
||||
this.radius = 5;
|
||||
|
6009
pnpm-lock.yaml
generated
6009
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user