Compare commits

...

12 Commits

Author SHA1 Message Date
Per Brolin
97614b8af5 Updated to 9.4.0 2023-02-15 15:54:02 +01:00
Knut Sveidqvist
343e48302e Fix for direction issue with elk rendering 2023-02-15 15:12:52 +01:00
Per Brolin
aef989fe03 Corrected sequenceRenderer 2023-02-15 15:11:23 +01:00
Per Brolin
0c38f20281 Clearing sequence diagram before rendering 2023-02-15 14:17:46 +01:00
Knut Sveidqvist
eed427b4ac Adding simple direction logic 2023-02-15 14:10:38 +01:00
Knut Sveidqvist
027296df68 Working version before applying direction logic 2023-02-15 13:54:33 +01:00
Per Brolin
a956be7bbf Release candidate 2023-02-10 11:03:25 +01:00
Per Brolin
e0286be8d2 Corrected typo 2023-02-10 08:58:58 +01:00
Knut Sveidqvist
74df4a7a68 Mind map coming in from the cold. A lazy loaded diagram in the same way as timeline. 2023-02-08 17:42:58 +01:00
Knut Sveidqvist
38a84a7fe0 Merge branch 'develop' into release/9.4.0 2023-02-08 14:00:02 +01:00
Knut Sveidqvist
5e864c3b9b Merge branch 'timeline' into release/9.4.0 2023-02-08 13:58:56 +01:00
Knut Sveidqvist
b5a4cc0e17 Merge pull request #4014 from mermaid-js/timeline
Timeline Diagram
2023-02-08 13:57:36 +01:00
38 changed files with 392 additions and 370 deletions

View File

