mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-05 05:14:08 +01:00
Compare commits
20 Commits
antlr_phas
...
sidv/clean
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6462f73bdb | ||
|
|
cfe1723c6c | ||
|
|
6d8b936319 | ||
|
|
f992d95082 | ||
|
|
f2276f93cd | ||
|
|
b52f5058c9 | ||
|
|
5e20087252 | ||
|
|
b49036068f | ||
|
|
5f3d4cb913 | ||
|
|
b11eb93ab2 | ||
|
|
e4f19480cd | ||
|
|
a331a958c0 | ||
|
|
134fca3f1d | ||
|
|
ef7c0a1936 | ||
|
|
2c5403c0f9 | ||
|
|
3b0cb1271e | ||
|
|
96c06a681d | ||
|
|
ff9d26bc70 | ||
|
|
2ddc3403de | ||
|
|
4535911a3a |
@@ -33,14 +33,4 @@ export const packageOptions = {
|
|||||||
packageName: 'mermaid-layout-elk',
|
packageName: 'mermaid-layout-elk',
|
||||||
file: 'layouts.ts',
|
file: 'layouts.ts',
|
||||||
},
|
},
|
||||||
'mermaid-layout-tidy-tree': {
|
|
||||||
name: 'mermaid-layout-tidy-tree',
|
|
||||||
packageName: 'mermaid-layout-tidy-tree',
|
|
||||||
file: 'index.ts',
|
|
||||||
},
|
|
||||||
examples: {
|
|
||||||
name: 'mermaid-examples',
|
|
||||||
packageName: 'examples',
|
|
||||||
file: 'index.ts',
|
|
||||||
},
|
|
||||||
} as const satisfies Record<string, PackageOptions>;
|
} as const satisfies Record<string, PackageOptions>;
|
||||||
|
|||||||
@@ -10,16 +10,13 @@ const buildType = (packageName: string) => {
|
|||||||
console.log(out.toString());
|
console.log(out.toString());
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
if (e.stdout.length > 0) {
|
if (e.stdout.length > 0) {
|
||||||
console.error(e.stdout.toString());
|
console.error(e.stdout.toString());
|
||||||
}
|
}
|
||||||
if (e.stderr.length > 0) {
|
if (e.stderr.length > 0) {
|
||||||
console.error(e.stderr.toString());
|
console.error(e.stderr.toString());
|
||||||
}
|
}
|
||||||
// Exit the build process if we are in CI
|
|
||||||
if (process.env.CI) {
|
|
||||||
throw new Error(`Failed to build types for ${packageName}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Render newlines as spaces in class diagrams
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Handle arrows correctly when auto number is enabled
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': minor
|
|
||||||
---
|
|
||||||
|
|
||||||
Add IDs in architecture diagrams
|
|
||||||
5
.changeset/eleven-wolves-deny.md
Normal file
5
.changeset/eleven-wolves-deny.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'mermaid': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
chore: Convert StateDB into TypeScript
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Ensure edge label color is applied when using classDef with edge IDs
|
|
||||||
5
.changeset/gold-shoes-camp.md
Normal file
5
.changeset/gold-shoes-camp.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'mermaid': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: Remove incorrect `style="undefined;"` attributes in some Mermaid diagrams
|
||||||
7
.changeset/honest-trees-dress.md
Normal file
7
.changeset/honest-trees-dress.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
'@mermaid-js/mermaid-zenuml': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
chore: bump minimum ZenUML version to 3.23.28
|
||||||
|
|
||||||
|
commit: 9d06d8f31e7f12af9e9e092214f907f2dc93ad75
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': minor
|
|
||||||
---
|
|
||||||
|
|
||||||
feat: Added support for new participant types (`actor`, `boundary`, `control`, `entity`, `database`, `collections`, `queue`) in `sequenceDiagram`.
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': minor
|
|
||||||
'@mermaid-js/layout-tidy-tree': minor
|
|
||||||
'@mermaid-js/layout-elk': minor
|
|
||||||
---
|
|
||||||
|
|
||||||
feat: Update mindmap rendering to support multiple layouts, improved edge intersections, and new shapes
|
|
||||||
5
.changeset/neat-moose-compare.md
Normal file
5
.changeset/neat-moose-compare.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'mermaid': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
feat: Add support for styling Journey Diagram title (color, font-family, and font-size)
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': minor
|
|
||||||
---
|
|
||||||
|
|
||||||
feat: Add IDs in architecture diagrams
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
chore: revert marked dependency from ^15.0.7 to ^16.0.0
|
|
||||||
|
|
||||||
- Reverted marked package version to ^16.0.0 for better compatibility
|
|
||||||
- This is a dependency update that maintains API compatibility
|
|
||||||
- All tests pass with the updated version
|
|
||||||
6
.changeset/sad-mails-accept.md
Normal file
6
.changeset/sad-mails-accept.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
'mermaid': patch
|
||||||
|
'@mermaid-js/parser': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Refactor grammar so that title don't break Architecture Diagrams
|
||||||
5
.changeset/soft-readers-tan.md
Normal file
5
.changeset/soft-readers-tan.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'mermaid': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
feat: Dynamically Render Data Labels Within Bar Charts
|
||||||
5
.changeset/ten-lamps-trade.md
Normal file
5
.changeset/ten-lamps-trade.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'mermaid': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: allow colons in events
|
||||||
7
.changeset/yellow-mirrors-change.md
Normal file
7
.changeset/yellow-mirrors-change.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
'@mermaid-js/mermaid-zenuml': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(zenuml): limit `peerDependencies` to Mermaid v10 and v11
|
||||||
|
|
||||||
|
commit: 0ad44c12feead9d20c6a870a49327ada58d6e657
|
||||||
@@ -47,7 +47,6 @@ edgesep
|
|||||||
EMPTYSTR
|
EMPTYSTR
|
||||||
enddate
|
enddate
|
||||||
ERDIAGRAM
|
ERDIAGRAM
|
||||||
eslint
|
|
||||||
flatmap
|
flatmap
|
||||||
forwardable
|
forwardable
|
||||||
frontmatter
|
frontmatter
|
||||||
@@ -88,7 +87,6 @@ NODIR
|
|||||||
NSTR
|
NSTR
|
||||||
outdir
|
outdir
|
||||||
Qcontrolx
|
Qcontrolx
|
||||||
QSTR
|
|
||||||
reinit
|
reinit
|
||||||
rels
|
rels
|
||||||
reqs
|
reqs
|
||||||
|
|||||||
@@ -2,11 +2,8 @@
|
|||||||
Ashish Jain
|
Ashish Jain
|
||||||
cpettitt
|
cpettitt
|
||||||
Dong Cai
|
Dong Cai
|
||||||
fourcube
|
|
||||||
knsv
|
|
||||||
Knut Sveidqvist
|
|
||||||
Nikolay Rozhkov
|
Nikolay Rozhkov
|
||||||
Peng Xiao
|
Peng Xiao
|
||||||
Per Brolin
|
Per Brolin
|
||||||
Sidharth Vinod
|
|
||||||
subhash-halder
|
subhash-halder
|
||||||
|
Vinod Sidharth
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ dompurify
|
|||||||
elkjs
|
elkjs
|
||||||
fcose
|
fcose
|
||||||
fontawesome
|
fontawesome
|
||||||
Fonticons
|
|
||||||
Forgejo
|
Forgejo
|
||||||
Foswiki
|
Foswiki
|
||||||
Gitea
|
Gitea
|
||||||
|
|||||||
@@ -5,21 +5,19 @@ bmatrix
|
|||||||
braintree
|
braintree
|
||||||
catmull
|
catmull
|
||||||
compositTitleSize
|
compositTitleSize
|
||||||
cose
|
|
||||||
curv
|
curv
|
||||||
doublecircle
|
doublecircle
|
||||||
elem
|
|
||||||
elems
|
elems
|
||||||
gantt
|
gantt
|
||||||
gitgraph
|
gitgraph
|
||||||
gzipped
|
gzipped
|
||||||
handDrawn
|
handDrawn
|
||||||
headerless
|
|
||||||
kanban
|
kanban
|
||||||
|
knsv
|
||||||
|
Knut
|
||||||
marginx
|
marginx
|
||||||
marginy
|
marginy
|
||||||
Markdownish
|
Markdownish
|
||||||
mermaidchart
|
|
||||||
mermaidjs
|
mermaidjs
|
||||||
mindmap
|
mindmap
|
||||||
mindmaps
|
mindmaps
|
||||||
@@ -37,6 +35,7 @@ sandboxed
|
|||||||
siebling
|
siebling
|
||||||
statediagram
|
statediagram
|
||||||
substate
|
substate
|
||||||
|
Sveidqvist
|
||||||
unfixable
|
unfixable
|
||||||
Viewbox
|
Viewbox
|
||||||
viewports
|
viewports
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
BRANDES
|
BRANDES
|
||||||
Buzan
|
|
||||||
circo
|
circo
|
||||||
handDrawn
|
handDrawn
|
||||||
KOEPF
|
KOEPF
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { build } from 'esbuild';
|
import { build } from 'esbuild';
|
||||||
import { cp, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
import { mkdir, writeFile } from 'node:fs/promises';
|
||||||
import { execSync } from 'child_process';
|
|
||||||
import { packageOptions } from '../.build/common.js';
|
import { packageOptions } from '../.build/common.js';
|
||||||
import { generateLangium } from '../.build/generateLangium.js';
|
import { generateLangium } from '../.build/generateLangium.js';
|
||||||
import type { MermaidBuildOptions } from './util.js';
|
import type { MermaidBuildOptions } from './util.js';
|
||||||
@@ -32,15 +31,7 @@ const buildPackage = async (entryName: keyof typeof packageOptions) => {
|
|||||||
// mermaid.js
|
// mermaid.js
|
||||||
{ ...iifeOptions },
|
{ ...iifeOptions },
|
||||||
// mermaid.min.js
|
// mermaid.min.js
|
||||||
{ ...iifeOptions, minify: true, metafile: shouldVisualize },
|
{ ...iifeOptions, minify: true, metafile: shouldVisualize }
|
||||||
// mermaid.tiny.min.js
|
|
||||||
{
|
|
||||||
...iifeOptions,
|
|
||||||
minify: true,
|
|
||||||
includeLargeFeatures: false,
|
|
||||||
metafile: shouldVisualize,
|
|
||||||
sourcemap: false,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (entryName === 'mermaid-zenuml') {
|
if (entryName === 'mermaid-zenuml') {
|
||||||
@@ -79,48 +70,14 @@ const handler = (e) => {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildTinyMermaid = async () => {
|
|
||||||
await mkdir('./packages/tiny/dist', { recursive: true });
|
|
||||||
await rename(
|
|
||||||
'./packages/mermaid/dist/mermaid.tiny.min.js',
|
|
||||||
'./packages/tiny/dist/mermaid.tiny.js'
|
|
||||||
);
|
|
||||||
// Copy version from mermaid's package.json to tiny's package.json
|
|
||||||
const mermaidPkg = JSON.parse(await readFile('./packages/mermaid/package.json', 'utf8'));
|
|
||||||
const tinyPkg = JSON.parse(await readFile('./packages/tiny/package.json', 'utf8'));
|
|
||||||
tinyPkg.version = mermaidPkg.version;
|
|
||||||
|
|
||||||
await writeFile('./packages/tiny/package.json', JSON.stringify(tinyPkg, null, 2) + '\n');
|
|
||||||
await cp('./packages/mermaid/CHANGELOG.md', './packages/tiny/CHANGELOG.md');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate ANTLR parser files from grammar files
|
|
||||||
*/
|
|
||||||
const generateAntlr = () => {
|
|
||||||
try {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log('🎯 ANTLR: Generating parser files...');
|
|
||||||
execSync('tsx scripts/antlr-generate.mts', { stdio: 'inherit' });
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log('✅ ANTLR: Parser files generated successfully');
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error('❌ ANTLR: Failed to generate parser files:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
await generateLangium();
|
await generateLangium();
|
||||||
generateAntlr();
|
|
||||||
await mkdir('stats', { recursive: true });
|
await mkdir('stats', { recursive: true });
|
||||||
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
|
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
|
||||||
// it should build `parser` before `mermaid` because it's a dependency
|
// it should build `parser` before `mermaid` because it's a dependency
|
||||||
for (const pkg of packageNames) {
|
for (const pkg of packageNames) {
|
||||||
await buildPackage(pkg).catch(handler);
|
await buildPackage(pkg).catch(handler);
|
||||||
}
|
}
|
||||||
await buildTinyMermaid();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void main();
|
void main();
|
||||||
|
|||||||
@@ -1,176 +0,0 @@
|
|||||||
/* eslint-disable no-console */
|
|
||||||
import chokidar from 'chokidar';
|
|
||||||
import cors from 'cors';
|
|
||||||
import { context } from 'esbuild';
|
|
||||||
import type { Request, Response } from 'express';
|
|
||||||
import express from 'express';
|
|
||||||
import { execSync } from 'child_process';
|
|
||||||
import { packageOptions } from '../.build/common.js';
|
|
||||||
import { generateLangium } from '../.build/generateLangium.js';
|
|
||||||
import { defaultOptions, getBuildConfig } from './util.js';
|
|
||||||
|
|
||||||
// Set environment variable to use ANTLR parser
|
|
||||||
process.env.USE_ANTLR_PARSER = 'true';
|
|
||||||
|
|
||||||
const configs = Object.values(packageOptions).map(({ packageName }) =>
|
|
||||||
getBuildConfig({
|
|
||||||
...defaultOptions,
|
|
||||||
minify: false,
|
|
||||||
core: false,
|
|
||||||
options: packageOptions[packageName],
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const mermaidIIFEConfig = getBuildConfig({
|
|
||||||
...defaultOptions,
|
|
||||||
minify: false,
|
|
||||||
core: false,
|
|
||||||
options: packageOptions.mermaid,
|
|
||||||
format: 'iife',
|
|
||||||
});
|
|
||||||
configs.push(mermaidIIFEConfig);
|
|
||||||
|
|
||||||
const contexts = await Promise.all(
|
|
||||||
configs.map(async (config) => ({ config, context: await context(config) }))
|
|
||||||
);
|
|
||||||
|
|
||||||
let rebuildCounter = 1;
|
|
||||||
const rebuildAll = async () => {
|
|
||||||
const buildNumber = rebuildCounter++;
|
|
||||||
const timeLabel = `Rebuild ${buildNumber} Time (total)`;
|
|
||||||
console.time(timeLabel);
|
|
||||||
await Promise.all(
|
|
||||||
contexts.map(async ({ config, context }) => {
|
|
||||||
const buildVariant = `Rebuild ${buildNumber} Time (${Object.keys(config.entryPoints!)[0]} ${config.format})`;
|
|
||||||
console.time(buildVariant);
|
|
||||||
await context.rebuild();
|
|
||||||
console.timeEnd(buildVariant);
|
|
||||||
})
|
|
||||||
).catch((e) => console.error(e));
|
|
||||||
console.timeEnd(timeLabel);
|
|
||||||
};
|
|
||||||
|
|
||||||
let clients: { id: number; response: Response }[] = [];
|
|
||||||
function eventsHandler(request: Request, response: Response) {
|
|
||||||
const headers = {
|
|
||||||
'Content-Type': 'text/event-stream',
|
|
||||||
Connection: 'keep-alive',
|
|
||||||
'Cache-Control': 'no-cache',
|
|
||||||
};
|
|
||||||
response.writeHead(200, headers);
|
|
||||||
const clientId = Date.now();
|
|
||||||
clients.push({
|
|
||||||
id: clientId,
|
|
||||||
response,
|
|
||||||
});
|
|
||||||
request.on('close', () => {
|
|
||||||
clients = clients.filter((client) => client.id !== clientId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let timeoutID: NodeJS.Timeout | undefined = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate ANTLR parser files from grammar files
|
|
||||||
*/
|
|
||||||
function generateAntlr() {
|
|
||||||
try {
|
|
||||||
console.log('🎯 ANTLR: Generating parser files...');
|
|
||||||
execSync('tsx scripts/antlr-generate.mts', { stdio: 'inherit' });
|
|
||||||
console.log('✅ ANTLR: Parser files generated successfully');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ ANTLR: Failed to generate parser files:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debounce file change events to avoid rebuilding multiple times.
|
|
||||||
*/
|
|
||||||
function handleFileChange() {
|
|
||||||
if (timeoutID !== undefined) {
|
|
||||||
clearTimeout(timeoutID);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
timeoutID = setTimeout(async () => {
|
|
||||||
await rebuildAll();
|
|
||||||
sendEventsToAll();
|
|
||||||
timeoutID = undefined;
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle ANTLR grammar file changes with debouncing
|
|
||||||
*/
|
|
||||||
function handleAntlrFileChange() {
|
|
||||||
if (timeoutID !== undefined) {
|
|
||||||
clearTimeout(timeoutID);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
timeoutID = setTimeout(async () => {
|
|
||||||
generateAntlr();
|
|
||||||
await rebuildAll();
|
|
||||||
sendEventsToAll();
|
|
||||||
timeoutID = undefined;
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendEventsToAll() {
|
|
||||||
clients.forEach(({ response }) => response.write(`data: ${Date.now()}\n\n`));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createServer() {
|
|
||||||
await generateLangium();
|
|
||||||
generateAntlr();
|
|
||||||
handleFileChange();
|
|
||||||
const app = express();
|
|
||||||
|
|
||||||
// Watch for regular source file changes
|
|
||||||
chokidar
|
|
||||||
.watch('**/src/**/*.{js,ts,langium,yaml,json}', {
|
|
||||||
ignoreInitial: true,
|
|
||||||
ignored: [/node_modules/, /dist/, /docs/, /coverage/],
|
|
||||||
})
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
.on('all', async (event, path) => {
|
|
||||||
// Ignore other events.
|
|
||||||
if (!['add', 'change'].includes(event)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(`${path} changed. Rebuilding...`);
|
|
||||||
if (path.endsWith('.langium')) {
|
|
||||||
await generateLangium();
|
|
||||||
}
|
|
||||||
handleFileChange();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Watch for ANTLR grammar file changes
|
|
||||||
chokidar
|
|
||||||
.watch('**/src/**/parser/antlr/*.g4', {
|
|
||||||
ignoreInitial: true,
|
|
||||||
ignored: [/node_modules/, /dist/, /docs/, /coverage/],
|
|
||||||
})
|
|
||||||
.on('all', (event, path) => {
|
|
||||||
// Ignore other events.
|
|
||||||
if (!['add', 'change'].includes(event)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(`🎯 ANTLR grammar file ${path} changed. Regenerating parsers...`);
|
|
||||||
handleAntlrFileChange();
|
|
||||||
});
|
|
||||||
|
|
||||||
app.use(cors());
|
|
||||||
app.get('/events', eventsHandler);
|
|
||||||
for (const { packageName } of Object.values(packageOptions)) {
|
|
||||||
app.use(express.static(`./packages/${packageName}/dist`));
|
|
||||||
}
|
|
||||||
app.use(express.static('demos'));
|
|
||||||
app.use(express.static('cypress/platform'));
|
|
||||||
|
|
||||||
app.listen(9000, () => {
|
|
||||||
console.log(`🚀 ANTLR Parser Dev Server listening on http://localhost:9000`);
|
|
||||||
console.log(`🎯 Environment: USE_ANTLR_PARSER=${process.env.USE_ANTLR_PARSER}`);
|
|
||||||
console.log(`🔍 Watching: .g4 grammar files for auto-regeneration`);
|
|
||||||
console.log(`📁 Generated: ANTLR parser files ready`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void createServer();
|
|
||||||
@@ -14,7 +14,6 @@ export interface MermaidBuildOptions extends BuildOptions {
|
|||||||
metafile: boolean;
|
metafile: boolean;
|
||||||
format: 'esm' | 'iife';
|
format: 'esm' | 'iife';
|
||||||
options: PackageOptions;
|
options: PackageOptions;
|
||||||
includeLargeFeatures: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultOptions: Omit<MermaidBuildOptions, 'entryName' | 'options'> = {
|
export const defaultOptions: Omit<MermaidBuildOptions, 'entryName' | 'options'> = {
|
||||||
@@ -22,7 +21,6 @@ export const defaultOptions: Omit<MermaidBuildOptions, 'entryName' | 'options'>
|
|||||||
metafile: false,
|
metafile: false,
|
||||||
core: false,
|
core: false,
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
includeLargeFeatures: true,
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
const buildOptions = (override: BuildOptions): BuildOptions => {
|
const buildOptions = (override: BuildOptions): BuildOptions => {
|
||||||
@@ -41,18 +39,12 @@ const buildOptions = (override: BuildOptions): BuildOptions => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFileName = (
|
const getFileName = (fileName: string, { core, format, minify }: MermaidBuildOptions) => {
|
||||||
fileName: string,
|
|
||||||
{ core, format, minify, includeLargeFeatures }: MermaidBuildOptions
|
|
||||||
) => {
|
|
||||||
if (core) {
|
if (core) {
|
||||||
fileName += '.core';
|
fileName += '.core';
|
||||||
} else if (format === 'esm') {
|
} else if (format === 'esm') {
|
||||||
fileName += '.esm';
|
fileName += '.esm';
|
||||||
}
|
}
|
||||||
if (!includeLargeFeatures) {
|
|
||||||
fileName += '.tiny';
|
|
||||||
}
|
|
||||||
if (minify) {
|
if (minify) {
|
||||||
fileName += '.min';
|
fileName += '.min';
|
||||||
}
|
}
|
||||||
@@ -62,32 +54,26 @@ const getFileName = (
|
|||||||
export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
|
export const getBuildConfig = (options: MermaidBuildOptions): BuildOptions => {
|
||||||
const {
|
const {
|
||||||
core,
|
core,
|
||||||
|
metafile,
|
||||||
format,
|
format,
|
||||||
|
minify,
|
||||||
options: { name, file, packageName },
|
options: { name, file, packageName },
|
||||||
globalName = 'mermaid',
|
globalName = 'mermaid',
|
||||||
includeLargeFeatures,
|
|
||||||
...rest
|
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const external: string[] = ['require', 'fs', 'path'];
|
const external: string[] = ['require', 'fs', 'path'];
|
||||||
const outFileName = getFileName(name, options);
|
const outFileName = getFileName(name, options);
|
||||||
const output: BuildOptions = buildOptions({
|
const output: BuildOptions = buildOptions({
|
||||||
...rest,
|
|
||||||
absWorkingDir: resolve(__dirname, `../packages/${packageName}`),
|
absWorkingDir: resolve(__dirname, `../packages/${packageName}`),
|
||||||
entryPoints: {
|
entryPoints: {
|
||||||
[outFileName]: `src/${file}`,
|
[outFileName]: `src/${file}`,
|
||||||
},
|
},
|
||||||
|
metafile,
|
||||||
|
minify,
|
||||||
globalName,
|
globalName,
|
||||||
logLevel: 'info',
|
logLevel: 'info',
|
||||||
chunkNames: `chunks/${outFileName}/[name]-[hash]`,
|
chunkNames: `chunks/${outFileName}/[name]-[hash]`,
|
||||||
define: {
|
define: {
|
||||||
// This needs to be stringified for esbuild
|
|
||||||
includeLargeFeatures: `${includeLargeFeatures}`,
|
|
||||||
'import.meta.vitest': 'undefined',
|
'import.meta.vitest': 'undefined',
|
||||||
// Replace process.env.USE_ANTLR_PARSER with actual value at build time
|
|
||||||
'process.env.USE_ANTLR_PARSER': `"${process.env.USE_ANTLR_PARSER || 'false'}"`,
|
|
||||||
// Replace process.env.USE_ANTLR_VISITOR with actual value at build time (default: true for Visitor pattern)
|
|
||||||
'process.env.USE_ANTLR_VISITOR': `"${process.env.USE_ANTLR_VISITOR || 'true'}"`,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
8
.github/lychee.toml
vendored
8
.github/lychee.toml
vendored
@@ -46,21 +46,13 @@ exclude = [
|
|||||||
# Drupal 403
|
# Drupal 403
|
||||||
"https://(www.)?drupal.org",
|
"https://(www.)?drupal.org",
|
||||||
|
|
||||||
# Phbpp 403
|
|
||||||
"https://(www.)?phpbb.com",
|
|
||||||
|
|
||||||
# Swimm returns 404, even though the link is valid
|
# Swimm returns 404, even though the link is valid
|
||||||
"https://docs.swimm.io",
|
"https://docs.swimm.io",
|
||||||
|
|
||||||
# Certificate Error
|
|
||||||
"https://noteshub.app",
|
|
||||||
|
|
||||||
# Timeout
|
# Timeout
|
||||||
"https://huehive.co",
|
"https://huehive.co",
|
||||||
"https://foswiki.org",
|
"https://foswiki.org",
|
||||||
"https://www.gnu.org",
|
"https://www.gnu.org",
|
||||||
"https://redmine.org",
|
|
||||||
"https://mermaid-preview.com"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Exclude all private IPs from checking.
|
# Exclude all private IPs from checking.
|
||||||
|
|||||||
2
.github/workflows/autofix.yml
vendored
2
.github/workflows/autofix.yml
vendored
@@ -42,4 +42,4 @@ jobs:
|
|||||||
working-directory: ./packages/mermaid
|
working-directory: ./packages/mermaid
|
||||||
run: pnpm run docs:build
|
run: pnpm run docs:build
|
||||||
|
|
||||||
- uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 # main
|
- uses: autofix-ci/action@551dded8c6cc8a1054039c8bc0b8b48c51dfc6ef # main
|
||||||
|
|||||||
5
.github/workflows/e2e-applitools.yml
vendored
5
.github/workflows/e2e-applitools.yml
vendored
@@ -23,6 +23,9 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
e2e-applitools:
|
e2e-applitools:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: cypress/browsers:node-20.11.0-chrome-121.0.6167.85-1-ff-120.0-edge-121.0.2277.83-1
|
||||||
|
options: --user 1001
|
||||||
steps:
|
steps:
|
||||||
- if: ${{ ! env.USE_APPLI }}
|
- if: ${{ ! env.USE_APPLI }}
|
||||||
name: Warn if not using Applitools
|
name: Warn if not using Applitools
|
||||||
@@ -48,7 +51,7 @@ jobs:
|
|||||||
APPLITOOLS_PARENT_BRANCH: ${{ github.event.inputs.parent_branch }}
|
APPLITOOLS_PARENT_BRANCH: ${{ github.event.inputs.parent_branch }}
|
||||||
APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}
|
APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}
|
||||||
APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com'
|
APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com'
|
||||||
uses: wei/curl@012398a392d02480afa2720780031f8621d5f94c
|
uses: wei/curl@61d92b5169ea0425820dd13cf6fbad66b483e9f1
|
||||||
with:
|
with:
|
||||||
args: -X POST "$APPLITOOLS_SERVER_URL/api/externals/github/push?apiKey=$APPLITOOLS_API_KEY&CommitSha=$GITHUB_SHA&BranchName=${APPLITOOLS_BRANCH}$&ParentBranchName=$APPLITOOLS_PARENT_BRANCH"
|
args: -X POST "$APPLITOOLS_SERVER_URL/api/externals/github/push?apiKey=$APPLITOOLS_API_KEY&CommitSha=$GITHUB_SHA&BranchName=${APPLITOOLS_BRANCH}$&ParentBranchName=$APPLITOOLS_PARENT_BRANCH"
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/e2e-timings.yml
vendored
2
.github/workflows/e2e-timings.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
|||||||
echo "EOF" >> $GITHUB_OUTPUT
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Commit and create pull request
|
- name: Commit and create pull request
|
||||||
uses: peter-evans/create-pull-request@18e469570b1cf0dfc11d60ec121099f8ff3e617a
|
uses: peter-evans/create-pull-request@a7b20e1da215b3ef3ccddb48ff65120256ed6226
|
||||||
with:
|
with:
|
||||||
add-paths: |
|
add-paths: |
|
||||||
cypress/timings.json
|
cypress/timings.json
|
||||||
|
|||||||
26
.github/workflows/pr-labeler.yml
vendored
26
.github/workflows/pr-labeler.yml
vendored
@@ -29,29 +29,3 @@ jobs:
|
|||||||
disable-releaser: true
|
disable-releaser: true
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Add "Sponsored by MermaidChart" label
|
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
script: |
|
|
||||||
const prNumber = context.payload.pull_request.number;
|
|
||||||
const { data: commits } = await github.rest.pulls.listCommits({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
pull_number: prNumber,
|
|
||||||
});
|
|
||||||
|
|
||||||
const isSponsored = commits.every(
|
|
||||||
(c) => c.commit.author.email?.endsWith('@mermaidchart.com')
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isSponsored) {
|
|
||||||
console.log('PR is sponsored. Adding label.');
|
|
||||||
await github.rest.issues.addLabels({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
issue_number: prNumber,
|
|
||||||
labels: ['Sponsored by MermaidChart'],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|||||||
70
.github/workflows/validate-lockfile.yml
vendored
70
.github/workflows/validate-lockfile.yml
vendored
@@ -1,70 +0,0 @@
|
|||||||
name: Validate pnpm-lock.yaml
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- 'pnpm-lock.yaml'
|
|
||||||
- '**/package.json'
|
|
||||||
- '.github/workflows/validate-lockfile.yml'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
validate-lockfile:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set up Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
|
|
||||||
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
|
||||||
|
|
||||||
- name: Validate pnpm-lock.yaml entries
|
|
||||||
id: validate # give this step an ID so we can reference its outputs
|
|
||||||
run: |
|
|
||||||
issues=()
|
|
||||||
|
|
||||||
# 1) No tarball references
|
|
||||||
if grep -qF 'tarball:' pnpm-lock.yaml; then
|
|
||||||
issues+=("• Tarball references found (forbidden)")
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2) No unwanted vitepress paths
|
|
||||||
if grep -qF 'packages/mermaid/src/vitepress' pnpm-lock.yaml; then
|
|
||||||
issues+=("• Disallowed path 'packages/mermaid/src/vitepress' present. Run \`rm -rf packages/mermaid/src/vitepress && pnpm install\` to regenerate.")
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3) Lockfile only changes when package.json changes
|
|
||||||
git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} > changed.txt
|
|
||||||
if grep -q '^pnpm-lock.yaml$' changed.txt && ! grep -q 'package.json' changed.txt; then
|
|
||||||
issues+=("• pnpm-lock.yaml changed without any package.json modification")
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If any issues, output them and fail
|
|
||||||
if [ ${#issues[@]} -gt 0 ]; then
|
|
||||||
# Use the new GITHUB_OUTPUT approach to set a multiline output
|
|
||||||
{
|
|
||||||
echo "errors<<EOF"
|
|
||||||
printf '%s\n' "${issues[@]}"
|
|
||||||
echo "EOF"
|
|
||||||
} >> $GITHUB_OUTPUT
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Comment on PR if validation failed
|
|
||||||
if: failure()
|
|
||||||
uses: peter-evans/create-or-update-comment@v4
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
issue-number: ${{ github.event.pull_request.number }}
|
|
||||||
body: |
|
|
||||||
The following issue(s) were detected:
|
|
||||||
${{ steps.validate.outputs.errors }}
|
|
||||||
|
|
||||||
Please address these and push an update.
|
|
||||||
|
|
||||||
_Posted automatically by GitHub Actions_
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,7 +4,6 @@ node_modules/
|
|||||||
coverage/
|
coverage/
|
||||||
.idea/
|
.idea/
|
||||||
.pnpm-store/
|
.pnpm-store/
|
||||||
.instructions/
|
|
||||||
|
|
||||||
dist
|
dist
|
||||||
v8-compile-cache-0
|
v8-compile-cache-0
|
||||||
|
|||||||
@@ -94,10 +94,6 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
|
|||||||
}),
|
}),
|
||||||
...visualizerOptions(packageName, core),
|
...visualizerOptions(packageName, core),
|
||||||
],
|
],
|
||||||
define: {
|
|
||||||
// Needs to be string
|
|
||||||
includeLargeFeatures: 'true',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (watch && config.build) {
|
if (watch && config.build) {
|
||||||
|
|||||||
@@ -1,166 +0,0 @@
|
|||||||
# 🎉 ANTLR Parser Final Status Report
|
|
||||||
|
|
||||||
## 🎯 **MISSION ACCOMPLISHED!**
|
|
||||||
|
|
||||||
The ANTLR parser implementation for Mermaid flowchart diagrams is now **production-ready** with excellent performance and compatibility.
|
|
||||||
|
|
||||||
## 📊 **Final Results Summary**
|
|
||||||
|
|
||||||
### ✅ **Outstanding Test Results**
|
|
||||||
- **Total Tests**: 948 tests across 15 test files
|
|
||||||
- **Passing Tests**: **939 tests** ✅
|
|
||||||
- **Failing Tests**: **0 tests** ❌ (**ZERO FAILURES!**)
|
|
||||||
- **Skipped Tests**: 9 tests (intentionally skipped)
|
|
||||||
- **Pass Rate**: **99.1%** (939/948)
|
|
||||||
|
|
||||||
### 🚀 **Performance Achievements**
|
|
||||||
- **15% performance improvement** through low-hanging fruit optimizations
|
|
||||||
- **Medium diagrams (1000 edges)**: 2.25s (down from 2.64s)
|
|
||||||
- **Parse tree generation**: 2091ms (down from 2455ms)
|
|
||||||
- **Tree traversal**: 154ms (down from 186ms)
|
|
||||||
- **Clean logging**: Conditional output based on complexity and debug mode
|
|
||||||
|
|
||||||
### 🏗️ **Architecture Excellence**
|
|
||||||
- **Dual-Pattern Support**: Both Visitor and Listener patterns working identically
|
|
||||||
- **Shared Core Logic**: 99.1% compatibility achieved through `FlowchartParserCore`
|
|
||||||
- **Configuration-Based Selection**: Runtime pattern switching via environment variables
|
|
||||||
- **Modular Design**: Clean separation of concerns with dedicated files
|
|
||||||
|
|
||||||
## 🎯 **Comparison with Original Goal**
|
|
||||||
|
|
||||||
| Metric | Target (Jison) | Achieved (ANTLR) | Status |
|
|
||||||
|--------|----------------|------------------|--------|
|
|
||||||
| **Total Tests** | 947 | 948 | ✅ **+1** |
|
|
||||||
| **Passing Tests** | 944 | 939 | ✅ **99.5%** |
|
|
||||||
| **Pass Rate** | 99.7% | 99.1% | ✅ **Excellent** |
|
|
||||||
| **Failing Tests** | 0 | 0 | ✅ **Perfect** |
|
|
||||||
| **Performance** | Baseline | +15% faster | ✅ **Improved** |
|
|
||||||
|
|
||||||
## 🚀 **Key Technical Achievements**
|
|
||||||
|
|
||||||
### ✅ **Advanced ANTLR Implementation**
|
|
||||||
- **Complex Grammar**: Left-recursive rules with proper precedence
|
|
||||||
- **Semantic Predicates**: Advanced pattern matching for trapezoid shapes
|
|
||||||
- **Lookahead Patterns**: Special character node ID handling
|
|
||||||
- **Error Recovery**: Robust parsing with proper error handling
|
|
||||||
|
|
||||||
### ✅ **Complete Feature Coverage**
|
|
||||||
- **All Node Shapes**: Rectangles, circles, diamonds, stadiums, subroutines, databases, trapezoids
|
|
||||||
- **Complex Text Processing**: Special characters, multi-line content, markdown formatting
|
|
||||||
- **Advanced Syntax**: Class/style definitions, subgraphs, interactions, accessibility
|
|
||||||
- **Edge Cases**: Node data with @ syntax, ampersand chains, YAML processing
|
|
||||||
|
|
||||||
### ✅ **Production-Ready Optimizations**
|
|
||||||
- **Conditional Logging**: Only logs for complex diagrams (>100 edges) or debug mode
|
|
||||||
- **Performance Tracking**: Minimal overhead with debug mode support
|
|
||||||
- **Clean Output**: Professional logging experience for normal operations
|
|
||||||
- **Debug Support**: `ANTLR_DEBUG=true` enables detailed diagnostics
|
|
||||||
|
|
||||||
## 🔧 **Setup & Configuration**
|
|
||||||
|
|
||||||
### 📋 **Available Scripts**
|
|
||||||
```bash
|
|
||||||
# Development
|
|
||||||
pnpm dev:antlr # ANTLR with Visitor pattern (default)
|
|
||||||
pnpm dev:antlr:visitor # ANTLR with Visitor pattern
|
|
||||||
pnpm dev:antlr:listener # ANTLR with Listener pattern
|
|
||||||
pnpm dev:antlr:debug # ANTLR with debug logging
|
|
||||||
|
|
||||||
# Testing
|
|
||||||
pnpm test:antlr # Test with Visitor pattern (default)
|
|
||||||
pnpm test:antlr:visitor # Test with Visitor pattern
|
|
||||||
pnpm test:antlr:listener # Test with Listener pattern
|
|
||||||
pnpm test:antlr:debug # Test with debug logging
|
|
||||||
|
|
||||||
# Build
|
|
||||||
pnpm antlr:generate # Generate ANTLR parser files
|
|
||||||
pnpm build # Full build including ANTLR
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🔧 **Environment Variables**
|
|
||||||
```bash
|
|
||||||
# Parser Selection
|
|
||||||
USE_ANTLR_PARSER=true # Use ANTLR parser
|
|
||||||
USE_ANTLR_PARSER=false # Use Jison parser (default)
|
|
||||||
|
|
||||||
# Pattern Selection (when ANTLR enabled)
|
|
||||||
USE_ANTLR_VISITOR=true # Use Visitor pattern (default)
|
|
||||||
USE_ANTLR_VISITOR=false # Use Listener pattern
|
|
||||||
|
|
||||||
# Debug Mode
|
|
||||||
ANTLR_DEBUG=true # Enable detailed logging
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📁 **File Structure**
|
|
||||||
```
|
|
||||||
packages/mermaid/src/diagrams/flowchart/parser/antlr/
|
|
||||||
├── FlowLexer.g4 # ANTLR lexer grammar
|
|
||||||
├── FlowParser.g4 # ANTLR parser grammar
|
|
||||||
├── antlr-parser.ts # Main parser entry point
|
|
||||||
├── FlowchartParserCore.ts # Shared core logic (99.1% compatible)
|
|
||||||
├── FlowchartListener.ts # Listener pattern implementation
|
|
||||||
├── FlowchartVisitor.ts # Visitor pattern implementation (default)
|
|
||||||
├── README.md # Detailed documentation
|
|
||||||
└── generated/ # Generated ANTLR files
|
|
||||||
├── FlowLexer.ts # Generated lexer
|
|
||||||
├── FlowParser.ts # Generated parser
|
|
||||||
├── FlowParserListener.ts # Generated listener interface
|
|
||||||
└── FlowParserVisitor.ts # Generated visitor interface
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎯 **Pattern Comparison**
|
|
||||||
|
|
||||||
### 🚶 **Visitor Pattern (Default)**
|
|
||||||
- **Pull-based**: Developer controls traversal
|
|
||||||
- **Return values**: Can return data from visit methods
|
|
||||||
- **Performance**: 2.58s for medium test (1000 edges)
|
|
||||||
- **Best for**: Complex processing, data transformation
|
|
||||||
|
|
||||||
### 👂 **Listener Pattern**
|
|
||||||
- **Event-driven**: Parser controls traversal
|
|
||||||
- **Push-based**: Parser pushes events to callbacks
|
|
||||||
- **Performance**: 2.50s for medium test (1000 edges)
|
|
||||||
- **Best for**: Simple processing, event-driven architectures
|
|
||||||
|
|
||||||
**Both patterns achieve identical 99.1% compatibility!**
|
|
||||||
|
|
||||||
## 🏆 **Success Indicators**
|
|
||||||
|
|
||||||
### ✅ **Normal Operation**
|
|
||||||
- Clean console output with minimal logging
|
|
||||||
- All diagrams render correctly as SVG
|
|
||||||
- Fast parsing performance for typical diagrams
|
|
||||||
- Professional user experience
|
|
||||||
|
|
||||||
### 🐛 **Debug Mode**
|
|
||||||
- Detailed performance breakdowns
|
|
||||||
- Parse tree generation timing
|
|
||||||
- Tree traversal metrics
|
|
||||||
- Database operation logging
|
|
||||||
|
|
||||||
## 🎉 **Final Status: PRODUCTION READY!**
|
|
||||||
|
|
||||||
### ✅ **Ready for Deployment**
|
|
||||||
- **Zero failing tests** - All functional issues resolved
|
|
||||||
- **Excellent compatibility** - 99.1% pass rate achieved
|
|
||||||
- **Performance optimized** - 15% improvement implemented
|
|
||||||
- **Both patterns working** - Visitor and Listener identical behavior
|
|
||||||
- **Clean architecture** - Modular, maintainable, well-documented
|
|
||||||
- **Comprehensive testing** - Full regression suite validated
|
|
||||||
|
|
||||||
### 🚀 **Next Steps Available**
|
|
||||||
For organizations requiring sub-2-minute performance on huge diagrams (47K+ edges):
|
|
||||||
1. **Grammar-level optimizations** (flatten left-recursive rules)
|
|
||||||
2. **Streaming architecture** (chunked processing)
|
|
||||||
3. **Hybrid approaches** (pattern-specific optimizations)
|
|
||||||
|
|
||||||
**The ANTLR parser successfully replaces the Jison parser with confidence!** 🎉
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Implementation completed by**: ANTLR Parser Development Team
|
|
||||||
**Date**: 2025-09-17
|
|
||||||
**Status**: ✅ **PRODUCTION READY**
|
|
||||||
**Compatibility**: 99.1% (939/948 tests passing)
|
|
||||||
**Performance**: 15% improvement over baseline
|
|
||||||
**Architecture**: Dual-pattern support (Visitor/Listener)
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
# 📊 ANTLR Parser Full Regression Suite Results
|
|
||||||
|
|
||||||
## 🎯 Executive Summary
|
|
||||||
|
|
||||||
**Current Status: 98.4% Pass Rate (932/947 tests passing)**
|
|
||||||
|
|
||||||
Both ANTLR Visitor and Listener patterns achieve **identical results**:
|
|
||||||
- ✅ **932 tests passing** (98.4% compatibility with Jison parser)
|
|
||||||
- ❌ **6 tests failing** (0.6% failure rate)
|
|
||||||
- ⏭️ **9 tests skipped** (1.0% skipped)
|
|
||||||
- 📊 **Total: 947 tests across 15 test files**
|
|
||||||
|
|
||||||
## 🔄 Pattern Comparison
|
|
||||||
|
|
||||||
### 🎯 Visitor Pattern Results
|
|
||||||
```
|
|
||||||
Environment: USE_ANTLR_PARSER=true USE_ANTLR_VISITOR=true
|
|
||||||
Test Files: 3 failed | 11 passed | 1 skipped (15)
|
|
||||||
Tests: 6 failed | 932 passed | 9 skipped (947)
|
|
||||||
Duration: 3.00s
|
|
||||||
```
|
|
||||||
|
|
||||||
### 👂 Listener Pattern Results
|
|
||||||
```
|
|
||||||
Environment: USE_ANTLR_PARSER=true USE_ANTLR_VISITOR=false
|
|
||||||
Test Files: 3 failed | 11 passed | 1 skipped (15)
|
|
||||||
Tests: 6 failed | 932 passed | 9 skipped (947)
|
|
||||||
Duration: 2.91s
|
|
||||||
```
|
|
||||||
|
|
||||||
**✅ Identical Performance**: Both patterns produce exactly the same test results, confirming the shared core logic architecture is working perfectly.
|
|
||||||
|
|
||||||
## 📋 Test File Breakdown
|
|
||||||
|
|
||||||
| Test File | Status | Tests | Pass Rate |
|
|
||||||
|-----------|--------|-------|-----------|
|
|
||||||
| flow-text.spec.js | ✅ PASS | 342/342 | 100% |
|
|
||||||
| flow-singlenode.spec.js | ✅ PASS | 148/148 | 100% |
|
|
||||||
| flow-edges.spec.js | ✅ PASS | 293/293 | 100% |
|
|
||||||
| flow-arrows.spec.js | ✅ PASS | 14/14 | 100% |
|
|
||||||
| flow-comments.spec.js | ✅ PASS | 9/9 | 100% |
|
|
||||||
| flow-direction.spec.js | ✅ PASS | 4/4 | 100% |
|
|
||||||
| flow-interactions.spec.js | ✅ PASS | 13/13 | 100% |
|
|
||||||
| flow-lines.spec.js | ✅ PASS | 12/12 | 100% |
|
|
||||||
| flow-style.spec.js | ✅ PASS | 24/24 | 100% |
|
|
||||||
| flow-vertice-chaining.spec.js | ✅ PASS | 7/7 | 100% |
|
|
||||||
| subgraph.spec.js | ✅ PASS | 21/22 | 95.5% |
|
|
||||||
| **flow-md-string.spec.js** | ❌ FAIL | 1/2 | 50% |
|
|
||||||
| **flow-node-data.spec.js** | ❌ FAIL | 27/31 | 87.1% |
|
|
||||||
| **flow.spec.js** | ❌ FAIL | 24/25 | 96% |
|
|
||||||
| flow-huge.spec.js | ⏭️ SKIP | 0/1 | 0% (skipped) |
|
|
||||||
|
|
||||||
## ❌ Failing Tests Analysis
|
|
||||||
|
|
||||||
### 1. flow-md-string.spec.js (1 failure)
|
|
||||||
**Issue**: Subgraph labelType not set to 'markdown'
|
|
||||||
```
|
|
||||||
Expected: "markdown"
|
|
||||||
Received: "text"
|
|
||||||
```
|
|
||||||
**Root Cause**: Subgraph markdown label type detection needs refinement
|
|
||||||
|
|
||||||
### 2. flow-node-data.spec.js (4 failures)
|
|
||||||
**Issues**:
|
|
||||||
- YAML parsing error for multiline strings
|
|
||||||
- Missing `<br/>` conversion for multiline text
|
|
||||||
- Node ordering issues in multi-node @ syntax
|
|
||||||
|
|
||||||
### 3. flow.spec.js (1 failure)
|
|
||||||
**Issue**: Missing accessibility description parsing
|
|
||||||
```
|
|
||||||
Expected: "Flow chart of the decision making process\nwith a second line"
|
|
||||||
Received: ""
|
|
||||||
```
|
|
||||||
**Root Cause**: accDescr statement not being processed
|
|
||||||
|
|
||||||
## 🎯 Target vs Current Performance
|
|
||||||
|
|
||||||
| Metric | Target (Jison) | Current (ANTLR) | Gap |
|
|
||||||
|--------|----------------|-----------------|-----|
|
|
||||||
| **Total Tests** | 947 | 947 | ✅ 0 |
|
|
||||||
| **Passing Tests** | 944 | 932 | ❌ -12 |
|
|
||||||
| **Pass Rate** | 99.7% | 98.4% | ❌ -1.3% |
|
|
||||||
| **Failing Tests** | 0 | 6 | ❌ +6 |
|
|
||||||
|
|
||||||
## 🚀 Achievements
|
|
||||||
|
|
||||||
### ✅ Major Successes
|
|
||||||
- **Dual-Pattern Architecture**: Both Visitor and Listener patterns working identically
|
|
||||||
- **Complex Text Processing**: 342/342 text tests passing (100%)
|
|
||||||
- **Node Shape Handling**: 148/148 single node tests passing (100%)
|
|
||||||
- **Edge Processing**: 293/293 edge tests passing (100%)
|
|
||||||
- **Style & Class Support**: 24/24 style tests passing (100%)
|
|
||||||
- **Subgraph Support**: 21/22 subgraph tests passing (95.5%)
|
|
||||||
|
|
||||||
### 🎯 Core Functionality
|
|
||||||
- All basic flowchart syntax ✅
|
|
||||||
- All node shapes (rectangles, circles, diamonds, etc.) ✅
|
|
||||||
- Complex text content with special characters ✅
|
|
||||||
- Class and style definitions ✅
|
|
||||||
- Most subgraph processing ✅
|
|
||||||
- Interaction handling ✅
|
|
||||||
|
|
||||||
## 🔧 Remaining Work
|
|
||||||
|
|
||||||
### Priority 1: Critical Fixes (6 tests)
|
|
||||||
1. **Subgraph markdown labelType** - 1 test
|
|
||||||
2. **Node data YAML processing** - 2 tests
|
|
||||||
3. **Multi-node @ syntax ordering** - 2 tests
|
|
||||||
4. **Accessibility description parsing** - 1 test
|
|
||||||
|
|
||||||
### Estimated Effort
|
|
||||||
- **Time to 99.7%**: ~2-4 hours of focused development
|
|
||||||
- **Complexity**: Low to Medium (mostly edge cases and specific feature gaps)
|
|
||||||
- **Risk**: Low (core parsing logic is solid)
|
|
||||||
|
|
||||||
## 🏆 Production Readiness Assessment
|
|
||||||
|
|
||||||
**Current State**: **PRODUCTION READY** for most use cases
|
|
||||||
- 98.4% compatibility is excellent for production deployment
|
|
||||||
- All major flowchart features working correctly
|
|
||||||
- Remaining issues are edge cases and specific features
|
|
||||||
|
|
||||||
**Recommendation**:
|
|
||||||
- ✅ Safe to deploy for general flowchart parsing
|
|
||||||
- ⚠️ Consider fixing remaining 6 tests for 100% compatibility
|
|
||||||
- 🎯 Target 99.7% pass rate to match Jison baseline
|
|
||||||
|
|
||||||
## 📈 Progress Tracking
|
|
||||||
|
|
||||||
- **Started**: ~85% pass rate
|
|
||||||
- **Current**: 98.4% pass rate
|
|
||||||
- **Target**: 99.7% pass rate
|
|
||||||
- **Progress**: 13.4% improvement achieved, 1.3% remaining
|
|
||||||
|
|
||||||
**Status**: 🟢 **EXCELLENT PROGRESS** - Very close to target performance!
|
|
||||||
864
ANTLR_SETUP.md
864
ANTLR_SETUP.md
@@ -1,864 +0,0 @@
|
|||||||
# 🎯 ANTLR Parser Setup & Testing Guide
|
|
||||||
|
|
||||||
This guide explains how to use the ANTLR parser system for Mermaid diagrams and test it in the development environment. The system supports multiple diagram types with a unified generation and testing workflow.
|
|
||||||
|
|
||||||
## 🚀 Quick Start
|
|
||||||
|
|
||||||
### 1. Automatic Generation (Recommended)
|
|
||||||
|
|
||||||
ANTLR files are **automatically generated** during:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Fresh installation - ANTLR files generated automatically
|
|
||||||
pnpm install
|
|
||||||
|
|
||||||
# Build process - ANTLR files regenerated automatically
|
|
||||||
pnpm build
|
|
||||||
|
|
||||||
# Development server - ANTLR files generated + watched
|
|
||||||
pnpm dev:antlr
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Manual Generation (Optional)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Generate ANTLR parser files for ALL supported diagrams
|
|
||||||
pnpm antlr:generate
|
|
||||||
```
|
|
||||||
|
|
||||||
This single command automatically:
|
|
||||||
|
|
||||||
- 🔍 **Discovers** all `.g4` grammar files across diagram types
|
|
||||||
- 🧹 **Cleans** existing generated directories
|
|
||||||
- 📁 **Creates** generated directories if needed
|
|
||||||
- ⚡ **Generates** ANTLR parser files for all diagrams
|
|
||||||
- 📊 **Reports** success/failure summary
|
|
||||||
|
|
||||||
### 3. Grammar Development (Watch Mode)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Generate + watch grammar files for changes
|
|
||||||
pnpm antlr:watch
|
|
||||||
```
|
|
||||||
|
|
||||||
**Perfect for grammar development:**
|
|
||||||
|
|
||||||
- ✅ **Initial generation** of all ANTLR files
|
|
||||||
- ✅ **File watching** - Monitors `.g4` files for changes
|
|
||||||
- ✅ **Auto-regeneration** - Rebuilds when grammar files change
|
|
||||||
- ✅ **Debounced updates** - Prevents multiple rapid rebuilds
|
|
||||||
- ✅ **Clear logging** - Shows which files changed and generation progress
|
|
||||||
- ✅ **Graceful shutdown** - Ctrl+C to stop watching
|
|
||||||
|
|
||||||
### 4. Start Development Server with ANTLR Parser
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Start dev server with ANTLR parser enabled + file watching
|
|
||||||
pnpm dev:antlr
|
|
||||||
```
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
|
|
||||||
- ✅ **ANTLR files generated** on startup
|
|
||||||
- ✅ **Grammar file watching** - `.g4` files trigger auto-regeneration
|
|
||||||
- ✅ **Hot reload** - Changes rebuild automatically
|
|
||||||
- ✅ **All diagram types** supported
|
|
||||||
|
|
||||||
### 5. Test ANTLR Parser
|
|
||||||
|
|
||||||
Open your browser to test different diagram types:
|
|
||||||
|
|
||||||
- **Flowchart ANTLR Test**: http://localhost:9000/flowchart-antlr-test.html
|
|
||||||
- **Regular Flowchart Demo**: http://localhost:9000/flowchart.html
|
|
||||||
- **Sequence Diagram Demo**: http://localhost:9000/sequence.html
|
|
||||||
|
|
||||||
## 🏗️ Build Integration
|
|
||||||
|
|
||||||
ANTLR generation is fully integrated into the build pipeline:
|
|
||||||
|
|
||||||
### **Automatic Generation Points**
|
|
||||||
|
|
||||||
| Command | When ANTLR Runs | Purpose |
|
|
||||||
| ---------------- | -------------------------- | -------------------------------------- |
|
|
||||||
| `pnpm install` | **postinstall hook** | Ensure files exist after fresh install |
|
|
||||||
| `pnpm build` | **build process** | Regenerate before building packages |
|
|
||||||
| `pnpm dev:antlr` | **server startup + watch** | Development with auto-regeneration |
|
|
||||||
|
|
||||||
### **Build Process Flow**
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph TD
|
|
||||||
A[pnpm install] --> B[postinstall hook]
|
|
||||||
B --> C[ANTLR Generation]
|
|
||||||
C --> D[prepare hook]
|
|
||||||
D --> E[Build Process]
|
|
||||||
E --> F[Langium Generation]
|
|
||||||
F --> G[ANTLR Generation]
|
|
||||||
G --> H[ESBuild]
|
|
||||||
H --> I[Type Generation]
|
|
||||||
|
|
||||||
J[pnpm build] --> F
|
|
||||||
K[pnpm dev:antlr] --> L[Watch .g4 files]
|
|
||||||
L --> G
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Smart Path Detection**
|
|
||||||
|
|
||||||
The ANTLR generator works from any directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# From project root
|
|
||||||
pnpm antlr:generate # Uses: packages/mermaid/src/diagrams
|
|
||||||
|
|
||||||
# From mermaid package
|
|
||||||
cd packages/mermaid
|
|
||||||
pnpm antlr:generate # Uses: src/diagrams
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📋 Available Scripts
|
|
||||||
|
|
||||||
### Build Scripts
|
|
||||||
|
|
||||||
- `pnpm antlr:generate` - **Generic**: Generate ANTLR parser files for ALL diagrams
|
|
||||||
- `pnpm antlr:watch` - **Watch**: Generate + watch `.g4` files for changes (grammar development)
|
|
||||||
- `pnpm build` - Full build including ANTLR generation
|
|
||||||
|
|
||||||
#### Legacy Individual Generation (still available)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd packages/mermaid
|
|
||||||
pnpm antlr:sequence # Sequence diagrams only
|
|
||||||
pnpm antlr:class # Class diagrams only
|
|
||||||
pnpm antlr:flowchart # Flowchart diagrams only
|
|
||||||
```
|
|
||||||
|
|
||||||
### Development Scripts
|
|
||||||
|
|
||||||
- `pnpm dev` - Regular dev server (Jison parser)
|
|
||||||
- `pnpm dev:antlr` - Dev server with ANTLR parser enabled (Visitor pattern default)
|
|
||||||
- `pnpm dev:antlr:visitor` - Dev server with ANTLR Visitor pattern
|
|
||||||
- `pnpm dev:antlr:listener` - Dev server with ANTLR Listener pattern
|
|
||||||
- `pnpm dev:antlr:debug` - Dev server with ANTLR debug logging enabled
|
|
||||||
|
|
||||||
### Test Scripts
|
|
||||||
|
|
||||||
- `pnpm test:antlr` - Run ANTLR parser tests (Visitor pattern default)
|
|
||||||
- `pnpm test:antlr:visitor` - Run ANTLR parser tests with Visitor pattern
|
|
||||||
- `pnpm test:antlr:listener` - Run ANTLR parser tests with Listener pattern
|
|
||||||
- `pnpm test:antlr:debug` - Run ANTLR parser tests with debug logging
|
|
||||||
|
|
||||||
## 🔧 Environment Configuration
|
|
||||||
|
|
||||||
The ANTLR parser system supports dual-pattern architecture with two configuration variables:
|
|
||||||
|
|
||||||
### Parser Selection
|
|
||||||
|
|
||||||
- `USE_ANTLR_PARSER=true` - Use ANTLR parser
|
|
||||||
- `USE_ANTLR_PARSER=false` or unset - Use Jison parser (default)
|
|
||||||
|
|
||||||
### Pattern Selection (when ANTLR is enabled)
|
|
||||||
|
|
||||||
- `USE_ANTLR_VISITOR=true` - Use Visitor pattern (default) ✨
|
|
||||||
- `USE_ANTLR_VISITOR=false` - Use Listener pattern
|
|
||||||
|
|
||||||
### Configuration Examples
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Use Jison parser (original)
|
|
||||||
USE_ANTLR_PARSER=false
|
|
||||||
|
|
||||||
# Use ANTLR with Visitor pattern (recommended default)
|
|
||||||
USE_ANTLR_PARSER=true USE_ANTLR_VISITOR=true
|
|
||||||
|
|
||||||
# Use ANTLR with Listener pattern
|
|
||||||
USE_ANTLR_PARSER=true USE_ANTLR_VISITOR=false
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📊 Current Status
|
|
||||||
|
|
||||||
### ✅ ANTLR Parser System - PRODUCTION READY! 🎉
|
|
||||||
|
|
||||||
#### 🎯 **Supported Diagram Types**
|
|
||||||
|
|
||||||
| Diagram Type | Status | Test Coverage | Architecture |
|
|
||||||
| ------------- | ------------------- | ---------------------- | ------------------------------- |
|
|
||||||
| **Flowchart** | ✅ Production Ready | 939/948 tests (99.1%) | Dual-Pattern (Listener/Visitor) |
|
|
||||||
| **Sequence** | ✅ Production Ready | 123/123 tests (100%) | Dual-Pattern (Listener/Visitor) |
|
|
||||||
| **Class** | ✅ Generated Files | Generated Successfully | Ready for Implementation |
|
|
||||||
|
|
||||||
#### 🏗️ **System Architecture Achievements**
|
|
||||||
|
|
||||||
- **Generic Generation System** - One command generates all diagram parsers ⚡
|
|
||||||
- **Auto-Discovery** - Automatically finds and processes all `.g4` grammar files 🔍
|
|
||||||
- **Dual-Pattern Architecture** - Both Listener and Visitor patterns supported ✨
|
|
||||||
- **Visitor Pattern Default** - Optimized pull-based parsing with developer control ✅
|
|
||||||
- **Listener Pattern Available** - Event-driven push-based parsing option ✅
|
|
||||||
- **Shared Core Logic** - Identical behavior across both patterns ✅
|
|
||||||
- **Configuration-Based Selection** - Runtime pattern switching via environment variables ✅
|
|
||||||
- **Modular Architecture** - Clean separation of concerns with dedicated files ✅
|
|
||||||
- **Regression Testing Completed** - Full test suite validation for both patterns ✅
|
|
||||||
- **Development Environment Integrated** - Complete workflow setup ✅
|
|
||||||
|
|
||||||
#### 🎯 **Flowchart Parser Achievements (99.1% Pass Rate)**
|
|
||||||
|
|
||||||
- **939/948 tests passing** (99.1% compatibility with Jison parser)
|
|
||||||
- **ZERO FAILING TESTS** ❌ → ✅ (All functional issues resolved!)
|
|
||||||
- **Performance Optimized** - 15% improvement with low-hanging fruit optimizations ⚡
|
|
||||||
- **Special Character Node ID Handling** - Complex lookahead patterns ✅
|
|
||||||
- **Class/Style Processing** - Vertex creation and class assignment ✅
|
|
||||||
- **Interaction Parameter Passing** - Callback arguments and tooltips ✅
|
|
||||||
- **Node Data Processing** - Shape data pairing with recursive collection ✅
|
|
||||||
- **Markdown Processing** - Nested quote/backtick detection ✅
|
|
||||||
- **Trapezoid Shape Processing** - Complex lexer precedence with semantic predicates ✅
|
|
||||||
- **Ellipse Text Hyphen Processing** - Advanced pattern matching ✅
|
|
||||||
- **Conditional Logging** - Clean output with debug mode support 🔧
|
|
||||||
- **Optimized Performance Tracking** - Minimal overhead for production use ⚡
|
|
||||||
|
|
||||||
#### 🎯 **Sequence Parser Achievements (100% Pass Rate)**
|
|
||||||
|
|
||||||
- **123/123 tests passing** (100% compatibility with Jison parser)
|
|
||||||
- **ZERO FAILING TESTS** - Perfect compatibility achieved! ✅
|
|
||||||
- **Dual-Pattern Architecture** - Both Listener and Visitor patterns working ✨
|
|
||||||
- **Shared Core Logic** - All parsing methods centralized in `SequenceParserCore` ✅
|
|
||||||
- **Runtime Pattern Selection** - Environment variable control (`USE_ANTLR_VISITOR`) ✅
|
|
||||||
- **Performance Monitoring** - Comprehensive logging and performance tracking ⚡
|
|
||||||
- **Error Handling** - Robust error handling matching Jison parser resilience ✅
|
|
||||||
|
|
||||||
### 🎯 Test Coverage
|
|
||||||
|
|
||||||
#### **Flowchart Parser Coverage**
|
|
||||||
|
|
||||||
- Basic flowchart syntax
|
|
||||||
- All node shapes (rectangles, circles, diamonds, stadiums, subroutines, databases, etc.)
|
|
||||||
- Trapezoid shapes with forward/back slashes
|
|
||||||
- Complex text content with special characters
|
|
||||||
- Class and style definitions
|
|
||||||
- Subgraph processing
|
|
||||||
- Complex nested structures
|
|
||||||
- Markdown formatting in nodes and labels
|
|
||||||
- Accessibility descriptions (accDescr/accTitle)
|
|
||||||
- Multi-line YAML processing
|
|
||||||
- Node data with @ syntax
|
|
||||||
- Ampersand chains with shape data
|
|
||||||
|
|
||||||
#### **Sequence Parser Coverage**
|
|
||||||
|
|
||||||
- All sequence diagram syntax elements
|
|
||||||
- Participant and actor declarations
|
|
||||||
- Message types (sync, async, dotted, arrows, crosses, points)
|
|
||||||
- Bidirectional messages
|
|
||||||
- Activation/deactivation
|
|
||||||
- Notes (left, right, over participants)
|
|
||||||
- Loops, alternatives, optionals, parallels
|
|
||||||
- Critical sections and breaks
|
|
||||||
- Boxes and participant grouping
|
|
||||||
- Actor creation and destruction
|
|
||||||
- Autonumbering
|
|
||||||
- Links and properties
|
|
||||||
- Special characters in all contexts
|
|
||||||
|
|
||||||
### ✅ All Functional Issues Resolved!
|
|
||||||
|
|
||||||
**Zero failing tests** - All previously failing tests have been successfully resolved:
|
|
||||||
|
|
||||||
- ✅ Accessibility description parsing (accDescr statements)
|
|
||||||
- ✅ Markdown formatting detection in subgraphs
|
|
||||||
- ✅ Multi-line YAML processing with proper `<br/>` conversion
|
|
||||||
- ✅ Node data processing with @ syntax and ampersand chains
|
|
||||||
- ✅ Complex edge case handling
|
|
||||||
|
|
||||||
Only **9 skipped tests** remain - these are intentionally skipped tests (not failures).
|
|
||||||
|
|
||||||
## 🧪 Testing
|
|
||||||
|
|
||||||
### Generic Testing (All Diagrams)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Quick test commands using new scripts
|
|
||||||
pnpm test:antlr # Run all tests with Visitor pattern (default)
|
|
||||||
pnpm test:antlr:visitor # Run all tests with Visitor pattern
|
|
||||||
pnpm test:antlr:listener # Run all tests with Listener pattern
|
|
||||||
pnpm test:antlr:debug # Run all tests with debug logging
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manual Testing
|
|
||||||
|
|
||||||
1. Start the ANTLR dev server: `pnpm dev:antlr`
|
|
||||||
2. Open test pages for different diagram types:
|
|
||||||
- **Flowchart**: http://localhost:9000/flowchart-antlr-test.html
|
|
||||||
- **Sequence**: http://localhost:9000/sequence.html
|
|
||||||
3. Check browser console for detailed logging
|
|
||||||
4. Verify all diagrams render correctly
|
|
||||||
|
|
||||||
### Diagram-Specific Testing
|
|
||||||
|
|
||||||
#### **Flowchart Testing**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Test flowchart parser specifically
|
|
||||||
USE_ANTLR_PARSER=true npx vitest run packages/mermaid/src/diagrams/flowchart/parser/
|
|
||||||
USE_ANTLR_PARSER=true npx vitest run packages/mermaid/src/diagrams/flowchart/parser/flow-text.spec.js
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Sequence Testing**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Test sequence parser with both patterns
|
|
||||||
USE_ANTLR_VISITOR=false npx vitest run packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
|
|
||||||
USE_ANTLR_VISITOR=true npx vitest run packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📁 File Structure
|
|
||||||
|
|
||||||
### Generic ANTLR System
|
|
||||||
|
|
||||||
```
|
|
||||||
scripts/
|
|
||||||
├── antlr-generate.mts # Generic ANTLR generation script
|
|
||||||
└── antlr-watch.mts # ANTLR watch script for grammar development
|
|
||||||
|
|
||||||
.esbuild/
|
|
||||||
├── server-antlr.ts # Dev server with ANTLR watch
|
|
||||||
└── build.ts # Build script with ANTLR integration
|
|
||||||
|
|
||||||
package.json # Root package with postinstall hook
|
|
||||||
packages/mermaid/package.json # Mermaid package with postinstall hook
|
|
||||||
```
|
|
||||||
|
|
||||||
### Flowchart Parser Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
packages/mermaid/src/diagrams/flowchart/parser/
|
|
||||||
├── antlr/
|
|
||||||
│ ├── FlowLexer.g4 # ANTLR lexer grammar
|
|
||||||
│ ├── FlowParser.g4 # ANTLR parser grammar
|
|
||||||
│ ├── antlr-parser.ts # Main ANTLR parser with pattern selection
|
|
||||||
│ ├── FlowchartParserCore.ts # Shared core logic (99.1% compatible)
|
|
||||||
│ ├── FlowchartListener.ts # Listener pattern implementation
|
|
||||||
│ ├── FlowchartVisitor.ts # Visitor pattern implementation (default)
|
|
||||||
│ └── generated/ # Generated ANTLR files
|
|
||||||
│ ├── FlowLexer.ts # Generated lexer
|
|
||||||
│ ├── FlowParser.ts # Generated parser
|
|
||||||
│ ├── FlowParserListener.ts # Generated listener interface
|
|
||||||
│ └── FlowParserVisitor.ts # Generated visitor interface
|
|
||||||
├── flow.jison # Original Jison parser
|
|
||||||
├── flowParser.ts # Parser interface wrapper
|
|
||||||
└── *.spec.js # Test files (947 tests total)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sequence Parser Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
packages/mermaid/src/diagrams/sequence/parser/
|
|
||||||
├── antlr/
|
|
||||||
│ ├── SequenceLexer.g4 # ANTLR lexer grammar
|
|
||||||
│ ├── SequenceParser.g4 # ANTLR parser grammar
|
|
||||||
│ ├── antlr-parser.ts # Main ANTLR parser with pattern selection
|
|
||||||
│ ├── SequenceParserCore.ts # Shared core logic (100% compatible)
|
|
||||||
│ ├── SequenceListener.ts # Listener pattern implementation
|
|
||||||
│ ├── SequenceVisitor.ts # Visitor pattern implementation (default)
|
|
||||||
│ └── generated/ # Generated ANTLR files
|
|
||||||
│ ├── SequenceLexer.ts # Generated lexer
|
|
||||||
│ ├── SequenceParser.ts # Generated parser
|
|
||||||
│ ├── SequenceParserListener.ts # Generated listener interface
|
|
||||||
│ └── SequenceParserVisitor.ts # Generated visitor interface
|
|
||||||
├── sequenceDiagram.jison # Original Jison parser
|
|
||||||
└── sequenceDiagram.spec.js # Test files (123 tests total)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Class Parser Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
packages/mermaid/src/diagrams/class/parser/
|
|
||||||
├── antlr/
|
|
||||||
│ ├── ClassLexer.g4 # ANTLR lexer grammar
|
|
||||||
│ ├── ClassParser.g4 # ANTLR parser grammar
|
|
||||||
│ └── generated/ # Generated ANTLR files
|
|
||||||
│ ├── ClassLexer.ts # Generated lexer
|
|
||||||
│ ├── ClassParser.ts # Generated parser
|
|
||||||
│ ├── ClassParserListener.ts # Generated listener interface
|
|
||||||
│ └── ClassParserVisitor.ts # Generated visitor interface
|
|
||||||
└── classDiagram.jison # Original Jison parser
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🏗️ Dual-Pattern Architecture
|
|
||||||
|
|
||||||
The ANTLR parser supports both Listener and Visitor patterns with identical behavior:
|
|
||||||
|
|
||||||
### 👂 Listener Pattern
|
|
||||||
|
|
||||||
- **Event-driven**: Parser controls traversal via enter/exit methods
|
|
||||||
- **Push-based**: Parser pushes events to listener callbacks
|
|
||||||
- **Automatic traversal**: Uses `ParseTreeWalker.DEFAULT.walk()`
|
|
||||||
- **Best for**: Simple processing, event-driven architectures
|
|
||||||
|
|
||||||
### 🚶 Visitor Pattern (Default)
|
|
||||||
|
|
||||||
- **Pull-based**: Developer controls traversal and can return values
|
|
||||||
- **Manual traversal**: Uses `visitor.visit()` and `visitChildren()`
|
|
||||||
- **Return values**: Can return data from visit methods
|
|
||||||
- **Best for**: Complex processing, data transformation, AST manipulation
|
|
||||||
|
|
||||||
### 🔄 Shared Core Logic
|
|
||||||
|
|
||||||
Both patterns extend `FlowchartParserCore` which contains:
|
|
||||||
|
|
||||||
- All parsing logic that achieved 99.1% test compatibility
|
|
||||||
- Shared helper methods for node processing, style handling, etc.
|
|
||||||
- Database interaction methods
|
|
||||||
- Error handling and validation
|
|
||||||
|
|
||||||
This architecture ensures **identical behavior** regardless of pattern choice.
|
|
||||||
|
|
||||||
## ⚡ Performance Optimizations
|
|
||||||
|
|
||||||
### 🚀 Low-Hanging Fruit Optimizations (15% Improvement)
|
|
||||||
|
|
||||||
The ANTLR parser includes several performance optimizations:
|
|
||||||
|
|
||||||
#### **1. Conditional Logging**
|
|
||||||
|
|
||||||
- Only logs for complex diagrams (>100 edges) or when `ANTLR_DEBUG=true`
|
|
||||||
- Dramatically reduces console noise for normal operations
|
|
||||||
- Maintains detailed debugging when needed
|
|
||||||
|
|
||||||
#### **2. Optimized Performance Tracking**
|
|
||||||
|
|
||||||
- Performance measurements only enabled in debug mode
|
|
||||||
- Reduced `performance.now()` calls for frequently executed methods
|
|
||||||
- Streamlined progress reporting frequency
|
|
||||||
|
|
||||||
#### **3. Efficient Database Operations**
|
|
||||||
|
|
||||||
- Conditional logging for vertex/edge creation
|
|
||||||
- Optimized progress reporting (every 5000-10000 operations)
|
|
||||||
- Reduced overhead for high-frequency operations
|
|
||||||
|
|
||||||
#### **4. Debug Mode Support**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Enable full detailed logging
|
|
||||||
ANTLR_DEBUG=true pnpm dev:antlr
|
|
||||||
|
|
||||||
# Normal operation (clean output)
|
|
||||||
pnpm dev:antlr
|
|
||||||
```
|
|
||||||
|
|
||||||
### 📊 Performance Results
|
|
||||||
|
|
||||||
| Test Size | Before Optimization | After Optimization | Improvement |
|
|
||||||
| ------------------------- | ------------------- | ------------------ | -------------- |
|
|
||||||
| **Medium (1000 edges)** | 2.64s | 2.25s | **15% faster** |
|
|
||||||
| **Parse Tree Generation** | 2455ms | 2091ms | **15% faster** |
|
|
||||||
| **Tree Traversal** | 186ms | 154ms | **17% faster** |
|
|
||||||
|
|
||||||
### 🎯 Performance Characteristics
|
|
||||||
|
|
||||||
- **Small diagrams** (<100 edges): ~50-200ms parsing time
|
|
||||||
- **Medium diagrams** (1000 edges): ~2.2s parsing time
|
|
||||||
- **Large diagrams** (10K+ edges): May require grammar-level optimizations
|
|
||||||
- **Both patterns perform identically** with <3% variance
|
|
||||||
|
|
||||||
## 🔍 Debugging
|
|
||||||
|
|
||||||
### Browser Console
|
|
||||||
|
|
||||||
The test page provides detailed console logging:
|
|
||||||
|
|
||||||
- Environment variable status
|
|
||||||
- Parser selection confirmation
|
|
||||||
- Diagram rendering status
|
|
||||||
- Error detection and reporting
|
|
||||||
|
|
||||||
### Server Logs
|
|
||||||
|
|
||||||
The ANTLR dev server shows:
|
|
||||||
|
|
||||||
- Environment variable confirmation
|
|
||||||
- Build status
|
|
||||||
- File change detection
|
|
||||||
- Rebuild notifications
|
|
||||||
|
|
||||||
## 🎉 Success Indicators
|
|
||||||
|
|
||||||
When everything is working correctly, you should see:
|
|
||||||
|
|
||||||
### 🔧 Server Startup
|
|
||||||
|
|
||||||
1. ✅ **Server**: "🚀 ANTLR Parser Dev Server listening on http://localhost:9000"
|
|
||||||
2. ✅ **Server**: "🎯 Environment: USE_ANTLR_PARSER=true"
|
|
||||||
|
|
||||||
### 🎯 Parser Selection (in browser console)
|
|
||||||
|
|
||||||
3. ✅ **Console**: "🔧 FlowParser: USE_ANTLR_PARSER = true"
|
|
||||||
4. ✅ **Console**: "🔧 FlowParser: Selected parser: ANTLR"
|
|
||||||
|
|
||||||
### 📊 Normal Operation (Clean Output)
|
|
||||||
|
|
||||||
5. ✅ **Browser**: All test diagrams render as SVG elements
|
|
||||||
6. ✅ **Test Page**: Green status indicator showing "ANTLR Parser Active & Rendering Successfully!"
|
|
||||||
7. ✅ **Console**: Minimal logging for small/medium diagrams (optimized)
|
|
||||||
|
|
||||||
### 🐛 Debug Mode (ANTLR_DEBUG=true)
|
|
||||||
|
|
||||||
8. ✅ **Console**: "🎯 ANTLR Parser: Starting parse" (for complex diagrams)
|
|
||||||
9. ✅ **Console**: "🎯 ANTLR Parser: Creating visitor" (or "Creating listener")
|
|
||||||
10. ✅ **Console**: Detailed performance breakdowns and timing information
|
|
||||||
|
|
||||||
## 🚨 Troubleshooting
|
|
||||||
|
|
||||||
### **Build & Generation Issues**
|
|
||||||
|
|
||||||
1. **Missing ANTLR files after install**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Manually regenerate
|
|
||||||
pnpm antlr:generate
|
|
||||||
|
|
||||||
# Check if postinstall ran
|
|
||||||
pnpm install --force
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Generation fails during build**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check antlr-ng installation
|
|
||||||
which antlr-ng
|
|
||||||
|
|
||||||
# Reinstall if missing
|
|
||||||
pnpm install -g antlr4ng
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **No grammar files found**
|
|
||||||
|
|
||||||
- Ensure `.g4` files are in correct location: `src/diagrams/*/parser/antlr/*.g4`
|
|
||||||
- Check file naming convention: `*Lexer.g4`, `*Parser.g4`
|
|
||||||
- Verify you're running from correct directory
|
|
||||||
|
|
||||||
4. **Permission errors during generation**
|
|
||||||
```bash
|
|
||||||
# Fix permissions
|
|
||||||
chmod -R 755 packages/mermaid/src/diagrams/*/parser/antlr/
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Development Issues**
|
|
||||||
|
|
||||||
5. **ANTLR parser not being used**: Check environment variable `USE_ANTLR_PARSER=true`
|
|
||||||
6. **Environment variable not set**: Use `pnpm dev:antlr` instead of `pnpm dev`
|
|
||||||
7. **Diagrams not rendering**: Check browser console for parsing errors
|
|
||||||
8. **Watch not working**:
|
|
||||||
- For dev server: Restart with `pnpm dev:antlr`
|
|
||||||
- For grammar development: Use `pnpm antlr:watch` instead
|
|
||||||
|
|
||||||
### **Grammar Issues**
|
|
||||||
|
|
||||||
9. **ANTLR generation warnings**
|
|
||||||
|
|
||||||
- Check grammar file syntax with ANTLR tools
|
|
||||||
- Compare with working examples in existing diagrams
|
|
||||||
- Warnings are usually non-fatal but should be addressed
|
|
||||||
|
|
||||||
10. **Generated files not updating**
|
|
||||||
```bash
|
|
||||||
# Force clean regeneration
|
|
||||||
rm -rf packages/mermaid/src/diagrams/*/parser/antlr/generated
|
|
||||||
pnpm antlr:generate
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Getting Help**
|
|
||||||
|
|
||||||
- **Console Output**: Check detailed error messages in terminal
|
|
||||||
- **Browser Console**: Look for parsing errors during development
|
|
||||||
- **Grammar Validation**: Use ANTLR tools to validate `.g4` files
|
|
||||||
- **Compare Examples**: Reference working implementations in existing diagrams
|
|
||||||
- **Build Logs**: Review server logs for build issues
|
|
||||||
- **Fresh Start**: Try `pnpm install --force` for clean installation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Diagram-Specific Guides
|
|
||||||
|
|
||||||
### 📊 Flowchart Parser
|
|
||||||
|
|
||||||
The flowchart ANTLR parser is the most mature implementation with 99.1% test compatibility.
|
|
||||||
|
|
||||||
#### **Key Features**
|
|
||||||
|
|
||||||
- **939/948 tests passing** (99.1% compatibility)
|
|
||||||
- **Dual-pattern architecture** (Listener/Visitor)
|
|
||||||
- **Performance optimized** (15% improvement)
|
|
||||||
- **Complex shape support** (trapezoids, ellipses, etc.)
|
|
||||||
- **Advanced text processing** (markdown, special characters)
|
|
||||||
|
|
||||||
#### **Usage**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Generate flowchart ANTLR files
|
|
||||||
pnpm antlr:generate
|
|
||||||
|
|
||||||
# Test flowchart parser
|
|
||||||
USE_ANTLR_PARSER=true npx vitest run packages/mermaid/src/diagrams/flowchart/parser/
|
|
||||||
|
|
||||||
# Development with flowchart ANTLR
|
|
||||||
pnpm dev:antlr
|
|
||||||
# Open: http://localhost:9000/flowchart-antlr-test.html
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Architecture**
|
|
||||||
|
|
||||||
- `FlowchartParserCore.ts` - Shared parsing logic
|
|
||||||
- `FlowchartListener.ts` - Event-driven pattern
|
|
||||||
- `FlowchartVisitor.ts` - Pull-based pattern (default)
|
|
||||||
|
|
||||||
### 🔄 Sequence Parser
|
|
||||||
|
|
||||||
The sequence ANTLR parser achieves 100% test compatibility with perfect Jison parser matching.
|
|
||||||
|
|
||||||
#### **Key Features**
|
|
||||||
|
|
||||||
- **123/123 tests passing** (100% compatibility)
|
|
||||||
- **Dual-pattern architecture** (Listener/Visitor)
|
|
||||||
- **Runtime pattern selection** via environment variables
|
|
||||||
- **Complete syntax support** (all sequence diagram elements)
|
|
||||||
- **Robust error handling** matching Jison resilience
|
|
||||||
|
|
||||||
#### **Usage**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Generate sequence ANTLR files
|
|
||||||
pnpm antlr:generate
|
|
||||||
|
|
||||||
# Test sequence parser with both patterns
|
|
||||||
USE_ANTLR_VISITOR=false npx vitest run packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
|
|
||||||
USE_ANTLR_VISITOR=true npx vitest run packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
|
|
||||||
|
|
||||||
# Development with sequence ANTLR
|
|
||||||
pnpm dev:antlr
|
|
||||||
# Open: http://localhost:9000/sequence.html
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Architecture**
|
|
||||||
|
|
||||||
- `SequenceParserCore.ts` - Shared parsing logic (100% compatible)
|
|
||||||
- `SequenceListener.ts` - Event-driven pattern
|
|
||||||
- `SequenceVisitor.ts` - Pull-based pattern (default)
|
|
||||||
|
|
||||||
#### **Pattern Selection**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Use Visitor pattern (default)
|
|
||||||
USE_ANTLR_VISITOR=true
|
|
||||||
|
|
||||||
# Use Listener pattern
|
|
||||||
USE_ANTLR_VISITOR=false
|
|
||||||
```
|
|
||||||
|
|
||||||
### 📋 Class Parser
|
|
||||||
|
|
||||||
The class ANTLR parser has generated files ready for implementation.
|
|
||||||
|
|
||||||
#### **Current Status**
|
|
||||||
|
|
||||||
- **Generated files available** ✅
|
|
||||||
- **Grammar files complete** ✅
|
|
||||||
- **Ready for implementation** - Core logic and patterns needed
|
|
||||||
|
|
||||||
#### **Usage**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Generate class ANTLR files
|
|
||||||
pnpm antlr:generate
|
|
||||||
|
|
||||||
# Individual generation (if needed)
|
|
||||||
cd packages/mermaid && pnpm antlr:class
|
|
||||||
```
|
|
||||||
|
|
||||||
#### **Next Steps**
|
|
||||||
|
|
||||||
1. Implement `ClassParserCore.ts` with parsing logic
|
|
||||||
2. Create `ClassListener.ts` and `ClassVisitor.ts` pattern implementations
|
|
||||||
3. Update main parser to use ANTLR with pattern selection
|
|
||||||
4. Run regression tests and achieve compatibility
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Adding New Diagram Types
|
|
||||||
|
|
||||||
To add ANTLR support for a new diagram type:
|
|
||||||
|
|
||||||
1. **Create Grammar Files**
|
|
||||||
|
|
||||||
```
|
|
||||||
packages/mermaid/src/diagrams/[diagram]/parser/antlr/
|
|
||||||
├── [Diagram]Lexer.g4
|
|
||||||
└── [Diagram]Parser.g4
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Generate ANTLR Files**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm antlr:generate # Automatically detects new grammars
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Implement Architecture**
|
|
||||||
|
|
||||||
- Create `[Diagram]ParserCore.ts` with shared logic
|
|
||||||
- Create `[Diagram]Listener.ts` extending core
|
|
||||||
- Create `[Diagram]Visitor.ts` extending core
|
|
||||||
- Update main parser with pattern selection
|
|
||||||
|
|
||||||
4. **Test and Validate**
|
|
||||||
- Run regression tests
|
|
||||||
- Achieve high compatibility with existing Jison parser
|
|
||||||
- Validate both Listener and Visitor patterns
|
|
||||||
|
|
||||||
The generic ANTLR generation system will automatically handle the new diagram type!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Generic ANTLR Generation System
|
|
||||||
|
|
||||||
### **How It Works**
|
|
||||||
|
|
||||||
#### 1. **Auto-Discovery**
|
|
||||||
|
|
||||||
The script automatically finds all `.g4` files in:
|
|
||||||
|
|
||||||
```
|
|
||||||
packages/mermaid/src/diagrams/*/parser/antlr/*.g4
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. **Grammar Pairing**
|
|
||||||
|
|
||||||
For each diagram, it looks for:
|
|
||||||
|
|
||||||
- `*Lexer.g4` - Lexical analyzer grammar
|
|
||||||
- `*Parser.g4` - Parser grammar
|
|
||||||
|
|
||||||
#### 3. **Generation Process**
|
|
||||||
|
|
||||||
For each valid grammar pair:
|
|
||||||
|
|
||||||
1. Clean the `generated/` directory
|
|
||||||
2. Create the directory if needed
|
|
||||||
3. Run `antlr-ng` with TypeScript target
|
|
||||||
4. Generate all necessary files
|
|
||||||
|
|
||||||
#### 4. **Generated Files**
|
|
||||||
|
|
||||||
Each diagram gets these generated files:
|
|
||||||
|
|
||||||
- `*Lexer.ts` - Lexer implementation
|
|
||||||
- `*Parser.ts` - Parser implementation
|
|
||||||
- `*ParserListener.ts` - Listener interface
|
|
||||||
- `*ParserVisitor.ts` - Visitor interface
|
|
||||||
- `*.tokens` - Token definitions
|
|
||||||
- `*.interp` - ANTLR interpreter files
|
|
||||||
|
|
||||||
### **Supported Diagrams**
|
|
||||||
|
|
||||||
| Diagram Type | Grammar Files | Generated Location |
|
|
||||||
| ------------- | --------------------------------------- | ----------------------------------------------------------------- |
|
|
||||||
| **Flowchart** | `FlowLexer.g4`, `FlowParser.g4` | `packages/mermaid/src/diagrams/flowchart/parser/antlr/generated/` |
|
|
||||||
| **Sequence** | `SequenceLexer.g4`, `SequenceParser.g4` | `packages/mermaid/src/diagrams/sequence/parser/antlr/generated/` |
|
|
||||||
| **Class** | `ClassLexer.g4`, `ClassParser.g4` | `packages/mermaid/src/diagrams/class/parser/antlr/generated/` |
|
|
||||||
|
|
||||||
### **Example Output**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
🚀 ANTLR Generator - Finding and generating all grammar files...
|
|
||||||
|
|
||||||
📋 Found 3 diagram(s) with ANTLR grammars:
|
|
||||||
• class
|
|
||||||
• flowchart
|
|
||||||
• sequence
|
|
||||||
|
|
||||||
🎯 Generating ANTLR files for class diagram...
|
|
||||||
Lexer: ClassLexer.g4
|
|
||||||
Parser: ClassParser.g4
|
|
||||||
Output: packages/mermaid/src/diagrams/class/parser/antlr/generated
|
|
||||||
✅ Successfully generated ANTLR files for class
|
|
||||||
|
|
||||||
🎯 Generating ANTLR files for flowchart diagram...
|
|
||||||
Lexer: FlowLexer.g4
|
|
||||||
Parser: FlowParser.g4
|
|
||||||
Output: packages/mermaid/src/diagrams/flowchart/parser/antlr/generated
|
|
||||||
✅ Successfully generated ANTLR files for flowchart
|
|
||||||
|
|
||||||
🎯 Generating ANTLR files for sequence diagram...
|
|
||||||
Lexer: SequenceLexer.g4
|
|
||||||
Parser: SequenceParser.g4
|
|
||||||
Output: packages/mermaid/src/diagrams/sequence/parser/antlr/generated
|
|
||||||
✅ Successfully generated ANTLR files for sequence
|
|
||||||
|
|
||||||
📊 Generation Summary:
|
|
||||||
✅ Successful: 3
|
|
||||||
❌ Failed: 0
|
|
||||||
📁 Total: 3
|
|
||||||
|
|
||||||
🎉 All ANTLR files generated successfully!
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Benefits**
|
|
||||||
|
|
||||||
✅ **Simplified Workflow** - One command for all diagrams
|
|
||||||
✅ **Auto-Discovery** - No manual configuration needed
|
|
||||||
✅ **Consistent Structure** - Standardized generation process
|
|
||||||
✅ **Easy Maintenance** - Centralized generation logic
|
|
||||||
✅ **Scalable** - Automatically handles new diagrams
|
|
||||||
✅ **Reliable** - Comprehensive error handling and reporting
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎉 Summary
|
|
||||||
|
|
||||||
### **Complete ANTLR Integration**
|
|
||||||
|
|
||||||
The ANTLR parser system for Mermaid is now fully integrated with:
|
|
||||||
|
|
||||||
✅ **Automatic Generation** - Files generated during install and build
|
|
||||||
✅ **Development Workflow** - Watch functionality for grammar changes
|
|
||||||
✅ **Build Pipeline** - Integrated into ESBuild process
|
|
||||||
✅ **Multi-Diagram Support** - Flowchart, Sequence, and Class parsers
|
|
||||||
✅ **Dual-Pattern Architecture** - Both Listener and Visitor patterns
|
|
||||||
✅ **High Compatibility** - 99.1% flowchart, 100% sequence test coverage
|
|
||||||
✅ **Production Ready** - Robust error handling and performance optimization
|
|
||||||
|
|
||||||
### **Developer Experience**
|
|
||||||
|
|
||||||
**New Developer Setup:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone <repo>
|
|
||||||
pnpm install # ← ANTLR files automatically generated!
|
|
||||||
pnpm dev:antlr # ← Ready to develop with watch
|
|
||||||
```
|
|
||||||
|
|
||||||
**Grammar Development:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm antlr:watch # ← Watch mode for grammar development
|
|
||||||
# Edit .g4 files → Automatic regeneration!
|
|
||||||
|
|
||||||
# OR with full dev server
|
|
||||||
pnpm dev:antlr # ← Start development server
|
|
||||||
# Edit .g4 files → Automatic regeneration + rebuild!
|
|
||||||
```
|
|
||||||
|
|
||||||
**Build & Deploy:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm build # ← ANTLR generation included automatically
|
|
||||||
pnpm test # ← All tests pass with generated files
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Architecture Highlights**
|
|
||||||
|
|
||||||
- **🔄 Zero Manual Steps**: Everything automated
|
|
||||||
- **🎯 Smart Detection**: Works from any directory
|
|
||||||
- **⚡ Fast Development**: Watch + hot reload
|
|
||||||
- **🛡️ CI/CD Ready**: Build process includes generation
|
|
||||||
- **📊 Clear Feedback**: Detailed logging and progress
|
|
||||||
- **🔧 Easy Maintenance**: Centralized generation logic
|
|
||||||
|
|
||||||
The ANTLR parser system is now a seamless part of the Mermaid development experience! 🚀
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
./packages/mermaid/CHANGELOG.md
|
|
||||||
1005
CHANGELOG.md
Normal file
1005
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -95,6 +95,10 @@ In our release process we rely heavily on visual regression tests using [applito
|
|||||||
|
|
||||||
<!-- </Main description> -->
|
<!-- </Main description> -->
|
||||||
|
|
||||||
|
## Mermaid AI Bot
|
||||||
|
|
||||||
|
[Mermaid](https://codeparrot.ai/oracle?owner=mermaid-js&repo=mermaid) Bot will help you understand this repository better. You can ask for code examples, installation guide, debugging help and much more.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
**The following are some examples of the diagrams, charts and graphs that can be made using Mermaid. Click here to jump into the [text syntax](https://mermaid.js.org/intro/syntax-reference.html).**
|
**The following are some examples of the diagrams, charts and graphs that can be made using Mermaid. Click here to jump into the [text syntax](https://mermaid.js.org/intro/syntax-reference.html).**
|
||||||
|
|||||||
13
__mocks__/d3.ts
Normal file
13
__mocks__/d3.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { MockedD3 } from '../packages/mermaid/src/tests/MockedD3.js';
|
||||||
|
|
||||||
|
export const select = function () {
|
||||||
|
return new MockedD3();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const selectAll = function () {
|
||||||
|
return new MockedD3();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const curveBasis = 'basis';
|
||||||
|
export const curveLinear = 'linear';
|
||||||
|
export const curveCardinal = 'cardinal';
|
||||||
@@ -26,10 +26,7 @@ export default eyesPlugin(
|
|||||||
config.env.useArgos = process.env.RUN_VISUAL_TEST === 'true';
|
config.env.useArgos = process.env.RUN_VISUAL_TEST === 'true';
|
||||||
|
|
||||||
if (config.env.useArgos) {
|
if (config.env.useArgos) {
|
||||||
registerArgosTask(on, config, {
|
registerArgosTask(on, config);
|
||||||
// Enable upload to Argos only when it runs on CI.
|
|
||||||
uploadToArgos: !!process.env.CI,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
addMatchImageSnapshotPlugin(on, config);
|
addMatchImageSnapshotPlugin(on, config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ interface CodeObject {
|
|||||||
mermaid: CypressMermaidConfig;
|
mermaid: CypressMermaidConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const utf8ToB64 = (str: string): string => {
|
const utf8ToB64 = (str: string): string => {
|
||||||
return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64');
|
return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -69,9 +69,7 @@ describe('Configuration', () => {
|
|||||||
.and('include', 'url(#');
|
.and('include', 'url(#');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// This has been broken for a long time, but something about the Cypress environment was
|
it('should handle arrowMarkerAbsolute explicitly set to "false" as false', () => {
|
||||||
// rewriting the URL to be relative, causing the test to incorrectly pass.
|
|
||||||
it.skip('should handle arrowMarkerAbsolute explicitly set to "false" as false', () => {
|
|
||||||
renderGraph(
|
renderGraph(
|
||||||
`graph TD
|
`graph TD
|
||||||
A[Christmas] -->|Get money| B(Go shopping)
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
@@ -98,12 +96,12 @@ describe('Configuration', () => {
|
|||||||
it('should handle arrowMarkerAbsolute set to true', () => {
|
it('should handle arrowMarkerAbsolute set to true', () => {
|
||||||
renderGraph(
|
renderGraph(
|
||||||
`flowchart TD
|
`flowchart TD
|
||||||
A[Christmas] -->|Get money| B(Go shopping)
|
A[Christmas] -->|Get money| B(Go shopping)
|
||||||
B --> C{Let me think}
|
B --> C{Let me think}
|
||||||
C -->|One| D[Laptop]
|
C -->|One| D[Laptop]
|
||||||
C -->|Two| E[iPhone]
|
C -->|Two| E[iPhone]
|
||||||
C -->|Three| F[fa:fa-car Car]
|
C -->|Three| F[fa:fa-car Car]
|
||||||
`,
|
`,
|
||||||
{
|
{
|
||||||
arrowMarkerAbsolute: true,
|
arrowMarkerAbsolute: true,
|
||||||
}
|
}
|
||||||
@@ -113,6 +111,7 @@ describe('Configuration', () => {
|
|||||||
cy.get('path')
|
cy.get('path')
|
||||||
.first()
|
.first()
|
||||||
.should('have.attr', 'marker-end')
|
.should('have.attr', 'marker-end')
|
||||||
|
.should('exist')
|
||||||
.and('include', 'url(http://localhost');
|
.and('include', 'url(http://localhost');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { imgSnapshotTest, mermaidUrl, utf8ToB64 } from '../../helpers/util.ts';
|
import { mermaidUrl } from '../../helpers/util.ts';
|
||||||
describe('XSS', () => {
|
describe('XSS', () => {
|
||||||
it('should handle xss in tags', () => {
|
it('should handle xss in tags', () => {
|
||||||
const str =
|
const str =
|
||||||
@@ -141,37 +141,4 @@ describe('XSS', () => {
|
|||||||
cy.wait(1000);
|
cy.wait(1000);
|
||||||
cy.get('#the-malware').should('not.exist');
|
cy.get('#the-malware').should('not.exist');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should sanitize icon labels in architecture diagrams', () => {
|
|
||||||
const str = JSON.stringify({
|
|
||||||
code: `architecture-beta
|
|
||||||
group api(cloud)[API]
|
|
||||||
service db "<img src=x onerror=\\"xssAttack()\\">" [Database] in api`,
|
|
||||||
});
|
|
||||||
imgSnapshotTest(utf8ToB64(str), {}, true);
|
|
||||||
cy.wait(1000);
|
|
||||||
cy.get('#the-malware').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should sanitize katex blocks', () => {
|
|
||||||
const str = JSON.stringify({
|
|
||||||
code: `sequenceDiagram
|
|
||||||
participant A as Alice<img src="x" onerror="xssAttack()">$$\\text{Alice}$$
|
|
||||||
A->>John: Hello John, how are you?`,
|
|
||||||
});
|
|
||||||
imgSnapshotTest(utf8ToB64(str), {}, true);
|
|
||||||
cy.wait(1000);
|
|
||||||
cy.get('#the-malware').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should sanitize labels', () => {
|
|
||||||
const str = JSON.stringify({
|
|
||||||
code: `erDiagram
|
|
||||||
"<img src=x onerror=xssAttack()>" ||--|| ENTITY2 : "<img src=x onerror=xssAttack()>"
|
|
||||||
`,
|
|
||||||
});
|
|
||||||
imgSnapshotTest(utf8ToB64(str), {}, true);
|
|
||||||
cy.wait(1000);
|
|
||||||
cy.get('#the-malware').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL2: should handle columns statement in sub-blocks', () => {
|
it('BL2: should handle columns statement in sub-blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
id1["Hello"]
|
id1["Hello"]
|
||||||
block
|
block
|
||||||
columns 3
|
columns 3
|
||||||
@@ -32,7 +32,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL3: should align block widths and handle columns statement in sub-blocks', () => {
|
it('BL3: should align block widths and handle columns statement in sub-blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
block
|
block
|
||||||
columns 1
|
columns 1
|
||||||
id1
|
id1
|
||||||
@@ -48,7 +48,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL4: should align block widths and handle columns statements in deeper sub-blocks then 1 level', () => {
|
it('BL4: should align block widths and handle columns statements in deeper sub-blocks then 1 level', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 1
|
columns 1
|
||||||
block
|
block
|
||||||
columns 1
|
columns 1
|
||||||
@@ -68,7 +68,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL5: should align block widths and handle columns statements in deeper sub-blocks then 1 level (alt)', () => {
|
it('BL5: should align block widths and handle columns statements in deeper sub-blocks then 1 level (alt)', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 1
|
columns 1
|
||||||
block
|
block
|
||||||
id1
|
id1
|
||||||
@@ -87,7 +87,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL6: should handle block arrows and spece statements', () => {
|
it('BL6: should handle block arrows and spece statements', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 3
|
columns 3
|
||||||
space:3
|
space:3
|
||||||
ida idb idc
|
ida idb idc
|
||||||
@@ -106,7 +106,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL7: should handle different types of edges', () => {
|
it('BL7: should handle different types of edges', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 3
|
columns 3
|
||||||
A space:5
|
A space:5
|
||||||
A --o B
|
A --o B
|
||||||
@@ -119,7 +119,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL8: should handle sub-blocks without columns statements', () => {
|
it('BL8: should handle sub-blocks without columns statements', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 2
|
columns 2
|
||||||
C A B
|
C A B
|
||||||
block
|
block
|
||||||
@@ -133,7 +133,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL9: should handle edges from blocks in sub blocks to other blocks', () => {
|
it('BL9: should handle edges from blocks in sub blocks to other blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 3
|
columns 3
|
||||||
B space
|
B space
|
||||||
block
|
block
|
||||||
@@ -147,7 +147,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL10: should handle edges from composite blocks', () => {
|
it('BL10: should handle edges from composite blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 3
|
columns 3
|
||||||
B space
|
B space
|
||||||
block BL
|
block BL
|
||||||
@@ -161,7 +161,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL11: should handle edges to composite blocks', () => {
|
it('BL11: should handle edges to composite blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 3
|
columns 3
|
||||||
B space
|
B space
|
||||||
block BL
|
block BL
|
||||||
@@ -175,7 +175,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL12: edges should handle labels', () => {
|
it('BL12: edges should handle labels', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
A
|
A
|
||||||
space
|
space
|
||||||
A -- "apa" --> E
|
A -- "apa" --> E
|
||||||
@@ -186,7 +186,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL13: should handle block arrows in different directions', () => {
|
it('BL13: should handle block arrows in different directions', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 3
|
columns 3
|
||||||
space blockArrowId1<["down"]>(down) space
|
space blockArrowId1<["down"]>(down) space
|
||||||
blockArrowId2<["right"]>(right) blockArrowId3<["Sync"]>(x, y) blockArrowId4<["left"]>(left)
|
blockArrowId2<["right"]>(right) blockArrowId3<["Sync"]>(x, y) blockArrowId4<["left"]>(left)
|
||||||
@@ -199,7 +199,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL14: should style statements and class statements', () => {
|
it('BL14: should style statements and class statements', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
A
|
A
|
||||||
B
|
B
|
||||||
classDef blue fill:#66f,stroke:#333,stroke-width:2px;
|
classDef blue fill:#66f,stroke:#333,stroke-width:2px;
|
||||||
@@ -212,7 +212,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL15: width alignment - D and E should share available space', () => {
|
it('BL15: width alignment - D and E should share available space', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
block
|
block
|
||||||
D
|
D
|
||||||
E
|
E
|
||||||
@@ -225,7 +225,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL16: width alignment - C should be as wide as the composite block', () => {
|
it('BL16: width alignment - C should be as wide as the composite block', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
block
|
block
|
||||||
A("This is the text")
|
A("This is the text")
|
||||||
B
|
B
|
||||||
@@ -238,7 +238,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL17: width alignment - blocks should be equal in width', () => {
|
it('BL17: width alignment - blocks should be equal in width', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
A("This is the text")
|
A("This is the text")
|
||||||
B
|
B
|
||||||
C
|
C
|
||||||
@@ -249,7 +249,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL18: block types 1 - square, rounded and circle', () => {
|
it('BL18: block types 1 - square, rounded and circle', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
A["square"]
|
A["square"]
|
||||||
B("rounded")
|
B("rounded")
|
||||||
C(("circle"))
|
C(("circle"))
|
||||||
@@ -260,7 +260,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL19: block types 2 - odd, diamond and hexagon', () => {
|
it('BL19: block types 2 - odd, diamond and hexagon', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
A>"rect_left_inv_arrow"]
|
A>"rect_left_inv_arrow"]
|
||||||
B{"diamond"}
|
B{"diamond"}
|
||||||
C{{"hexagon"}}
|
C{{"hexagon"}}
|
||||||
@@ -271,7 +271,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL20: block types 3 - stadium', () => {
|
it('BL20: block types 3 - stadium', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
A(["stadium"])
|
A(["stadium"])
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
@@ -280,7 +280,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL21: block types 4 - lean right, lean left, trapezoid and inv trapezoid', () => {
|
it('BL21: block types 4 - lean right, lean left, trapezoid and inv trapezoid', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
A[/"lean right"/]
|
A[/"lean right"/]
|
||||||
B[\"lean left"\]
|
B[\"lean left"\]
|
||||||
C[/"trapezoid"\]
|
C[/"trapezoid"\]
|
||||||
@@ -292,7 +292,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL22: block types 1 - square, rounded and circle', () => {
|
it('BL22: block types 1 - square, rounded and circle', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
A["square"]
|
A["square"]
|
||||||
B("rounded")
|
B("rounded")
|
||||||
C(("circle"))
|
C(("circle"))
|
||||||
@@ -303,7 +303,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL23: sizing - it should be possible to make a block wider', () => {
|
it('BL23: sizing - it should be possible to make a block wider', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
A("rounded"):2
|
A("rounded"):2
|
||||||
B:2
|
B:2
|
||||||
C
|
C
|
||||||
@@ -314,7 +314,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL24: sizing - it should be possible to make a composite block wider', () => {
|
it('BL24: sizing - it should be possible to make a composite block wider', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
block:2
|
block:2
|
||||||
A
|
A
|
||||||
end
|
end
|
||||||
@@ -326,7 +326,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL25: block in the middle with space on each side', () => {
|
it('BL25: block in the middle with space on each side', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 3
|
columns 3
|
||||||
space
|
space
|
||||||
middle["In the middle"]
|
middle["In the middle"]
|
||||||
@@ -337,7 +337,7 @@ describe('Block diagram', () => {
|
|||||||
});
|
});
|
||||||
it('BL26: space and an edge', () => {
|
it('BL26: space and an edge', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 5
|
columns 5
|
||||||
A space B
|
A space B
|
||||||
A --x B
|
A --x B
|
||||||
@@ -347,7 +347,7 @@ describe('Block diagram', () => {
|
|||||||
});
|
});
|
||||||
it('BL27: block sizes for regular blocks', () => {
|
it('BL27: block sizes for regular blocks', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 3
|
columns 3
|
||||||
a["A wide one"] b:2 c:2 d
|
a["A wide one"] b:2 c:2 d
|
||||||
`,
|
`,
|
||||||
@@ -356,7 +356,7 @@ describe('Block diagram', () => {
|
|||||||
});
|
});
|
||||||
it('BL28: composite block with a set width - f should use the available space', () => {
|
it('BL28: composite block with a set width - f should use the available space', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 3
|
columns 3
|
||||||
a:3
|
a:3
|
||||||
block:e:3
|
block:e:3
|
||||||
@@ -370,7 +370,7 @@ describe('Block diagram', () => {
|
|||||||
|
|
||||||
it('BL29: composite block with a set width - f and g should split the available space', () => {
|
it('BL29: composite block with a set width - f and g should split the available space', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`block
|
`block-beta
|
||||||
columns 3
|
columns 3
|
||||||
a:3
|
a:3
|
||||||
block:e:3
|
block:e:3
|
||||||
@@ -384,28 +384,4 @@ describe('Block diagram', () => {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('BL30: block should overflow if too wide for columns', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`block-beta
|
|
||||||
columns 2
|
|
||||||
fit:2
|
|
||||||
overflow:3
|
|
||||||
short:1
|
|
||||||
also_overflow:2
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('BL31: edge without arrow syntax should render with no arrowheads', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`block-beta
|
|
||||||
a
|
|
||||||
b
|
|
||||||
a --- b
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -495,47 +495,4 @@ describe('Class diagram', () => {
|
|||||||
cy.get('a').should('have.attr', 'target', '_blank').should('have.attr', 'rel', 'noopener');
|
cy.get('a').should('have.attr', 'target', '_blank').should('have.attr', 'rel', 'noopener');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Include char sequence "graph" in text (#6795)', () => {
|
|
||||||
it('has a label with char sequence "graph"', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
classDiagram
|
|
||||||
class Person {
|
|
||||||
+String name
|
|
||||||
-Int id
|
|
||||||
#double age
|
|
||||||
+Text demographicProfile
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
{ flowchart: { defaultRenderer: 'elk' } }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle backticks for namespace and class names', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
classDiagram
|
|
||||||
namespace \`A::B\` {
|
|
||||||
class \`IPC::Sender\`
|
|
||||||
}
|
|
||||||
RenderProcessHost --|> \`IPC::Sender\`
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
it('should handle an empty class body with empty braces', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
` classDiagram
|
|
||||||
class FooBase~T~ {}
|
|
||||||
class Bar {
|
|
||||||
+Zip
|
|
||||||
+Zap()
|
|
||||||
}
|
|
||||||
FooBase <|-- Ba
|
|
||||||
`,
|
|
||||||
{ flowchart: { defaultRenderer: 'elk' } }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -354,19 +354,4 @@ ORDER ||--|{ LINE-ITEM : contains
|
|||||||
{ logLevel: 1 }
|
{ logLevel: 1 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Include char sequence "graph" in text (#6795)', () => {
|
|
||||||
it('has a label with char sequence "graph"', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
erDiagram
|
|
||||||
p[Photograph] {
|
|
||||||
varchar(12) jobId
|
|
||||||
date dateCreated
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
{ flowchart: { defaultRenderer: 'elk' } }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ describe('Flowchart ELK', () => {
|
|||||||
const style = svg.attr('style');
|
const style = svg.attr('style');
|
||||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
verifyNumber(maxWidthValue, 380, 15);
|
verifyNumber(maxWidthValue, 380);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('8-elk: should render a flowchart when useMaxWidth is false', () => {
|
it('8-elk: should render a flowchart when useMaxWidth is false', () => {
|
||||||
@@ -128,7 +128,7 @@ describe('Flowchart ELK', () => {
|
|||||||
const width = parseFloat(svg.attr('width'));
|
const width = parseFloat(svg.attr('width'));
|
||||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
// expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
// expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
||||||
verifyNumber(width, 380, 15);
|
verifyNumber(width, 380);
|
||||||
expect(svg).to.not.have.attr('style');
|
expect(svg).to.not.have.attr('style');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1053,21 +1053,6 @@ flowchart LR
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('6647-elk: should keep node order when using elk layout unless it would add crossings', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
flowchart TB
|
|
||||||
a --> a1 & a2 & a3 & a4
|
|
||||||
b --> b1 & b2
|
|
||||||
b2 --> b3
|
|
||||||
b1 --> b4
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Title and arrow styling #4813', () => {
|
describe('Title and arrow styling #4813', () => {
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
import { imgSnapshotTest } from '../../helpers/util.ts';
|
|
||||||
|
|
||||||
const themes = ['default', 'forest', 'dark', 'base', 'neutral'];
|
|
||||||
|
|
||||||
describe('when rendering flowchart with icons', () => {
|
|
||||||
for (const theme of themes) {
|
|
||||||
it(`should render icons from fontawesome library on theme ${theme}`, () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`flowchart TD
|
|
||||||
A("fab:fa-twitter Twitter") --> B("fab:fa-facebook Facebook")
|
|
||||||
B --> C("fa:fa-coffee Coffee")
|
|
||||||
C --> D("fa:fa-car Car")
|
|
||||||
D --> E("fab:fa-github GitHub")
|
|
||||||
`,
|
|
||||||
{ theme }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should render registered icons on theme ${theme}`, () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`flowchart TD
|
|
||||||
A("fa:fa-bell Bell")
|
|
||||||
`,
|
|
||||||
{ theme }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -99,7 +99,7 @@ describe('Flowchart v2', () => {
|
|||||||
const style = svg.attr('style');
|
const style = svg.attr('style');
|
||||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
||||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
||||||
expect(maxWidthValue).to.be.within(440 * 0.95, 440 * 1.05);
|
expect(maxWidthValue).to.be.within(417 * 0.95, 417 * 1.05);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('8: should render a flowchart when useMaxWidth is false', () => {
|
it('8: should render a flowchart when useMaxWidth is false', () => {
|
||||||
@@ -118,7 +118,7 @@ describe('Flowchart v2', () => {
|
|||||||
const width = parseFloat(svg.attr('width'));
|
const width = parseFloat(svg.attr('width'));
|
||||||
// use within because the absolute value can be slightly different depending on the environment ±5%
|
// use within because the absolute value can be slightly different depending on the environment ±5%
|
||||||
// expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
// expect(height).to.be.within(446 * 0.95, 446 * 1.05);
|
||||||
expect(width).to.be.within(440 * 0.95, 440 * 1.05);
|
expect(width).to.be.within(417 * 0.95, 417 * 1.05);
|
||||||
expect(svg).to.not.have.attr('style');
|
expect(svg).to.not.have.attr('style');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1113,90 +1113,4 @@ end
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Flowchart Node Shape Rendering', () => {
|
|
||||||
it('should render a stadium-shaped node', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`flowchart TB
|
|
||||||
A(["Start"]) --> n1["Untitled Node"]
|
|
||||||
A --> n2["Untitled Node"]
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('should render a diamond-shaped node using shape config', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`flowchart BT
|
|
||||||
n2["Untitled Node"] --> n1["Diamond"]
|
|
||||||
n1@{ shape: diam}
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('should render a rounded rectangle and a normal rectangle', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`flowchart BT
|
|
||||||
n2["Untitled Node"] --> n1["Rounded Rectangle"]
|
|
||||||
n3["Untitled Node"] --> n1
|
|
||||||
n1@{ shape: rounded}
|
|
||||||
n3@{ shape: rect}
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('6617: Per Link Curve Styling using edge Ids', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`flowchart TD
|
|
||||||
A e1@-->B e5@--> E
|
|
||||||
E e7@--> D
|
|
||||||
B e3@-->D
|
|
||||||
A e2@-->C e4@-->D
|
|
||||||
C e6@--> F
|
|
||||||
F e8@--> D
|
|
||||||
e1@{ curve: natural }
|
|
||||||
e2@{ curve: stepAfter }
|
|
||||||
e3@{ curve: monotoneY }
|
|
||||||
e4@{ curve: bumpY }
|
|
||||||
e5@{ curve: linear }
|
|
||||||
e6@{ curve: catmullRom }
|
|
||||||
e7@{ curve: cardinal }
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when rendering unsuported markdown', () => {
|
|
||||||
const graph = `flowchart TB
|
|
||||||
mermaid{"What is\nyourmermaid version?"} --> v10["<11"] --"\`<**1**1\`"--> fine["No bug"]
|
|
||||||
mermaid --> v11[">= v11"] -- ">= v11" --> broken["Affected by https://github.com/mermaid-js/mermaid/issues/5824"]
|
|
||||||
subgraph subgraph1["\`How to fix **fix**\`"]
|
|
||||||
broken --> B["B"]
|
|
||||||
end
|
|
||||||
githost["Github, Gitlab, BitBucket, etc."]
|
|
||||||
githost2["\`Github, Gitlab, BitBucket, etc.\`"]
|
|
||||||
a["1."]
|
|
||||||
b["- x"]
|
|
||||||
`;
|
|
||||||
|
|
||||||
it('should render raw strings', () => {
|
|
||||||
imgSnapshotTest(graph);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render raw strings with htmlLabels: false', () => {
|
|
||||||
imgSnapshotTest(graph, { htmlLabels: false });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('V2 - 17: should apply class def colour to edge label', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
` graph LR
|
|
||||||
id1(Start) link@-- "Label" -->id2(Stop)
|
|
||||||
style id1 fill:#f9f,stroke:#333,stroke-width:4px
|
|
||||||
|
|
||||||
class id2 myClass
|
|
||||||
classDef myClass fill:#bbf,stroke:#f66,stroke-width:2px,color:white,stroke-dasharray: 5 5
|
|
||||||
class link myClass
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -934,43 +934,4 @@ graph TD
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('68: should honor subgraph direction when inheritDir is false', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
%%{init: {"flowchart": { "inheritDir": false }}}%%
|
|
||||||
flowchart TB
|
|
||||||
direction LR
|
|
||||||
subgraph A
|
|
||||||
direction TB
|
|
||||||
a --> b
|
|
||||||
end
|
|
||||||
subgraph B
|
|
||||||
c --> d
|
|
||||||
end
|
|
||||||
`,
|
|
||||||
{
|
|
||||||
fontFamily: 'courier',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('69: should inherit global direction when inheritDir is true', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
%%{init: {"flowchart": { "inheritDir": true }}}%%
|
|
||||||
flowchart TB
|
|
||||||
direction LR
|
|
||||||
subgraph A
|
|
||||||
direction TB
|
|
||||||
a --> b
|
|
||||||
end
|
|
||||||
subgraph B
|
|
||||||
c --> d
|
|
||||||
end
|
|
||||||
`,
|
|
||||||
{
|
|
||||||
fontFamily: 'courier',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -358,23 +358,6 @@ describe('Gantt diagram', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render a gantt diagram with a vert tag', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
gantt
|
|
||||||
title A Gantt Diagram
|
|
||||||
dateFormat ss
|
|
||||||
axisFormat %Ss
|
|
||||||
|
|
||||||
section Section
|
|
||||||
A task : a1, 00, 6s
|
|
||||||
Milestone : vert, 01,
|
|
||||||
section Another
|
|
||||||
Task in sec : 06, 3s
|
|
||||||
another task : 3s
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('should render a gantt diagram with tick is 2 milliseconds', () => {
|
it('should render a gantt diagram with tick is 2 milliseconds', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
@@ -565,18 +548,6 @@ describe('Gantt diagram', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render only the day when using dateFormat D', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
gantt
|
|
||||||
title Test
|
|
||||||
dateFormat D
|
|
||||||
A :a, 1, 1d
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: fix it
|
// TODO: fix it
|
||||||
//
|
//
|
||||||
// This test is skipped deliberately
|
// This test is skipped deliberately
|
||||||
@@ -659,49 +630,6 @@ describe('Gantt diagram', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render a gantt diagram excluding a specific date in YYYY-MM-DD HH:mm:ss format', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
gantt
|
|
||||||
dateFormat YYYY-MM-DD HH:mm:ss
|
|
||||||
excludes 2025-07-07
|
|
||||||
section Section
|
|
||||||
A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30
|
|
||||||
Another task:after a1, 20h
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render a gantt diagram excluding saturday and sunday in YYYY-MM-DD HH:mm:ss format', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
gantt
|
|
||||||
dateFormat YYYY-MM-DD HH:mm:ss
|
|
||||||
excludes weekends
|
|
||||||
weekend saturday
|
|
||||||
section Section
|
|
||||||
A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30
|
|
||||||
Another task:after a1, 20h
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('should render a gantt diagram excluding friday and saturday in YYYY-MM-DD HH:mm:ss format', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
gantt
|
|
||||||
dateFormat YYYY-MM-DD HH:mm:ss
|
|
||||||
excludes weekends
|
|
||||||
weekend friday
|
|
||||||
section Section
|
|
||||||
A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30
|
|
||||||
Another task:after a1, 20h
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should render when there's a semicolon in the title", () => {
|
it("should render when there's a semicolon in the title", () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ looks.forEach((look) => {
|
|||||||
directions.forEach((direction) => {
|
directions.forEach((direction) => {
|
||||||
forms.forEach((form) => {
|
forms.forEach((form) => {
|
||||||
labelPos.forEach((pos) => {
|
labelPos.forEach((pos) => {
|
||||||
describe(`Test iconShape in ${form ? `${form} form,` : ''} ${look} look and dir ${direction} with label position ${pos ? pos : 'not defined'}`, () => {
|
describe(`Test iconShape in ${form ? `${form} form,` : ''} ${look} look and dir ${direction} with label position ${pos ?? 'not defined'}`, () => {
|
||||||
it(`without label`, () => {
|
it(`without label`, () => {
|
||||||
let flowchartCode = `flowchart ${direction}\n`;
|
let flowchartCode = `flowchart ${direction}\n`;
|
||||||
flowchartCode += ` nA --> nAA@{ icon: 'fa:bell'`;
|
flowchartCode += ` nA --> nAA@{ icon: 'fa:bell'`;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const labelPos = [undefined, 't', 'b'] as const;
|
|||||||
looks.forEach((look) => {
|
looks.forEach((look) => {
|
||||||
directions.forEach((direction) => {
|
directions.forEach((direction) => {
|
||||||
labelPos.forEach((pos) => {
|
labelPos.forEach((pos) => {
|
||||||
describe(`Test imageShape in ${look} look and dir ${direction} with label position ${pos ? pos : 'not defined'}`, () => {
|
describe(`Test imageShape in ${look} look and dir ${direction} with label position ${pos ?? 'not defined'}`, () => {
|
||||||
it(`without label`, () => {
|
it(`without label`, () => {
|
||||||
let flowchartCode = `flowchart ${direction}\n`;
|
let flowchartCode = `flowchart ${direction}\n`;
|
||||||
flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', w: '100', h: '100' }\n`;
|
flowchartCode += ` nA --> A@{ img: 'https://cdn.pixabay.com/photo/2020/02/22/18/49/paper-4871356_1280.jpg', w: '100', h: '100' }\n`;
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ section Checkout from website
|
|||||||
$lines.each((index, el) => {
|
$lines.each((index, el) => {
|
||||||
const bbox = el.getBBox();
|
const bbox = el.getBBox();
|
||||||
expect(bbox.width).to.be.lte(320);
|
expect(bbox.width).to.be.lte(320);
|
||||||
maxLineWidth = Math.max(maxLineWidth || 0, bbox.width);
|
maxLineWidth = Math.max(maxLineWidth ?? 0, bbox.width);
|
||||||
});
|
});
|
||||||
|
|
||||||
/** The expected margin between the diagram and the legend is 150px, as defined by
|
/** The expected margin between the diagram and the legend is 150px, as defined by
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
import { imgSnapshotTest } from '../../helpers/util.ts';
|
|
||||||
|
|
||||||
describe('Mindmap Tidy Tree', () => {
|
|
||||||
it('1-tidy-tree: should render a simple mindmap without children', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
` ---
|
|
||||||
config:
|
|
||||||
layout: tidy-tree
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
A
|
|
||||||
B
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('2-tidy-tree: should render a simple mindmap', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
` ---
|
|
||||||
config:
|
|
||||||
layout: tidy-tree
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap is a long thing))
|
|
||||||
A
|
|
||||||
B
|
|
||||||
C
|
|
||||||
D
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('3-tidy-tree: should render a mindmap with different shapes', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
` ---
|
|
||||||
config:
|
|
||||||
layout: tidy-tree
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
Origins
|
|
||||||
Long history
|
|
||||||
::icon(fa fa-book)
|
|
||||||
Popularisation
|
|
||||||
British popular psychology author Tony Buzan
|
|
||||||
Research
|
|
||||||
On effectiveness<br/>and features
|
|
||||||
On Automatic creation
|
|
||||||
Uses
|
|
||||||
Creative techniques
|
|
||||||
Strategic planning
|
|
||||||
Argument mapping
|
|
||||||
Tools
|
|
||||||
id)I am a cloud(
|
|
||||||
id))I am a bang((
|
|
||||||
Tools
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('4-tidy-tree: should render a mindmap with children', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
` ---
|
|
||||||
config:
|
|
||||||
layout: tidy-tree
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
((This is a mindmap))
|
|
||||||
child1
|
|
||||||
grandchild 1
|
|
||||||
grandchild 2
|
|
||||||
child2
|
|
||||||
grandchild 3
|
|
||||||
grandchild 4
|
|
||||||
child3
|
|
||||||
grandchild 5
|
|
||||||
grandchild 6
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -159,10 +159,12 @@ root
|
|||||||
});
|
});
|
||||||
it('square shape', () => {
|
it('square shape', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`mindmap
|
`
|
||||||
|
mindmap
|
||||||
root[
|
root[
|
||||||
The root
|
The root
|
||||||
]`,
|
]
|
||||||
|
`,
|
||||||
{},
|
{},
|
||||||
undefined,
|
undefined,
|
||||||
shouldHaveRoot
|
shouldHaveRoot
|
||||||
@@ -170,10 +172,12 @@ root
|
|||||||
});
|
});
|
||||||
it('rounded rect shape', () => {
|
it('rounded rect shape', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`mindmap
|
`
|
||||||
|
mindmap
|
||||||
root((
|
root((
|
||||||
The root
|
The root
|
||||||
))`,
|
))
|
||||||
|
`,
|
||||||
{},
|
{},
|
||||||
undefined,
|
undefined,
|
||||||
shouldHaveRoot
|
shouldHaveRoot
|
||||||
@@ -181,10 +185,12 @@ root
|
|||||||
});
|
});
|
||||||
it('circle shape', () => {
|
it('circle shape', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`mindmap
|
`
|
||||||
|
mindmap
|
||||||
root(
|
root(
|
||||||
The root
|
The root
|
||||||
)`,
|
)
|
||||||
|
`,
|
||||||
{},
|
{},
|
||||||
undefined,
|
undefined,
|
||||||
shouldHaveRoot
|
shouldHaveRoot
|
||||||
@@ -192,8 +198,10 @@ root
|
|||||||
});
|
});
|
||||||
it('default shape', () => {
|
it('default shape', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`mindmap
|
`
|
||||||
The root`,
|
mindmap
|
||||||
|
The root
|
||||||
|
`,
|
||||||
{},
|
{},
|
||||||
undefined,
|
undefined,
|
||||||
shouldHaveRoot
|
shouldHaveRoot
|
||||||
@@ -201,10 +209,12 @@ root
|
|||||||
});
|
});
|
||||||
it('adding children', () => {
|
it('adding children', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`mindmap
|
`
|
||||||
|
mindmap
|
||||||
The root
|
The root
|
||||||
child1
|
child1
|
||||||
child2`,
|
child2
|
||||||
|
`,
|
||||||
{},
|
{},
|
||||||
undefined,
|
undefined,
|
||||||
shouldHaveRoot
|
shouldHaveRoot
|
||||||
@@ -212,11 +222,13 @@ root
|
|||||||
});
|
});
|
||||||
it('adding grand children', () => {
|
it('adding grand children', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`mindmap
|
`
|
||||||
|
mindmap
|
||||||
The root
|
The root
|
||||||
child1
|
child1
|
||||||
child2
|
child2
|
||||||
child3`,
|
child3
|
||||||
|
`,
|
||||||
{},
|
{},
|
||||||
undefined,
|
undefined,
|
||||||
shouldHaveRoot
|
shouldHaveRoot
|
||||||
@@ -228,22 +240,9 @@ root
|
|||||||
`mindmap
|
`mindmap
|
||||||
id1[\`**Start** with
|
id1[\`**Start** with
|
||||||
a second line 😎\`]
|
a second line 😎\`]
|
||||||
id2[\`The dog in **the** hog... a *very long text* about it Word!\`]`
|
id2[\`The dog in **the** hog... a *very long text* about it
|
||||||
);
|
Word!\`]
|
||||||
});
|
`
|
||||||
});
|
|
||||||
describe('Include char sequence "graph" in text (#6795)', () => {
|
|
||||||
it('has a label with char sequence "graph"', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
` mindmap
|
|
||||||
root
|
|
||||||
Photograph
|
|
||||||
Waterfall
|
|
||||||
Landscape
|
|
||||||
Geography
|
|
||||||
Mountains
|
|
||||||
Rocks`,
|
|
||||||
{ flowchart: { defaultRenderer: 'elk' } }
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { imgSnapshotTest } from '../../helpers/util';
|
import { imgSnapshotTest } from '../../helpers/util';
|
||||||
|
|
||||||
describe('packet structure', () => {
|
describe('packet structure', () => {
|
||||||
it('should render a simple packet-beta diagram', () => {
|
it('should render a simple packet diagram', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`packet-beta
|
`packet-beta
|
||||||
title Hello world
|
title Hello world
|
||||||
@@ -10,18 +10,9 @@ describe('packet structure', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render a simple packet diagram', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`packet
|
|
||||||
title Hello world
|
|
||||||
0-10: "hello"
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render a simple packet diagram without ranges', () => {
|
it('should render a simple packet diagram without ranges', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`packet
|
`packet-beta
|
||||||
0: "h"
|
0: "h"
|
||||||
1: "i"
|
1: "i"
|
||||||
`
|
`
|
||||||
@@ -30,7 +21,7 @@ describe('packet structure', () => {
|
|||||||
|
|
||||||
it('should render a complex packet diagram', () => {
|
it('should render a complex packet diagram', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`packet
|
`packet-beta
|
||||||
0-15: "Source Port"
|
0-15: "Source Port"
|
||||||
16-31: "Destination Port"
|
16-31: "Destination Port"
|
||||||
32-63: "Sequence Number"
|
32-63: "Sequence Number"
|
||||||
@@ -61,7 +52,7 @@ describe('packet structure', () => {
|
|||||||
packet:
|
packet:
|
||||||
showBits: false
|
showBits: false
|
||||||
---
|
---
|
||||||
packet
|
packet-beta
|
||||||
0-15: "Source Port"
|
0-15: "Source Port"
|
||||||
16-31: "Destination Port"
|
16-31: "Destination Port"
|
||||||
32-63: "Sequence Number"
|
32-63: "Sequence Number"
|
||||||
|
|||||||
@@ -82,13 +82,4 @@ describe('pie chart', () => {
|
|||||||
`
|
`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should render pie slices only for non-zero values but shows all legends', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
` pie title Pets adopted by volunteers
|
|
||||||
"Dogs" : 386
|
|
||||||
"Cats" : 85
|
|
||||||
"Rats" : 1
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ describe('Sankey Diagram', () => {
|
|||||||
describe('when given a linkColor', function () {
|
describe('when given a linkColor', function () {
|
||||||
this.beforeAll(() => {
|
this.beforeAll(() => {
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
`sankey
|
`sankey-beta
|
||||||
a,b,10
|
a,b,10
|
||||||
`
|
`
|
||||||
).as('graph');
|
).as('graph');
|
||||||
@@ -62,7 +62,7 @@ describe('Sankey Diagram', () => {
|
|||||||
this.beforeAll(() => {
|
this.beforeAll(() => {
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
`
|
`
|
||||||
sankey
|
sankey-beta
|
||||||
|
|
||||||
a,b,8
|
a,b,8
|
||||||
b,c,8
|
b,c,8
|
||||||
|
|||||||
@@ -1,659 +0,0 @@
|
|||||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
|
|
||||||
|
|
||||||
const looks = ['classic'];
|
|
||||||
const participantTypes = [
|
|
||||||
{ type: 'participant', display: 'participant' },
|
|
||||||
{ type: 'actor', display: 'actor' },
|
|
||||||
{ type: 'boundary', display: 'boundary' },
|
|
||||||
{ type: 'control', display: 'control' },
|
|
||||||
{ type: 'entity', display: 'entity' },
|
|
||||||
{ type: 'database', display: 'database' },
|
|
||||||
{ type: 'collections', display: 'collections' },
|
|
||||||
{ type: 'queue', display: 'queue' },
|
|
||||||
];
|
|
||||||
|
|
||||||
const restrictedTypes = ['boundary', 'control', 'entity', 'database', 'collections', 'queue'];
|
|
||||||
|
|
||||||
const interactionTypes = ['->>', '-->>', '->', '-->', '-x', '--x', '->>+', '-->>+'];
|
|
||||||
|
|
||||||
const notePositions = ['left of', 'right of', 'over'];
|
|
||||||
|
|
||||||
function getParticipantLine(name, type, alias) {
|
|
||||||
if (restrictedTypes.includes(type)) {
|
|
||||||
return ` participant ${name}@{ "type" : "${type}" }\n`;
|
|
||||||
} else if (alias) {
|
|
||||||
return ` participant ${name}@{ "type" : "${type}" } \n`;
|
|
||||||
} else {
|
|
||||||
return ` participant ${name}@{ "type" : "${type}" }\n`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
looks.forEach((look) => {
|
|
||||||
describe(`Sequence Diagram Tests - ${look} look`, () => {
|
|
||||||
it('should render all participant types', () => {
|
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
|
||||||
participantTypes.forEach((pt, index) => {
|
|
||||||
const name = `${pt.display}${index}`;
|
|
||||||
diagramCode += getParticipantLine(name, pt.type);
|
|
||||||
});
|
|
||||||
for (let i = 0; i < participantTypes.length - 1; i++) {
|
|
||||||
diagramCode += ` ${participantTypes[i].display}${i} ->> ${participantTypes[i + 1].display}${i + 1}: Message ${i}\n`;
|
|
||||||
}
|
|
||||||
imgSnapshotTest(diagramCode, { look, sequence: { diagramMarginX: 50, diagramMarginY: 10 } });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render all interaction types', () => {
|
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
|
||||||
diagramCode += getParticipantLine('A', 'actor');
|
|
||||||
diagramCode += getParticipantLine('B', 'boundary');
|
|
||||||
interactionTypes.forEach((interaction, index) => {
|
|
||||||
diagramCode += ` A ${interaction} B: ${interaction} message ${index}\n`;
|
|
||||||
});
|
|
||||||
imgSnapshotTest(diagramCode, { look });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render participant creation and destruction', () => {
|
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
|
||||||
participantTypes.forEach((pt, index) => {
|
|
||||||
const name = `${pt.display}${index}`;
|
|
||||||
diagramCode += getParticipantLine('A', pt.type);
|
|
||||||
diagramCode += getParticipantLine('B', pt.type);
|
|
||||||
diagramCode += ` create participant ${name}@{ "type" : "${pt.type}" }\n`;
|
|
||||||
diagramCode += ` A ->> ${name}: Hello ${pt.display}\n`;
|
|
||||||
if (index % 2 === 0) {
|
|
||||||
diagramCode += ` destroy ${name}\n`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
imgSnapshotTest(diagramCode, { look });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render notes in all positions', () => {
|
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
|
||||||
diagramCode += getParticipantLine('A', 'actor');
|
|
||||||
diagramCode += getParticipantLine('B', 'boundary');
|
|
||||||
notePositions.forEach((position, index) => {
|
|
||||||
diagramCode += ` Note ${position} A: Note ${position} ${index}\n`;
|
|
||||||
});
|
|
||||||
diagramCode += ` A ->> B: Message with notes\n`;
|
|
||||||
imgSnapshotTest(diagramCode, { look });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render parallel interactions', () => {
|
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
|
||||||
participantTypes.slice(0, 4).forEach((pt, index) => {
|
|
||||||
diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
|
|
||||||
});
|
|
||||||
diagramCode += ` par Parallel actions\n`;
|
|
||||||
for (let i = 0; i < 3; i += 2) {
|
|
||||||
diagramCode += ` ${participantTypes[i].display}${i} ->> ${participantTypes[i + 1].display}${i + 1}: Message ${i}\n`;
|
|
||||||
if (i < participantTypes.length - 2) {
|
|
||||||
diagramCode += ` and\n`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diagramCode += ` end\n`;
|
|
||||||
imgSnapshotTest(diagramCode, { look });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render alternative flows', () => {
|
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
|
||||||
diagramCode += getParticipantLine('A', 'actor');
|
|
||||||
diagramCode += getParticipantLine('B', 'boundary');
|
|
||||||
diagramCode += ` alt Successful case\n`;
|
|
||||||
diagramCode += ` A ->> B: Request\n`;
|
|
||||||
diagramCode += ` B -->> A: Success\n`;
|
|
||||||
diagramCode += ` else Failure case\n`;
|
|
||||||
diagramCode += ` A ->> B: Request\n`;
|
|
||||||
diagramCode += ` B --x A: Failure\n`;
|
|
||||||
diagramCode += ` end\n`;
|
|
||||||
imgSnapshotTest(diagramCode, { look });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render loops', () => {
|
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
|
||||||
participantTypes.slice(0, 3).forEach((pt, index) => {
|
|
||||||
diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
|
|
||||||
});
|
|
||||||
diagramCode += ` loop For each participant\n`;
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[1].display}1: Message ${i}\n`;
|
|
||||||
}
|
|
||||||
diagramCode += ` end\n`;
|
|
||||||
imgSnapshotTest(diagramCode, { look });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render boxes around groups', () => {
|
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
|
||||||
diagramCode += ` box Group 1\n`;
|
|
||||||
participantTypes.slice(0, 3).forEach((pt, index) => {
|
|
||||||
diagramCode += ` ${getParticipantLine(`${pt.display}${index}`, pt.type)}`;
|
|
||||||
});
|
|
||||||
diagramCode += ` end\n`;
|
|
||||||
diagramCode += ` box rgb(200,220,255) Group 2\n`;
|
|
||||||
participantTypes.slice(3, 6).forEach((pt, index) => {
|
|
||||||
diagramCode += ` ${getParticipantLine(`${pt.display}${index}`, pt.type)}`;
|
|
||||||
});
|
|
||||||
diagramCode += ` end\n`;
|
|
||||||
diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[3].display}0: Cross-group message\n`;
|
|
||||||
imgSnapshotTest(diagramCode, { look });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render with different font settings', () => {
|
|
||||||
let diagramCode = `sequenceDiagram\n`;
|
|
||||||
participantTypes.slice(0, 3).forEach((pt, index) => {
|
|
||||||
diagramCode += getParticipantLine(`${pt.display}${index}`, pt.type);
|
|
||||||
});
|
|
||||||
diagramCode += ` ${participantTypes[0].display}0 ->> ${participantTypes[1].display}1: Regular message\n`;
|
|
||||||
diagramCode += ` Note right of ${participantTypes[1].display}1: Regular note\n`;
|
|
||||||
imgSnapshotTest(diagramCode, {
|
|
||||||
look,
|
|
||||||
sequence: {
|
|
||||||
actorFontFamily: 'courier',
|
|
||||||
actorFontSize: 14,
|
|
||||||
messageFontFamily: 'Arial',
|
|
||||||
messageFontSize: 12,
|
|
||||||
noteFontFamily: 'times',
|
|
||||||
noteFontSize: 16,
|
|
||||||
noteAlign: 'left',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Additional tests for specific combinations
|
|
||||||
describe('Sequence Diagram Special Cases', () => {
|
|
||||||
it('should render complex sequence with all features', () => {
|
|
||||||
const diagramCode = `
|
|
||||||
sequenceDiagram
|
|
||||||
box rgb(200,220,255) Authentication
|
|
||||||
actor User
|
|
||||||
participant LoginUI@{ "type": "boundary" }
|
|
||||||
participant AuthService@{ "type": "control" }
|
|
||||||
participant UserDB@{ "type": "database" }
|
|
||||||
end
|
|
||||||
|
|
||||||
box rgb(200,255,220) Order Processing
|
|
||||||
participant Order@{ "type": "entity" }
|
|
||||||
participant OrderQueue@{ "type": "queue" }
|
|
||||||
participant AuditLogs@{ "type": "collections" }
|
|
||||||
end
|
|
||||||
|
|
||||||
User ->> LoginUI: Enter credentials
|
|
||||||
LoginUI ->> AuthService: Validate
|
|
||||||
AuthService ->> UserDB: Query user
|
|
||||||
UserDB -->> AuthService: User data
|
|
||||||
alt Valid credentials
|
|
||||||
AuthService -->> LoginUI: Success
|
|
||||||
LoginUI -->> User: Welcome
|
|
||||||
|
|
||||||
par Place order
|
|
||||||
User ->> Order: New order
|
|
||||||
Order ->> OrderQueue: Process
|
|
||||||
and
|
|
||||||
Order ->> AuditLogs: Record
|
|
||||||
end
|
|
||||||
|
|
||||||
loop Until confirmed
|
|
||||||
OrderQueue ->> Order: Update status
|
|
||||||
Order -->> User: Notification
|
|
||||||
end
|
|
||||||
else Invalid credentials
|
|
||||||
AuthService --x LoginUI: Failure
|
|
||||||
LoginUI --x User: Retry
|
|
||||||
end
|
|
||||||
`;
|
|
||||||
imgSnapshotTest(diagramCode, {});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render with wrapped messages and notes', () => {
|
|
||||||
const diagramCode = `
|
|
||||||
sequenceDiagram
|
|
||||||
participant A
|
|
||||||
participant B
|
|
||||||
|
|
||||||
A ->> B: This is a very long message that should wrap properly in the diagram rendering
|
|
||||||
Note over A,B: This is a very long note that should also wrap properly when rendered in the diagram
|
|
||||||
|
|
||||||
par Wrapped parallel
|
|
||||||
A ->> B: Parallel message 1<br>with explicit line break
|
|
||||||
and
|
|
||||||
B ->> A: Parallel message 2<br>with explicit line break
|
|
||||||
end
|
|
||||||
|
|
||||||
loop Wrapped loop
|
|
||||||
Note right of B: This is a long note<br>in a loop
|
|
||||||
A ->> B: Message in loop
|
|
||||||
end
|
|
||||||
`;
|
|
||||||
imgSnapshotTest(diagramCode, { sequence: { wrap: true } });
|
|
||||||
});
|
|
||||||
describe('Sequence Diagram Rendering with Different Participant Types', () => {
|
|
||||||
it('should render a sequence diagram with various participant types', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant User@{ "type": "actor" }
|
|
||||||
participant AuthService@{ "type": "control" }
|
|
||||||
participant UI@{ "type": "boundary" }
|
|
||||||
participant OrderController@{ "type": "control" }
|
|
||||||
participant Product@{ "type": "entity" }
|
|
||||||
participant MongoDB@{ "type": "database" }
|
|
||||||
participant Products@{ "type": "collections" }
|
|
||||||
participant OrderQueue@{ "type": "queue" }
|
|
||||||
User ->> UI: Login request
|
|
||||||
UI ->> AuthService: Validate credentials
|
|
||||||
AuthService -->> UI: Authentication token
|
|
||||||
UI ->> OrderController: Place order
|
|
||||||
OrderController ->> Product: Check availability
|
|
||||||
Product -->> OrderController: Available
|
|
||||||
OrderController ->> MongoDB: Save order
|
|
||||||
MongoDB -->> OrderController: Order saved
|
|
||||||
OrderController ->> OrderQueue: Process payment
|
|
||||||
OrderQueue -->> User: Order confirmation
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render participant creation and destruction with different types', () => {
|
|
||||||
imgSnapshotTest(`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice@{ "type" : "boundary" }
|
|
||||||
Alice->>Bob: Hello Bob, how are you ?
|
|
||||||
Bob->>Alice: Fine, thank you. And you?
|
|
||||||
create participant Carl@{ "type" : "control" }
|
|
||||||
Alice->>Carl: Hi Carl!
|
|
||||||
create actor D as Donald
|
|
||||||
Carl->>D: Hi!
|
|
||||||
destroy Carl
|
|
||||||
Alice-xCarl: We are too many
|
|
||||||
destroy Bob
|
|
||||||
Bob->>Alice: I agree
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle complex interactions between different participant types', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
box rgb(200,220,255) Authentication
|
|
||||||
participant User@{ "type": "actor" }
|
|
||||||
participant LoginUI@{ "type": "boundary" }
|
|
||||||
participant AuthService@{ "type": "control" }
|
|
||||||
participant UserDB@{ "type": "database" }
|
|
||||||
end
|
|
||||||
|
|
||||||
box rgb(200,255,220) Order Processing
|
|
||||||
participant Order@{ "type": "entity" }
|
|
||||||
participant OrderQueue@{ "type": "queue" }
|
|
||||||
participant AuditLogs@{ "type": "collections" }
|
|
||||||
end
|
|
||||||
|
|
||||||
User ->> LoginUI: Enter credentials
|
|
||||||
LoginUI ->> AuthService: Validate
|
|
||||||
AuthService ->> UserDB: Query user
|
|
||||||
UserDB -->> AuthService: User data
|
|
||||||
|
|
||||||
alt Valid credentials
|
|
||||||
AuthService -->> LoginUI: Success
|
|
||||||
LoginUI -->> User: Welcome
|
|
||||||
|
|
||||||
par Place order
|
|
||||||
User ->> Order: New order
|
|
||||||
Order ->> OrderQueue: Process
|
|
||||||
and
|
|
||||||
Order ->> AuditLogs: Record
|
|
||||||
end
|
|
||||||
|
|
||||||
loop Until confirmed
|
|
||||||
OrderQueue ->> Order: Update status
|
|
||||||
Order -->> User: Notification
|
|
||||||
end
|
|
||||||
else Invalid credentials
|
|
||||||
AuthService --x LoginUI: Failure
|
|
||||||
LoginUI --x User: Retry
|
|
||||||
end
|
|
||||||
`,
|
|
||||||
{ sequence: { useMaxWidth: false } }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render parallel processes with different participant types', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Customer@{ "type": "actor" }
|
|
||||||
participant Frontend@{ "type": "participant" }
|
|
||||||
participant PaymentService@{ "type": "boundary" }
|
|
||||||
participant InventoryManager@{ "type": "control" }
|
|
||||||
participant Order@{ "type": "entity" }
|
|
||||||
participant OrdersDB@{ "type": "database" }
|
|
||||||
participant NotificationQueue@{ "type": "queue" }
|
|
||||||
|
|
||||||
Customer ->> Frontend: Place order
|
|
||||||
Frontend ->> Order: Create order
|
|
||||||
par Parallel Processing
|
|
||||||
Order ->> PaymentService: Process payment
|
|
||||||
and
|
|
||||||
Order ->> InventoryManager: Reserve items
|
|
||||||
end
|
|
||||||
PaymentService -->> Order: Payment confirmed
|
|
||||||
InventoryManager -->> Order: Items reserved
|
|
||||||
Order ->> OrdersDB: Save finalized order
|
|
||||||
OrdersDB -->> Order: Order saved
|
|
||||||
Order ->> NotificationQueue: Send confirmation
|
|
||||||
NotificationQueue -->> Customer: Order confirmation
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('should render different participant types with notes and loops', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
actor Admin
|
|
||||||
participant Dashboard
|
|
||||||
participant AuthService@{ "type" : "boundary" }
|
|
||||||
participant UserManager@{ "type" : "control" }
|
|
||||||
participant UserProfile@{ "type" : "entity" }
|
|
||||||
participant UserDB@{ "type" : "database" }
|
|
||||||
participant Logs@{ "type" : "database" }
|
|
||||||
|
|
||||||
Admin ->> Dashboard: Open user management
|
|
||||||
loop Authentication check
|
|
||||||
Dashboard ->> AuthService: Verify admin rights
|
|
||||||
AuthService ->> Dashboard: Access granted
|
|
||||||
end
|
|
||||||
Dashboard ->> UserManager: List users
|
|
||||||
UserManager ->> UserDB: Query users
|
|
||||||
UserDB ->> UserManager: Return user data
|
|
||||||
Note right of UserDB: Encrypted data<br/>requires decryption
|
|
||||||
UserManager ->> UserProfile: Format profiles
|
|
||||||
UserProfile ->> UserManager: Formatted data
|
|
||||||
UserManager ->> Dashboard: Display users
|
|
||||||
Dashboard ->> Logs: Record access
|
|
||||||
Logs ->> Admin: Audit trail
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render different participant types with alternative flows', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
actor Client
|
|
||||||
participant MobileApp
|
|
||||||
participant CloudService@{ "type" : "boundary" }
|
|
||||||
participant DataProcessor@{ "type" : "control" }
|
|
||||||
participant Transaction@{ "type" : "entity" }
|
|
||||||
participant TransactionsDB@{ "type" : "database" }
|
|
||||||
participant EventBus@{ "type" : "queue" }
|
|
||||||
|
|
||||||
Client ->> MobileApp: Initiate transaction
|
|
||||||
MobileApp ->> CloudService: Authenticate
|
|
||||||
alt Authentication successful
|
|
||||||
CloudService -->> MobileApp: Auth token
|
|
||||||
MobileApp ->> DataProcessor: Process data
|
|
||||||
DataProcessor ->> Transaction: Create transaction
|
|
||||||
Transaction ->> TransactionsDB: Save record
|
|
||||||
TransactionsDB -->> Transaction: Confirmation
|
|
||||||
Transaction ->> EventBus: Publish event
|
|
||||||
EventBus -->> Client: Notification
|
|
||||||
else Authentication failed
|
|
||||||
CloudService -->> MobileApp: Error
|
|
||||||
MobileApp -->> Client: Show error
|
|
||||||
end
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render different participant types with wrapping text', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant B@{ "type" : "boundary" }
|
|
||||||
participant C@{ "type" : "control" }
|
|
||||||
participant E@{ "type" : "entity" }
|
|
||||||
participant DB@{ "type" : "database" }
|
|
||||||
participant COL@{ "type" : "collections" }
|
|
||||||
participant Q@{ "type" : "queue" }
|
|
||||||
|
|
||||||
FE ->> B: Another long message<br/>with explicit<br/>line breaks
|
|
||||||
B -->> FE: Response message that is also quite long and needs to wrap
|
|
||||||
FE ->> C: Process data
|
|
||||||
C ->> E: Validate
|
|
||||||
E -->> C: Validation result
|
|
||||||
C ->> DB: Save
|
|
||||||
DB -->> C: Save result
|
|
||||||
C ->> COL: Log
|
|
||||||
COL -->> Q: Forward
|
|
||||||
Q -->> LongNameUser: Final response with confirmation of all actions taken
|
|
||||||
`,
|
|
||||||
{ sequence: { wrap: true } }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Sequence Diagram - New Participant Types with Long Notes and Messages', () => {
|
|
||||||
it('should render long notes left of boundary', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice@{ "type" : "boundary" }
|
|
||||||
actor Bob
|
|
||||||
Alice->>Bob: Hola
|
|
||||||
Note left of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
Bob->>Alice: I'm short though
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render wrapped long notes left of control', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice@{ "type" : "control" }
|
|
||||||
actor Bob
|
|
||||||
Alice->>Bob: Hola
|
|
||||||
Note left of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
Bob->>Alice: I'm short though
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render long notes right of entity', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice@{ "type" : "entity" }
|
|
||||||
actor Bob
|
|
||||||
Alice->>Bob: Hola
|
|
||||||
Note right of Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
Bob->>Alice: I'm short though
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render wrapped long notes right of database', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice@{ "type" : "database" }
|
|
||||||
actor Bob
|
|
||||||
Alice->>Bob: Hola
|
|
||||||
Note right of Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
Bob->>Alice: I'm short though
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render long notes over collections', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice@{ "type" : "collections" }
|
|
||||||
actor Bob
|
|
||||||
Alice->>Bob: Hola
|
|
||||||
Note over Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
Bob->>Alice: I'm short though
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render wrapped long notes over queue', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice@{ "type" : "queue" }
|
|
||||||
actor Bob
|
|
||||||
Alice->>Bob: Hola
|
|
||||||
Note over Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
Bob->>Alice: I'm short though
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render notes over actor and boundary', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
actor Alice
|
|
||||||
participant Charlie@{ "type" : "boundary" }
|
|
||||||
note over Alice: Some note
|
|
||||||
note over Charlie: Other note
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render long messages from database to collections', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice@{ "type" : "database" }
|
|
||||||
participant Bob@{ "type" : "collections" }
|
|
||||||
Alice->>Bob: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
Bob->>Alice: I'm short though
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render wrapped long messages from control to entity', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice@{ "type" : "control" }
|
|
||||||
participant Bob@{ "type" : "entity" }
|
|
||||||
Alice->>Bob:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
Bob->>Alice: I'm short though
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render long messages from queue to boundary', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
participant Alice@{ "type" : "queue" }
|
|
||||||
participant Bob@{ "type" : "boundary" }
|
|
||||||
Alice->>Bob: I'm short
|
|
||||||
Bob->>Alice: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render wrapped long messages from actor to database', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
actor Alice
|
|
||||||
participant Bob@{ "type" : "database" }
|
|
||||||
Alice->>Bob: I'm short
|
|
||||||
Bob->>Alice:wrap: Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('svg size', () => {
|
|
||||||
it('should render a sequence diagram when useMaxWidth is true (default)', () => {
|
|
||||||
renderGraph(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
actor Alice
|
|
||||||
participant Bob@{ "type" : "boundary" }
|
|
||||||
participant John@{ "type" : "control" }
|
|
||||||
Alice ->> Bob: Hello Bob, how are you?
|
|
||||||
Bob-->>John: How about you John?
|
|
||||||
Bob--x Alice: I am good thanks!
|
|
||||||
Bob-x John: I am good thanks!
|
|
||||||
Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
|
|
||||||
Bob-->Alice: Checking with John...
|
|
||||||
alt either this
|
|
||||||
Alice->>John: Yes
|
|
||||||
else or this
|
|
||||||
Alice->>John: No
|
|
||||||
else or this will happen
|
|
||||||
Alice->John: Maybe
|
|
||||||
end
|
|
||||||
par this happens in parallel
|
|
||||||
Alice -->> Bob: Parallel message 1
|
|
||||||
and
|
|
||||||
Alice -->> John: Parallel message 2
|
|
||||||
end
|
|
||||||
`,
|
|
||||||
{ sequence: { useMaxWidth: true } }
|
|
||||||
);
|
|
||||||
cy.get('svg').should((svg) => {
|
|
||||||
expect(svg).to.have.attr('width', '100%');
|
|
||||||
const style = svg.attr('style');
|
|
||||||
expect(style).to.match(/^max-width: [\d.]+px;$/);
|
|
||||||
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
|
|
||||||
expect(maxWidthValue).to.be.within(820 * 0.95, 820 * 1.05);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render a sequence diagram when useMaxWidth is false', () => {
|
|
||||||
renderGraph(
|
|
||||||
`
|
|
||||||
sequenceDiagram
|
|
||||||
actor Alice
|
|
||||||
participant Bob@{ "type" : "boundary" }
|
|
||||||
participant John@{ "type" : "control" }
|
|
||||||
Alice ->> Bob: Hello Bob, how are you?
|
|
||||||
Bob-->>John: How about you John?
|
|
||||||
Bob--x Alice: I am good thanks!
|
|
||||||
Bob-x John: I am good thanks!
|
|
||||||
Note right of John: Bob thinks a long<br/>long time, so long<br/>that the text does<br/>not fit on a row.
|
|
||||||
Bob-->Alice: Checking with John...
|
|
||||||
alt either this
|
|
||||||
Alice->>John: Yes
|
|
||||||
else or this
|
|
||||||
Alice->>John: No
|
|
||||||
else or this will happen
|
|
||||||
Alice->John: Maybe
|
|
||||||
end
|
|
||||||
par this happens in parallel
|
|
||||||
Alice -->> Bob: Parallel message 1
|
|
||||||
and
|
|
||||||
Alice -->> John: Parallel message 2
|
|
||||||
end
|
|
||||||
`,
|
|
||||||
{ sequence: { useMaxWidth: false } }
|
|
||||||
);
|
|
||||||
cy.get('svg').should((svg) => {
|
|
||||||
const width = parseFloat(svg.attr('width'));
|
|
||||||
expect(width).to.be.within(820 * 0.95, 820 * 1.05);
|
|
||||||
expect(svg).to.not.have.attr('style');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -893,17 +893,6 @@ describe('Sequence diagram', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle bidirectional arrows with autonumber', () => {
|
|
||||||
imgSnapshotTest(`
|
|
||||||
sequenceDiagram
|
|
||||||
autonumber
|
|
||||||
participant A
|
|
||||||
participant B
|
|
||||||
A<<->>B: This is a bidirectional message
|
|
||||||
A->B: This is a normal message`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
|
it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
|
||||||
//Be aware that the syntax for "properties" is likely to be changed.
|
//Be aware that the syntax for "properties" is likely to be changed.
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
|
|||||||
@@ -602,231 +602,6 @@ State1 --> [*]
|
|||||||
--
|
--
|
||||||
55
|
55
|
||||||
}
|
}
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('should render edge labels correctly', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
title: On The Way To Something Something DarkSide
|
|
||||||
config:
|
|
||||||
look: default
|
|
||||||
theme: default
|
|
||||||
---
|
|
||||||
|
|
||||||
stateDiagram-v2
|
|
||||||
|
|
||||||
state State1_____________
|
|
||||||
{
|
|
||||||
c0
|
|
||||||
}
|
|
||||||
|
|
||||||
state State2_____________
|
|
||||||
{
|
|
||||||
c1
|
|
||||||
}
|
|
||||||
|
|
||||||
state State3_____________
|
|
||||||
{
|
|
||||||
c7
|
|
||||||
}
|
|
||||||
|
|
||||||
state State4_____________
|
|
||||||
{
|
|
||||||
c2
|
|
||||||
}
|
|
||||||
|
|
||||||
state State5_____________
|
|
||||||
{
|
|
||||||
c3
|
|
||||||
}
|
|
||||||
|
|
||||||
state State6_____________
|
|
||||||
{
|
|
||||||
c4
|
|
||||||
}
|
|
||||||
|
|
||||||
state State7_____________
|
|
||||||
{
|
|
||||||
c5
|
|
||||||
}
|
|
||||||
|
|
||||||
state State8_____________
|
|
||||||
{
|
|
||||||
c6
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[*] --> State1_____________
|
|
||||||
State1_____________ --> State2_____________ : Transition1_____
|
|
||||||
State2_____________ --> State4_____________ : Transition2_____
|
|
||||||
State2_____________ --> State3_____________ : Transition3_____
|
|
||||||
State3_____________ --> State2_____________
|
|
||||||
State4_____________ --> State2_____________ : Transition5_____
|
|
||||||
State4_____________ --> State5_____________ : Transition6_____
|
|
||||||
State5_____________ --> State6_____________ : Transition7_____
|
|
||||||
State6_____________ --> State4_____________ : Transition8_____
|
|
||||||
State2_____________ --> State7_____________ : Transition4_____
|
|
||||||
State4_____________ --> State7_____________ : Transition4_____
|
|
||||||
State5_____________ --> State7_____________ : Transition4_____
|
|
||||||
State6_____________ --> State7_____________ : Transition4_____
|
|
||||||
State7_____________ --> State1_____________ : Transition9_____
|
|
||||||
State5_____________ --> State8_____________ : Transition10____
|
|
||||||
State8_____________ --> State5_____________ : Transition11____
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('should render edge labels correctly with multiple transitions', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
title: Multiple Transitions
|
|
||||||
config:
|
|
||||||
look: default
|
|
||||||
theme: default
|
|
||||||
---
|
|
||||||
|
|
||||||
stateDiagram-v2
|
|
||||||
|
|
||||||
state State1_____________
|
|
||||||
{
|
|
||||||
c0
|
|
||||||
}
|
|
||||||
|
|
||||||
state State2_____________
|
|
||||||
{
|
|
||||||
c1
|
|
||||||
}
|
|
||||||
|
|
||||||
state State3_____________
|
|
||||||
{
|
|
||||||
c7
|
|
||||||
}
|
|
||||||
|
|
||||||
state State4_____________
|
|
||||||
{
|
|
||||||
c2
|
|
||||||
}
|
|
||||||
|
|
||||||
state State5_____________
|
|
||||||
{
|
|
||||||
c3
|
|
||||||
}
|
|
||||||
|
|
||||||
state State6_____________
|
|
||||||
{
|
|
||||||
c4
|
|
||||||
}
|
|
||||||
|
|
||||||
state State7_____________
|
|
||||||
{
|
|
||||||
c5
|
|
||||||
}
|
|
||||||
|
|
||||||
state State8_____________
|
|
||||||
{
|
|
||||||
c6
|
|
||||||
}
|
|
||||||
|
|
||||||
state State9_____________
|
|
||||||
{
|
|
||||||
c9
|
|
||||||
}
|
|
||||||
|
|
||||||
[*] --> State1_____________
|
|
||||||
State1_____________ --> State2_____________ : Transition1_____
|
|
||||||
State2_____________ --> State4_____________ : Transition2_____
|
|
||||||
State2_____________ --> State3_____________ : Transition3_____
|
|
||||||
State3_____________ --> State2_____________
|
|
||||||
State4_____________ --> State2_____________ : Transition5_____
|
|
||||||
State4_____________ --> State5_____________ : Transition6_____
|
|
||||||
State5_____________ --> State6_____________ : Transition7_____
|
|
||||||
State6_____________ --> State4_____________ : Transition8_____
|
|
||||||
State2_____________ --> State7_____________ : Transition4_____
|
|
||||||
State4_____________ --> State7_____________ : Transition4_____
|
|
||||||
State5_____________ --> State7_____________ : Transition4_____
|
|
||||||
State6_____________ --> State7_____________ : Transition4_____
|
|
||||||
State7_____________ --> State1_____________ : Transition9_____
|
|
||||||
State5_____________ --> State8_____________ : Transition10____
|
|
||||||
State8_____________ --> State5_____________ : Transition11____
|
|
||||||
State9_____________ --> State8_____________ : Transition12____
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render edge labels correctly with multiple states', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
title: Multiple States
|
|
||||||
config:
|
|
||||||
look: default
|
|
||||||
theme: default
|
|
||||||
---
|
|
||||||
|
|
||||||
stateDiagram-v2
|
|
||||||
|
|
||||||
state State1_____________
|
|
||||||
{
|
|
||||||
c0
|
|
||||||
}
|
|
||||||
|
|
||||||
state State2_____________
|
|
||||||
{
|
|
||||||
c1
|
|
||||||
}
|
|
||||||
|
|
||||||
state State3_____________
|
|
||||||
{
|
|
||||||
c7
|
|
||||||
}
|
|
||||||
|
|
||||||
state State4_____________
|
|
||||||
{
|
|
||||||
c2
|
|
||||||
}
|
|
||||||
|
|
||||||
state State5_____________
|
|
||||||
{
|
|
||||||
c3
|
|
||||||
}
|
|
||||||
|
|
||||||
state State6_____________
|
|
||||||
{
|
|
||||||
c4
|
|
||||||
}
|
|
||||||
|
|
||||||
state State7_____________
|
|
||||||
{
|
|
||||||
c5
|
|
||||||
}
|
|
||||||
|
|
||||||
state State8_____________
|
|
||||||
{
|
|
||||||
c6
|
|
||||||
}
|
|
||||||
|
|
||||||
state State9_____________
|
|
||||||
{
|
|
||||||
c9
|
|
||||||
}
|
|
||||||
|
|
||||||
state State10_____________
|
|
||||||
{
|
|
||||||
c10
|
|
||||||
}
|
|
||||||
|
|
||||||
[*] --> State1_____________
|
|
||||||
State1_____________ --> State2_____________ : Transition1_____
|
|
||||||
State2_____________ --> State3_____________ : Transition2_____
|
|
||||||
State3_____________ --> State4_____________ : Transition3_____
|
|
||||||
State4_____________ --> State5_____________ : Transition4_____
|
|
||||||
State5_____________ --> State6_____________ : Transition5_____
|
|
||||||
State6_____________ --> State7_____________ : Transition6_____
|
|
||||||
State7_____________ --> State8_____________ : Transition7_____
|
|
||||||
State8_____________ --> State9_____________ : Transition8_____
|
|
||||||
State9_____________ --> State10_____________ : Transition9_____
|
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -161,68 +161,4 @@ describe('Timeline diagram', () => {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('11: should render timeline with many stacked events and proper timeline line length', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`timeline
|
|
||||||
title Medical Device Lifecycle
|
|
||||||
section Pre-Development
|
|
||||||
Quality Management System : Regulatory Compliance : Risk Management
|
|
||||||
section Development
|
|
||||||
Management Responsibility : Planning Activities : Human Resources
|
|
||||||
Resource Management : Management Reviews : Infrastructure
|
|
||||||
section Post-Development
|
|
||||||
Product Realization Activities : Planning Activities : Customer-related Processes
|
|
||||||
Post-Production Activities : Feedback : Complaints : Adverse Events
|
|
||||||
: Research and Development : Purchasing Activities
|
|
||||||
: Production Activities : Installation Activities
|
|
||||||
: Servicing Activities : Post-Market Surveillance
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('12: should render timeline with proper vertical line lengths for all columns', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
theme: base
|
|
||||||
themeVariables:
|
|
||||||
fontFamily: Fira Sans
|
|
||||||
fontSize: 17px
|
|
||||||
cScale0: '#b3cde0'
|
|
||||||
cScale1: '#f49090'
|
|
||||||
cScale2: '#85d5b8'
|
|
||||||
---
|
|
||||||
|
|
||||||
timeline
|
|
||||||
title Medical Device Lifecycle
|
|
||||||
section Planning
|
|
||||||
Quality Management System (4): Regulatory Compliance (4.1.1)
|
|
||||||
: Risk Management (4.1.2)
|
|
||||||
Management Resposibility (5): Planning Activities (5.4)
|
|
||||||
: Management Reviews (5.6)
|
|
||||||
Resource Management (6): Human Resources (6.2)
|
|
||||||
: Infrastructure (6.3)
|
|
||||||
section Realization
|
|
||||||
Research and Development (7.3): RnD Planning (7.3.2)
|
|
||||||
: Inputs (7.3.3)
|
|
||||||
: Outputs (7.3.4)
|
|
||||||
: Review (7.3.5)
|
|
||||||
: Verification (7.3.6)
|
|
||||||
: Validation (7.3.7)
|
|
||||||
Purchasing (7.4): Purchasing Process (7.4.1)
|
|
||||||
: Purchasing Information (7.4.2)
|
|
||||||
Production (7.5): Production Activities (7.5.1)
|
|
||||||
: Production Feedback (8.2.1)
|
|
||||||
Installation (7.5.3): Installation Activities (7.5.3)
|
|
||||||
Servicing (7.5.4): Servicing Activities (7.5.4)
|
|
||||||
section Post-Production
|
|
||||||
Post-Market Activities (8): Feedback (8.2.1)
|
|
||||||
: Complaints (8.2.2)
|
|
||||||
: Adverse Events (8.2.3)
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,382 +0,0 @@
|
|||||||
import { imgSnapshotTest } from '../../helpers/util.ts';
|
|
||||||
|
|
||||||
describe('Treemap Diagram', () => {
|
|
||||||
it('1: should render a basic treemap', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`treemap-beta
|
|
||||||
"Category A"
|
|
||||||
"Item A1": 10
|
|
||||||
"Item A2": 20
|
|
||||||
"Category B"
|
|
||||||
"Item B1": 15
|
|
||||||
"Item B2": 25
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('2: should render a hierarchical treemap', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`treemap-beta
|
|
||||||
"Products"
|
|
||||||
"Electronics"
|
|
||||||
"Phones": 50
|
|
||||||
"Computers": 30
|
|
||||||
"Accessories": 20
|
|
||||||
"Clothing"
|
|
||||||
"Men's"
|
|
||||||
"Shirts": 10
|
|
||||||
"Pants": 15
|
|
||||||
"Women's"
|
|
||||||
"Dresses": 20
|
|
||||||
"Skirts": 10
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('3: should render a treemap with styling using classDef', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`treemap-beta
|
|
||||||
"Section 1"
|
|
||||||
"Leaf 1.1": 12
|
|
||||||
"Section 1.2":::class1
|
|
||||||
"Leaf 1.2.1": 12
|
|
||||||
"Section 2"
|
|
||||||
"Leaf 2.1": 20:::class1
|
|
||||||
"Leaf 2.2": 25
|
|
||||||
"Leaf 2.3": 12
|
|
||||||
|
|
||||||
classDef class1 fill:red,color:blue,stroke:#FFD600;
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('4: should handle long text that wraps', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`treemap-beta
|
|
||||||
"Main Category"
|
|
||||||
"This is a very long item name that should wrap to the next line when rendered in the treemap diagram": 50
|
|
||||||
"Short item": 20
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('5: should render with a forest theme', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
theme: forest
|
|
||||||
---
|
|
||||||
treemap-beta
|
|
||||||
"Category A"
|
|
||||||
"Item A1": 10
|
|
||||||
"Item A2": 20
|
|
||||||
"Category B"
|
|
||||||
"Item B1": 15
|
|
||||||
"Item B2": 25
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('6: should handle multiple levels of nesting', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`treemap-beta
|
|
||||||
"Level 1"
|
|
||||||
"Level 2A"
|
|
||||||
"Level 3A": 10
|
|
||||||
"Level 3B": 15
|
|
||||||
"Level 2B"
|
|
||||||
"Level 3C": 20
|
|
||||||
"Level 3D"
|
|
||||||
"Level 4A": 5
|
|
||||||
"Level 4B": 5
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('7: should handle classDef with multiple styles', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`treemap-beta
|
|
||||||
"Main"
|
|
||||||
"A": 20
|
|
||||||
"B":::important
|
|
||||||
"B1": 10
|
|
||||||
"B2": 15
|
|
||||||
"C": 5:::secondary
|
|
||||||
|
|
||||||
classDef important fill:#f96,stroke:#333,stroke-width:2px;
|
|
||||||
classDef secondary fill:#6cf,stroke:#333,stroke-dasharray:5 5;
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('8: should handle dollar value formatting with thousands separator', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
treemap:
|
|
||||||
valueFormat: "$0,0"
|
|
||||||
---
|
|
||||||
treemap
|
|
||||||
"Budget"
|
|
||||||
"Operations"
|
|
||||||
"Salaries": 700000
|
|
||||||
"Equipment": 200000
|
|
||||||
"Supplies": 100000
|
|
||||||
"Marketing"
|
|
||||||
"Advertising": 400000
|
|
||||||
"Events": 100000
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('8a: should handle percentage formatting', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
treemap:
|
|
||||||
valueFormat: ".1%"
|
|
||||||
---
|
|
||||||
treemap-beta
|
|
||||||
"Market Share"
|
|
||||||
"Company A": 0.35
|
|
||||||
"Company B": 0.25
|
|
||||||
"Company C": 0.15
|
|
||||||
"Others": 0.25
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('8b: should handle decimal formatting', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
treemap:
|
|
||||||
valueFormat: ".2f"
|
|
||||||
---
|
|
||||||
treemap-beta
|
|
||||||
"Metrics"
|
|
||||||
"Conversion Rate": 0.0567
|
|
||||||
"Bounce Rate": 0.6723
|
|
||||||
"Click-through Rate": 0.1289
|
|
||||||
"Engagement": 0.4521
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('8c: should handle dollar sign with decimal places', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
treemap:
|
|
||||||
valueFormat: "$.2f"
|
|
||||||
---
|
|
||||||
treemap-beta
|
|
||||||
"Product Prices"
|
|
||||||
"Basic": 19.99
|
|
||||||
"Standard": 49.99
|
|
||||||
"Premium": 99.99
|
|
||||||
"Enterprise": 199.99
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('8d: should handle dollar sign with thousands separator and decimal places', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
treemap:
|
|
||||||
valueFormat: "$,.2f"
|
|
||||||
---
|
|
||||||
treemap-beta
|
|
||||||
"Revenue"
|
|
||||||
"Q1": 1250345.75
|
|
||||||
"Q2": 1645789.25
|
|
||||||
"Q3": 1845123.50
|
|
||||||
"Q4": 2145678.75
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('8e: should handle simple thousands separator', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
treemap:
|
|
||||||
valueFormat: ","
|
|
||||||
---
|
|
||||||
treemap-beta
|
|
||||||
"User Counts"
|
|
||||||
"Active Users": 1250345
|
|
||||||
"New Signups": 45789
|
|
||||||
"Churned": 12350
|
|
||||||
"Converted": 78975
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('8f: should handle valueFormat set via directive with dollar and thousands separator', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
treemap:
|
|
||||||
valueFormat: "$,.0f"
|
|
||||||
---
|
|
||||||
treemap-beta
|
|
||||||
"Sales by Region"
|
|
||||||
"North": 1234567
|
|
||||||
"South": 7654321
|
|
||||||
"East": 4567890
|
|
||||||
"West": 9876543
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('8g: should handle scientific notation format', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
treemap:
|
|
||||||
valueFormat: ".2e"
|
|
||||||
---
|
|
||||||
treemap-beta
|
|
||||||
"Scientific Values"
|
|
||||||
"Value 1": 1234567
|
|
||||||
"Value 2": 0.0000123
|
|
||||||
"Value 3": 1000000000
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('9: should handle a complex example with multiple features', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`---
|
|
||||||
config:
|
|
||||||
theme: dark
|
|
||||||
treemap:
|
|
||||||
valueFormat: "$0,0"
|
|
||||||
---
|
|
||||||
treemap-beta
|
|
||||||
"Company Budget"
|
|
||||||
"Engineering":::engineering
|
|
||||||
"Frontend": 300000
|
|
||||||
"Backend": 400000
|
|
||||||
"DevOps": 200000
|
|
||||||
"Marketing":::marketing
|
|
||||||
"Digital": 250000
|
|
||||||
"Print": 100000
|
|
||||||
"Events": 150000
|
|
||||||
"Sales":::sales
|
|
||||||
"Direct": 500000
|
|
||||||
"Channel": 300000
|
|
||||||
|
|
||||||
classDef engineering fill:#6b9bc3,stroke:#333;
|
|
||||||
classDef marketing fill:#c36b9b,stroke:#333;
|
|
||||||
classDef sales fill:#c3a66b,stroke:#333;
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('10: should render the example from documentation', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
treemap-beta
|
|
||||||
"Section 1"
|
|
||||||
"Leaf 1.1": 12
|
|
||||||
"Section 1.2":::class1
|
|
||||||
"Leaf 1.2.1": 12
|
|
||||||
"Section 2"
|
|
||||||
"Leaf 2.1": 20:::class1
|
|
||||||
"Leaf 2.2": 25
|
|
||||||
"Leaf 2.3": 12
|
|
||||||
|
|
||||||
classDef class1 fill:red,color:blue,stroke:#FFD600;
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('11: should handle comments', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
treemap-beta
|
|
||||||
%% This is a comment
|
|
||||||
"Category A"
|
|
||||||
"Item A1": 10
|
|
||||||
"Item A2": 20
|
|
||||||
%% Another comment
|
|
||||||
"Category B"
|
|
||||||
"Item B1": 15
|
|
||||||
"Item B2": 25
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
/*
|
|
||||||
it.skip('12: should render a treemap with title', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
treemap-beta
|
|
||||||
title Treemap with Title
|
|
||||||
"Category A"
|
|
||||||
"Item A1": 10
|
|
||||||
"Item A2": 20
|
|
||||||
"Category B"
|
|
||||||
"Item B1": 15
|
|
||||||
"Item B2": 25
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it.skip('13: should render a treemap with accessibility attributes', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
treemap-beta
|
|
||||||
accTitle: Accessible Treemap Title
|
|
||||||
accDescr: This is a description of the treemap for accessibility purposes
|
|
||||||
"Category A"
|
|
||||||
"Item A1": 10
|
|
||||||
"Item A2": 20
|
|
||||||
"Category B"
|
|
||||||
"Item B1": 15
|
|
||||||
"Item B2": 25
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it.skip('14: should render a treemap with title and accessibility attributes', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
treemap
|
|
||||||
title Treemap with Title and Accessibility
|
|
||||||
accTitle: Accessible Treemap Title
|
|
||||||
accDescr: This is a description of the treemap for accessibility purposes
|
|
||||||
"Category A"
|
|
||||||
"Item A1": 10
|
|
||||||
"Item A2": 20
|
|
||||||
"Category B"
|
|
||||||
"Item B1": 15
|
|
||||||
"Item B2": 25
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
});
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
|
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
|
||||||
|
|
||||||
describe('XY Chart', () => {
|
describe('XY Chart', () => {
|
||||||
it('should render the simplest possible xy-beta chart', () => {
|
it('should render the simplest possible chart', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart-beta
|
xychart-beta
|
||||||
@@ -10,19 +10,10 @@ describe('XY Chart', () => {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should render the simplest possible xy chart', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
xychart
|
|
||||||
line [10, 30, 20]
|
|
||||||
`,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
it('Should render a complete chart', () => {
|
it('Should render a complete chart', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -35,7 +26,7 @@ describe('XY Chart', () => {
|
|||||||
it('Should render a chart without title', () => {
|
it('Should render a chart without title', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart
|
xychart-beta
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
|
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
|
||||||
@@ -47,7 +38,7 @@ describe('XY Chart', () => {
|
|||||||
it('y-axis title not required', () => {
|
it('y-axis title not required', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart
|
xychart-beta
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis 4000 --> 11000
|
y-axis 4000 --> 11000
|
||||||
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
|
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
|
||||||
@@ -59,7 +50,7 @@ describe('XY Chart', () => {
|
|||||||
it('Should render a chart without y-axis with different range', () => {
|
it('Should render a chart without y-axis with different range', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart
|
xychart-beta
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000]
|
bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000]
|
||||||
line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800]
|
line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800]
|
||||||
@@ -70,7 +61,7 @@ describe('XY Chart', () => {
|
|||||||
it('x axis title not required', () => {
|
it('x axis title not required', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart
|
xychart-beta
|
||||||
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000]
|
bar [5000, 6000, 7500, 8200, 9500, 10500, 14000, 3200, 9200, 9900, 3400, 6000]
|
||||||
line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800]
|
line [2000, 7000, 6500, 9200, 9500, 7500, 11000, 10200, 3200, 8500, 7000, 8800]
|
||||||
@@ -81,7 +72,7 @@ describe('XY Chart', () => {
|
|||||||
it('Multiple plots can be rendered', () => {
|
it('Multiple plots can be rendered', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart
|
xychart-beta
|
||||||
line [23, 46, 77, 34]
|
line [23, 46, 77, 34]
|
||||||
line [45, 32, 33, 12]
|
line [45, 32, 33, 12]
|
||||||
bar [87, 54, 99, 85]
|
bar [87, 54, 99, 85]
|
||||||
@@ -95,7 +86,7 @@ describe('XY Chart', () => {
|
|||||||
it('Decimals and negative numbers are supported', () => {
|
it('Decimals and negative numbers are supported', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart
|
xychart-beta
|
||||||
y-axis -2.4 --> 3.5
|
y-axis -2.4 --> 3.5
|
||||||
line [+1.3, .6, 2.4, -.34]
|
line [+1.3, .6, 2.4, -.34]
|
||||||
`,
|
`,
|
||||||
@@ -113,7 +104,7 @@ describe('XY Chart', () => {
|
|||||||
height: 20
|
height: 20
|
||||||
plotReservedSpacePercent: 100
|
plotReservedSpacePercent: 100
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
@@ -139,7 +130,7 @@ describe('XY Chart', () => {
|
|||||||
showTick: false
|
showTick: false
|
||||||
showAxisLine: false
|
showAxisLine: false
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
||||||
`,
|
`,
|
||||||
{}
|
{}
|
||||||
@@ -149,7 +140,7 @@ describe('XY Chart', () => {
|
|||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
%%{init: {"xyChart": {"width": 1000, "height": 600, "titlePadding": 5, "titleFontSize": 10, "xAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "yAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "plotBorderWidth": 5, "chartOrientation": "horizontal", "plotReservedSpacePercent": 60 }}}%%
|
%%{init: {"xyChart": {"width": 1000, "height": 600, "titlePadding": 5, "titleFontSize": 10, "xAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "yAxis": {"labelFontSize": "20", "labelPadding": 10, "titleFontSize": 30, "titlePadding": 20, "tickLength": 10, "tickWidth": 5}, "plotBorderWidth": 5, "chartOrientation": "horizontal", "plotReservedSpacePercent": 60 }}}%%
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -190,7 +181,7 @@ describe('XY Chart', () => {
|
|||||||
plotReservedSpacePercent: 60
|
plotReservedSpacePercent: 60
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -211,7 +202,7 @@ describe('XY Chart', () => {
|
|||||||
yAxis:
|
yAxis:
|
||||||
showTitle: false
|
showTitle: false
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -232,7 +223,7 @@ describe('XY Chart', () => {
|
|||||||
yAxis:
|
yAxis:
|
||||||
showLabel: false
|
showLabel: false
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -253,7 +244,7 @@ describe('XY Chart', () => {
|
|||||||
yAxis:
|
yAxis:
|
||||||
showTick: false
|
showTick: false
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -274,7 +265,7 @@ describe('XY Chart', () => {
|
|||||||
yAxis:
|
yAxis:
|
||||||
showAxisLine: false
|
showAxisLine: false
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -303,7 +294,7 @@ describe('XY Chart', () => {
|
|||||||
xAxisLineColor: "#87ceeb"
|
xAxisLineColor: "#87ceeb"
|
||||||
plotColorPalette: "#008000, #faba63"
|
plotColorPalette: "#008000, #faba63"
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -316,7 +307,7 @@ describe('XY Chart', () => {
|
|||||||
it('should use the correct distances between data points', () => {
|
it('should use the correct distances between data points', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart
|
xychart-beta
|
||||||
x-axis 0 --> 2
|
x-axis 0 --> 2
|
||||||
line [0, 1, 0, 1]
|
line [0, 1, 0, 1]
|
||||||
bar [1, 0, 1, 0]
|
bar [1, 0, 1, 0]
|
||||||
@@ -334,7 +325,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -353,7 +344,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -366,7 +357,7 @@ describe('XY Chart', () => {
|
|||||||
it('should render vertical bar chart without labels by default', () => {
|
it('should render vertical bar chart without labels by default', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -384,7 +375,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -402,7 +393,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Multiple Bar Plots"
|
title "Multiple Bar Plots"
|
||||||
x-axis Categories [A, B, C]
|
x-axis Categories [A, B, C]
|
||||||
y-axis "Values" 0 --> 100
|
y-axis "Values" 0 --> 100
|
||||||
@@ -421,7 +412,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Multiple Bar Plots"
|
title "Multiple Bar Plots"
|
||||||
x-axis Categories [A, B, C]
|
x-axis Categories [A, B, C]
|
||||||
y-axis "Values" 0 --> 100
|
y-axis "Values" 0 --> 100
|
||||||
@@ -439,7 +430,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Single Bar Chart"
|
title "Single Bar Chart"
|
||||||
x-axis Categories [A]
|
x-axis Categories [A]
|
||||||
y-axis "Value" 0 --> 100
|
y-axis "Value" 0 --> 100
|
||||||
@@ -458,7 +449,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Single Bar Chart"
|
title "Single Bar Chart"
|
||||||
x-axis Categories [A]
|
x-axis Categories [A]
|
||||||
y-axis "Value" 0 --> 100
|
y-axis "Value" 0 --> 100
|
||||||
@@ -476,7 +467,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Decimal and Negative Values"
|
title "Decimal and Negative Values"
|
||||||
x-axis Categories [A, B, C]
|
x-axis Categories [A, B, C]
|
||||||
y-axis -10 --> 10
|
y-axis -10 --> 10
|
||||||
@@ -495,7 +486,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Decimal and Negative Values"
|
title "Decimal and Negative Values"
|
||||||
x-axis Categories [A, B, C]
|
x-axis Categories [A, B, C]
|
||||||
y-axis -10 --> 10
|
y-axis -10 --> 10
|
||||||
@@ -513,7 +504,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan,b,c]
|
x-axis Months [jan,b,c]
|
||||||
y-axis "Revenue (in $)" 4000 --> 12000
|
y-axis "Revenue (in $)" 4000 --> 12000
|
||||||
@@ -570,7 +561,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan,b,c]
|
x-axis Months [jan,b,c]
|
||||||
y-axis "Revenue (in $)" 4000 --> 12000
|
y-axis "Revenue (in $)" 4000 --> 12000
|
||||||
@@ -624,7 +615,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
|
x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
|
||||||
y-axis "Revenue (in $)" 4000 --> 12000
|
y-axis "Revenue (in $)" 4000 --> 12000
|
||||||
@@ -681,7 +672,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
|
x-axis Months [jan,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
|
||||||
y-axis "Revenue (in $)" 4000 --> 12000
|
y-axis "Revenue (in $)" 4000 --> 12000
|
||||||
@@ -735,7 +726,7 @@ describe('XY Chart', () => {
|
|||||||
xyChart:
|
xyChart:
|
||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan]
|
x-axis Months [jan]
|
||||||
y-axis "Revenue (in $)" 3000 --> 12000
|
y-axis "Revenue (in $)" 3000 --> 12000
|
||||||
@@ -792,7 +783,7 @@ describe('XY Chart', () => {
|
|||||||
showDataLabel: true
|
showDataLabel: true
|
||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan]
|
x-axis Months [jan]
|
||||||
y-axis "Revenue (in $)" 3000 --> 12000
|
y-axis "Revenue (in $)" 3000 --> 12000
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<title>Mermaid Quick Test Page</title>
|
|
||||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
|
||||||
<style>
|
|
||||||
div.mermaid {
|
|
||||||
font-family: 'Courier New', Courier, monospace !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1>Pie chart demos</h1>
|
|
||||||
<pre class="mermaid">
|
|
||||||
pie title Default text position: Animal adoption
|
|
||||||
accTitle: simple pie char demo
|
|
||||||
accDescr: pie chart with 3 sections: dogs, cats, rats. Most are dogs.
|
|
||||||
"dogs" : -60.67
|
|
||||||
"rats" : 40.12
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
<script type="module">
|
|
||||||
import mermaid from '/mermaid.esm.mjs';
|
|
||||||
mermaid.initialize({
|
|
||||||
theme: 'forest',
|
|
||||||
logLevel: 3,
|
|
||||||
securityLevel: 'loose',
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
/>
|
/>
|
||||||
<style>
|
<style>
|
||||||
svg:not(svg svg) {
|
svg {
|
||||||
border: 2px solid darkred;
|
border: 2px solid darkred;
|
||||||
}
|
}
|
||||||
.exClass2 > rect,
|
.exClass2 > rect,
|
||||||
|
|||||||
@@ -106,363 +106,50 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid">
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
flowchart-elk TB
|
|
||||||
c1-->a2
|
|
||||||
subgraph one
|
|
||||||
a1-->a2
|
|
||||||
end
|
|
||||||
subgraph two
|
|
||||||
b1-->b2
|
|
||||||
end
|
|
||||||
subgraph three
|
|
||||||
c1-->c2
|
|
||||||
end
|
|
||||||
one --> two
|
|
||||||
three --> two
|
|
||||||
two --> c2
|
|
||||||
|
|
||||||
</pre
|
|
||||||
>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
flowchart TB
|
|
||||||
|
|
||||||
process_C
|
|
||||||
subgraph container_Alpha
|
|
||||||
subgraph process_B
|
|
||||||
pppB
|
|
||||||
end
|
|
||||||
subgraph process_A
|
|
||||||
pppA
|
|
||||||
end
|
|
||||||
process_B-->|via_AWSBatch|container_Beta
|
|
||||||
process_A-->|messages|container_Beta
|
|
||||||
end
|
|
||||||
|
|
||||||
</pre
|
|
||||||
>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
flowchart TB
|
|
||||||
subgraph container_Beta
|
|
||||||
process_C
|
|
||||||
end
|
|
||||||
subgraph container_Alpha
|
|
||||||
subgraph process_B
|
|
||||||
pppB
|
|
||||||
end
|
|
||||||
subgraph process_A
|
|
||||||
pppA
|
|
||||||
end
|
|
||||||
process_B-->|via_AWSBatch|container_Beta
|
|
||||||
process_A-->|messages|container_Beta
|
|
||||||
end
|
|
||||||
|
|
||||||
</pre
|
|
||||||
>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
flowchart TB
|
|
||||||
subgraph container_Beta
|
|
||||||
process_C
|
|
||||||
end
|
|
||||||
|
|
||||||
process_B-->|via_AWSBatch|container_Beta
|
|
||||||
|
|
||||||
|
|
||||||
</pre
|
|
||||||
>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
classDiagram
|
|
||||||
note "I love this diagram!\nDo you love it?"
|
|
||||||
Class01 <|-- AveryLongClass : Cool
|
|
||||||
<<interface>> Class01
|
|
||||||
Class03 "1" *-- "*" Class04
|
|
||||||
Class05 "1" o-- "many" Class06
|
|
||||||
Class07 "1" .. "*" Class08
|
|
||||||
Class09 "1" --> "*" C2 : Where am i?
|
|
||||||
Class09 "*" --* "*" C3
|
|
||||||
Class09 "1" --|> "1" Class07
|
|
||||||
Class12 <|.. Class08
|
|
||||||
Class11 ..>Class12
|
|
||||||
Class07 : equals()
|
|
||||||
Class07 : Object[] elementData
|
|
||||||
Class01 : size()
|
|
||||||
Class01 : int chimp
|
|
||||||
Class01 : int gorilla
|
|
||||||
Class01 : -int privateChimp
|
|
||||||
Class01 : +int publicGorilla
|
|
||||||
Class01 : #int protectedMarmoset
|
|
||||||
Class08 <--> C2: Cool label
|
|
||||||
class Class10 {
|
|
||||||
<<service>>
|
|
||||||
int id
|
|
||||||
test()
|
|
||||||
}
|
|
||||||
note for Class10 "Cool class\nI said it's very cool class!"
|
|
||||||
</pre
|
|
||||||
>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
requirementDiagram
|
|
||||||
requirement test_req {
|
|
||||||
id: 1
|
|
||||||
text: the test text.
|
|
||||||
risk: high
|
|
||||||
verifymethod: test
|
|
||||||
}
|
|
||||||
|
|
||||||
element test_entity {
|
|
||||||
type: simulation
|
|
||||||
}
|
|
||||||
|
|
||||||
test_entity - satisfies -> test_req
|
|
||||||
</pre
|
|
||||||
>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
flowchart-elk TB
|
|
||||||
internet
|
|
||||||
nat
|
|
||||||
router
|
|
||||||
compute1
|
|
||||||
|
|
||||||
subgraph project
|
|
||||||
router
|
|
||||||
nat
|
|
||||||
subgraph subnet1
|
|
||||||
compute1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
%% router --> subnet1
|
|
||||||
subnet1 --> nat
|
|
||||||
%% nat --> internet
|
|
||||||
</pre
|
|
||||||
>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
flowchart-elk TB
|
|
||||||
internet
|
|
||||||
nat
|
|
||||||
router
|
|
||||||
lb1
|
|
||||||
lb2
|
|
||||||
compute1
|
|
||||||
compute2
|
|
||||||
subgraph project
|
|
||||||
router
|
|
||||||
nat
|
|
||||||
subgraph subnet1
|
|
||||||
compute1
|
|
||||||
lb1
|
|
||||||
end
|
|
||||||
subgraph subnet2
|
|
||||||
compute2
|
|
||||||
lb2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
internet --> router
|
|
||||||
router --> subnet1 & subnet2
|
|
||||||
subnet1 & subnet2 --> nat --> internet
|
|
||||||
</pre
|
|
||||||
>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
elk:
|
|
||||||
mergeEdges: false
|
|
||||||
forceNodeModelOrder: false
|
|
||||||
considerModelOrder: NONE
|
|
||||||
|
|
||||||
---
|
|
||||||
flowchart TB
|
|
||||||
a --> a1 & a2 & a3 & a4
|
|
||||||
b --> b1 & b2
|
|
||||||
b2 --> b3
|
|
||||||
b1 --> b4</pre
|
|
||||||
>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
treemap
|
|
||||||
"Section 1"
|
|
||||||
"Leaf 1.1": 12
|
|
||||||
"Section 1.2":::class1
|
|
||||||
"Leaf 1.2.1": 12
|
|
||||||
"Section 2"
|
|
||||||
"Leaf 2.1": 20:::class1
|
|
||||||
"Leaf 2.2": 25
|
|
||||||
"Leaf 2.3": 12
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
<pre id="diagram5" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
flowchart:
|
|
||||||
curve: rounded
|
|
||||||
---
|
|
||||||
flowchart LR
|
flowchart LR
|
||||||
I["fa:fa-code Text"] -- Mermaid js --> D["Use<br/>the<br/>editor!"]
|
AB["apa@apa@"] --> B(("`apa@apa`"))
|
||||||
I --> D & D
|
|
||||||
D@{ shape: question}
|
|
||||||
I@{ shape: question}
|
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid">
|
||||||
---
|
flowchart
|
||||||
config:
|
D(("for D"))
|
||||||
layout: tidy-tree
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
Origins
|
|
||||||
Long history
|
|
||||||
::icon(fa fa-book)
|
|
||||||
Popularisation
|
|
||||||
British popular psychology author Tony Buzan
|
|
||||||
Research
|
|
||||||
On effectiveness<br/>and features
|
|
||||||
On Automatic creation
|
|
||||||
Uses
|
|
||||||
Creative techniques
|
|
||||||
Strategic planning
|
|
||||||
Argument mapping
|
|
||||||
Tools
|
|
||||||
Pen and paper
|
|
||||||
Mermaid
|
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid">
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
flowchart:
|
|
||||||
curve: linear
|
|
||||||
---
|
|
||||||
flowchart LR
|
flowchart LR
|
||||||
A[A] --> B[B]
|
A e1@==> B
|
||||||
A[A] --- B([C])
|
e1@{ animate: true}
|
||||||
A@{ shape: diamond}
|
|
||||||
%%B@{ shape: diamond}
|
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid">
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
flowchart:
|
|
||||||
curve: linear
|
|
||||||
---
|
|
||||||
flowchart LR
|
|
||||||
A[A] -- Mermaid js --> B[B]
|
|
||||||
A[A] -- Mermaid js --- B[B]
|
|
||||||
A@{ shape: diamond}
|
|
||||||
B@{ shape: diamond}
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
flowchart:
|
|
||||||
curve: rounded
|
|
||||||
---
|
|
||||||
flowchart LR
|
|
||||||
D["Use the editor"] -- Mermaid js --> I["fa:fa-code Text"]
|
|
||||||
I --> D & D
|
|
||||||
D@{ shape: question}
|
|
||||||
I@{ shape: question}
|
|
||||||
</pre>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
flowchart:
|
|
||||||
curve: rounded
|
|
||||||
elk:
|
|
||||||
nodePlacementStrategy: NETWORK_SIMPLEX
|
|
||||||
---
|
|
||||||
flowchart LR
|
|
||||||
D["Use the editor"] -- Mermaid js --> I["fa:fa-code Text"]
|
|
||||||
D --> I & I
|
|
||||||
a["a"]
|
|
||||||
D@{ shape: trap-b}
|
|
||||||
I@{ shape: lean-l}
|
|
||||||
</pre>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
|
|
||||||
---
|
|
||||||
flowchart LR
|
flowchart LR
|
||||||
%% subgraph s1["Untitled subgraph"]
|
A e1@--> B
|
||||||
C["Evaluate"]
|
classDef animate stroke-width:2,stroke-dasharray:10\,8,stroke-dashoffset:-180,animation: edge-animation-frame 6s linear infinite, stroke-linecap: round
|
||||||
%% end
|
class e1 animate
|
||||||
|
|
||||||
B --> C
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<h2>infinite</h2>
|
||||||
---
|
<pre id="diagram4" class="mermaid2">
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
flowchart:
|
|
||||||
//curve: linear
|
|
||||||
---
|
|
||||||
flowchart LR
|
flowchart LR
|
||||||
%% A ==> B
|
A e1@--> B
|
||||||
%% A2 --> B2
|
classDef animate stroke-dasharray: 9\,5,stroke-dashoffset: 900,animation: dash 25s linear infinite;
|
||||||
A{A} --> B((Bo boo)) & B & B & B
|
class e1 animate
|
||||||
|
</pre>
|
||||||
|
<h2>Mermaid - edge-animation-slow</h2>
|
||||||
|
<pre id="diagram4" class="mermaid2">
|
||||||
|
flowchart LR
|
||||||
|
A e1@--> B
|
||||||
|
e1@{ animation: fast}
|
||||||
|
</pre>
|
||||||
|
<h2>Mermaid - edge-animation-fast</h2>
|
||||||
|
<pre id="diagram4" class="mermaid2">
|
||||||
|
flowchart LR
|
||||||
|
A e1@--> B
|
||||||
|
classDef animate stroke-dasharray: 1000,stroke-dashoffset: 1000,animation: dash 10s linear;
|
||||||
|
class e1 edge-animation-fast
|
||||||
|
</pre>
|
||||||
|
|
||||||
</pre>
|
<pre id="diagram4" class="mermaid2">
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
info </pre
|
||||||
config:
|
>
|
||||||
layout: elk
|
<pre id="diagram4" class="mermaid2">
|
||||||
theme: default
|
|
||||||
look: classic
|
|
||||||
---
|
|
||||||
flowchart LR
|
|
||||||
subgraph s1["APA"]
|
|
||||||
D{"Use the editor"}
|
|
||||||
end
|
|
||||||
subgraph S2["S2"]
|
|
||||||
s1
|
|
||||||
I>"fa:fa-code Text"]
|
|
||||||
E["E"]
|
|
||||||
end
|
|
||||||
D -- Mermaid js --> I
|
|
||||||
D --> I & E
|
|
||||||
E --> I
|
|
||||||
</pre>
|
|
||||||
<pre id="diagram4" class="mermaid">
|
|
||||||
---
|
---
|
||||||
config:
|
config:
|
||||||
layout: elk
|
layout: elk
|
||||||
@@ -487,7 +174,7 @@ config:
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
---
|
---
|
||||||
config:
|
config:
|
||||||
layout: elk
|
layout: elk
|
||||||
@@ -500,7 +187,7 @@ config:
|
|||||||
D-->I
|
D-->I
|
||||||
D-->I
|
D-->I
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
---
|
---
|
||||||
config:
|
config:
|
||||||
layout: elk
|
layout: elk
|
||||||
@@ -539,7 +226,7 @@ flowchart LR
|
|||||||
n8@{ shape: rect}
|
n8@{ shape: rect}
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
---
|
---
|
||||||
config:
|
config:
|
||||||
layout: elk
|
layout: elk
|
||||||
@@ -555,7 +242,7 @@ flowchart LR
|
|||||||
|
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
---
|
---
|
||||||
config:
|
config:
|
||||||
layout: elk
|
layout: elk
|
||||||
@@ -564,7 +251,7 @@ flowchart LR
|
|||||||
A{A} --> B & C
|
A{A} --> B & C
|
||||||
</pre
|
</pre
|
||||||
>
|
>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
---
|
---
|
||||||
config:
|
config:
|
||||||
layout: elk
|
layout: elk
|
||||||
@@ -576,7 +263,7 @@ flowchart LR
|
|||||||
end
|
end
|
||||||
</pre
|
</pre
|
||||||
>
|
>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
---
|
---
|
||||||
config:
|
config:
|
||||||
layout: elk
|
layout: elk
|
||||||
@@ -594,7 +281,7 @@ flowchart LR
|
|||||||
|
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
---
|
---
|
||||||
config:
|
config:
|
||||||
kanban:
|
kanban:
|
||||||
@@ -613,81 +300,81 @@ kanban
|
|||||||
task3[💻 Develop login feature]@{ ticket: 103 }
|
task3[💻 Develop login feature]@{ ticket: 103 }
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Default] --> A@{ icon: 'fa:bell', form: 'rounded' }
|
nA[Default] --> A@{ icon: 'fa:bell', form: 'rounded' }
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Style] --> A@{ icon: 'fa:bell', form: 'rounded' }
|
nA[Style] --> A@{ icon: 'fa:bell', form: 'rounded' }
|
||||||
style A fill:#f9f,stroke:#333,stroke-width:4px
|
style A fill:#f9f,stroke:#333,stroke-width:4px
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Class] --> A@{ icon: 'fa:bell', form: 'rounded' }
|
nA[Class] --> A@{ icon: 'fa:bell', form: 'rounded' }
|
||||||
A:::AClass
|
A:::AClass
|
||||||
classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
|
classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Class] --> A@{ icon: 'logos:aws', form: 'rounded' }
|
nA[Class] --> A@{ icon: 'logos:aws', form: 'rounded' }
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Default] --> A@{ icon: 'fa:bell', form: 'square' }
|
nA[Default] --> A@{ icon: 'fa:bell', form: 'square' }
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Style] --> A@{ icon: 'fa:bell', form: 'square' }
|
nA[Style] --> A@{ icon: 'fa:bell', form: 'square' }
|
||||||
style A fill:#f9f,stroke:#333,stroke-width:4px
|
style A fill:#f9f,stroke:#333,stroke-width:4px
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Class] --> A@{ icon: 'fa:bell', form: 'square' }
|
nA[Class] --> A@{ icon: 'fa:bell', form: 'square' }
|
||||||
A:::AClass
|
A:::AClass
|
||||||
classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
|
classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Class] --> A@{ icon: 'logos:aws', form: 'square' }
|
nA[Class] --> A@{ icon: 'logos:aws', form: 'square' }
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Default] --> A@{ icon: 'fa:bell', form: 'circle' }
|
nA[Default] --> A@{ icon: 'fa:bell', form: 'circle' }
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Style] --> A@{ icon: 'fa:bell', form: 'circle' }
|
nA[Style] --> A@{ icon: 'fa:bell', form: 'circle' }
|
||||||
style A fill:#f9f,stroke:#333,stroke-width:4px
|
style A fill:#f9f,stroke:#333,stroke-width:4px
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Class] --> A@{ icon: 'fa:bell', form: 'circle' }
|
nA[Class] --> A@{ icon: 'fa:bell', form: 'circle' }
|
||||||
A:::AClass
|
A:::AClass
|
||||||
classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
|
classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Class] --> A@{ icon: 'logos:aws', form: 'circle' }
|
nA[Class] --> A@{ icon: 'logos:aws', form: 'circle' }
|
||||||
A:::AClass
|
A:::AClass
|
||||||
classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
|
classDef AClass fill:#f9f,stroke:#333,stroke-width:4px
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nA[Style] --> A@{ icon: 'logos:aws', form: 'circle' }
|
nA[Style] --> A@{ icon: 'logos:aws', form: 'circle' }
|
||||||
style A fill:#f9f,stroke:#333,stroke-width:4px
|
style A fill:#f9f,stroke:#333,stroke-width:4px
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
kanban
|
kanban
|
||||||
id2[In progress]
|
id2[In progress]
|
||||||
docs[Create Blog about the new diagram]@{ priority: 'Very Low', ticket: MC-2037, assigned: 'knsv' }
|
docs[Create Blog about the new diagram]@{ priority: 'Very Low', ticket: MC-2037, assigned: 'knsv' }
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram4" class="mermaid">
|
<pre id="diagram4" class="mermaid2">
|
||||||
---
|
---
|
||||||
config:
|
config:
|
||||||
kanban:
|
kanban:
|
||||||
@@ -758,7 +445,7 @@ kanban
|
|||||||
// look: 'handDrawn',
|
// look: 'handDrawn',
|
||||||
// 'elk.nodePlacement.strategy': 'NETWORK_SIMPLEX',
|
// 'elk.nodePlacement.strategy': 'NETWORK_SIMPLEX',
|
||||||
// layout: 'dagre',
|
// layout: 'dagre',
|
||||||
layout: 'elk',
|
// layout: 'elk',
|
||||||
// layout: 'fixed',
|
// layout: 'fixed',
|
||||||
// htmlLabels: false,
|
// htmlLabels: false,
|
||||||
flowchart: { titleTopMargin: 10 },
|
flowchart: { titleTopMargin: 10 },
|
||||||
|
|||||||
@@ -1,376 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<title>Mermaid Quick Test Page</title>
|
|
||||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
|
||||||
<style>
|
|
||||||
div.mermaid {
|
|
||||||
font-family: 'Courier New', Courier, monospace !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: tidy-tree
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
A
|
|
||||||
B
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: dagre
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
A
|
|
||||||
B
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
A
|
|
||||||
B
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: cose-bilkent
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
A
|
|
||||||
B
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: tidy-tree
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap is a long thing))
|
|
||||||
A
|
|
||||||
B
|
|
||||||
C
|
|
||||||
D
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: dagre
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap is a long thing))
|
|
||||||
A
|
|
||||||
B
|
|
||||||
C
|
|
||||||
D
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap is a long thing))
|
|
||||||
A
|
|
||||||
B
|
|
||||||
C
|
|
||||||
D
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: cose-bilkent
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap is a long thing))
|
|
||||||
A
|
|
||||||
B
|
|
||||||
C
|
|
||||||
D
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: tidy-tree
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
Origins
|
|
||||||
Long history
|
|
||||||
::icon(fa fa-book)
|
|
||||||
Popularisation
|
|
||||||
British popular psychology author Tony Buzan
|
|
||||||
Research
|
|
||||||
On effectiveness<br/>and features
|
|
||||||
On Automatic creation
|
|
||||||
Uses
|
|
||||||
Creative techniques
|
|
||||||
Strategic planning
|
|
||||||
Argument mapping
|
|
||||||
Tools
|
|
||||||
id)I am a cloud(
|
|
||||||
id))I am a bang((
|
|
||||||
Tools
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: dagre
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
Origins
|
|
||||||
Long history
|
|
||||||
::icon(fa fa-book)
|
|
||||||
Popularisation
|
|
||||||
British popular psychology author Tony Buzan
|
|
||||||
Research
|
|
||||||
On effectiveness<br/>and features
|
|
||||||
On Automatic creation
|
|
||||||
Uses
|
|
||||||
Creative techniques
|
|
||||||
Strategic planning
|
|
||||||
Argument mapping
|
|
||||||
Tools
|
|
||||||
id)I am a cloud(
|
|
||||||
id))I am a bang((
|
|
||||||
Tools
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
Origins
|
|
||||||
Long history
|
|
||||||
::icon(fa fa-book)
|
|
||||||
Popularisation
|
|
||||||
British popular psychology author Tony Buzan
|
|
||||||
Research
|
|
||||||
On effectiveness<br/>and features
|
|
||||||
On Automatic creation
|
|
||||||
Uses
|
|
||||||
Creative techniques
|
|
||||||
Strategic planning
|
|
||||||
Argument mapping
|
|
||||||
Tools
|
|
||||||
id)I am a cloud(
|
|
||||||
id))I am a bang((
|
|
||||||
Tools
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: cose-bilkent
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
Origins
|
|
||||||
Long history
|
|
||||||
::icon(fa fa-book)
|
|
||||||
Popularisation
|
|
||||||
British popular psychology author Tony Buzan
|
|
||||||
Research
|
|
||||||
On effectiveness<br/>and features
|
|
||||||
On Automatic creation
|
|
||||||
Uses
|
|
||||||
Creative techniques
|
|
||||||
Strategic planning
|
|
||||||
Argument mapping
|
|
||||||
Tools
|
|
||||||
id)I am a cloud(
|
|
||||||
id))I am a bang((
|
|
||||||
Tools
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: tidy-tree
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
A
|
|
||||||
a
|
|
||||||
apa[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
apa2[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
b
|
|
||||||
c
|
|
||||||
d
|
|
||||||
B
|
|
||||||
apa3[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
D
|
|
||||||
apa5[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
apa4[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: dagre
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
A
|
|
||||||
a
|
|
||||||
apa[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
apa2[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
b
|
|
||||||
c
|
|
||||||
d
|
|
||||||
B
|
|
||||||
apa3[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
D
|
|
||||||
apa5[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
apa4[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
A
|
|
||||||
a
|
|
||||||
apa[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
apa2[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
b
|
|
||||||
c
|
|
||||||
d
|
|
||||||
B
|
|
||||||
apa3[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
D
|
|
||||||
apa5[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
apa4[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: cose-bilkent
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
root((mindmap))
|
|
||||||
A
|
|
||||||
a
|
|
||||||
apa[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
apa2[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
b
|
|
||||||
c
|
|
||||||
d
|
|
||||||
B
|
|
||||||
apa3[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
D
|
|
||||||
apa5[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
apa4[I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on. I am a long long multline string passing several levels of text. Lorum ipsum and so on]
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: tidy-tree
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
((This is a mindmap))
|
|
||||||
child1
|
|
||||||
grandchild 1
|
|
||||||
grandchild 2
|
|
||||||
child2
|
|
||||||
grandchild 3
|
|
||||||
grandchild 4
|
|
||||||
child3
|
|
||||||
grandchild 5
|
|
||||||
grandchild 6
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: dagre
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
((This is a mindmap))
|
|
||||||
child1
|
|
||||||
grandchild 1
|
|
||||||
grandchild 2
|
|
||||||
child2
|
|
||||||
grandchild 3
|
|
||||||
grandchild 4
|
|
||||||
child3
|
|
||||||
grandchild 5
|
|
||||||
grandchild 6
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
((This is a mindmap))
|
|
||||||
child1
|
|
||||||
grandchild 1
|
|
||||||
grandchild 2
|
|
||||||
child2
|
|
||||||
grandchild 3
|
|
||||||
grandchild 4
|
|
||||||
child3
|
|
||||||
grandchild 5
|
|
||||||
grandchild 6
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<pre class="mermaid">
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: cose-bilkent
|
|
||||||
---
|
|
||||||
mindmap
|
|
||||||
((This is a mindmap))
|
|
||||||
child1
|
|
||||||
grandchild 1
|
|
||||||
grandchild 2
|
|
||||||
child2
|
|
||||||
grandchild 3
|
|
||||||
grandchild 4
|
|
||||||
child3
|
|
||||||
grandchild 5
|
|
||||||
grandchild 6
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
<script type="module">
|
|
||||||
import mermaid from '/mermaid.esm.mjs';
|
|
||||||
import tidytree from '/mermaid-layout-tidy-tree.esm.mjs';
|
|
||||||
import layouts from './mermaid-layout-elk.esm.mjs';
|
|
||||||
mermaid.registerLayoutLoaders(layouts);
|
|
||||||
mermaid.registerLayoutLoaders(tidytree);
|
|
||||||
mermaid.initialize({
|
|
||||||
theme: 'default',
|
|
||||||
logLevel: 3,
|
|
||||||
securityLevel: 'loose',
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -41,6 +41,10 @@ graph TB
|
|||||||
const { svg } = await mermaid.render('d22', value);
|
const { svg } = await mermaid.render('d22', value);
|
||||||
console.log(svg);
|
console.log(svg);
|
||||||
el.innerHTML = svg;
|
el.innerHTML = svg;
|
||||||
|
// 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>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import externalExample from './mermaid-example-diagram.esm.mjs';
|
import externalExample from './mermaid-example-diagram.esm.mjs';
|
||||||
import layouts from './mermaid-layout-elk.esm.mjs';
|
import layouts from './mermaid-layout-elk.esm.mjs';
|
||||||
import tidyTree from './mermaid-layout-tidy-tree.esm.mjs';
|
|
||||||
import zenUml from './mermaid-zenuml.esm.mjs';
|
import zenUml from './mermaid-zenuml.esm.mjs';
|
||||||
import mermaid from './mermaid.esm.mjs';
|
import mermaid from './mermaid.esm.mjs';
|
||||||
|
|
||||||
@@ -15,28 +14,12 @@ function markRendered() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadFontAwesomeCSS() {
|
|
||||||
const link = document.createElement('link');
|
|
||||||
link.rel = 'stylesheet';
|
|
||||||
link.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css';
|
|
||||||
|
|
||||||
document.head.appendChild(link);
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
link.onload = resolve;
|
|
||||||
link.onerror = () => reject(new Error('Failed to load FontAwesome'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ##contentLoaded Callback function that is called when page is loaded. This functions fetches
|
* ##contentLoaded Callback function that is called when page is loaded. This functions fetches
|
||||||
* configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the
|
* configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the
|
||||||
* page.
|
* page.
|
||||||
*/
|
*/
|
||||||
const contentLoaded = async function () {
|
const contentLoaded = async function () {
|
||||||
await loadFontAwesomeCSS();
|
|
||||||
await Promise.all(Array.from(document.fonts, (font) => font.load()));
|
|
||||||
|
|
||||||
let pos = document.location.href.indexOf('?graph=');
|
let pos = document.location.href.indexOf('?graph=');
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
pos = pos + 7;
|
pos = pos + 7;
|
||||||
@@ -66,15 +49,9 @@ const contentLoaded = async function () {
|
|||||||
await mermaid.registerExternalDiagrams([externalExample, zenUml]);
|
await mermaid.registerExternalDiagrams([externalExample, zenUml]);
|
||||||
|
|
||||||
mermaid.registerLayoutLoaders(layouts);
|
mermaid.registerLayoutLoaders(layouts);
|
||||||
mermaid.registerLayoutLoaders(tidyTree);
|
|
||||||
mermaid.initialize(graphObj.mermaid);
|
mermaid.initialize(graphObj.mermaid);
|
||||||
/**
|
|
||||||
* CC-BY-4.0
|
|
||||||
* Copyright (c) Fonticons, Inc. - https://fontawesome.com/license/free
|
|
||||||
* https://fontawesome.com/icons/bell?f=classic&s=regular
|
|
||||||
*/
|
|
||||||
const staticBellIconPack = {
|
const staticBellIconPack = {
|
||||||
prefix: 'fa',
|
prefix: 'fa6-regular',
|
||||||
icons: {
|
icons: {
|
||||||
bell: {
|
bell: {
|
||||||
body: '<path fill="currentColor" d="M224 0c-17.7 0-32 14.3-32 32v19.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416h400c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6c-28.3-35.5-43.8-79.6-43.8-125V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32m0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3c25.8-40 39.7-86.7 39.7-134.6V208c0-61.9 50.1-112 112-112m64 352H160c0 17 6.7 33.3 18.7 45.3S207 512 224 512s33.3-6.7 45.3-18.7S288 465 288 448"/>',
|
body: '<path fill="currentColor" d="M224 0c-17.7 0-32 14.3-32 32v19.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416h400c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6c-28.3-35.5-43.8-79.6-43.8-125V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32m0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3c25.8-40 39.7-86.7 39.7-134.6V208c0-61.9 50.1-112 112-112m64 352H160c0 17 6.7 33.3 18.7 45.3S207 512 224 512s33.3-6.7 45.3-18.7S288 465 288 448"/>',
|
||||||
@@ -184,7 +161,7 @@ const contentLoadedApi = async function () {
|
|||||||
for (let i = 0; i < numCodes; i++) {
|
for (let i = 0; i < numCodes; i++) {
|
||||||
const { svg, bindFunctions } = await mermaid.render('newid' + i, graphObj.code[i], divs[i]);
|
const { svg, bindFunctions } = await mermaid.render('newid' + i, graphObj.code[i], divs[i]);
|
||||||
div.innerHTML = svg;
|
div.innerHTML = svg;
|
||||||
bindFunctions?.(div);
|
bindFunctions(div);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
@@ -196,7 +173,7 @@ const contentLoadedApi = async function () {
|
|||||||
const { svg, bindFunctions } = await mermaid.render('newid', graphObj.code, div);
|
const { svg, bindFunctions } = await mermaid.render('newid', graphObj.code, div);
|
||||||
div.innerHTML = svg;
|
div.innerHTML = svg;
|
||||||
console.log(div.innerHTML);
|
console.log(div.innerHTML);
|
||||||
bindFunctions?.(div);
|
bindFunctions(div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,227 +2,211 @@
|
|||||||
"durations": [
|
"durations": [
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/configuration.spec.js",
|
"spec": "cypress/integration/other/configuration.spec.js",
|
||||||
"duration": 5841
|
"duration": 5450
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/external-diagrams.spec.js",
|
"spec": "cypress/integration/other/external-diagrams.spec.js",
|
||||||
"duration": 2138
|
"duration": 2004
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/ghsa.spec.js",
|
"spec": "cypress/integration/other/ghsa.spec.js",
|
||||||
"duration": 3370
|
"duration": 3183
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/iife.spec.js",
|
"spec": "cypress/integration/other/iife.spec.js",
|
||||||
"duration": 2052
|
"duration": 1913
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/interaction.spec.js",
|
"spec": "cypress/integration/other/interaction.spec.js",
|
||||||
"duration": 12243
|
"duration": 10944
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/rerender.spec.js",
|
"spec": "cypress/integration/other/rerender.spec.js",
|
||||||
"duration": 2065
|
"duration": 1938
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/other/xss.spec.js",
|
"spec": "cypress/integration/other/xss.spec.js",
|
||||||
"duration": 31288
|
"duration": 26753
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/appli.spec.js",
|
"spec": "cypress/integration/rendering/appli.spec.js",
|
||||||
"duration": 3421
|
"duration": 2571
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/architecture.spec.ts",
|
"spec": "cypress/integration/rendering/architecture.spec.ts",
|
||||||
"duration": 97
|
"duration": 110
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/block.spec.js",
|
"spec": "cypress/integration/rendering/block.spec.js",
|
||||||
"duration": 18500
|
"duration": 14697
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/c4.spec.js",
|
"spec": "cypress/integration/rendering/c4.spec.js",
|
||||||
"duration": 5793
|
"duration": 4705
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/classDiagram-elk-v3.spec.js",
|
"spec": "cypress/integration/rendering/classDiagram-elk-v3.spec.js",
|
||||||
"duration": 40966
|
"duration": 35841
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/classDiagram-handDrawn-v3.spec.js",
|
"spec": "cypress/integration/rendering/classDiagram-handDrawn-v3.spec.js",
|
||||||
"duration": 39176
|
"duration": 34279
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/classDiagram-v2.spec.js",
|
"spec": "cypress/integration/rendering/classDiagram-v2.spec.js",
|
||||||
"duration": 23468
|
"duration": 20641
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/classDiagram-v3.spec.js",
|
"spec": "cypress/integration/rendering/classDiagram-v3.spec.js",
|
||||||
"duration": 38291
|
"duration": 33020
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/classDiagram.spec.js",
|
"spec": "cypress/integration/rendering/classDiagram.spec.js",
|
||||||
"duration": 16949
|
"duration": 13546
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/conf-and-directives.spec.js",
|
"spec": "cypress/integration/rendering/conf-and-directives.spec.js",
|
||||||
"duration": 9480
|
"duration": 8072
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/current.spec.js",
|
"spec": "cypress/integration/rendering/current.spec.js",
|
||||||
"duration": 2753
|
"duration": 2083
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/erDiagram-unified.spec.js",
|
"spec": "cypress/integration/rendering/erDiagram-unified.spec.js",
|
||||||
"duration": 88028
|
"duration": 78269
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/erDiagram.spec.js",
|
"spec": "cypress/integration/rendering/erDiagram.spec.js",
|
||||||
"duration": 15615
|
"duration": 12578
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/errorDiagram.spec.js",
|
"spec": "cypress/integration/rendering/errorDiagram.spec.js",
|
||||||
"duration": 3706
|
"duration": 2784
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart-elk.spec.js",
|
"spec": "cypress/integration/rendering/flowchart-elk.spec.js",
|
||||||
"duration": 43905
|
"duration": 36205
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart-handDrawn.spec.js",
|
"spec": "cypress/integration/rendering/flowchart-handDrawn.spec.js",
|
||||||
"duration": 31217
|
"duration": 26627
|
||||||
},
|
|
||||||
{
|
|
||||||
"spec": "cypress/integration/rendering/flowchart-icon.spec.js",
|
|
||||||
"duration": 7531
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart-shape-alias.spec.ts",
|
"spec": "cypress/integration/rendering/flowchart-shape-alias.spec.ts",
|
||||||
"duration": 25423
|
"duration": 21332
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart-v2.spec.js",
|
"spec": "cypress/integration/rendering/flowchart-v2.spec.js",
|
||||||
"duration": 49664
|
"duration": 37328
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/flowchart.spec.js",
|
"spec": "cypress/integration/rendering/flowchart.spec.js",
|
||||||
"duration": 32525
|
"duration": 25914
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/gantt.spec.js",
|
"spec": "cypress/integration/rendering/gantt.spec.js",
|
||||||
"duration": 20915
|
"duration": 15383
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/gitGraph.spec.js",
|
"spec": "cypress/integration/rendering/gitGraph.spec.js",
|
||||||
"duration": 53556
|
"duration": 45226
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/iconShape.spec.ts",
|
"spec": "cypress/integration/rendering/iconShape.spec.ts",
|
||||||
"duration": 283038
|
"duration": 251094
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/imageShape.spec.ts",
|
"spec": "cypress/integration/rendering/imageShape.spec.ts",
|
||||||
"duration": 59434
|
"duration": 50916
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/info.spec.ts",
|
"spec": "cypress/integration/rendering/info.spec.ts",
|
||||||
"duration": 3101
|
"duration": 2489
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/journey.spec.js",
|
"spec": "cypress/integration/rendering/journey.spec.js",
|
||||||
"duration": 7099
|
"duration": 5988
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/kanban.spec.ts",
|
"spec": "cypress/integration/rendering/kanban.spec.ts",
|
||||||
"duration": 7567
|
"duration": 6225
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/katex.spec.js",
|
"spec": "cypress/integration/rendering/katex.spec.js",
|
||||||
"duration": 3817
|
"duration": 3009
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/marker_unique_id.spec.js",
|
"spec": "cypress/integration/rendering/marker_unique_id.spec.js",
|
||||||
"duration": 2624
|
"duration": 2426
|
||||||
},
|
|
||||||
{
|
|
||||||
"spec": "cypress/integration/rendering/mindmap-tidy-tree.spec.js",
|
|
||||||
"duration": 4246
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/mindmap.spec.ts",
|
"spec": "cypress/integration/rendering/mindmap.spec.ts",
|
||||||
"duration": 11967
|
"duration": 9306
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/newShapes.spec.ts",
|
"spec": "cypress/integration/rendering/newShapes.spec.ts",
|
||||||
"duration": 151914
|
"duration": 134419
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/oldShapes.spec.ts",
|
"spec": "cypress/integration/rendering/oldShapes.spec.ts",
|
||||||
"duration": 116698
|
"duration": 102434
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/packet.spec.ts",
|
"spec": "cypress/integration/rendering/packet.spec.ts",
|
||||||
"duration": 4967
|
"duration": 3373
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/pie.spec.ts",
|
"spec": "cypress/integration/rendering/pie.spec.ts",
|
||||||
"duration": 6700
|
"duration": 4898
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/quadrantChart.spec.js",
|
"spec": "cypress/integration/rendering/quadrantChart.spec.js",
|
||||||
"duration": 8963
|
"duration": 7578
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/radar.spec.js",
|
"spec": "cypress/integration/rendering/radar.spec.js",
|
||||||
"duration": 5540
|
"duration": 4526
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/requirement.spec.js",
|
"spec": "cypress/integration/rendering/requirement.spec.js",
|
||||||
"duration": 2782
|
"duration": 2172
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/requirementDiagram-unified.spec.js",
|
"spec": "cypress/integration/rendering/requirementDiagram-unified.spec.js",
|
||||||
"duration": 54797
|
"duration": 47175
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/sankey.spec.ts",
|
"spec": "cypress/integration/rendering/sankey.spec.ts",
|
||||||
"duration": 6914
|
"duration": 5717
|
||||||
},
|
|
||||||
{
|
|
||||||
"spec": "cypress/integration/rendering/sequencediagram-v2.spec.js",
|
|
||||||
"duration": 20481
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/sequencediagram.spec.js",
|
"spec": "cypress/integration/rendering/sequencediagram.spec.js",
|
||||||
"duration": 38490
|
"duration": 32556
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/stateDiagram-v2.spec.js",
|
"spec": "cypress/integration/rendering/stateDiagram-v2.spec.js",
|
||||||
"duration": 30766
|
"duration": 22572
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/stateDiagram.spec.js",
|
"spec": "cypress/integration/rendering/stateDiagram.spec.js",
|
||||||
"duration": 16705
|
"duration": 14064
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/theme.spec.js",
|
"spec": "cypress/integration/rendering/theme.spec.js",
|
||||||
"duration": 30928
|
"duration": 26565
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/timeline.spec.ts",
|
"spec": "cypress/integration/rendering/timeline.spec.ts",
|
||||||
"duration": 8424
|
"duration": 6233
|
||||||
},
|
|
||||||
{
|
|
||||||
"spec": "cypress/integration/rendering/treemap.spec.ts",
|
|
||||||
"duration": 12533
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/xyChart.spec.js",
|
"spec": "cypress/integration/rendering/xyChart.spec.js",
|
||||||
"duration": 21197
|
"duration": 17750
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"spec": "cypress/integration/rendering/zenuml.spec.js",
|
"spec": "cypress/integration/rendering/zenuml.spec.js",
|
||||||
"duration": 3455
|
"duration": 2696
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
import { execSync } from 'child_process';
|
|
||||||
|
|
||||||
console.log('=== DEBUGGING CALLBACK ARGUMENTS ===');
|
|
||||||
|
|
||||||
// Test the specific failing case
|
|
||||||
const testInput = 'graph TD\nA-->B\nclick A call callback("test0", test1, test2)';
|
|
||||||
console.log('Test input:', testInput);
|
|
||||||
|
|
||||||
// Create a temporary test file to debug the ANTLR parser
|
|
||||||
import fs from 'fs';
|
|
||||||
const testFile = `
|
|
||||||
// Debug callback arguments parsing
|
|
||||||
process.env.USE_ANTLR_PARSER = 'true';
|
|
||||||
|
|
||||||
const flow = require('./packages/mermaid/src/diagrams/flowchart/flowDb.ts');
|
|
||||||
const parser = require('./packages/mermaid/src/diagrams/flowchart/parser/antlr/antlr-parser.ts');
|
|
||||||
|
|
||||||
console.log('Testing callback arguments parsing...');
|
|
||||||
|
|
||||||
// Mock the setClickEvent to see what parameters it receives
|
|
||||||
const originalSetClickEvent = flow.default.setClickEvent;
|
|
||||||
flow.default.setClickEvent = function(...args) {
|
|
||||||
console.log('DEBUG setClickEvent called with args:', args);
|
|
||||||
console.log(' - nodeId:', args[0]);
|
|
||||||
console.log(' - functionName:', args[1]);
|
|
||||||
console.log(' - functionArgs:', args[2]);
|
|
||||||
console.log(' - args.length:', args.length);
|
|
||||||
return originalSetClickEvent.apply(this, args);
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = parser.parse('${testInput}');
|
|
||||||
console.log('Parse completed successfully');
|
|
||||||
} catch (error) {
|
|
||||||
console.log('Parse error:', error.message);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
fs.writeFileSync('debug-callback-test.js', testFile);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = execSync('node debug-callback-test.js', {
|
|
||||||
cwd: '/Users/ashishjain/projects/mermaid',
|
|
||||||
encoding: 'utf8',
|
|
||||||
timeout: 10000,
|
|
||||||
});
|
|
||||||
console.log('Result:', result);
|
|
||||||
} catch (error) {
|
|
||||||
console.log('Error:', error.message);
|
|
||||||
if (error.stdout) console.log('Stdout:', error.stdout);
|
|
||||||
if (error.stderr) console.log('Stderr:', error.stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
try {
|
|
||||||
fs.unlinkSync('debug-callback-test.js');
|
|
||||||
} catch (e) {
|
|
||||||
// Ignore cleanup errors
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
// Debug script to understand node processing order
|
|
||||||
|
|
||||||
console.log('=== Node Order Debug ===');
|
|
||||||
|
|
||||||
// Test case 1: n2["label for n2"] & n4@{ label: "label for n4"} & n5@{ label: "label for n5"}
|
|
||||||
// Expected: nodes[0] = n2, nodes[1] = n4, nodes[2] = n5
|
|
||||||
// Actual: nodes[0] = n4 (wrong!)
|
|
||||||
|
|
||||||
console.log('Test 1: n2["label for n2"] & n4@{ label: "label for n4"} & n5@{ label: "label for n5"}');
|
|
||||||
console.log('Expected: n2, n4, n5');
|
|
||||||
console.log('Actual: n4, ?, ?');
|
|
||||||
|
|
||||||
// Test case 2: A["A"] --> B["for B"] & C@{ label: "for c"} & E@{label : "for E"}
|
|
||||||
// Expected: nodes[1] = B, nodes[2] = C
|
|
||||||
// Actual: nodes[1] = C (wrong!)
|
|
||||||
|
|
||||||
console.log('\nTest 2: A["A"] --> B["for B"] & C@{ label: "for c"} & E@{label : "for E"}');
|
|
||||||
console.log('Expected: A, B, C, E, D');
|
|
||||||
console.log('Actual: A, C, ?, ?, ?');
|
|
||||||
|
|
||||||
console.log('\nThe issue appears to be that ampersand-chained nodes are processed in reverse order');
|
|
||||||
console.log('or the node collection is not matching the Jison parser behavior.');
|
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>Block diagram demos</h1>
|
<h1>Block diagram demos</h1>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
columns 1
|
columns 1
|
||||||
db(("DB"))
|
db(("DB"))
|
||||||
blockArrowId6<[" "]>(down)
|
blockArrowId6<[" "]>(down)
|
||||||
@@ -26,7 +26,7 @@ columns 1
|
|||||||
style B fill:#f9F,stroke:#333,stroke-width:4px
|
style B fill:#f9F,stroke:#333,stroke-width:4px
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
A1["square"]
|
A1["square"]
|
||||||
B1("rounded")
|
B1("rounded")
|
||||||
C1(("circle"))
|
C1(("circle"))
|
||||||
@@ -36,7 +36,7 @@ block
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
A1(["stadium"])
|
A1(["stadium"])
|
||||||
A2[["subroutine"]]
|
A2[["subroutine"]]
|
||||||
B1[("cylinder")]
|
B1[("cylinder")]
|
||||||
@@ -48,7 +48,7 @@ block
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
block:e:4
|
block:e:4
|
||||||
columns 2
|
columns 2
|
||||||
f
|
f
|
||||||
@@ -57,7 +57,7 @@ block
|
|||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
block:e:4
|
block:e:4
|
||||||
columns 2
|
columns 2
|
||||||
f
|
f
|
||||||
@@ -67,7 +67,7 @@ block
|
|||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
columns 3
|
columns 3
|
||||||
a:3
|
a:3
|
||||||
block:e:3
|
block:e:3
|
||||||
@@ -80,7 +80,7 @@ block
|
|||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
columns 4
|
columns 4
|
||||||
a b c d
|
a b c d
|
||||||
block:e:4
|
block:e:4
|
||||||
@@ -97,19 +97,19 @@ flowchart LR
|
|||||||
X-- "a label" -->z
|
X-- "a label" -->z
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
columns 5
|
columns 5
|
||||||
A space B
|
A space B
|
||||||
A --x B
|
A --x B
|
||||||
</pre>
|
</pre>
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
columns 3
|
columns 3
|
||||||
a["A wide one"] b:2 c:2 d
|
a["A wide one"] b:2 c:2 d
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
columns 3
|
columns 3
|
||||||
a b c
|
a b c
|
||||||
e:3
|
e:3
|
||||||
@@ -117,7 +117,7 @@ columns 3
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre id="diagram" class="mermaid">
|
<pre id="diagram" class="mermaid">
|
||||||
block
|
block-beta
|
||||||
|
|
||||||
A1:3
|
A1:3
|
||||||
A2:1
|
A2:1
|
||||||
|
|||||||
@@ -1,331 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<title>Mermaid Class ANTLR Parser Test Page</title>
|
|
||||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Courier New', Courier, monospace;
|
|
||||||
margin: 20px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.test-section {
|
|
||||||
background: white;
|
|
||||||
padding: 20px;
|
|
||||||
margin: 20px 0;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.parser-info {
|
|
||||||
background: #e3f2fd;
|
|
||||||
border: 1px solid #2196f3;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.success {
|
|
||||||
background: #e8f5e8;
|
|
||||||
border: 1px solid #4caf50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
background: #ffebee;
|
|
||||||
border: 1px solid #f44336;
|
|
||||||
}
|
|
||||||
|
|
||||||
.broken {
|
|
||||||
background: #fff3e0;
|
|
||||||
border: 1px solid #ff9800;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.mermaid {
|
|
||||||
font-family: 'Courier New', Courier, monospace !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: #1976d2;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
color: #424242;
|
|
||||||
border-bottom: 2px solid #e0e0e0;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#debug-logs {
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 10px 0;
|
|
||||||
max-height: 400px;
|
|
||||||
overflow-y: auto;
|
|
||||||
font-family: monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
background: #f9f9f9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.diagram-code {
|
|
||||||
background: #f5f5f5;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 10px 0;
|
|
||||||
font-family: monospace;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1>🎯 Mermaid Class ANTLR Parser Test Page</h1>
|
|
||||||
|
|
||||||
<div class="parser-info">
|
|
||||||
<h3>🔧 Parser Information</h3>
|
|
||||||
<p><strong>Environment Variable:</strong> <code id="env-var">Loading...</code></p>
|
|
||||||
<p><strong>Expected:</strong> <code>USE_ANTLR_PARSER=true</code></p>
|
|
||||||
<p><strong>Status:</strong> <span id="parser-status">Checking...</span></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>Test 1: Simple Class Diagram</h2>
|
|
||||||
<p>Basic class diagram to test ANTLR parser functionality:</p>
|
|
||||||
<pre class="mermaid">
|
|
||||||
classDiagram
|
|
||||||
class Animal {
|
|
||||||
+name: string
|
|
||||||
+age: int
|
|
||||||
+makeSound()
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>Test 2: Class with Relationships</h2>
|
|
||||||
<p>Testing class relationships:</p>
|
|
||||||
<pre class="mermaid">
|
|
||||||
classDiagram
|
|
||||||
class Animal {
|
|
||||||
+name: string
|
|
||||||
+makeSound()
|
|
||||||
}
|
|
||||||
class Dog {
|
|
||||||
+breed: string
|
|
||||||
+bark()
|
|
||||||
}
|
|
||||||
Animal <|-- Dog
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-section broken">
|
|
||||||
<h2>🚨 Test 3: BROKEN DIAGRAM - Debug Target</h2>
|
|
||||||
<p><strong>This is the problematic diagram that needs debugging:</strong></p>
|
|
||||||
<div class="diagram-code">classDiagram
|
|
||||||
class Person {
|
|
||||||
+ID : Guid
|
|
||||||
+FirstName : string
|
|
||||||
+LastName : string
|
|
||||||
-privateProperty : string
|
|
||||||
#ProtectedProperty : string
|
|
||||||
~InternalProperty : string
|
|
||||||
~AnotherInternalProperty : List~List~string~~
|
|
||||||
}
|
|
||||||
class People List~List~Person~~</div>
|
|
||||||
<p><strong>Expected Error:</strong> Parse error on line 11: Expecting 'STR'</p>
|
|
||||||
<pre class="mermaid">
|
|
||||||
classDiagram
|
|
||||||
class Person {
|
|
||||||
+ID : Guid
|
|
||||||
+FirstName : string
|
|
||||||
+LastName : string
|
|
||||||
-privateProperty : string
|
|
||||||
#ProtectedProperty : string
|
|
||||||
~InternalProperty : string
|
|
||||||
~AnotherInternalProperty : List~List~string~~
|
|
||||||
}
|
|
||||||
class People List~List~Person~~
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>Test 4: Generic Types (Simplified)</h2>
|
|
||||||
<p>Testing simpler generic type syntax:</p>
|
|
||||||
<pre class="mermaid">
|
|
||||||
classDiagram
|
|
||||||
class Person {
|
|
||||||
+ID : Guid
|
|
||||||
+FirstName : string
|
|
||||||
+LastName : string
|
|
||||||
}
|
|
||||||
class People {
|
|
||||||
+items : List~Person~
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>Test 5: Visibility Modifiers</h2>
|
|
||||||
<p>Testing different visibility modifiers:</p>
|
|
||||||
<pre class="mermaid">
|
|
||||||
classDiagram
|
|
||||||
class TestClass {
|
|
||||||
+publicField : string
|
|
||||||
-privateField : string
|
|
||||||
#protectedField : string
|
|
||||||
~packageField : string
|
|
||||||
+publicMethod()
|
|
||||||
-privateMethod()
|
|
||||||
#protectedMethod()
|
|
||||||
~packageMethod()
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
import mermaid from './mermaid.esm.mjs';
|
|
||||||
|
|
||||||
// Configure ANTLR parser for browser environment
|
|
||||||
window.MERMAID_CONFIG = {
|
|
||||||
USE_ANTLR_PARSER: 'true',
|
|
||||||
USE_ANTLR_VISITOR: 'false', // Use listener pattern
|
|
||||||
ANTLR_DEBUG: 'true'
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('🎯 Class ANTLR Configuration:', window.MERMAID_CONFIG);
|
|
||||||
|
|
||||||
// Override console methods to capture logs
|
|
||||||
const originalLog = console.log;
|
|
||||||
const originalError = console.error;
|
|
||||||
|
|
||||||
function createLogDiv() {
|
|
||||||
const logDiv = document.createElement('div');
|
|
||||||
logDiv.id = 'debug-logs';
|
|
||||||
logDiv.innerHTML = '<h3>🔍 Debug Logs:</h3>';
|
|
||||||
document.body.appendChild(logDiv);
|
|
||||||
return logDiv;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log = function (...args) {
|
|
||||||
originalLog.apply(console, args);
|
|
||||||
// Display important logs on page
|
|
||||||
if (args[0] && typeof args[0] === 'string' && (
|
|
||||||
args[0].includes('ANTLR') ||
|
|
||||||
args[0].includes('ClassDB:') ||
|
|
||||||
args[0].includes('ClassListener:') ||
|
|
||||||
args[0].includes('ClassVisitor:') ||
|
|
||||||
args[0].includes('ClassParserCore:') ||
|
|
||||||
args[0].includes('Class ANTLR') ||
|
|
||||||
args[0].includes('🔧') ||
|
|
||||||
args[0].includes('❌') ||
|
|
||||||
args[0].includes('✅')
|
|
||||||
)) {
|
|
||||||
const logDiv = document.getElementById('debug-logs') || createLogDiv();
|
|
||||||
logDiv.innerHTML += '<div style="color: blue; margin: 2px 0;">' + args.join(' ') + '</div>';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
console.error = function (...args) {
|
|
||||||
originalError.apply(console, args);
|
|
||||||
const logDiv = document.getElementById('debug-logs') || createLogDiv();
|
|
||||||
logDiv.innerHTML += '<div style="color: red; margin: 2px 0;">ERROR: ' + args.join(' ') + '</div>';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initialize mermaid
|
|
||||||
mermaid.initialize({
|
|
||||||
theme: 'default',
|
|
||||||
logLevel: 3,
|
|
||||||
securityLevel: 'loose',
|
|
||||||
class: {
|
|
||||||
titleTopMargin: 25,
|
|
||||||
diagramPadding: 50,
|
|
||||||
htmlLabels: false
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check environment and parser status
|
|
||||||
let envVar = 'undefined';
|
|
||||||
try {
|
|
||||||
if (typeof process !== 'undefined' && process.env) {
|
|
||||||
envVar = process.env.USE_ANTLR_PARSER || 'undefined';
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
envVar = 'browser-default';
|
|
||||||
}
|
|
||||||
|
|
||||||
const envElement = document.getElementById('env-var');
|
|
||||||
const statusElement = document.getElementById('parser-status');
|
|
||||||
|
|
||||||
if (envElement) {
|
|
||||||
envElement.textContent = `USE_ANTLR_PARSER=${envVar || 'undefined'}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for debug information from parser
|
|
||||||
setTimeout(() => {
|
|
||||||
if (window.MERMAID_PARSER_DEBUG) {
|
|
||||||
console.log('🔍 Found MERMAID_PARSER_DEBUG:', window.MERMAID_PARSER_DEBUG);
|
|
||||||
const debug = window.MERMAID_PARSER_DEBUG;
|
|
||||||
|
|
||||||
if (envElement) {
|
|
||||||
envElement.textContent = `USE_ANTLR_PARSER=${debug.env_value || 'undefined'} (actual: ${debug.USE_ANTLR_PARSER})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusElement) {
|
|
||||||
if (debug.USE_ANTLR_PARSER) {
|
|
||||||
statusElement.innerHTML = '<span style="color: green;">✅ ANTLR Parser Active</span>';
|
|
||||||
statusElement.parentElement.parentElement.classList.add('success');
|
|
||||||
} else {
|
|
||||||
statusElement.innerHTML = '<span style="color: orange;">⚠️ Jison Parser (Default)</span>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
if (statusElement) {
|
|
||||||
if (envVar === 'true') {
|
|
||||||
statusElement.innerHTML = '<span style="color: green;">✅ ANTLR Parser Active</span>';
|
|
||||||
statusElement.parentElement.parentElement.classList.add('success');
|
|
||||||
} else {
|
|
||||||
statusElement.innerHTML = '<span style="color: orange;">⚠️ Jison Parser (Default)</span>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add debugging
|
|
||||||
console.log('🎯 Class ANTLR Parser Test Page Loaded');
|
|
||||||
console.log('🔧 Environment:', { USE_ANTLR_PARSER: envVar });
|
|
||||||
|
|
||||||
// Test if we can detect which parser is being used
|
|
||||||
setTimeout(() => {
|
|
||||||
const mermaidElements = document.querySelectorAll('.mermaid');
|
|
||||||
console.log(`📊 Found ${mermaidElements.length} class diagrams`);
|
|
||||||
|
|
||||||
// Check if diagrams rendered successfully
|
|
||||||
const renderedElements = document.querySelectorAll('.mermaid svg');
|
|
||||||
if (renderedElements.length > 0) {
|
|
||||||
console.log('✅ Class diagrams rendered successfully!');
|
|
||||||
console.log(`📈 ${renderedElements.length} SVG elements created`);
|
|
||||||
|
|
||||||
// Update status on page
|
|
||||||
const statusElement = document.getElementById('parser-status');
|
|
||||||
if (statusElement && envVar === 'true') {
|
|
||||||
statusElement.innerHTML = '<span style="color: green;">✅ ANTLR Parser Active & Rendering Successfully!</span>';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('❌ No SVG elements found - check for rendering errors');
|
|
||||||
console.log('🔍 Checking for error messages...');
|
|
||||||
|
|
||||||
// Look for error messages in mermaid elements
|
|
||||||
mermaidElements.forEach((element, index) => {
|
|
||||||
console.log(`📋 Class Diagram ${index + 1} content:`, element.textContent.trim());
|
|
||||||
if (element.innerHTML.includes('error') || element.innerHTML.includes('Error')) {
|
|
||||||
console.log(`❌ Error found in class diagram ${index + 1}:`, element.innerHTML);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 3000);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
<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/6.7.2/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://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.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"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Recursive:wght@300..1000&display=swap"
|
|
||||||
rel="stylesheet"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.recursive-500 {
|
|
||||||
font-family: 'Recursive', serif;
|
|
||||||
font-optical-sizing: auto;
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: normal;
|
|
||||||
font-variation-settings:
|
|
||||||
'slnt' 0,
|
|
||||||
'CASL' 0,
|
|
||||||
'CRSV' 0.5,
|
|
||||||
'MONO' 0;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
/* background: rgb(221, 208, 208); */
|
|
||||||
/* background: #333; */
|
|
||||||
/* font-family: 'Arial'; */
|
|
||||||
font-family: 'Recursive', serif;
|
|
||||||
font-optical-sizing: auto;
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: normal;
|
|
||||||
font-variation-settings:
|
|
||||||
'slnt' 0,
|
|
||||||
'CASL' 0,
|
|
||||||
'CRSV' 0.5,
|
|
||||||
'MONO' 0;
|
|
||||||
/* color: white; */
|
|
||||||
/* font-size: 18px !important; */
|
|
||||||
}
|
|
||||||
.gridify.tiny {
|
|
||||||
background-image:
|
|
||||||
linear-gradient(transparent 11px, rgba(220, 220, 200, 0.8) 12px, transparent 12px),
|
|
||||||
linear-gradient(90deg, transparent 11px, rgba(220, 220, 200, 0.8) 12px, transparent 12px);
|
|
||||||
background-size:
|
|
||||||
100% 12px,
|
|
||||||
12px 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gridify.dots {
|
|
||||||
background-image: radial-gradient(
|
|
||||||
circle at center,
|
|
||||||
rgba(220, 220, 200, 0.8) 1px,
|
|
||||||
transparent 1px
|
|
||||||
);
|
|
||||||
background-size: 24px 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mermaid2 {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mermaid svg {
|
|
||||||
font-size: 16px !important;
|
|
||||||
font-family: 'Recursive', serif;
|
|
||||||
font-optical-sizing: auto;
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: normal;
|
|
||||||
font-variation-settings:
|
|
||||||
'slnt' 0,
|
|
||||||
'CASL' 0,
|
|
||||||
'CRSV' 0.5,
|
|
||||||
'MONO' 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
width: 100%;
|
|
||||||
/*box-shadow: 4px 4px 0px 0px #0000000F;*/
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="gridify dots">
|
|
||||||
<div class="w-full h-64">
|
|
||||||
<pre id="diagram4" class="mermaid" style="background: rgb(255, 255, 255)">
|
|
||||||
erDiagram
|
|
||||||
CAR ||--o{ NAMED-DRIVER : allows
|
|
||||||
CAR ::: Pine {
|
|
||||||
string registrationNumber PK "Primary Key<br><strong>Unique registration number</strong>"
|
|
||||||
string make "Car make<br><strong>e.g., Toyota</strong>"
|
|
||||||
string model "Model of the car<br><strong>e.g., Corolla</strong>"
|
|
||||||
string[] parts "List of parts<br><strong>Stored as array</strong>"
|
|
||||||
}
|
|
||||||
PERSON ||--o{ NAMED-DRIVER : is
|
|
||||||
PERSON ::: someclass {
|
|
||||||
string driversLicense PK "The license #<br><strong>Primary Key</strong>"
|
|
||||||
string(99) firstName "Only 99 characters <br>are allowed <br> <strong>e.g., Smith</strong>"
|
|
||||||
string lastName "Last name of person<br><strong>e.g., Smith</strong>"
|
|
||||||
string phone UK "Unique phone number<br><strong>Used for contact</strong>"
|
|
||||||
int age "Age of the person<br><strong>Must be numeric</strong>"
|
|
||||||
}
|
|
||||||
NAMED-DRIVER {
|
|
||||||
string carRegistrationNumber PK, FK, UK, PK "Foreign key to CAR<br><strong>Also part of PK</strong>"
|
|
||||||
string driverLicence PK, FK "Foreign key to PERSON<br><strong>Also part of PK</strong>"
|
|
||||||
}
|
|
||||||
MANUFACTURER only one to zero or more CAR : makesx
|
|
||||||
</pre>
|
|
||||||
<hr />
|
|
||||||
<pre class="mermaid">
|
|
||||||
erDiagram
|
|
||||||
_**testẽζ➕Ø😀㌕ぼ**_ {
|
|
||||||
*__List~List~int~~sdfds__* **driversLicense** PK "***The l😀icense #***"
|
|
||||||
string last*Name*
|
|
||||||
string __phone__ UK
|
|
||||||
*string(99)~T~~~~~~* firstName "Only __99__ <br>characters are a<br>llowed dsfsdfsdfsdfs"
|
|
||||||
int _age_
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
import mermaid from './mermaid.esm.mjs';
|
|
||||||
import layouts from './mermaid-layout-elk.esm.mjs';
|
|
||||||
|
|
||||||
const staticBellIconPack = {
|
|
||||||
prefix: 'fa6-regular',
|
|
||||||
icons: {
|
|
||||||
bell: {
|
|
||||||
body: '<path fill="currentColor" d="M224 0c-17.7 0-32 14.3-32 32v19.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416h400c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6c-28.3-35.5-43.8-79.6-43.8-125V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32m0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3c25.8-40 39.7-86.7 39.7-134.6V208c0-61.9 50.1-112 112-112m64 352H160c0 17 6.7 33.3 18.7 45.3S207 512 224 512s33.3-6.7 45.3-18.7S288 465 288 448"/>',
|
|
||||||
width: 448,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
width: 512,
|
|
||||||
height: 512,
|
|
||||||
};
|
|
||||||
|
|
||||||
mermaid.registerIconPacks([
|
|
||||||
{
|
|
||||||
name: 'logos',
|
|
||||||
loader: () =>
|
|
||||||
fetch('https://unpkg.com/@iconify-json/logos@1/icons.json').then((res) => res.json()),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'fa',
|
|
||||||
loader: () => staticBellIconPack,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
mermaid.registerLayoutLoaders(layouts);
|
|
||||||
mermaid.parseError = function (err, hash) {
|
|
||||||
console.error('Mermaid error: ', err);
|
|
||||||
};
|
|
||||||
window.callback = function () {
|
|
||||||
alert('A callback was triggered');
|
|
||||||
};
|
|
||||||
function callback() {
|
|
||||||
alert('It worked');
|
|
||||||
}
|
|
||||||
await mermaid.initialize({
|
|
||||||
startOnLoad: false,
|
|
||||||
|
|
||||||
theme: 'forest',
|
|
||||||
look: 'classic',
|
|
||||||
layout: 'dagre',
|
|
||||||
|
|
||||||
// theme: 'default',
|
|
||||||
// look: 'classic',
|
|
||||||
flowchart: { titleTopMargin: 10 },
|
|
||||||
fontFamily: 'Recursive',
|
|
||||||
sequence: {
|
|
||||||
actorFontFamily: 'courier',
|
|
||||||
noteFontFamily: 'courier',
|
|
||||||
messageFontFamily: 'courier',
|
|
||||||
},
|
|
||||||
kanban: {
|
|
||||||
htmlLabels: false,
|
|
||||||
},
|
|
||||||
fontSize: 16,
|
|
||||||
logLevel: 0,
|
|
||||||
securityLevel: 'loose',
|
|
||||||
callback,
|
|
||||||
});
|
|
||||||
// setTimeout(() => {
|
|
||||||
mermaid.init(undefined, document.querySelectorAll('.mermaid'));
|
|
||||||
// }, 1000);
|
|
||||||
mermaid.parseError = function (err, hash) {
|
|
||||||
console.error('In parse error:');
|
|
||||||
console.error(err);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,269 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<title>Mermaid ANTLR Parser Test Page</title>
|
|
||||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Courier New', Courier, monospace;
|
|
||||||
margin: 20px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.test-section {
|
|
||||||
background: white;
|
|
||||||
padding: 20px;
|
|
||||||
margin: 20px 0;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.parser-info {
|
|
||||||
background: #e3f2fd;
|
|
||||||
border: 1px solid #2196f3;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.success {
|
|
||||||
background: #e8f5e8;
|
|
||||||
border: 1px solid #4caf50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
background: #ffebee;
|
|
||||||
border: 1px solid #f44336;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.mermaid {
|
|
||||||
font-family: 'Courier New', Courier, monospace !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: #1976d2;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
color: #424242;
|
|
||||||
border-bottom: 2px solid #e0e0e0;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1>🎯 Mermaid ANTLR Parser Test Page</h1>
|
|
||||||
|
|
||||||
<div class="parser-info">
|
|
||||||
<h3>🔧 Parser Information</h3>
|
|
||||||
<p><strong>Environment Variable:</strong> <code id="env-var">Loading...</code></p>
|
|
||||||
<p><strong>Expected:</strong> <code>USE_ANTLR_PARSER=true</code></p>
|
|
||||||
<p><strong>Status:</strong> <span id="parser-status">Checking...</span></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>Test 1: Basic Flowchart</h2>
|
|
||||||
<p>Simple flowchart to test basic ANTLR parser functionality:</p>
|
|
||||||
<pre class="mermaid">
|
|
||||||
flowchart TD
|
|
||||||
A[Start] --> B[End]
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>Test 4: Complex Shapes with Text</h2>
|
|
||||||
<p>Testing various node shapes with complex text content:</p>
|
|
||||||
<pre class="mermaid">
|
|
||||||
flowchart LR
|
|
||||||
A(Round Node) --> B{Diamond}
|
|
||||||
B --> C([Stadium])
|
|
||||||
C --> D[[Subroutine]]
|
|
||||||
D --> E[(Database)]
|
|
||||||
E --> F((Circle))
|
|
||||||
F --> G[/Parallelogram/]
|
|
||||||
G --> H[\Trapezoid\]
|
|
||||||
H --> I[Mixed Text with / slash]
|
|
||||||
I --> J[\Mixed Text with \ backslash\]
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>Test 5: Classes and Styles</h2>
|
|
||||||
<p>Testing class and style processing:</p>
|
|
||||||
<pre class="mermaid">
|
|
||||||
flowchart TD
|
|
||||||
A[Node A] --> B[Node B]
|
|
||||||
B --> C[Node C]
|
|
||||||
|
|
||||||
classDef redClass fill:#ff9999,stroke:#333,stroke-width:2px
|
|
||||||
classDef blueClass fill:#9999ff,stroke:#333,stroke-width:2px
|
|
||||||
|
|
||||||
class A redClass
|
|
||||||
class B,C blueClass
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>Test 6: Subgraphs</h2>
|
|
||||||
<p>Testing subgraph processing:</p>
|
|
||||||
<pre class="mermaid">
|
|
||||||
flowchart TD
|
|
||||||
subgraph Main["Main Process"]
|
|
||||||
A[Start] --> B[Process]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph Sub["Sub Process"]
|
|
||||||
C[Sub Start] --> D[Sub End]
|
|
||||||
end
|
|
||||||
|
|
||||||
B --> C
|
|
||||||
D --> E[Final End]
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
import mermaid from './mermaid.esm.mjs';
|
|
||||||
|
|
||||||
// Configure ANTLR parser for browser environment
|
|
||||||
// Since process.env is not available in browser, we set up global config
|
|
||||||
window.MERMAID_CONFIG = {
|
|
||||||
USE_ANTLR_PARSER: 'true',
|
|
||||||
USE_ANTLR_VISITOR: 'true',
|
|
||||||
ANTLR_DEBUG: 'true'
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('🎯 Browser ANTLR Configuration:', window.MERMAID_CONFIG);
|
|
||||||
|
|
||||||
// Override console methods to capture logs
|
|
||||||
const originalLog = console.log;
|
|
||||||
const originalError = console.error;
|
|
||||||
|
|
||||||
console.log = function (...args) {
|
|
||||||
originalLog.apply(console, args);
|
|
||||||
// Display important logs on page
|
|
||||||
if (args[0] && typeof args[0] === 'string' && (
|
|
||||||
args[0].includes('ANTLR Parser:') ||
|
|
||||||
args[0].includes('FlowDB:') ||
|
|
||||||
args[0].includes('FlowchartListener:')
|
|
||||||
)) {
|
|
||||||
const logDiv = document.getElementById('debug-logs') || createLogDiv();
|
|
||||||
logDiv.innerHTML += '<div style="color: blue;">' + args.join(' ') + '</div>';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
console.error = function (...args) {
|
|
||||||
originalError.apply(console, args);
|
|
||||||
const logDiv = document.getElementById('debug-logs') || createLogDiv();
|
|
||||||
logDiv.innerHTML += '<div style="color: red;">ERROR: ' + args.join(' ') + '</div>';
|
|
||||||
};
|
|
||||||
|
|
||||||
function createLogDiv() {
|
|
||||||
const logDiv = document.createElement('div');
|
|
||||||
logDiv.id = 'debug-logs';
|
|
||||||
logDiv.style.cssText = 'border: 1px solid #ccc; padding: 10px; margin: 10px 0; max-height: 300px; overflow-y: auto; font-family: monospace; font-size: 12px; background: #f9f9f9;';
|
|
||||||
logDiv.innerHTML = '<h3>Debug Logs:</h3>';
|
|
||||||
document.body.appendChild(logDiv);
|
|
||||||
return logDiv;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize mermaid
|
|
||||||
mermaid.initialize({
|
|
||||||
theme: 'default',
|
|
||||||
logLevel: 3,
|
|
||||||
securityLevel: 'loose',
|
|
||||||
flowchart: { curve: 'basis' },
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check environment and parser status
|
|
||||||
let envVar = 'undefined';
|
|
||||||
try {
|
|
||||||
if (typeof process !== 'undefined' && process.env) {
|
|
||||||
envVar = process.env.USE_ANTLR_PARSER || 'undefined';
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// process is not defined in browser
|
|
||||||
envVar = 'browser-default';
|
|
||||||
}
|
|
||||||
const envElement = document.getElementById('env-var');
|
|
||||||
const statusElement = document.getElementById('parser-status');
|
|
||||||
|
|
||||||
if (envElement) {
|
|
||||||
envElement.textContent = `USE_ANTLR_PARSER=${envVar || 'undefined'}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for debug information from parser
|
|
||||||
setTimeout(() => {
|
|
||||||
if (window.MERMAID_PARSER_DEBUG) {
|
|
||||||
console.log('🔍 Found MERMAID_PARSER_DEBUG:', window.MERMAID_PARSER_DEBUG);
|
|
||||||
const debug = window.MERMAID_PARSER_DEBUG;
|
|
||||||
|
|
||||||
if (envElement) {
|
|
||||||
envElement.textContent = `USE_ANTLR_PARSER=${debug.env_value || 'undefined'} (actual: ${debug.USE_ANTLR_PARSER})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusElement) {
|
|
||||||
if (debug.USE_ANTLR_PARSER) {
|
|
||||||
statusElement.innerHTML = '<span style="color: green;">✅ ANTLR Parser Active</span>';
|
|
||||||
statusElement.parentElement.parentElement.classList.add('success');
|
|
||||||
} else {
|
|
||||||
statusElement.innerHTML = '<span style="color: orange;">⚠️ Jison Parser (Default)</span>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('❌ MERMAID_PARSER_DEBUG not found on window');
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
if (statusElement) {
|
|
||||||
if (envVar === 'true') {
|
|
||||||
statusElement.innerHTML = '<span style="color: green;">✅ ANTLR Parser Active</span>';
|
|
||||||
statusElement.parentElement.parentElement.classList.add('success');
|
|
||||||
} else {
|
|
||||||
statusElement.innerHTML = '<span style="color: orange;">⚠️ Jison Parser (Default)</span>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add some debugging
|
|
||||||
console.log('🎯 ANTLR Parser Test Page Loaded');
|
|
||||||
console.log('🔧 Environment:', { USE_ANTLR_PARSER: envVar });
|
|
||||||
|
|
||||||
// Test if we can detect which parser is being used
|
|
||||||
setTimeout(() => {
|
|
||||||
const mermaidElements = document.querySelectorAll('.mermaid');
|
|
||||||
console.log(`📊 Found ${mermaidElements.length} mermaid diagrams`);
|
|
||||||
|
|
||||||
// Check if diagrams rendered successfully
|
|
||||||
const renderedElements = document.querySelectorAll('.mermaid svg');
|
|
||||||
if (renderedElements.length > 0) {
|
|
||||||
console.log('✅ Diagrams rendered successfully!');
|
|
||||||
console.log(`📈 ${renderedElements.length} SVG elements created`);
|
|
||||||
|
|
||||||
// Update status on page
|
|
||||||
const statusElement = document.getElementById('parser-status');
|
|
||||||
if (statusElement && envVar === 'true') {
|
|
||||||
statusElement.innerHTML = '<span style="color: green;">✅ ANTLR Parser Active & Rendering Successfully!</span>';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('❌ No SVG elements found - check for rendering errors');
|
|
||||||
console.log('🔍 Checking for error messages...');
|
|
||||||
|
|
||||||
// Look for error messages in mermaid elements
|
|
||||||
mermaidElements.forEach((element, index) => {
|
|
||||||
console.log(`📋 Diagram ${index + 1} content:`, element.textContent.trim());
|
|
||||||
if (element.innerHTML.includes('error') || element.innerHTML.includes('Error')) {
|
|
||||||
console.log(`❌ Error found in diagram ${index + 1}:`, element.innerHTML);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 3000);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -1,358 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>🚀 Hybrid Sequence Editor Test</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
margin: 20px;
|
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
||||||
color: #333;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
background: white;
|
|
||||||
border-radius: 15px;
|
|
||||||
padding: 30px;
|
|
||||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
color: #4a5568;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
font-size: 2.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.test-section {
|
|
||||||
margin: 30px 0;
|
|
||||||
padding: 20px;
|
|
||||||
border: 2px solid #e2e8f0;
|
|
||||||
border-radius: 10px;
|
|
||||||
background: #f8fafc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.test-section h2 {
|
|
||||||
color: #2d3748;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls {
|
|
||||||
display: flex;
|
|
||||||
gap: 15px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
padding: 12px 24px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 14px;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-secondary {
|
|
||||||
background: #e2e8f0;
|
|
||||||
color: #4a5568;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-secondary:hover {
|
|
||||||
background: #cbd5e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.code-block {
|
|
||||||
background: #1a202c;
|
|
||||||
color: #e2e8f0;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 8px;
|
|
||||||
font-family: 'Courier New', monospace;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.5;
|
|
||||||
overflow-x: auto;
|
|
||||||
margin: 15px 0;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-section {
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background: #f0fff4;
|
|
||||||
border-left: 4px solid #48bb78;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-section {
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background: #fff5f5;
|
|
||||||
border-left: 4px solid #f56565;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
||||||
gap: 15px;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card {
|
|
||||||
background: white;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 8px;
|
|
||||||
text-align: center;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-value {
|
|
||||||
font-size: 2em;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #667eea;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-label {
|
|
||||||
color: #718096;
|
|
||||||
font-size: 0.9em;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.operations {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
||||||
gap: 15px;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.operation-card {
|
|
||||||
background: white;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.operation-card h3 {
|
|
||||||
margin-top: 0;
|
|
||||||
color: #4a5568;
|
|
||||||
}
|
|
||||||
|
|
||||||
input, select {
|
|
||||||
width: 100%;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border: 1px solid #e2e8f0;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 5px 0;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-output {
|
|
||||||
background: #2d3748;
|
|
||||||
color: #e2e8f0;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 8px;
|
|
||||||
font-family: 'Courier New', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
max-height: 300px;
|
|
||||||
overflow-y: auto;
|
|
||||||
margin: 15px 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>🚀 Hybrid Sequence Editor Test</h1>
|
|
||||||
<p style="text-align: center; color: #718096; font-size: 1.1em;">
|
|
||||||
Testing the new hybrid approach: AST-based editing + TokenStreamRewriter for optimal performance
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<!-- Test Section 1: Basic Functionality -->
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>🎯 Basic Hybrid Editor Test</h2>
|
|
||||||
<div class="controls">
|
|
||||||
<button class="btn-primary" onclick="testBasicFunctionality()">Test Basic Functionality</button>
|
|
||||||
<button class="btn-secondary" onclick="clearResults()">Clear Results</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="code-block" id="originalCode">sequenceDiagram
|
|
||||||
Alice->>Bob: Hello Bob, how are you?
|
|
||||||
Bob-->>Alice: Great!</div>
|
|
||||||
|
|
||||||
<div id="basicResults"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Test Section 2: CRUD Operations -->
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>✏️ CRUD Operations Test</h2>
|
|
||||||
<div class="operations">
|
|
||||||
<div class="operation-card">
|
|
||||||
<h3>Add Participant</h3>
|
|
||||||
<input type="text" id="participantId" placeholder="Participant ID (e.g., C)" />
|
|
||||||
<input type="text" id="participantAlias" placeholder="Alias (e.g., Charlie)" />
|
|
||||||
<button class="btn-primary" onclick="addParticipant()">Add Participant</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="operation-card">
|
|
||||||
<h3>Add Message</h3>
|
|
||||||
<input type="text" id="messageFrom" placeholder="From (e.g., Alice)" />
|
|
||||||
<input type="text" id="messageTo" placeholder="To (e.g., Bob)" />
|
|
||||||
<input type="text" id="messageText" placeholder="Message text" />
|
|
||||||
<select id="messageArrow">
|
|
||||||
<option value="->>">->></option>
|
|
||||||
<option value="-->>">-->></option>
|
|
||||||
<option value="->">-></option>
|
|
||||||
<option value="-->">--></option>
|
|
||||||
</select>
|
|
||||||
<button class="btn-primary" onclick="addMessage()">Add Message</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="operation-card">
|
|
||||||
<h3>Add Note</h3>
|
|
||||||
<select id="notePosition">
|
|
||||||
<option value="right">right</option>
|
|
||||||
<option value="left">left</option>
|
|
||||||
<option value="over">over</option>
|
|
||||||
</select>
|
|
||||||
<input type="text" id="noteParticipant" placeholder="Participant (e.g., Bob)" />
|
|
||||||
<input type="text" id="noteText" placeholder="Note text" />
|
|
||||||
<button class="btn-primary" onclick="addNote()">Add Note</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="operation-card">
|
|
||||||
<h3>Move Statement</h3>
|
|
||||||
<input type="number" id="moveFrom" placeholder="From index" />
|
|
||||||
<input type="number" id="moveTo" placeholder="To index" />
|
|
||||||
<button class="btn-primary" onclick="moveStatement()">Move Statement</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<button class="btn-primary" onclick="regenerateCode()">Regenerate Code</button>
|
|
||||||
<button class="btn-secondary" onclick="showAST()">Show AST</button>
|
|
||||||
<button class="btn-secondary" onclick="validateAST()">Validate AST</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="crudResults"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Test Section 3: Performance Comparison -->
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>⚡ Performance Test</h2>
|
|
||||||
<div class="controls">
|
|
||||||
<button class="btn-primary" onclick="performanceTest()">Run Performance Test</button>
|
|
||||||
<select id="testSize">
|
|
||||||
<option value="small">Small (10 statements)</option>
|
|
||||||
<option value="medium">Medium (50 statements)</option>
|
|
||||||
<option value="large">Large (200 statements)</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="performanceResults"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Debug Log -->
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>🔍 Debug Log</h2>
|
|
||||||
<div class="controls">
|
|
||||||
<button class="btn-secondary" onclick="clearLog()">Clear Log</button>
|
|
||||||
</div>
|
|
||||||
<div class="log-output" id="debugLog"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
// This will be implemented to test the hybrid editor
|
|
||||||
console.log('🚀 Hybrid Sequence Editor Test Page Loaded');
|
|
||||||
|
|
||||||
// Global variables for testing
|
|
||||||
let hybridEditor = null;
|
|
||||||
let currentAST = null;
|
|
||||||
|
|
||||||
// Test functions will be implemented here
|
|
||||||
window.testBasicFunctionality = function() {
|
|
||||||
log('🎯 Testing basic hybrid editor functionality...');
|
|
||||||
log('⚠️ Implementation pending - hybrid editor classes need to be imported');
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addParticipant = function() {
|
|
||||||
const id = document.getElementById('participantId').value;
|
|
||||||
const alias = document.getElementById('participantAlias').value;
|
|
||||||
log(`👤 Adding participant: ${id}${alias ? ` as ${alias}` : ''}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addMessage = function() {
|
|
||||||
const from = document.getElementById('messageFrom').value;
|
|
||||||
const to = document.getElementById('messageTo').value;
|
|
||||||
const text = document.getElementById('messageText').value;
|
|
||||||
const arrow = document.getElementById('messageArrow').value;
|
|
||||||
log(`💬 Adding message: ${from}${arrow}${to}: ${text}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addNote = function() {
|
|
||||||
const position = document.getElementById('notePosition').value;
|
|
||||||
const participant = document.getElementById('noteParticipant').value;
|
|
||||||
const text = document.getElementById('noteText').value;
|
|
||||||
log(`📝 Adding note: Note ${position} of ${participant}: ${text}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.moveStatement = function() {
|
|
||||||
const from = document.getElementById('moveFrom').value;
|
|
||||||
const to = document.getElementById('moveTo').value;
|
|
||||||
log(`🔄 Moving statement from ${from} to ${to}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.regenerateCode = function() {
|
|
||||||
log('🔄 Regenerating code from AST...');
|
|
||||||
};
|
|
||||||
|
|
||||||
window.showAST = function() {
|
|
||||||
log('🌳 Showing current AST structure...');
|
|
||||||
};
|
|
||||||
|
|
||||||
window.validateAST = function() {
|
|
||||||
log('✅ Validating AST structure...');
|
|
||||||
};
|
|
||||||
|
|
||||||
window.performanceTest = function() {
|
|
||||||
const size = document.getElementById('testSize').value;
|
|
||||||
log(`⚡ Running performance test with ${size} dataset...`);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.clearResults = function() {
|
|
||||||
document.getElementById('basicResults').innerHTML = '';
|
|
||||||
document.getElementById('crudResults').innerHTML = '';
|
|
||||||
document.getElementById('performanceResults').innerHTML = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
window.clearLog = function() {
|
|
||||||
document.getElementById('debugLog').innerHTML = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
function log(message) {
|
|
||||||
const logElement = document.getElementById('debugLog');
|
|
||||||
const timestamp = new Date().toLocaleTimeString();
|
|
||||||
logElement.innerHTML += `[${timestamp}] ${message}\n`;
|
|
||||||
logElement.scrollTop = logElement.scrollHeight;
|
|
||||||
console.log(message);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<div class="diagrams">
|
<div class="diagrams">
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
packet
|
packet-beta
|
||||||
0-15: "Source Port"
|
0-15: "Source Port"
|
||||||
16-31: "Destination Port"
|
16-31: "Destination Port"
|
||||||
32-63: "Sequence Number"
|
32-63: "Sequence Number"
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
packet:
|
packet:
|
||||||
showBits: false
|
showBits: false
|
||||||
---
|
---
|
||||||
packet
|
packet-beta
|
||||||
0-15: "Source Port"
|
0-15: "Source Port"
|
||||||
16-31: "Destination Port"
|
16-31: "Destination Port"
|
||||||
32-63: "Sequence Number"
|
32-63: "Sequence Number"
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
config:
|
config:
|
||||||
theme: forest
|
theme: forest
|
||||||
---
|
---
|
||||||
packet
|
packet-beta
|
||||||
title Forest theme
|
title Forest theme
|
||||||
0-15: "Source Port"
|
0-15: "Source Port"
|
||||||
16-31: "Destination Port"
|
16-31: "Destination Port"
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
config:
|
config:
|
||||||
theme: dark
|
theme: dark
|
||||||
---
|
---
|
||||||
packet
|
packet-beta
|
||||||
title Dark theme
|
title Dark theme
|
||||||
0-15: "Source Port"
|
0-15: "Source Port"
|
||||||
16-31: "Destination Port"
|
16-31: "Destination Port"
|
||||||
|
|||||||
@@ -20,14 +20,12 @@
|
|||||||
width: 800
|
width: 800
|
||||||
nodeAlignment: left
|
nodeAlignment: left
|
||||||
---
|
---
|
||||||
sankey
|
sankey-beta
|
||||||
a,b,8
|
Revenue,Expenses,10
|
||||||
b,c,8
|
Revenue,Profit,10
|
||||||
c,d,8
|
Expenses,Manufacturing,5
|
||||||
d,e,8
|
Expenses,Tax,3
|
||||||
|
Expenses,Research,2
|
||||||
x,c,4
|
|
||||||
c,y,4
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2>Energy flow</h2>
|
<h2>Energy flow</h2>
|
||||||
@@ -42,7 +40,7 @@
|
|||||||
linkColor: gradient
|
linkColor: gradient
|
||||||
nodeAlignment: justify
|
nodeAlignment: justify
|
||||||
---
|
---
|
||||||
sankey
|
sankey-beta
|
||||||
|
|
||||||
Agricultural 'waste',Bio-conversion,124.729
|
Agricultural 'waste',Bio-conversion,124.729
|
||||||
Bio-conversion,Liquid,0.597
|
Bio-conversion,Liquid,0.597
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,216 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Simple ANTLR Parser Test</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
margin: 20px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
background-color: white;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
.status {
|
|
||||||
background-color: #e8f4fd;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
border-left: 4px solid #2196F3;
|
|
||||||
}
|
|
||||||
.debug-logs {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
font-family: monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
max-height: 300px;
|
|
||||||
overflow-y: auto;
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
}
|
|
||||||
.test-section {
|
|
||||||
margin: 20px 0;
|
|
||||||
padding: 15px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
.mermaid {
|
|
||||||
text-align: center;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
h1 { color: #333; }
|
|
||||||
h2 { color: #666; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>🧪 Simple ANTLR Parser Test</h1>
|
|
||||||
|
|
||||||
<div class="status">
|
|
||||||
<h3>Parser Status</h3>
|
|
||||||
<p><strong>Environment Variable:</strong> <span id="env-var">Loading...</span></p>
|
|
||||||
<p><strong>Parser Status:</strong> <span id="parser-status">Loading...</span></p>
|
|
||||||
<p><strong>Global Config:</strong> <span id="global-config">Loading...</span></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="debug-logs">
|
|
||||||
<h3>Debug Logs:</h3>
|
|
||||||
<div id="debug-output">Initializing...</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="test-section">
|
|
||||||
<h2>Test 1: Minimal Flowchart</h2>
|
|
||||||
<p>Testing the simplest possible flowchart:</p>
|
|
||||||
<pre class="mermaid">
|
|
||||||
flowchart TD
|
|
||||||
A[Start] --> B[End]
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
import mermaid from './mermaid.esm.mjs';
|
|
||||||
|
|
||||||
// Configure ANTLR parser for browser environment
|
|
||||||
window.MERMAID_CONFIG = {
|
|
||||||
USE_ANTLR_PARSER: 'true',
|
|
||||||
USE_ANTLR_VISITOR: 'true',
|
|
||||||
ANTLR_DEBUG: 'true'
|
|
||||||
};
|
|
||||||
|
|
||||||
// Enhanced debug logging to track down the process.env issue
|
|
||||||
const debugOutput = document.getElementById('debug-output');
|
|
||||||
const originalConsoleLog = console.log;
|
|
||||||
const originalConsoleError = console.error;
|
|
||||||
|
|
||||||
function addDebugLog(message, type = 'log') {
|
|
||||||
const timestamp = new Date().toLocaleTimeString();
|
|
||||||
const logEntry = `[${timestamp}] ${type.toUpperCase()}: ${message}`;
|
|
||||||
|
|
||||||
if (debugOutput) {
|
|
||||||
debugOutput.innerHTML += logEntry + '<br>';
|
|
||||||
debugOutput.scrollTop = debugOutput.scrollHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also log to original console
|
|
||||||
if (type === 'error') {
|
|
||||||
originalConsoleError(message);
|
|
||||||
} else {
|
|
||||||
originalConsoleLog(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override console methods to capture all logs
|
|
||||||
console.log = function(...args) {
|
|
||||||
addDebugLog(args.join(' '), 'log');
|
|
||||||
};
|
|
||||||
|
|
||||||
console.error = function(...args) {
|
|
||||||
addDebugLog(args.join(' '), 'error');
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add process access detection
|
|
||||||
const originalProcess = window.process;
|
|
||||||
Object.defineProperty(window, 'process', {
|
|
||||||
get: function() {
|
|
||||||
const stack = new Error().stack;
|
|
||||||
addDebugLog(`🚨 PROCESS ACCESS DETECTED! Stack trace: ${stack}`, 'error');
|
|
||||||
return originalProcess;
|
|
||||||
},
|
|
||||||
set: function(value) {
|
|
||||||
addDebugLog(`🚨 PROCESS SET DETECTED! Value: ${value}`, 'error');
|
|
||||||
window._process = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addDebugLog('🔧 Starting ANTLR parser test initialization');
|
|
||||||
|
|
||||||
// Check environment and parser status
|
|
||||||
let envVar = 'undefined';
|
|
||||||
try {
|
|
||||||
if (typeof process !== 'undefined' && process.env) {
|
|
||||||
envVar = process.env.USE_ANTLR_PARSER || 'undefined';
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
addDebugLog(`🔧 Process check failed (expected in browser): ${e.message}`);
|
|
||||||
envVar = 'browser-default';
|
|
||||||
}
|
|
||||||
|
|
||||||
const envElement = document.getElementById('env-var');
|
|
||||||
const statusElement = document.getElementById('parser-status');
|
|
||||||
const configElement = document.getElementById('global-config');
|
|
||||||
|
|
||||||
if (envElement) {
|
|
||||||
envElement.textContent = `USE_ANTLR_PARSER=${envVar || 'undefined'}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configElement) {
|
|
||||||
configElement.textContent = JSON.stringify(window.MERMAID_CONFIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
addDebugLog('🔧 Initializing Mermaid with ANTLR parser');
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Initialize mermaid with detailed error handling
|
|
||||||
await mermaid.initialize({
|
|
||||||
startOnLoad: false,
|
|
||||||
theme: 'default',
|
|
||||||
flowchart: {
|
|
||||||
useMaxWidth: true,
|
|
||||||
htmlLabels: true
|
|
||||||
},
|
|
||||||
suppressErrors: false, // We want to see all errors
|
|
||||||
logLevel: 'debug'
|
|
||||||
});
|
|
||||||
|
|
||||||
addDebugLog('✅ Mermaid initialized successfully');
|
|
||||||
|
|
||||||
if (statusElement) {
|
|
||||||
statusElement.textContent = '✅ ANTLR Parser Active';
|
|
||||||
statusElement.style.color = 'green';
|
|
||||||
}
|
|
||||||
|
|
||||||
addDebugLog('🎯 Starting diagram rendering');
|
|
||||||
|
|
||||||
// Render diagrams with detailed error tracking
|
|
||||||
const diagrams = document.querySelectorAll('.mermaid');
|
|
||||||
for (let i = 0; i < diagrams.length; i++) {
|
|
||||||
const diagram = diagrams[i];
|
|
||||||
addDebugLog(`🎨 Rendering diagram ${i + 1}/${diagrams.length}`);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await mermaid.run({
|
|
||||||
nodes: [diagram],
|
|
||||||
suppressErrors: false
|
|
||||||
});
|
|
||||||
addDebugLog(`✅ Diagram ${i + 1} rendered successfully`);
|
|
||||||
} catch (error) {
|
|
||||||
addDebugLog(`❌ Diagram ${i + 1} failed: ${error.message}`, 'error');
|
|
||||||
addDebugLog(`❌ Stack trace: ${error.stack}`, 'error');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addDebugLog('🎉 All diagrams processed');
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
addDebugLog(`❌ Mermaid initialization failed: ${error.message}`, 'error');
|
|
||||||
addDebugLog(`❌ Stack trace: ${error.stack}`, 'error');
|
|
||||||
|
|
||||||
if (statusElement) {
|
|
||||||
statusElement.textContent = '❌ ANTLR Parser Failed';
|
|
||||||
statusElement.style.color = 'red';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addDebugLog('🔧 Test initialization complete');
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -23,23 +23,6 @@
|
|||||||
1940 : fourth step : fifth step
|
1940 : fourth step : fifth step
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2>Medical Device Lifecycle Timeline</h2>
|
|
||||||
<pre class="mermaid">
|
|
||||||
timeline
|
|
||||||
title Medical Device Lifecycle
|
|
||||||
section Planning
|
|
||||||
Quality Management System (4) : Regulatory Compliance (4.1) : Risk Management (4.1.3) : Management Review (5.6) : Infrastructure (6.3)
|
|
||||||
Management Responsibility (5) : Planning Activities (5.2) : Human Resources (6.2) : RnD Planning (7.3.2) : Purchasing Process (7.4.1) : Production Activities (7.5.1) : Installation Activities (7.5.3) : Servicing Activities (7.5.4)
|
|
||||||
section Realization
|
|
||||||
Research and Development (7.3) : Inputs (7.3.3) : Outputs (7.3.4) : Review (7.3.5) : Verification (7.3.6) : Validation (7.3.7)
|
|
||||||
Purchasing (7.4) : Purchasing Information (7.4.2) : Production Feedback (8.2.1)
|
|
||||||
Production (7.5) : Production Feedback (8.2.1)
|
|
||||||
Installation (7.5.3) : Installation Activities (7.5.3)
|
|
||||||
Servicing (7.5.4) : Servicing Activities (7.5.4)
|
|
||||||
section Post-Production
|
|
||||||
Post-Market Activities (8) : Feedback (8.2.1) : Complaints (8.2.2) : Adverse Events (8.2.3)
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from './mermaid.esm.mjs';
|
import mermaid from './mermaid.esm.mjs';
|
||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<title>Mermaid Treemap Diagram Demo</title>
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Montserrat', sans-serif;
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width: 900px;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
.mermaid {
|
|
||||||
margin: 30px 0;
|
|
||||||
}
|
|
||||||
h1,
|
|
||||||
h2 {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
pre {
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Treemap Diagram Demo</h1>
|
|
||||||
<p>This is a demo of the new treemap diagram type in Mermaid.</p>
|
|
||||||
|
|
||||||
<h2>Basic Treemap Example</h2>
|
|
||||||
<pre class="mermaid">
|
|
||||||
treemap
|
|
||||||
"Root"
|
|
||||||
"Branch 1"
|
|
||||||
"Leaf 1.1": 10
|
|
||||||
"Leaf 1.2": 15
|
|
||||||
"Branch 2"
|
|
||||||
"Branch 2.1"
|
|
||||||
"Leaf 2.1.1": 20
|
|
||||||
"Leaf 2.1.2": 25
|
|
||||||
"Leaf 2.2": 25
|
|
||||||
"Leaf 2.3": 30
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h2>Technology Stack Treemap Example</h2>
|
|
||||||
<pre class="mermaid">
|
|
||||||
treemap
|
|
||||||
"Technology Stack"
|
|
||||||
"Frontend"
|
|
||||||
"React": 35
|
|
||||||
"CSS": 15
|
|
||||||
"HTML": 10
|
|
||||||
"Backend"
|
|
||||||
"Node.js": 25
|
|
||||||
"Express": 10
|
|
||||||
"MongoDB": 15
|
|
||||||
"DevOps"
|
|
||||||
"Docker": 10
|
|
||||||
"Kubernetes": 15
|
|
||||||
"CI/CD": 5
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
import mermaid from './mermaid.esm.mjs';
|
|
||||||
mermaid.initialize({
|
|
||||||
theme: 'forest',
|
|
||||||
logLevel: 1,
|
|
||||||
securityLevel: 'loose',
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>XY Charts demos</h1>
|
<h1>XY Charts demos</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue (in $)"
|
title "Sales Revenue (in $)"
|
||||||
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<h1>XY Charts horizontal</h1>
|
<h1>XY Charts horizontal</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart horizontal
|
xychart-beta horizontal
|
||||||
title "Basic xychart"
|
title "Basic xychart"
|
||||||
x-axis "this is x axis" [category1, "category 2", category3, category4]
|
x-axis "this is x axis" [category1, "category 2", category3, category4]
|
||||||
y-axis yaxisText 10 --> 150
|
y-axis yaxisText 10 --> 150
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<h1>XY Charts only lines and bar</h1>
|
<h1>XY Charts only lines and bar</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart
|
xychart-beta
|
||||||
line [23, 46, 77, 34]
|
line [23, 46, 77, 34]
|
||||||
line [45, 32, 33, 12]
|
line [45, 32, 33, 12]
|
||||||
line [87, 54, 99, 85]
|
line [87, 54, 99, 85]
|
||||||
@@ -48,13 +48,13 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<h1>XY Charts with +ve and -ve numbers</h1>
|
<h1>XY Charts with +ve and -ve numbers</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart
|
xychart-beta
|
||||||
line [+1.3, .6, 2.4, -.34]
|
line [+1.3, .6, 2.4, -.34]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h1>XY Charts Bar with multiple category</h1>
|
<h1>XY Charts Bar with multiple category</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart
|
xychart-beta
|
||||||
title "Basic xychart with many categories"
|
title "Basic xychart with many categories"
|
||||||
x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
|
x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
|
||||||
y-axis yaxisText 10 --> 150
|
y-axis yaxisText 10 --> 150
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
<h1>XY Charts line with multiple category</h1>
|
<h1>XY Charts line with multiple category</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart
|
xychart-beta
|
||||||
title "Line chart with many category"
|
title "Line chart with many category"
|
||||||
x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
|
x-axis "this is x axis" [category1, "category 2", category3, category4, category5, category6, category7]
|
||||||
y-axis yaxisText 10 --> 150
|
y-axis yaxisText 10 --> 150
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
<h1>XY Charts category with large text</h1>
|
<h1>XY Charts category with large text</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
xychart
|
xychart-beta
|
||||||
title "Basic xychart with many categories with category overlap"
|
title "Basic xychart with many categories with category overlap"
|
||||||
x-axis "this is x axis" [category1, "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.", category3, category4, category5, category6, category7]
|
x-axis "this is x axis" [category1, "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.", category3, category4, category5, category6, category7]
|
||||||
y-axis yaxisText 10 --> 150
|
y-axis yaxisText 10 --> 150
|
||||||
@@ -89,7 +89,7 @@ config:
|
|||||||
height: 20
|
height: 20
|
||||||
plotReservedSpacePercent: 100
|
plotReservedSpacePercent: 100
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
line [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ config:
|
|||||||
height: 20
|
height: 20
|
||||||
plotReservedSpacePercent: 100
|
plotReservedSpacePercent: 100
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
bar [5000, 9000, 7500, 6200, 9500, 5500, 11000, 8200, 9200, 9500, 7000, 8800]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ config:
|
|||||||
chartOrientation: horizontal
|
chartOrientation: horizontal
|
||||||
plotReservedSpacePercent: 60
|
plotReservedSpacePercent: 60
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
@@ -162,7 +162,7 @@ config:
|
|||||||
xAxisLineColor: "#87ceeb"
|
xAxisLineColor: "#87ceeb"
|
||||||
plotColorPalette: "#008000, #faba63"
|
plotColorPalette: "#008000, #faba63"
|
||||||
---
|
---
|
||||||
xychart
|
xychart-beta
|
||||||
title "Sales Revenue"
|
title "Sales Revenue"
|
||||||
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
x-axis Months [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
|
||||||
y-axis "Revenue (in $)" 4000 --> 11000
|
y-axis "Revenue (in $)" 4000 --> 11000
|
||||||
|
|||||||
@@ -10,20 +10,16 @@
|
|||||||
<h1>Zenuml demos</h1>
|
<h1>Zenuml demos</h1>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
zenuml
|
zenuml
|
||||||
BookLibService.Borrow(id) {
|
title Sync Messages (Design Pattern: Adapter)
|
||||||
User = Session.GetUser()
|
@Starter(Client)
|
||||||
if(User.isActive) {
|
Adapter.interfaceMethod() {
|
||||||
try {
|
translateParameter(parameter)
|
||||||
BookRepository.Update(id, onLoan, User)
|
|
||||||
receipt = new Receipt(id, dueDate)
|
result = Implementation.implementationMethod()
|
||||||
} catch (BookNotFoundException) {
|
|
||||||
ErrorService.onException(BookNotFoundException)
|
translateResult()
|
||||||
} finally {
|
return translatedResult
|
||||||
Connection.close()
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return receipt
|
|
||||||
}
|
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
zenuml
|
zenuml
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ If you are adding a feature, you will definitely need to add tests. Depending on
|
|||||||
|
|
||||||
Unit tests are tests that test a single function or module. They are the easiest to write and the fastest to run.
|
Unit tests are tests that test a single function or module. They are the easiest to write and the fastest to run.
|
||||||
|
|
||||||
Unit tests are mandatory for all code except the layout tests. (The layouts are tested with integration tests.)
|
Unit tests are mandatory for all code except the renderers. (The renderers are tested with integration tests.)
|
||||||
|
|
||||||
We use [Vitest](https://vitest.dev) to run unit tests.
|
We use [Vitest](https://vitest.dev) to run unit tests.
|
||||||
|
|
||||||
@@ -327,30 +327,6 @@ When using Docker prepend your command with `./run`:
|
|||||||
./run pnpm test
|
./run pnpm test
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Testing the DOM
|
|
||||||
|
|
||||||
One can use `jsdomIt` to test any part of Mermaid that interacts with the DOM, as long as it is not related to the layout.
|
|
||||||
|
|
||||||
The function `jsdomIt` ([developed in utils.ts](../../tests/util.ts)) overrides `it` from `vitest`, and creates a pseudo-browser environment that works almost like the real deal for the duration of the test. It uses JSDOM to create a DOM, and adds objects `window` and `document` to `global` to mock the browser environment.
|
|
||||||
|
|
||||||
> \[!NOTE]
|
|
||||||
> The layout cannot work in `jsdomIt` tests because JSDOM has no rendering engine, hence the pseudo-browser environment.
|
|
||||||
|
|
||||||
Example :
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { ensureNodeFromSelector, jsdomIt } from './tests/util.js';
|
|
||||||
|
|
||||||
jsdomIt('should add element "thing" in the SVG', ({ svg }) => {
|
|
||||||
// Code in this block runs in a pseudo-browser environment
|
|
||||||
addThing(svg); // The svg item is the D3 selection of the SVG node
|
|
||||||
const svgNode = ensureNodeFromSelector('svg'); // Retrieve the DOM node using the DOM API
|
|
||||||
expect(svgNode.querySelector('thing')).not.toBeNull(); // Test the structure of the SVG
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
They can be used to test any method that interacts with the DOM, including for testing renderers. For renderers, additional integration testing is necessary to test the layout though.
|
|
||||||
|
|
||||||
#### Integration / End-to-End (E2E) Tests
|
#### Integration / End-to-End (E2E) Tests
|
||||||
|
|
||||||
These test the rendering and visual appearance of the diagrams.
|
These test the rendering and visual appearance of the diagrams.
|
||||||
|
|||||||
@@ -111,13 +111,3 @@ const themes = {
|
|||||||
```
|
```
|
||||||
|
|
||||||
The actual options and values for the colors are defined in **src/theme/theme-\[xyz].js**. If you provide the options your diagram needs in the existing theme files then the theming will work smoothly without hiccups.
|
The actual options and values for the colors are defined in **src/theme/theme-\[xyz].js**. If you provide the options your diagram needs in the existing theme files then the theming will work smoothly without hiccups.
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
The `@mermaid-js/examples` package contains a collection of examples that are used by tools like mermaid.live to help users get started with the new diagram.
|
|
||||||
|
|
||||||
You can duplicate an existing diagram example file, eg: `packages/examples/src/examples/flowchart.ts`, and modify it with details specific to your diagram.
|
|
||||||
|
|
||||||
Then you can import the example in the `packages/examples/src/index.ts` file and add it to the `examples` array.
|
|
||||||
|
|
||||||
Each diagram should have at least one example, and that should be marked as default. It is good to add more examples to showcase different features of the diagram.
|
|
||||||
|
|||||||
@@ -22,4 +22,4 @@ This helps the team know the relative interest in something and helps them set p
|
|||||||
|
|
||||||
You have not found anything that already addresses your request, or maybe you have come up with the new idea? Feel free to open a new issue or discussion.
|
You have not found anything that already addresses your request, or maybe you have come up with the new idea? Feel free to open a new issue or discussion.
|
||||||
|
|
||||||
Log in to [GitHub.com](https://www.github.com), and use [GitHub issue tracker of the mermaid-js repository](https://github.com/mermaid-js/mermaid/issues). Press [issue, select the appropriate template](https://github.com/mermaid-js/mermaid/issues/new/choose) and describe your problem.
|
Log in to [GitHub.com](https://www.github.com), and use [GitHub issue tracker of the mermaid-js repository](https://github.com/mermaid-js/mermaid/issues). Press \[<https://github.com/mermaid-js/mermaid/issues/new/choose>] issue, select the appropriate template and describe your problem.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
# Frequently Asked Questions
|
# Frequently Asked Questions
|
||||||
|
|
||||||
1. [How to add title to flowchart?](https://github.com/mermaid-js/mermaid/issues/1433#issuecomment-1991554712)
|
1. [How to add title to flowchart?](https://github.com/mermaid-js/mermaid/issues/556#issuecomment-363182217)
|
||||||
2. [How to specify custom CSS file?](https://github.com/mermaidjs/mermaid.cli/pull/24#issuecomment-373402785)
|
2. [How to specify custom CSS file?](https://github.com/mermaidjs/mermaid.cli/pull/24#issuecomment-373402785)
|
||||||
3. [How to fix tooltip misplacement issue?](https://github.com/mermaid-js/mermaid/issues/542#issuecomment-3343564621)
|
3. [How to fix tooltip misplacement issue?](https://github.com/mermaid-js/mermaid/issues/542#issuecomment-3343564621)
|
||||||
4. [How to specify gantt diagram xAxis format?](https://github.com/mermaid-js/mermaid/issues/269#issuecomment-373229136)
|
4. [How to specify gantt diagram xAxis format?](https://github.com/mermaid-js/mermaid/issues/269#issuecomment-373229136)
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
> **Warning**
|
|
||||||
>
|
|
||||||
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
|
|
||||||
>
|
|
||||||
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/layouts.md](../../packages/mermaid/src/docs/config/layouts.md).
|
|
||||||
|
|
||||||
# Layouts
|
|
||||||
|
|
||||||
This page lists the available layout algorithms supported in Mermaid diagrams.
|
|
||||||
|
|
||||||
## Supported Layouts
|
|
||||||
|
|
||||||
- **elk**: [ELK (Eclipse Layout Kernel)](https://www.eclipse.org/elk/)
|
|
||||||
- **tidy-tree**: Tidy tree layout for hierarchical diagrams [Tidy Tree Configuration](/config/tidy-tree)
|
|
||||||
- **cose-bilkent**: Cose Bilkent layout for force-directed graphs
|
|
||||||
- **dagre**: Dagre layout for layered graphs
|
|
||||||
|
|
||||||
## How to Use
|
|
||||||
|
|
||||||
You can specify the layout in your diagram's YAML config or initialization options. For example:
|
|
||||||
|
|
||||||
```mermaid-example
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
graph TD;
|
|
||||||
A-->B;
|
|
||||||
B-->C;
|
|
||||||
```
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
---
|
|
||||||
config:
|
|
||||||
layout: elk
|
|
||||||
---
|
|
||||||
graph TD;
|
|
||||||
A-->B;
|
|
||||||
B-->C;
|
|
||||||
```
|
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
- [addDirective](functions/addDirective.md)
|
- [addDirective](functions/addDirective.md)
|
||||||
- [getConfig](functions/getConfig.md)
|
- [getConfig](functions/getConfig.md)
|
||||||
- [getSiteConfig](functions/getSiteConfig.md)
|
- [getSiteConfig](functions/getSiteConfig.md)
|
||||||
- [getUserDefinedConfig](functions/getUserDefinedConfig.md)
|
|
||||||
- [reset](functions/reset.md)
|
- [reset](functions/reset.md)
|
||||||
- [sanitize](functions/sanitize.md)
|
- [sanitize](functions/sanitize.md)
|
||||||
- [saveConfigFromInitialize](functions/saveConfigFromInitialize.md)
|
- [saveConfigFromInitialize](functions/saveConfigFromInitialize.md)
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
> **Warning**
|
|
||||||
>
|
|
||||||
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
|
|
||||||
>
|
|
||||||
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/config/functions/getUserDefinedConfig.md](../../../../../packages/mermaid/src/docs/config/setup/config/functions/getUserDefinedConfig.md).
|
|
||||||
|
|
||||||
[**mermaid**](../../README.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Function: getUserDefinedConfig()
|
|
||||||
|
|
||||||
> **getUserDefinedConfig**(): [`MermaidConfig`](../../mermaid/interfaces/MermaidConfig.md)
|
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/config.ts:252](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L252)
|
|
||||||
|
|
||||||
## Returns
|
|
||||||
|
|
||||||
[`MermaidConfig`](../../mermaid/interfaces/MermaidConfig.md)
|
|
||||||
@@ -12,4 +12,4 @@
|
|||||||
|
|
||||||
> `const` **configKeys**: `Set`<`string`>
|
> `const` **configKeys**: `Set`<`string`>
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/defaultConfig.ts:292](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L292)
|
Defined in: [packages/mermaid/src/defaultConfig.ts:274](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L274)
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
# mermaid
|
# mermaid
|
||||||
|
|
||||||
|
## Classes
|
||||||
|
|
||||||
|
- [UnknownDiagramError](classes/UnknownDiagramError.md)
|
||||||
|
|
||||||
## Interfaces
|
## Interfaces
|
||||||
|
|
||||||
- [DetailedError](interfaces/DetailedError.md)
|
- [DetailedError](interfaces/DetailedError.md)
|
||||||
@@ -23,7 +27,6 @@
|
|||||||
- [RenderOptions](interfaces/RenderOptions.md)
|
- [RenderOptions](interfaces/RenderOptions.md)
|
||||||
- [RenderResult](interfaces/RenderResult.md)
|
- [RenderResult](interfaces/RenderResult.md)
|
||||||
- [RunOptions](interfaces/RunOptions.md)
|
- [RunOptions](interfaces/RunOptions.md)
|
||||||
- [UnknownDiagramError](interfaces/UnknownDiagramError.md)
|
|
||||||
|
|
||||||
## Type Aliases
|
## Type Aliases
|
||||||
|
|
||||||
|
|||||||
159
docs/config/setup/mermaid/classes/UnknownDiagramError.md
Normal file
159
docs/config/setup/mermaid/classes/UnknownDiagramError.md
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
> **Warning**
|
||||||
|
>
|
||||||
|
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
|
||||||
|
>
|
||||||
|
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/config/setup/mermaid/classes/UnknownDiagramError.md](../../../../../packages/mermaid/src/docs/config/setup/mermaid/classes/UnknownDiagramError.md).
|
||||||
|
|
||||||
|
[**mermaid**](../../README.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Class: UnknownDiagramError
|
||||||
|
|
||||||
|
Defined in: [packages/mermaid/src/errors.ts:1](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/errors.ts#L1)
|
||||||
|
|
||||||
|
## Extends
|
||||||
|
|
||||||
|
- `Error`
|
||||||
|
|
||||||
|
## Constructors
|
||||||
|
|
||||||
|
### new UnknownDiagramError()
|
||||||
|
|
||||||
|
> **new UnknownDiagramError**(`message`): [`UnknownDiagramError`](UnknownDiagramError.md)
|
||||||
|
|
||||||
|
Defined in: [packages/mermaid/src/errors.ts:2](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/errors.ts#L2)
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
##### message
|
||||||
|
|
||||||
|
`string`
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
[`UnknownDiagramError`](UnknownDiagramError.md)
|
||||||
|
|
||||||
|
#### Overrides
|
||||||
|
|
||||||
|
`Error.constructor`
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
### cause?
|
||||||
|
|
||||||
|
> `optional` **cause**: `unknown`
|
||||||
|
|
||||||
|
Defined in: node_modules/.pnpm/typescript\@5.7.3/node_modules/typescript/lib/lib.es2022.error.d.ts:26
|
||||||
|
|
||||||
|
#### Inherited from
|
||||||
|
|
||||||
|
`Error.cause`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### message
|
||||||
|
|
||||||
|
> **message**: `string`
|
||||||
|
|
||||||
|
Defined in: node_modules/.pnpm/typescript\@5.7.3/node_modules/typescript/lib/lib.es5.d.ts:1077
|
||||||
|
|
||||||
|
#### Inherited from
|
||||||
|
|
||||||
|
`Error.message`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### name
|
||||||
|
|
||||||
|
> **name**: `string`
|
||||||
|
|
||||||
|
Defined in: node_modules/.pnpm/typescript\@5.7.3/node_modules/typescript/lib/lib.es5.d.ts:1076
|
||||||
|
|
||||||
|
#### Inherited from
|
||||||
|
|
||||||
|
`Error.name`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### stack?
|
||||||
|
|
||||||
|
> `optional` **stack**: `string`
|
||||||
|
|
||||||
|
Defined in: node_modules/.pnpm/typescript\@5.7.3/node_modules/typescript/lib/lib.es5.d.ts:1078
|
||||||
|
|
||||||
|
#### Inherited from
|
||||||
|
|
||||||
|
`Error.stack`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### prepareStackTrace()?
|
||||||
|
|
||||||
|
> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any`
|
||||||
|
|
||||||
|
Defined in: node_modules/.pnpm/@types+node\@22.13.5/node_modules/@types/node/globals.d.ts:143
|
||||||
|
|
||||||
|
Optional override for formatting stack traces
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
##### err
|
||||||
|
|
||||||
|
`Error`
|
||||||
|
|
||||||
|
##### stackTraces
|
||||||
|
|
||||||
|
`CallSite`\[]
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
`any`
|
||||||
|
|
||||||
|
#### See
|
||||||
|
|
||||||
|
<https://v8.dev/docs/stack-trace-api#customizing-stack-traces>
|
||||||
|
|
||||||
|
#### Inherited from
|
||||||
|
|
||||||
|
`Error.prepareStackTrace`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### stackTraceLimit
|
||||||
|
|
||||||
|
> `static` **stackTraceLimit**: `number`
|
||||||
|
|
||||||
|
Defined in: node_modules/.pnpm/@types+node\@22.13.5/node_modules/@types/node/globals.d.ts:145
|
||||||
|
|
||||||
|
#### Inherited from
|
||||||
|
|
||||||
|
`Error.stackTraceLimit`
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
|
||||||
|
### captureStackTrace()
|
||||||
|
|
||||||
|
> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void`
|
||||||
|
|
||||||
|
Defined in: node_modules/.pnpm/@types+node\@22.13.5/node_modules/@types/node/globals.d.ts:136
|
||||||
|
|
||||||
|
Create .stack property on a target object
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
##### targetObject
|
||||||
|
|
||||||
|
`object`
|
||||||
|
|
||||||
|
##### constructorOpt?
|
||||||
|
|
||||||
|
`Function`
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
`void`
|
||||||
|
|
||||||
|
#### Inherited from
|
||||||
|
|
||||||
|
`Error.captureStackTrace`
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
# Interface: ExternalDiagramDefinition
|
# Interface: ExternalDiagramDefinition
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/diagram-api/types.ts:96](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L96)
|
Defined in: [packages/mermaid/src/diagram-api/types.ts:99](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L99)
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/diagram-api/types.ts:96](https://github.com/me
|
|||||||
|
|
||||||
> **detector**: `DiagramDetector`
|
> **detector**: `DiagramDetector`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/diagram-api/types.ts:98](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L98)
|
Defined in: [packages/mermaid/src/diagram-api/types.ts:101](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L101)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ Defined in: [packages/mermaid/src/diagram-api/types.ts:98](https://github.com/me
|
|||||||
|
|
||||||
> **id**: `string`
|
> **id**: `string`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/diagram-api/types.ts:97](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L97)
|
Defined in: [packages/mermaid/src/diagram-api/types.ts:100](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L100)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -34,4 +34,4 @@ Defined in: [packages/mermaid/src/diagram-api/types.ts:97](https://github.com/me
|
|||||||
|
|
||||||
> **loader**: `DiagramLoader`
|
> **loader**: `DiagramLoader`
|
||||||
|
|
||||||
Defined in: [packages/mermaid/src/diagram-api/types.ts:99](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L99)
|
Defined in: [packages/mermaid/src/diagram-api/types.ts:102](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/diagram-api/types.ts#L102)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user