@@ -36,9 +36,9 @@ const packageOptions = {
packageName: 'mermaid',
file: 'mermaid.ts',
},
'mermaid-mindmap': {
name: 'mermaid-mindmap',
packageName: 'mermaid-mindmap',
'mermaid-example-diagram': {
name: 'mermaid-example-diagram',
packageName: 'mermaid-example-diagram',
file: 'detector.ts',
},
};
@@ -114,7 +114,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
if (watch && config.build) {
config.build.watch = {
include: ['packages/mermaid-mindmap/src/**', 'packages/mermaid/src/**'],
include: ['packages/mermaid-example-diagram/src/**', 'packages/mermaid/src/**'],
};
}
@@ -139,7 +139,7 @@ const main = async () => {
if (watch) {
build(getBuildConfig({ minify: false, watch, core: false, entryName: 'mermaid' }));
if (!mermaidOnly) {
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' }));
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
}
} else if (visualize) {
await build(getBuildConfig({ minify: false, core: true, entryName: 'mermaid' }));

View File

@@ -22,7 +22,7 @@ async function createServer() {
app.use(cors);
app.use(express.static('./packages/mermaid/dist'));
// app.use(express.static('./packages/mermaid-example-diagram/dist'));
app.use(express.static('./packages/mermaid-mindmap/dist'));
app.use(express.static('./packages/mermaid-example-diagram/dist'));
app.use(vite.middlewares);
app.use(express.static('demos'));
app.use(express.static('cypress/platform'));

View File

@@ -2,8 +2,8 @@ import { urlSnapshotTest } from '../../helpers/util';
describe('mermaid', () => {
describe('registerDiagram', () => {
it('should work on @mermaid-js/mermaid-mindmap and mermaid-example-diagram', () => {
const url = 'http://localhost:9000/external-diagrams-mindmap.html';
it('should work on @mermaid-js/mermaid-example-diagram', () => {
const url = 'http://localhost:9000/external-diagrams-example-diagram.html';
urlSnapshotTest(url, {}, false, false);
});
});

View File

@@ -2,34 +2,8 @@
<body>
<h1>Should correctly load a third-party diagram using registerDiagram</h1>
<pre id="diagram" class="mermaid">
mindmap
root
A
B
C
D
E
A2
B2
C2
D2
E2
child1((Circle))
grandchild 1
grandchild 2
child2(Round rectangle)
grandchild 3
grandchild 4
child3[Square]
grandchild 5
::icon(mdi mdi-fire)
gc6((grand<br/>child 6))
::icon(mdi mdi-fire)
gc7((grand<br/>grand<br/>child 8))
example-diagram
</pre>
<!-- <pre id="diagram" class="mermaid2">
example-diagram
</pre> -->
<!-- <div id="cy"></div> -->
<!-- <script src="http://localhost:9000/packages/mermaid-mindmap/dist/mermaid-mindmap-detector.js"></script> -->
@@ -37,11 +11,11 @@ mindmap
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script> -->
<!-- <script type="module" src="./external-diagrams-mindmap.mjs" /> -->
<script type="module">
import mindmap from '../../packages/mermaid-mindmap/src/detector';
import exampleDiagram from '../../packages/mermaid-example-diagram/src/detector';
// import example from '../../packages/mermaid-example-diagram/src/detector';
import mermaid from '../../packages/mermaid/src/mermaid';
await mermaid.registerExternalDiagrams([mindmap]);
await mermaid.registerExternalDiagrams([exampleDiagram]);
await mermaid.initialize({ logLevel: 0 });
await mermaid.initThrowsErrorsAsync();
if (window.Cypress) {

View File

@@ -54,13 +54,17 @@
</style>
</head>
<body>
<pre id="diagram" class="mermaid2">
<pre id="diagram" class="mermaid">
%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
graph TB
a --> b
a --> c
b --> d
c --> d
graph BT
a{The cat in the hat} -- 1o --> b
a -- 2o --> c
a -- 3o --> d
g --2i--> a
d --1i--> a
h --3i -->a
b --> d(The dog in the hog)
c --> d
</pre>
<pre id="diagram" class="mermaid2">
flowchart-elk TB
@@ -227,7 +231,7 @@ sequenceDiagram
Customer->>+Merchant: Receives goods or services
</pre
>
<pre id="diagram" class="mermaid">
<pre id="diagram" class="mermaid2">
mindmap
root((mindmap))
Origins
@@ -246,6 +250,10 @@ mindmap
Pen and paper
Mermaid
</pre>
<br />
<pre id="diagram" class="mermaid2">
example-diagram
</pre>
<!-- <div id="cy"></div> -->
<!-- <script src="http://localhost:9000/packages/mermaid-mindmap/dist/mermaid-mindmap-detector.js"></script> -->
@@ -254,17 +262,17 @@ mindmap
<!-- <script src="./mermaid.js"></script> -->
<script type="module">
import mindmap from '../../packages/mermaid-mindmap/src/detector';
// import example from '../../packages/mermaid-example-diagram/src/detector';
// import mindmap from '../../packages/mermaid-mindmap/src/detector';
import example from '../../packages/mermaid-example-diagram/src/detector';
import mermaid from '../../packages/mermaid/src/mermaid';
await mermaid.registerExternalDiagrams([mindmap]);
await mermaid.registerExternalDiagrams([example]);
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'dark',
theme: 'forest',
startOnLoad: true,
logLevel: 0,
logLevel: 5,
flowchart: {
// defaultRenderer: 'elk',
useMaxWidth: false,

View File

@@ -1,81 +1,93 @@
<html>
<!DOCTYPE html>
<html lang="en">
<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"
/>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Mindmap Mermaid Quick Test Page</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
<style>
body {
/* background: rgb(221, 208, 208); */
/* background:#333; */
font-family: 'Arial';
/* font-size: 18px !important; */
}
h1 {
color: grey;
}
.mermaid2 {
display: none;
}
.mermaid svg {
/* font-size: 18px !important; */
background-color: #eee;
background-image: radial-gradient(#fff 1%, transparent 11%),
radial-gradient(#fff 1%, transparent 11%);
background-size: 20px 20px;
background-position: 0 0, 10px 10px;
background-repeat: repeat;
}
.malware {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 150px;
background: red;
color: black;
display: flex;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
font-size: 72px;
div.mermaid {
/* font-family: 'trebuchet ms', verdana, arial; */
font-family: 'Courier New', Courier, monospace !important;
}
</style>
</head>
<body>
<div>Security check</div>
<pre id="diagram" class="mermaid">
graph TD
A["test"] --"<p><style> * { display : none}</style>test</p>"--> B
<h1>Mindmap diagram demo</h1>
<pre class="mermaid">
mindmap
root
child1((Circle))
grandchild 1
grandchild 2
child2(Round rectangle)
grandchild 3
grandchild 4
child3[Square]
grandchild 5
::icon(mdi mdi-fire)
gc6((grand<br/>child 6))
::icon(mdi mdi-fire)
gc7((grand<br/>grand<br/>child 8))
</pre>
<!-- <div id="cy"></div> -->
<!-- <script src="http://localhost:9000/packages/mermaid-mindmap/dist/mermaid-mindmap-detector.js"></script> -->
<!-- <script src="./mermaid-example-diagram-detector.js"></script> -->
<!-- <script src="//cdn.jsdelivr.net/npm/mermaid@9.1.7/dist/mermaid.min.js"></script> -->
<!-- <script src="./mermaid.js"></script> -->
<h2>Mindmap with root wrapping text and a shape</h2>
<pre class="mermaid">
mindmap
root[A root with a long text that wraps to keep the node size in check]
</pre>
<script type="module">
import mindmap from '../../packages/mermaid-mindmap/src/detector';
// import example from '../../packages/mermaid-example-diagram/src/detector';
// import mermaid from './mermaid.esm.mjs';
import mermaid from '../../packages/mermaid/src/mermaid';
await mermaid.registerExternalDiagrams([mindmap]);
// import mermaidMindmap from './mermaid-mindmap.esm.mjs';
// import mermaidMindmap from 'https://cdn.jsdelivr.net/npm/@mermaid-js/mermaid-mindmap@9.3.0/+esm';
// await mermaid.registerExternalDiagrams([mermaidMindmap]);
const ALLOWED_TAGS = [
'a',
'b',
'blockquote',
'br',
'dd',
'div',
'dl',
'dt',
'em',
'foreignObject',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'h7',
'h8',
'hr',
'i',
'li',
'ul',
'ol',
'p',
'pre',
'span',
'strike',
'strong',
'table',
'tbody',
'td',
'tfoot',
'th',
'thead',
'tr',
];
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
mermaid.initialize({
theme: 'default',
theme: 'base',
startOnLoad: true,
logLevel: 0,
flowchart: {
@@ -94,10 +106,6 @@
console.error('In parse error:');
console.error(err);
};
// mermaid.test1('first_slow', 1200).then((r) => console.info(r));
// mermaid.test1('second_fast', 200).then((r) => console.info(r));
// mermaid.test1('third_fast', 200).then((r) => console.info(r));
// mermaid.test1('forth_slow', 1200).then((r) => console.info(r));
</script>
</body>
</html>

View File

@@ -1,5 +1,5 @@
import mermaid2 from '../../packages/mermaid/src/mermaid';
import mindmap from '../../packages/mermaid-mindmap/src/detector';
import externalExample from '../../packages/mermaid-example-diagram/src/detector';
function b64ToUtf8(str) {
return decodeURIComponent(escape(window.atob(str)));
@@ -44,7 +44,7 @@ const contentLoaded = async function () {
document.getElementsByTagName('body')[0].appendChild(div);
}
await mermaid2.registerExternalDiagrams([mindmap]);
await mermaid2.registerExternalDiagrams([externalExample]);
mermaid2.initialize(graphObj.mermaid);
await mermaid2.init();
markRendered();

View File

@@ -1,7 +1,7 @@
{
"name": "mermaid-monorepo",
"private": true,
"version": "9.3.0-rc1",
"version": "9.4.0",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"type": "module",
"packageManager": "pnpm@7.25.1",
@@ -18,7 +18,7 @@
"build:vite": "ts-node-esm --transpileOnly .vite/build.ts",
"build:mermaid": "pnpm build:vite --mermaid",
"build:viz": "pnpm build:mermaid --visualize",
"build:types": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-mindmap/tsconfig.json --emitDeclarationOnly",
"build:types": "tsc -p ./packages/mermaid/tsconfig.json --emitDeclarationOnly && tsc -p ./packages/mermaid-example-diagram/tsconfig.json --emitDeclarationOnly",
"build:watch": "pnpm build:vite --watch",
"build": "pnpm run -r clean && concurrently \"pnpm build:vite\" \"pnpm build:types\"",
"dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server.ts\"",

View File

@@ -1,3 +0,0 @@
### Do not refer this package. It is not ready.
### Refer mermaid-mindmap instead.

View File

@@ -1,36 +1,25 @@
{
"name": "@mermaid-js/mermaid-example-diagram",
"version": "9.2.0-rc2",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "dist/mermaid-mindmap.core.mjs",
"module": "dist/mermaid-mindmap.core.mjs",
"version": "9.3.0",
"description": "Example of external diagram module for MermaidJS.",
"module": "dist/mermaid-example-diagram.core.mjs",
"types": "dist/detector.d.ts",
"type": "module",
"exports": {
".": {
"require": "./dist/mermaid-example-diagram.min.js",
"import": "./dist/mermaid-example-diagram.core.mjs"
"import": "./dist/mermaid-example-diagram.core.mjs",
"types": "./dist/detector.d.ts"
},
"./*": "./*"
},
"keywords": [
"diagram",
"markdown",
"mindmap",
"example",
"mermaid"
],
"scripts": {
"clean": "rimraf dist",
"build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly",
"build:watch": "yarn build:code --watch",
"build:esbuild": "concurrently \"yarn build:code\" \"yarn build:types\"",
"build": "yarn clean; yarn build:esbuild",
"dev": "node .esbuild/serve.cjs",
"release": "yarn build",
"lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .",
"lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .",
"lint:jison": "ts-node-esm src/jison/lint.mts",
"todo-prepare": "concurrently \"husky install ../../.husky\" \"yarn build\"",
"todo-pre-commit": "lint-staged"
"prepublishOnly": "pnpm -w run build"
},
"repository": {
"type": "git",
@@ -48,9 +37,19 @@
"page"
]
},
"dependencies": {},
"dependencies": {
"@braintree/sanitize-url": "^6.0.0",
"cytoscape": "^3.23.0",
"cytoscape-cose-bilkent": "^4.1.0",
"cytoscape-fcose": "^2.1.0",
"d3": "^7.0.0",
"khroma": "^2.0.0",
"non-layered-tidy-tree-layout": "^2.0.2"
},
"devDependencies": {
"@types/cytoscape": "^3.19.9",
"concurrently": "^7.5.0",
"mermaid": "workspace:*",
"rimraf": "^3.0.2"
},
"resolutions": {

View File

@@ -1,18 +1,20 @@
// @ts-ignore: TODO Fix ts errors
export const id = 'example-diagram';
import type { ExternalDiagramDefinition } from 'mermaid';
/**
* Detector function that will be called by mermaid to determine if the diagram is this type of diagram.
*
* @param txt - The diagram text will be passed to the detector
* @returns True if the diagram text matches a diagram of this type
*/
const id = 'example-diagram';
export const detector = (txt: string) => {
const detector = (txt: string) => {
return txt.match(/^\s*example-diagram/) !== null;
};
export const loadDiagram = async () => {
const loader = async () => {
const { diagram } = await import('./diagram-definition');
return { id, diagram };
};
const plugin: ExternalDiagramDefinition = {
id,
detector,
loader,
};
export default plugin;

View File

@@ -12,5 +12,3 @@ export const diagram = {
styles,
injectUtils,
};
export { detector, id } from './detector';

View File

@@ -1,5 +1,17 @@
import { parser } from './parser/exampleDiagram';
import db from './exampleDiagramDb';
import * as db from './exampleDiagramDb';
import { injectUtils } from './mermaidUtils';
// Todo fix utils functions for tests
import {
log,
setLogLevel,
getConfig,
sanitizeText,
setupGraphViewBox,
} from '../../mermaid/src/diagram-api/diagramAPI';
injectUtils(log, setLogLevel, getConfig, sanitizeText, setupGraphViewBox);
describe('when parsing an info graph it', function () {
let ex;
beforeEach(function () {

View File

@@ -1,4 +1,8 @@
const warning = () => null;
const warning = (s: string) => {
// Todo remove debug code
// eslint-disable-next-line no-console
console.error('Log function was called before initialization', s);
};
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
@@ -19,13 +23,11 @@ export const log: Record<keyof typeof LEVELS, typeof console.log> = {
error: warning,
fatal: warning,
};
export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
export let getConfig: () => object;
export let sanitizeText: (str: string) => string;
export let commonDb: any;
/**
* Placeholder for the real function that will be injected by mermaid.
*/
export let commonDb: () => object;
// eslint-disable @typescript-eslint/no-explicit-any
export let setupGraphViewbox: (
graph: any,
@@ -34,25 +36,15 @@ export let setupGraphViewbox: (
useMaxWidth: boolean
) => void;
/**
* Function called by mermaid that injects utility functions that help the diagram to be a good citizen.
*
* @param _log - log from mermaid/src/diagramAPI.ts
* @param _setLogLevel - setLogLevel from mermaid/src/diagramAPI.ts
* @param _getConfig - getConfig from mermaid/src/diagramAPI.ts
* @param _sanitizeText - sanitizeText from mermaid/src/diagramAPI.ts
* @param _setupGraphViewbox - setupGraphViewbox from mermaid/src/diagramAPI.ts
* @param _commonDb -`commonDb` from mermaid/src/diagramAPI.ts
*/
export const injectUtils = (
_log: Record<keyof typeof LEVELS, typeof console.log>,
_setLogLevel: typeof setLogLevel,
_getConfig: typeof getConfig,
_sanitizeText: typeof sanitizeText,
_setupGraphViewbox: typeof setupGraphViewbox,
_setLogLevel: any,
_getConfig: any,
_sanitizeText: any,
_setupGraphViewbox: any,
_commonDb: any
) => {
_log.info('Mermaid utils injected into timeline-diagram');
_log.info('Mermaid utils injected');
log.trace = _log.trace;
log.debug = _log.debug;
log.info = _log.info;

View File

@@ -1,5 +1,6 @@
{
"extends": "../../tsconfig.json",
"module": "esnext",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"

View File

@@ -1,65 +0,0 @@
{
"name": "@mermaid-js/mermaid-mindmap",
"version": "9.3.0",
"description": "Mindmap diagram module for MermaidJS.",
"module": "dist/mermaid-mindmap.core.mjs",
"types": "dist/detector.d.ts",
"type": "module",
"exports": {
".": {
"import": "./dist/mermaid-mindmap.core.mjs",
"types": "./dist/detector.d.ts"
},
"./*": "./*"
},
"keywords": [
"diagram",
"markdown",
"mindmap",
"mermaid"
],
"scripts": {
"prepublishOnly": "pnpm -w run build"
},
"repository": {
"type": "git",
"url": "https://github.com/mermaid-js/mermaid"
},
"author": "Knut Sveidqvist",
"license": "MIT",
"standard": {
"ignore": [
"**/parser/*.js",
"dist/**/*.js",
"cypress/**/*.js"
],
"globals": [
"page"
]
},
"dependencies": {
"@braintree/sanitize-url": "^6.0.0",
"cytoscape": "^3.23.0",
"cytoscape-cose-bilkent": "^4.1.0",
"cytoscape-fcose": "^2.1.0",
"d3": "^7.0.0",
"khroma": "^2.0.0",
"non-layered-tidy-tree-layout": "^2.0.2"
},
"devDependencies": {
"@types/cytoscape": "^3.19.9",
"concurrently": "^7.5.0",
"mermaid": "workspace:*",
"rimraf": "^3.0.2"
},
"resolutions": {
"d3": "^7.0.0"
},
"files": [
"dist"
],
"sideEffects": [
"**/*.css",
"**/*.scss"
]
}

View File

@@ -1,59 +0,0 @@
const warning = (s: string) => {
// Todo remove debug code
// eslint-disable-next-line no-console
console.error('Log function was called before initialization', s);
};
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
export const LEVELS: Record<LogLevel, number> = {
trace: 0,
debug: 1,
info: 2,
warn: 3,
error: 4,
fatal: 5,
};
export const log: Record<keyof typeof LEVELS, typeof console.log> = {
trace: warning,
debug: warning,
info: warning,
warn: warning,
error: warning,
fatal: warning,
};
export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
export let getConfig: () => object;
export let sanitizeText: (str: string) => string;
export let commonDb: () => object;
// eslint-disable @typescript-eslint/no-explicit-any
export let setupGraphViewbox: (
graph: any,
svgElem: any,
padding: any,
useMaxWidth: boolean
) => void;
export const injectUtils = (
_log: Record<keyof typeof LEVELS, typeof console.log>,
_setLogLevel: any,
_getConfig: any,
_sanitizeText: any,
_setupGraphViewbox: any,
_commonDb: any
) => {
_log.info('Mermaid utils injected');
log.trace = _log.trace;
log.debug = _log.debug;
log.info = _log.info;
log.warn = _log.warn;
log.error = _log.error;
log.fatal = _log.fatal;
setLogLevel = _setLogLevel;
getConfig = _getConfig;
sanitizeText = _sanitizeText;
setupGraphViewbox = _setupGraphViewbox;
commonDb = _commonDb;
};

View File

@@ -1,10 +0,0 @@
{
"extends": "../../tsconfig.json",
"module": "esnext",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["./src/**/*.ts"],
"typeRoots": ["./src/types"]
}

View File

@@ -1,6 +1,6 @@
{
"name": "mermaid",
"version": "9.3.0",
"version": "9.4.0",
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"main": "./dist/mermaid.min.js",
"module": "./dist/mermaid.core.mjs",
@@ -53,6 +53,9 @@
},
"dependencies": {
"@braintree/sanitize-url": "^6.0.0",
"cytoscape": "^3.23.0",
"cytoscape-cose-bilkent": "^4.1.0",
"cytoscape-fcose": "^2.1.0",
"d3": "^7.0.0",
"dagre-d3-es": "7.0.8",
"dompurify": "2.4.3",
@@ -66,6 +69,7 @@
"uuid": "^9.0.0"
},
"devDependencies": {
"@types/cytoscape": "^3.19.9",
"@types/d3": "^7.4.0",
"@types/dompurify": "^2.4.0",
"@types/jsdom": "^20.0.1",

View File

@@ -1007,6 +1007,7 @@ const class_box = (parent, node) => {
};
const shapes = {
rhombus: question,
question,
rect,
labelRect,

View File

@@ -55,9 +55,10 @@ export const registerLazyLoadedDiagrams = (...diagrams: ExternalDiagramDefinitio
export const addDetector = (key: string, detector: DiagramDetector, loader?: DiagramLoader) => {
if (detectors[key]) {
throw new Error(`Detector with key ${key} already exists`);
log.error(`Detector with key ${key} already exists`);
} else {
detectors[key] = { detector, loader };
}
detectors[key] = { detector, loader };
log.debug(`Detector with key ${key} added${loader ? ' with loader' : ''}`);
};

View File

@@ -96,7 +96,10 @@ import errorStyles from '../diagrams/error/styles';
import flowchartElk from '../diagrams/flowchart/elk/detector';
import { registerLazyLoadedDiagrams } from './detectType';
// Lazy loaded diagrams
import timelineDetector from '../diagrams/timeline/detector';
import mindmapDetector from '../diagrams/mindmap/detector';
let hasLoadedDiagrams = false;
export const addDiagrams = () => {
if (hasLoadedDiagrams) {
@@ -105,7 +108,7 @@ export const addDiagrams = () => {
// This is added here to avoid race-conditions.
// We could optimize the loading logic somehow.
hasLoadedDiagrams = true;
registerLazyLoadedDiagrams(flowchartElk, timelineDetector);
registerLazyLoadedDiagrams(flowchartElk, timelineDetector, mindmapDetector);
registerDiagram(
'error',

View File

@@ -13,6 +13,8 @@ import { interpolateToCurve, getStylesFromArray } from '../../../utils';
import ELK from 'elkjs/lib/elk.bundled.js';
const elk = new ELK();
const portPos = {};
const conf = {};
export const setConf = function (cnf) {
const keys = Object.keys(cnf);
@@ -95,8 +97,36 @@ export const addVertices = function (vert, svgId, root, doc, diagObj, parentLook
labelData.labelNode = vertexNode;
}
const ports = [
{
id: vertex.id + '-west',
layoutOptions: {
'port.side': 'WEST',
},
},
{
id: vertex.id + '-east',
layoutOptions: {
'port.side': 'EAST',
},
},
{
id: vertex.id + '-south',
layoutOptions: {
'port.side': 'SOUTH',
},
},
{
id: vertex.id + '-north',
layoutOptions: {
'port.side': 'NORTH',
},
},
];
let radious = 0;
let _shape = '';
let layoutOptions = {};
// Set the shape based parameters
switch (vertex.type) {
case 'round':
@@ -108,6 +138,9 @@ export const addVertices = function (vert, svgId, root, doc, diagObj, parentLook
break;
case 'diamond':
_shape = 'question';
layoutOptions = {
portConstraints: 'FIXED_SIDE',
};
break;
case 'hexagon':
_shape = 'hexagon';
@@ -184,8 +217,10 @@ export const addVertices = function (vert, svgId, root, doc, diagObj, parentLook
const data = {
id: vertex.id,
ports: vertex.type === 'diamond' ? ports : [],
// labelStyle: styles.labelStyle,
// shape: _shape,
layoutOptions,
labelText: vertexText,
labelData,
// labels: [{ text: vertexText }],
@@ -235,6 +270,127 @@ export const addVertices = function (vert, svgId, root, doc, diagObj, parentLook
return graph;
};
const getNextPosition = (position, edgeDirection, graphDirection) => {
const portPos = {
TB: {
in: {
north: 'north',
},
out: {
south: 'west',
west: 'east',
east: 'south',
},
},
LR: {
in: {
west: 'west',
},
out: {
east: 'south',
south: 'north',
north: 'east',
},
},
RL: {
in: {
east: 'east',
},
out: {
west: 'north',
north: 'south',
south: 'west',
},
},
BT: {
in: {
south: 'south',
},
out: {
north: 'east',
east: 'west',
west: 'north',
},
},
};
portPos.TD = portPos.TB;
log.info('abc88', graphDirection, edgeDirection, position);
return portPos[graphDirection][edgeDirection][position];
// return 'south';
};
const getNextPort = (node, edgeDirection, graphDirection) => {
log.info('getNextPort abc88', { node, edgeDirection, graphDirection });
if (!portPos[node]) {
switch (graphDirection) {
case 'TB':
case 'TD':
portPos[node] = {
inPosition: 'north',
outPosition: 'south',
};
break;
case 'BT':
portPos[node] = {
inPosition: 'south',
outPosition: 'north',
};
break;
case 'RL':
portPos[node] = {
inPosition: 'east',
outPosition: 'west',
};
break;
case 'LR':
portPos[node] = {
inPosition: 'west',
outPosition: 'east',
};
break;
}
}
const result = edgeDirection === 'in' ? portPos[node].inPosition : portPos[node].outPosition;
if (edgeDirection === 'in') {
portPos[node].inPosition = getNextPosition(
portPos[node].inPosition,
edgeDirection,
graphDirection
);
} else {
portPos[node].outPosition = getNextPosition(
portPos[node].outPosition,
edgeDirection,
graphDirection
);
}
return result;
};
const getEdgeStartEndPoint = (edge, dir) => {
let source = edge.start;
let target = edge.end;
const startNode = nodeDb[source];
const endNode = nodeDb[target];
if (!startNode || !endNode) {
return { source, target };
}
if (startNode.type === 'diamond') {
source = `${source}-${getNextPort(source, 'out', dir)}`;
}
if (endNode.type === 'diamond') {
target = `${target}-${getNextPort(target, 'in', dir)}`;
}
// Add the edge to the graph
return { source, target };
};
/**
* Add edges to graph based on parsed graph definition
*
@@ -246,10 +402,10 @@ export const addVertices = function (vert, svgId, root, doc, diagObj, parentLook
* @param svg
*/
export const addEdges = function (edges, diagObj, graph, svg) {
// log.info('abc78 edges = ', edges);
log.info('abc78 edges = ', edges);
const labelsEl = svg.insert('g').attr('class', 'edgeLabels');
let linkIdCnt = {};
let dir = diagObj.db.getDirection();
let defaultStyle;
let defaultLabelStyle;
@@ -374,17 +530,19 @@ export const addEdges = function (edges, diagObj, graph, svg) {
edgeData.classes = 'flowchart-link ' + linkNameStart + ' ' + linkNameEnd;
const labelEl = insertEdgeLabel(labelsEl, edgeData);
// console.log('labelEl', labelEl, edgeData.width);
// calculate start and end points of the edge
const { source, target } = getEdgeStartEndPoint(edge, dir);
log.debug('abc78 source and target', source, target);
// Add the edge to the graph
graph.edges.push({
id: 'e' + edge.start + edge.end,
sources: [edge.start],
targets: [edge.end],
sources: [source],
targets: [target],
labelEl: labelEl,
labels: [
{
width: edgeData.width,
// width: 80,
height: edgeData.height,
orgWidth: edgeData.width,
orgHeight: edgeData.height,
@@ -396,8 +554,6 @@ export const addEdges = function (edges, diagObj, graph, svg) {
},
],
edgeData,
// targetPort: 'PortSide.NORTH',
// id: cnt,
});
});
return graph;
@@ -624,12 +780,15 @@ export const draw = async function (text, id, _version, diagObj) {
'elk.hierarchyHandling': 'INCLUDE_CHILDREN',
'org.eclipse.elk.padding': '[top=100, left=100, bottom=110, right=110]',
'elk.layered.spacing.edgeNodeBetweenLayers': '30',
// 'elk.layered.mergeEdges': 'true',
'elk.direction': 'DOWN',
// 'elk.ports.sameLayerEdges': true,
// 'nodePlacement.strategy': 'SIMPLE',
},
children: [],
edges: [],
};
log.info('Drawing flowchart using v3 renderer');
log.info('Drawing flowchart using v3 renderer', elk);
// Set the direction,
// Fetch the default direction, use TD if none was found
@@ -731,8 +890,10 @@ export const draw = async function (text, id, _version, diagObj) {
}
});
insertChildren(graph.children, parentLookupDb);
log.info('after layout', JSON.stringify(graph, null, 2));
const g = await elk.layout(graph);
drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0);
log.info('after layout', g);
g.edges?.map((edge) => {
insertEdge(edgesEl, edge, edge.edgeData, diagObj, parentLookupDb);
});

View File

@@ -238,6 +238,9 @@ export const setDirection = function (dir) {
if (direction.match(/.*v/)) {
direction = 'TB';
}
if (direction === 'TD') {
direction = 'TB';
}
};
/**

View File

@@ -1,5 +1,4 @@
import type { ExternalDiagramDefinition } from 'mermaid';
import type { ExternalDiagramDefinition } from '../../diagram-api/types';
const id = 'mindmap';
const detector = (txt: string) => {

View File

@@ -3,12 +3,10 @@ import mindmapParser from './parser/mindmap';
import * as mindmapDb from './mindmapDb';
import mindmapRenderer from './mindmapRenderer';
import mindmapStyles from './styles';
import { injectUtils } from './mermaidUtils';
export const diagram = {
db: mindmapDb,
renderer: mindmapRenderer,
parser: mindmapParser,
styles: mindmapStyles,
injectUtils,
};

View File

@@ -1,16 +1,16 @@
import { parser as mindmap } from './parser/mindmap';
import * as mindmapDB from './mindmapDb';
import { injectUtils } from './mermaidUtils';
// import { injectUtils } from './mermaidUtils';
// Todo fix utils functions for tests
import {
log,
// log,
setLogLevel,
getConfig,
sanitizeText,
setupGraphViewBox,
} from '../../mermaid/src/diagram-api/diagramAPI';
// getConfig,
// sanitizeText,
// setupGraphViewBox,
} from '../../diagram-api/diagramAPI';
injectUtils(log, setLogLevel, getConfig, sanitizeText, setupGraphViewBox);
// injectUtils(log, setLogLevel, getConfig, sanitizeText, setupGraphViewBox);
describe('when parsing a mindmap ', function () {
beforeEach(function () {

View File

@@ -1,5 +1,8 @@
/** Created by knut on 15-01-14. */
import { sanitizeText, getConfig, log } from './mermaidUtils';
import { getConfig } from '../../config';
import { sanitizeText as _sanitizeText } from '../../diagrams/common/common';
import { log } from '../../logger';
export const sanitizeText = (text) => _sanitizeText(text, getConfig());
let nodes = [];
let cnt = 0;

View File

@@ -1,6 +1,8 @@
/** Created by knut on 14-12-11. */
import { select } from 'd3';
import { log, getConfig, setupGraphViewbox } from './mermaidUtils';
import { log } from '../../logger';
import { getConfig } from '../../config';
import { setupGraphViewbox } from '../../setupGraphViewbox';
import svgDraw from './svgDraw';
import cytoscape from 'cytoscape';
import coseBilkent from 'cytoscape-cose-bilkent';

View File

@@ -631,6 +631,9 @@ function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoop
export const draw = function (_text: string, id: string, _version: string, diagObj: Diagram) {
const { securityLevel, sequence } = configApi.getConfig();
conf = sequence;
diagObj.db.clear();
// Parse the graph definition
diagObj.parser.parse(_text);
// Handle root and Document for when rendering in sandbox mode
let sandboxElement;
if (securityLevel === 'sandbox') {

View File

@@ -1,10 +1,10 @@
import mermaid, { type MermaidConfig } from 'mermaid';
import mindmap from '@mermaid-js/mermaid-mindmap';
// import mindmap from '@mermaid-js/mermaid-mindmap';
// import timeline from '@mermaid-js/mermaid-timeline';
const init = (async () => {
try {
await mermaid.registerExternalDiagrams([mindmap, timeline]);
await mermaid.registerExternalDiagrams([]);
} catch (e) {
console.error(e);
}

View File

@@ -32,9 +32,9 @@ export default defineConfig({
alias: {
mermaid: path.join(__dirname, '../../dist/mermaid.esm.min.mjs'), // Use this one to build
'@mermaid-js/mermaid-mindmap': path.join(
'@mermaid-js/mermaid-example-diagram': path.join(
__dirname,
'../../../mermaid-mindmap/dist/mermaid-mindmap.esm.min.mjs'
'../../../mermaid-example-diagram/dist/mermaid-example-diagram.esm.min.mjs'
), // Use this one to build
// '@mermaid-js/mermaid-timeline': path.join(
// __dirname,

43
pnpm-lock.yaml generated
View File

@@ -169,6 +169,15 @@ importers:
'@braintree/sanitize-url':
specifier: ^6.0.0
version: 6.0.0
cytoscape:
specifier: ^3.23.0
version: 3.23.0
cytoscape-cose-bilkent:
specifier: ^4.1.0
version: 4.1.0_cytoscape@3.23.0
cytoscape-fcose:
specifier: ^2.1.0
version: 2.1.0_cytoscape@3.23.0
d3:
specifier: ^7.0.0
version: 7.6.1
@@ -203,6 +212,9 @@ importers:
specifier: ^9.0.0
version: 9.0.0
devDependencies:
'@types/cytoscape':
specifier: ^3.19.9
version: 3.19.9
'@types/d3':
specifier: ^7.4.0
version: 7.4.0
@@ -304,15 +316,6 @@ importers:
version: 1.0.4-alpha.16_ifjhkyx3os4sbm7zdnvthc52am
packages/mermaid-example-diagram:
devDependencies:
concurrently:
specifier: ^7.5.0
version: 7.5.0
rimraf:
specifier: ^3.0.2
version: 3.0.2
packages/mermaid-mindmap:
dependencies:
'@braintree/sanitize-url':
specifier: ^6.0.0
@@ -328,7 +331,7 @@ importers:
version: 2.1.0_cytoscape@3.23.0
d3:
specifier: ^7.0.0
version: 7.6.1
version: 7.8.2
khroma:
specifier: ^2.0.0
version: 2.0.0
@@ -349,27 +352,11 @@ importers:
specifier: ^3.0.2
version: 3.0.2
packages/mermaid-timeline:
dependencies:
d3:
specifier: ^7.0.0
version: 7.6.1
khroma:
specifier: ^2.0.0
version: 2.0.0
devDependencies:
concurrently:
specifier: ^7.4.0
version: 7.5.0
rimraf:
specifier: ^3.0.2
version: 3.0.2
tests/webpack:
dependencies:
'@mermaid-js/mermaid-mindmap':
'@mermaid-js/mermaid-example-diagram':
specifier: workspace:*
version: link:../../packages/mermaid-mindmap
version: link:../../packages/mermaid-example-diagram
mermaid:
specifier: workspace:*
version: link:../../packages/mermaid

View File

@@ -18,6 +18,6 @@
},
"dependencies": {
"mermaid": "workspace:*",
"@mermaid-js/mermaid-mindmap": "workspace:*"
"@mermaid-js/mermaid-example-diagram": "workspace:*"
}
}