mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-03 07:36:41 +02:00
Compare commits
142 Commits
revert-347
...
develop_be
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6292bebcd3 | ||
![]() |
e1c63139b2 | ||
![]() |
edb30c9feb | ||
![]() |
66809ed972 | ||
![]() |
c66d5cb890 | ||
![]() |
fe8df78322 | ||
![]() |
7ed3c21a6d | ||
![]() |
3d0214d453 | ||
![]() |
d0e9de2744 | ||
![]() |
99264fab8a | ||
![]() |
d4519bb730 | ||
![]() |
6468c8e857 | ||
![]() |
503cbedc96 | ||
![]() |
a448409750 | ||
![]() |
b3ca701b8d | ||
![]() |
62e127f1b8 | ||
![]() |
696164c9a6 | ||
![]() |
56e1411d37 | ||
![]() |
908f5afe0f | ||
![]() |
1a46582e1e | ||
![]() |
1e71798467 | ||
![]() |
8c63d002e7 | ||
![]() |
67b1e8dbe9 | ||
![]() |
bc0be28f08 | ||
![]() |
eaa1602b1a | ||
![]() |
2a86ced835 | ||
![]() |
e8cef4aa81 | ||
![]() |
56954067ab | ||
![]() |
338ba704ba | ||
![]() |
8a489176c3 | ||
![]() |
f40f2a0b44 | ||
![]() |
d9406585c8 | ||
![]() |
9e35bf6e6f | ||
![]() |
0d0de49231 | ||
![]() |
dc53b2fde3 | ||
![]() |
98d214fd60 | ||
![]() |
adadc9ee26 | ||
![]() |
777f888892 | ||
![]() |
84dfc8ee4b | ||
![]() |
6f86047a8e | ||
![]() |
2d7a289105 | ||
![]() |
353b62aa0a | ||
![]() |
826cd67cc8 | ||
![]() |
9cb7054ff9 | ||
![]() |
6309300eb6 | ||
![]() |
0dce8f4104 | ||
![]() |
1c4eeb2d53 | ||
![]() |
d6245fdbda | ||
![]() |
aeb31fe1ae | ||
![]() |
395cc29701 | ||
![]() |
c93c7c75c9 | ||
![]() |
24ef5f9fe4 | ||
![]() |
d08882d043 | ||
![]() |
eea31a1046 | ||
![]() |
5d085fd3f6 | ||
![]() |
30e2b08028 | ||
![]() |
533da47516 | ||
![]() |
146c2e2dd9 | ||
![]() |
065756a90d | ||
![]() |
6819fc05da | ||
![]() |
bc14d56568 | ||
![]() |
01ca1cc8c7 | ||
![]() |
f69ead5e08 | ||
![]() |
f29974628b | ||
![]() |
ad2d098b52 | ||
![]() |
247061919b | ||
![]() |
0c308134a9 | ||
![]() |
3982d19e57 | ||
![]() |
55d706323d | ||
![]() |
51df0a68cc | ||
![]() |
ca053e0a11 | ||
![]() |
c260f7c20b | ||
![]() |
9f0137a34d | ||
![]() |
7bd7bcf4b8 | ||
![]() |
36ad4a847e | ||
![]() |
5791fc9a4d | ||
![]() |
d7093c4891 | ||
![]() |
506e427d56 | ||
![]() |
59f8f5f65e | ||
![]() |
3b30232e88 | ||
![]() |
e0aae3e31f | ||
![]() |
c21c026749 | ||
![]() |
b9cb7e9898 | ||
![]() |
1ea546a0a5 | ||
![]() |
ffdf268ba2 | ||
![]() |
f34008b71a | ||
![]() |
8f009ed815 | ||
![]() |
71d252f706 | ||
![]() |
135f2cc2fd | ||
![]() |
b83f18327a | ||
![]() |
d5fc319d4e | ||
![]() |
c343e4a1e3 | ||
![]() |
b72dad9c5b | ||
![]() |
2ada935842 | ||
![]() |
dab43da202 | ||
![]() |
0a944a5de1 | ||
![]() |
bb824f1147 | ||
![]() |
817a89df70 | ||
![]() |
827b3d47b7 | ||
![]() |
48d94568ce | ||
![]() |
95d92999bb | ||
![]() |
51a94e6904 | ||
![]() |
43954b9500 | ||
![]() |
636ff1c868 | ||
![]() |
7bf877d820 | ||
![]() |
e83c79a169 | ||
![]() |
5c8fda3891 | ||
![]() |
e1f399a06a | ||
![]() |
a481968ec1 | ||
![]() |
c7ec44da09 | ||
![]() |
22dbe49945 | ||
![]() |
25ed9063f2 | ||
![]() |
98506d888c | ||
![]() |
be7ab54a09 | ||
![]() |
5a2ca03fff | ||
![]() |
790922b938 | ||
![]() |
08af10d439 | ||
![]() |
811f838a2d | ||
![]() |
b4af820ed1 | ||
![]() |
ac629c91d6 | ||
![]() |
bb413e0022 | ||
![]() |
d83c9f5a70 | ||
![]() |
a7f0b2ba21 | ||
![]() |
c5bba0b153 | ||
![]() |
94868e48cb | ||
![]() |
e7ac2368c3 | ||
![]() |
bbaf2c2f20 | ||
![]() |
ecd175dd38 | ||
![]() |
5434cfc89d | ||
![]() |
407927c8ec | ||
![]() |
5905787bea | ||
![]() |
a61d95a005 | ||
![]() |
18201d326c | ||
![]() |
c7ba253e7c | ||
![]() |
f27dff2186 | ||
![]() |
0ee0862fae | ||
![]() |
d2df7173e3 | ||
![]() |
766e111ac1 | ||
![]() |
004ea9872b | ||
![]() |
bf4607cf08 | ||
![]() |
e06a7587ac | ||
![]() |
904eccc4fa |
@@ -1,20 +0,0 @@
|
||||
const { esmBuild, esmCoreBuild, iifeBuild } = require('./util.cjs');
|
||||
const { build } = require('esbuild');
|
||||
|
||||
const handler = (e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
};
|
||||
const watch = process.argv.includes('--watch');
|
||||
|
||||
// mermaid.js
|
||||
build(iifeBuild({ minify: false, watch })).catch(handler);
|
||||
// mermaid.esm.mjs
|
||||
build(esmBuild({ minify: false, watch })).catch(handler);
|
||||
|
||||
// mermaid.min.js
|
||||
build(esmBuild()).catch(handler);
|
||||
// mermaid.esm.min.mjs
|
||||
build(iifeBuild()).catch(handler);
|
||||
// mermaid.core.mjs (node_modules unbundled)
|
||||
build(esmCoreBuild()).catch(handler);
|
@@ -1,53 +0,0 @@
|
||||
const esbuild = require('esbuild');
|
||||
const http = require('http');
|
||||
const path = require('path');
|
||||
const { iifeBuild } = require('./util.cjs');
|
||||
|
||||
// Start esbuild's server on a random local port
|
||||
esbuild
|
||||
.serve(
|
||||
{
|
||||
servedir: path.join(__dirname, '..'),
|
||||
},
|
||||
iifeBuild({ minify: false })
|
||||
)
|
||||
.then((result) => {
|
||||
// The result tells us where esbuild's local server is
|
||||
const { host, port } = result;
|
||||
|
||||
// Then start a proxy server on port 3000
|
||||
http
|
||||
.createServer((req, res) => {
|
||||
if (req.url.includes('mermaid.js')) {
|
||||
req.url = '/dist/mermaid.js';
|
||||
}
|
||||
const options = {
|
||||
hostname: host,
|
||||
port: port,
|
||||
path: req.url,
|
||||
method: req.method,
|
||||
headers: req.headers,
|
||||
};
|
||||
|
||||
// Forward each incoming request to esbuild
|
||||
const proxyReq = http.request(options, (proxyRes) => {
|
||||
// If esbuild returns "not found", send a custom 404 page
|
||||
console.error('pp', req.url);
|
||||
if (proxyRes.statusCode === 404) {
|
||||
if (!req.url.endsWith('.html')) {
|
||||
res.writeHead(404, { 'Content-Type': 'text/html' });
|
||||
res.end('<h1>A custom 404 page</h1>');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, forward the response from esbuild to the client
|
||||
res.writeHead(proxyRes.statusCode, proxyRes.headers);
|
||||
proxyRes.pipe(res, { end: true });
|
||||
});
|
||||
|
||||
// Forward the body of the request to esbuild
|
||||
req.pipe(proxyReq, { end: true });
|
||||
})
|
||||
.listen(3000);
|
||||
});
|
@@ -1,100 +0,0 @@
|
||||
const { Generator } = require('jison');
|
||||
const fs = require('fs');
|
||||
const { dependencies } = require('../package.json');
|
||||
|
||||
/** @typedef {import('esbuild').BuildOptions} Options */
|
||||
|
||||
/**
|
||||
* @param {Options} override
|
||||
* @returns {Options}
|
||||
*/
|
||||
const buildOptions = (override = {}) => {
|
||||
return {
|
||||
bundle: true,
|
||||
minify: true,
|
||||
keepNames: true,
|
||||
banner: { js: '"use strict";' },
|
||||
globalName: 'mermaid',
|
||||
platform: 'browser',
|
||||
tsconfig: 'tsconfig.json',
|
||||
resolveExtensions: ['.ts', '.js', '.json', '.jison'],
|
||||
external: ['require', 'fs', 'path'],
|
||||
outdir: 'dist',
|
||||
plugins: [jisonPlugin],
|
||||
sourcemap: 'external',
|
||||
...override,
|
||||
};
|
||||
};
|
||||
|
||||
const getOutFiles = (extension) => {
|
||||
return {
|
||||
[`mermaid${extension}`]: 'src/mermaid.ts',
|
||||
[`diagramAPI${extension}`]: 'src/diagram-api/diagramAPI.ts',
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Build options for mermaid.esm.* build.
|
||||
*
|
||||
* For ESM browser use.
|
||||
*
|
||||
* @param {Options} override - Override options.
|
||||
* @returns {Options} ESBuild build options.
|
||||
*/
|
||||
exports.esmBuild = (override = { minify: true }) => {
|
||||
return buildOptions({
|
||||
format: 'esm',
|
||||
entryPoints: getOutFiles(`.esm${override.minify ? '.min' : ''}`),
|
||||
outExtension: { '.js': '.mjs' },
|
||||
...override,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Build options for mermaid.core.* build.
|
||||
*
|
||||
* This build does not bundle `./node_modules/`, as it is designed to be used with
|
||||
* Webpack/ESBuild/Vite to use mermaid inside an app/website.
|
||||
*
|
||||
* @param {Options} override - Override options.
|
||||
* @returns {Options} ESBuild build options.
|
||||
*/
|
||||
exports.esmCoreBuild = (override) => {
|
||||
return buildOptions({
|
||||
format: 'esm',
|
||||
entryPoints: getOutFiles(`.core`),
|
||||
outExtension: { '.js': '.mjs' },
|
||||
external: ['require', 'fs', 'path', ...Object.keys(dependencies)],
|
||||
platform: 'neutral',
|
||||
...override,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Build options for mermaid.js build.
|
||||
*
|
||||
* For IIFE browser use (where ESM is not yet supported).
|
||||
*
|
||||
* @param {Options} override - Override options.
|
||||
* @returns {Options} ESBuild build options.
|
||||
*/
|
||||
exports.iifeBuild = (override = { minify: true }) => {
|
||||
return buildOptions({
|
||||
entryPoints: getOutFiles(override.minify ? '.min' : ''),
|
||||
format: 'iife',
|
||||
...override,
|
||||
});
|
||||
};
|
||||
|
||||
const jisonPlugin = {
|
||||
name: 'jison',
|
||||
setup(build) {
|
||||
build.onLoad({ filter: /\.jison$/ }, async (args) => {
|
||||
// Load the file from the file system
|
||||
const source = await fs.promises.readFile(args.path, 'utf8');
|
||||
const contents = new Generator(source, { 'token-stack': true }).generate({
|
||||
moduleMain: '() => {}', // disable moduleMain (default one requires Node.JS modules)
|
||||
});
|
||||
return { contents, warnings: [] };
|
||||
});
|
||||
},
|
||||
};
|
@@ -3,3 +3,4 @@ dist/**
|
||||
docs/Setup.md
|
||||
cypress.config.js
|
||||
cypress/plugins/index.js
|
||||
coverage
|
73
.github/workflows/e2e-applitools.yml
vendored
Normal file
73
.github/workflows/e2e-applitools.yml
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
name: E2E (Applitools)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
# Because we want to limit Applitools usage, so we only want to start this
|
||||
# workflow on rare occasions/manually.
|
||||
inputs:
|
||||
parent_branch:
|
||||
required: true
|
||||
type: string
|
||||
default: master
|
||||
description: 'Parent branch to use for PRs'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
# on PRs from forks, this secret will always be empty, for security reasons
|
||||
USE_APPLI: ${{ secrets.APPLITOOLS_API_KEY && 'true' || '' }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- if: ${{ ! env.USE_APPLI }}
|
||||
name: Warn if not using Applitools
|
||||
run: |
|
||||
echo "::error,title=Not using Applitols::APPLITOOLS_API_KEY is empty, disabling Applitools for this run."
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: yarn
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
|
||||
- name: Run Build
|
||||
run: yarn build
|
||||
|
||||
- if: ${{ env.USE_APPLI }}
|
||||
name: Notify applitools of new batch
|
||||
# Copied from docs https://applitools.com/docs/topics/integrations/github-integration-ci-setup.html
|
||||
run: curl -L -d '' -X POST "$APPLITOOLS_SERVER_URL/api/externals/github/push?apiKey=$APPLITOOLS_API_KEY&CommitSha=$GITHUB_SHA&BranchName=${APPLITOOLS_BRANCH}$&ParentBranchName=$APPLITOOLS_PARENT_BRANCH"
|
||||
env:
|
||||
# e.g. mermaid-js/mermaid/my-branch
|
||||
APPLITOOLS_BRANCH: ${{ github.repository }}/${{ github.ref_name }}
|
||||
APPLITOOLS_PARENT_BRANCH: ${{ github.inputs.parent_branch }}
|
||||
APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}
|
||||
APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com'
|
||||
|
||||
- name: Run E2E Tests
|
||||
run: yarn e2e
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
# Mermaid applitools.config.js uses this to pick batch name.
|
||||
APPLI_BRANCH: ${{ github.ref_name }}
|
||||
APPLITOOLS_BATCH_ID: ${{ github.sha }}
|
||||
# e.g. mermaid-js/mermaid/my-branch
|
||||
APPLITOOLS_BRANCH: ${{ github.repository }}/${{ github.ref_name }}
|
||||
APPLITOOLS_PARENT_BRANCH: ${{ github.inputs.parent_branch }}
|
||||
APPLITOOLS_API_KEY: ${{ secrets.APPLITOOLS_API_KEY }}
|
||||
APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com'
|
44
.github/workflows/e2e.yml
vendored
44
.github/workflows/e2e.yml
vendored
@@ -9,30 +9,44 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
containers: [1, 2, 3, 4]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/cache@v3
|
||||
id: yarn-and-build-cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/Cypress
|
||||
build
|
||||
node_modules
|
||||
key: ${{ runner.os }}-node_modules-build-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node_modules-build-
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: yarn
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install Yarn
|
||||
run: npm i yarn --global
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
# Install NPM dependencies, cache them correctly
|
||||
# and run all Cypress tests
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v3
|
||||
# If CYPRESS_RECORD_KEY is set, run in parallel on all containers
|
||||
# Otherwise (e.g. if running from fork), we run on a single container only
|
||||
if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }}
|
||||
with:
|
||||
start: yarn dev
|
||||
wait-on: 'http://localhost:9000'
|
||||
# Disable recording if we don't have an API key
|
||||
# e.g. if this action was run from a fork
|
||||
record: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
|
||||
parallel: ${{ secrets.CYPRESS_RECORD_KEY != '' }}
|
||||
headless: true
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
|
||||
- name: Run Build
|
||||
run: yarn build
|
||||
|
||||
- name: Run E2E Tests
|
||||
run: yarn e2e
|
||||
env:
|
||||
CYPRESS_CACHE_FOLDER: .cache/Cypress
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
|
15
.github/workflows/lint.yml
vendored
15
.github/workflows/lint.yml
vendored
@@ -40,18 +40,3 @@ jobs:
|
||||
|
||||
- name: Verify Docs
|
||||
run: yarn docs:verify
|
||||
|
||||
- name: Check no `console.log()` in .jison files
|
||||
# ESLint can't parse .jison files directly
|
||||
# In the future, it might be worth making a `eslint-plugin-jison`, so
|
||||
# that this will be built into the `yarn lint` command.
|
||||
run: |
|
||||
shopt -s globstar
|
||||
mkdir -p tmp/
|
||||
for jison_file in src/**/*.jison; do
|
||||
outfile="tmp/$(basename -- "$jison_file" .jison)-jison.js"
|
||||
echo "Converting $jison_file to $outfile"
|
||||
# default module-type (CJS) always adds a console.log()
|
||||
yarn jison "$jison_file" --outfile "$outfile" --module-type "amd"
|
||||
done
|
||||
yarn eslint --no-eslintrc --rule no-console:error --parser "@babel/eslint-parser" "./tmp/*-jison.js"
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@@ -12,7 +12,11 @@ token
|
||||
|
||||
package-lock.json
|
||||
|
||||
.vscode/
|
||||
# ignore files in /.vscode/ except for launch.json and extensions.json
|
||||
/.vscode/**
|
||||
!/.vscode/launch.json
|
||||
!/.vscode/extensions.json
|
||||
|
||||
cypress/platform/current.html
|
||||
cypress/platform/experimental.html
|
||||
local/
|
||||
|
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"src/docs/**": ["yarn docs:build --git"],
|
||||
"src/docs.mts": ["yarn docs:build --git"],
|
||||
"*.{ts,js,json,html,md,mts}": ["eslint --fix", "prettier --write"]
|
||||
"*.{ts,js,json,html,md,mts}": ["eslint --fix", "prettier --write"],
|
||||
"*.jison": ["yarn lint:jison"]
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
dist
|
||||
cypress/platform/xss3.html
|
||||
.cache
|
||||
.cache
|
||||
coverage
|
89
.vite/build.ts
Normal file
89
.vite/build.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import { build, InlineConfig } from 'vite';
|
||||
import { resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import jisonPlugin from './jisonPlugin.js';
|
||||
import pkg from '../package.json' assert { type: 'json' };
|
||||
type OutputOptions = Exclude<
|
||||
Exclude<InlineConfig['build'], undefined>['rollupOptions'],
|
||||
undefined
|
||||
>['output'];
|
||||
|
||||
const { dependencies } = pkg;
|
||||
const watch = process.argv.includes('--watch');
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
interface BuildOptions {
|
||||
minify: boolean | 'esbuild';
|
||||
core?: boolean;
|
||||
watch?: boolean;
|
||||
}
|
||||
|
||||
export const getBuildConfig = ({ minify, core, watch }: BuildOptions): InlineConfig => {
|
||||
const external = ['require', 'fs', 'path'];
|
||||
let output: OutputOptions = [
|
||||
{
|
||||
name: 'mermaid',
|
||||
format: 'esm',
|
||||
sourcemap: true,
|
||||
entryFileNames: `[name].esm${minify ? '.min' : ''}.mjs`,
|
||||
},
|
||||
{
|
||||
name: 'mermaid',
|
||||
format: 'umd',
|
||||
sourcemap: true,
|
||||
entryFileNames: `[name]${minify ? '.min' : ''}.js`,
|
||||
},
|
||||
];
|
||||
|
||||
if (core) {
|
||||
// Core build is used to generate file without bundled dependencies.
|
||||
// This is used by downstream projects to bundle dependencies themselves.
|
||||
external.push(...Object.keys(dependencies));
|
||||
// This needs to be an array. Otherwise vite will build esm & umd with same name and overwrite esm with umd.
|
||||
output = [
|
||||
{
|
||||
format: 'esm',
|
||||
sourcemap: true,
|
||||
entryFileNames: `[name].core.mjs`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const config: InlineConfig = {
|
||||
configFile: false,
|
||||
build: {
|
||||
emptyOutDir: false,
|
||||
lib: {
|
||||
entry: resolve(__dirname, '../src/mermaid.ts'),
|
||||
name: 'mermaid',
|
||||
// the proper extensions will be added
|
||||
fileName: 'mermaid',
|
||||
},
|
||||
minify,
|
||||
rollupOptions: {
|
||||
external,
|
||||
output,
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.jison', '.js', '.ts', '.json'],
|
||||
},
|
||||
plugins: [jisonPlugin()],
|
||||
};
|
||||
|
||||
if (watch && config.build) {
|
||||
config.build.watch = {
|
||||
include: 'src/**',
|
||||
};
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
if (watch) {
|
||||
build(getBuildConfig({ minify: false, watch }));
|
||||
} else {
|
||||
build(getBuildConfig({ minify: false }));
|
||||
build(getBuildConfig({ minify: 'esbuild' }));
|
||||
build(getBuildConfig({ minify: false, core: true }));
|
||||
}
|
17
.vite/jisonPlugin.ts
Normal file
17
.vite/jisonPlugin.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { transformJison } from './jisonTransformer.js';
|
||||
const fileRegex = /\.(jison)$/;
|
||||
|
||||
export default function jison() {
|
||||
return {
|
||||
name: 'jison',
|
||||
|
||||
transform(src: string, id: string) {
|
||||
if (fileRegex.test(id)) {
|
||||
return {
|
||||
code: transformJison(src),
|
||||
map: null, // provide source map if available
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
17
.vite/jisonTransformer.ts
Normal file
17
.vite/jisonTransformer.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// @ts-ignore No typings for jison
|
||||
import jison from 'jison';
|
||||
|
||||
export const transformJison = (src: string): string => {
|
||||
// @ts-ignore No typings for jison
|
||||
const parser = new jison.Generator(src, {
|
||||
moduleType: 'js',
|
||||
'token-stack': true,
|
||||
});
|
||||
const source = parser.generate({ moduleMain: '() => {}' });
|
||||
const exporter = `
|
||||
parser.parser = parser;
|
||||
export { parser };
|
||||
export default parser;
|
||||
`;
|
||||
return `${source} ${exporter}`;
|
||||
};
|
26
.vite/server.ts
Normal file
26
.vite/server.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import express from 'express';
|
||||
import { createServer as createViteServer } from 'vite';
|
||||
// import { getBuildConfig } from './build';
|
||||
|
||||
async function createServer() {
|
||||
const app = express();
|
||||
|
||||
// Create Vite server in middleware mode
|
||||
const vite = await createViteServer({
|
||||
configFile: './vite.config.ts',
|
||||
server: { middlewareMode: true },
|
||||
appType: 'custom', // don't include Vite's default HTML handling middlewares
|
||||
});
|
||||
|
||||
app.use(vite.middlewares);
|
||||
app.use(express.static('dist'));
|
||||
app.use(express.static('demos'));
|
||||
app.use(express.static('cypress/platform'));
|
||||
|
||||
app.listen(9000, () => {
|
||||
console.log(`Listening on http://localhost:9000`);
|
||||
});
|
||||
}
|
||||
|
||||
// build(getBuildConfig({ minify: false, watch: true }));
|
||||
createServer();
|
6
.vite/tsconfig.json
Normal file
6
.vite/tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "ES2022"
|
||||
}
|
||||
}
|
8
.vscode/extensions.json
vendored
Normal file
8
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"zixuanchen.vitest-explorer",
|
||||
"luniclynx.bison"
|
||||
]
|
||||
}
|
17
.vscode/launch.json
vendored
Normal file
17
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Debug Current Test File",
|
||||
"autoAttachChildProcesses": true,
|
||||
"skipFiles": ["<node_internals>/**", "**/node_modules/**"],
|
||||
"program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
|
||||
"args": ["run", "${relativeFile}"],
|
||||
"smartStep": true,
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
const { Generator } = require('jison');
|
||||
const validate = require('schema-utils');
|
||||
|
||||
const schema = {
|
||||
title: 'Jison Parser options',
|
||||
type: 'object',
|
||||
properties: {
|
||||
'token-stack': {
|
||||
type: 'boolean',
|
||||
},
|
||||
debug: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
};
|
||||
|
||||
module.exports = function jisonLoader(source) {
|
||||
const options = this.getOptions();
|
||||
(validate.validate || validate)(schema, options, {
|
||||
name: 'Jison Loader',
|
||||
baseDataPath: 'options',
|
||||
});
|
||||
return new Generator(source, options).generate();
|
||||
};
|
@@ -1,46 +0,0 @@
|
||||
import { merge, mergeWithCustomize, customizeObject } from 'webpack-merge';
|
||||
import nodeExternals from 'webpack-node-externals';
|
||||
import baseConfig from './webpack.config.base';
|
||||
|
||||
export default (_env, args) => {
|
||||
return [
|
||||
// non-minified
|
||||
merge(baseConfig, {
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
}),
|
||||
// core [To be used by webpack/esbuild/vite etc to bundle mermaid]
|
||||
merge(baseConfig, {
|
||||
externals: [nodeExternals()],
|
||||
output: {
|
||||
filename: '[name].core.js',
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
},
|
||||
}),
|
||||
// umd
|
||||
merge(baseConfig, {
|
||||
output: {
|
||||
filename: '[name].min.js',
|
||||
},
|
||||
}),
|
||||
// esm
|
||||
mergeWithCustomize({
|
||||
customizeObject: customizeObject({
|
||||
'output.library': 'replace',
|
||||
}),
|
||||
})(baseConfig, {
|
||||
experiments: {
|
||||
outputModule: true,
|
||||
},
|
||||
output: {
|
||||
library: {
|
||||
type: 'module',
|
||||
},
|
||||
filename: '[name].esm.min.mjs',
|
||||
},
|
||||
}),
|
||||
];
|
||||
};
|
@@ -1,71 +0,0 @@
|
||||
import path from 'path';
|
||||
const esbuild = require('esbuild');
|
||||
const { ESBuildMinifyPlugin } = require('esbuild-loader');
|
||||
export const resolveRoot = (...relativePath) => path.resolve(__dirname, '..', ...relativePath);
|
||||
|
||||
export default {
|
||||
amd: false, // https://github.com/lodash/lodash/issues/3052
|
||||
target: 'web',
|
||||
entry: {
|
||||
mermaid: './src/mermaid',
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.wasm', '.mjs', '.js', '.ts', '.json', '.jison'],
|
||||
fallback: {
|
||||
fs: false, // jison generated code requires 'fs'
|
||||
path: require.resolve('path-browserify'),
|
||||
},
|
||||
},
|
||||
output: {
|
||||
path: resolveRoot('./dist'),
|
||||
filename: '[name].js',
|
||||
library: {
|
||||
name: 'mermaid',
|
||||
type: 'umd',
|
||||
export: 'default',
|
||||
},
|
||||
globalObject: 'typeof self !== "undefined" ? self : this',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
include: [resolveRoot('./src'), resolveRoot('./node_modules/dagre-d3-renderer/lib')],
|
||||
use: {
|
||||
loader: 'esbuild-loader',
|
||||
options: {
|
||||
implementation: esbuild,
|
||||
target: 'es2015',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// load scss to string
|
||||
test: /\.scss$/,
|
||||
use: ['css-to-string-loader', 'css-loader', 'sass-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.jison$/,
|
||||
use: {
|
||||
loader: path.resolve(__dirname, './loaders/jison.js'),
|
||||
options: {
|
||||
'token-stack': true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
devtool: 'source-map',
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new ESBuildMinifyPlugin({
|
||||
target: 'es2015',
|
||||
}),
|
||||
],
|
||||
},
|
||||
};
|
@@ -1,26 +0,0 @@
|
||||
import baseConfig, { resolveRoot } from './webpack.config.base';
|
||||
import { merge } from 'webpack-merge';
|
||||
|
||||
export default merge(baseConfig, {
|
||||
mode: 'development',
|
||||
entry: {
|
||||
mermaid: './src/mermaid',
|
||||
e2e: './cypress/platform/viewer.js',
|
||||
'bundle-test': './cypress/platform/bundle-test.js',
|
||||
},
|
||||
output: {
|
||||
globalObject: 'window',
|
||||
},
|
||||
devServer: {
|
||||
compress: true,
|
||||
port: 9000,
|
||||
static: [
|
||||
{ directory: resolveRoot('cypress', 'platform') },
|
||||
{ directory: resolveRoot('dist') },
|
||||
{ directory: resolveRoot('demos') },
|
||||
],
|
||||
},
|
||||
externals: {
|
||||
mermaid: 'mermaid',
|
||||
},
|
||||
});
|
@@ -1,3 +0,0 @@
|
||||
export const curveBasis = 'basis';
|
||||
export const curveLinear = 'linear';
|
||||
export const curveCardinal = 'cardinal';
|
@@ -1,4 +1,7 @@
|
||||
let NewD3 = function () {
|
||||
// @ts-nocheck TODO: Fix TS
|
||||
import { vi } from 'vitest';
|
||||
|
||||
const NewD3 = function () {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -56,9 +59,9 @@ export const MockD3 = (name, parent) => {
|
||||
children.push(mockElem);
|
||||
return mockElem;
|
||||
};
|
||||
elem.lower = jest.fn(() => elem);
|
||||
elem.attr = jest.fn(() => elem);
|
||||
elem.text = jest.fn(() => elem);
|
||||
elem.style = jest.fn(() => elem);
|
||||
elem.lower = vi.fn(() => elem);
|
||||
elem.attr = vi.fn(() => elem);
|
||||
elem.text = vi.fn(() => elem);
|
||||
elem.style = vi.fn(() => elem);
|
||||
return elem;
|
||||
};
|
3
__mocks__/dagre-d3.ts
Normal file
3
__mocks__/dagre-d3.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { vi } from 'vitest';
|
||||
|
||||
// export const render = vi.fn();
|
3
__mocks__/entity-decode/browser.ts
Normal file
3
__mocks__/entity-decode/browser.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = function (txt: string) {
|
||||
return txt;
|
||||
};
|
@@ -1,10 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: 'defaults, ie >= 11, current node',
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
@@ -4,6 +4,7 @@ const { defineConfig } = require('cypress');
|
||||
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');
|
||||
|
||||
module.exports = defineConfig({
|
||||
projectId: 'n2sma2',
|
||||
e2e: {
|
||||
specPattern: 'cypress/integration/**/*.{js,jsx,ts,tsx}',
|
||||
setupNodeEvents(on, config) {
|
@@ -1,4 +1,6 @@
|
||||
import { Base64 } from 'js-base64';
|
||||
const utf8ToB64 = (str) => {
|
||||
return window.btoa(unescape(encodeURIComponent(str)));
|
||||
};
|
||||
|
||||
export const mermaidUrl = (graphStr, options, api) => {
|
||||
const obj = {
|
||||
@@ -6,7 +8,7 @@ export const mermaidUrl = (graphStr, options, api) => {
|
||||
mermaid: options,
|
||||
};
|
||||
const objStr = JSON.stringify(obj);
|
||||
let url = 'http://localhost:9000/e2e.html?graph=' + Base64.encodeURI(objStr);
|
||||
let url = 'http://localhost:9000/e2e.html?graph=' + utf8ToB64(objStr);
|
||||
if (api) {
|
||||
url = 'http://localhost:9000/xss.html?graph=' + graphStr;
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ describe('XSS', () => {
|
||||
|
||||
it('should not allow tags in the css', () => {
|
||||
const str =
|
||||
'eyJjb2RlIjoiJSV7aW5pdDogeyAnZm9udEZhbWlseSc6ICdcXFwiPjwvc3R5bGU-PGltZyBzcmM9eCBvbmVycm9yPXhzc0F0dGFjaygpPid9IH0lJVxuZ3JhcGggTFJcbiAgICAgQSAtLT4gQiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9';
|
||||
'eyJjb2RlIjoiJSV7aW5pdDogeyAnZm9udEZhbWlseSc6ICdcXFwiPjwvc3R5bGU+PGltZyBzcmM9eCBvbmVycm9yPXhzc0F0dGFjaygpPid9IH0lJVxuZ3JhcGggTFJcbiAgICAgQSAtLT4gQiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9';
|
||||
|
||||
const url = mermaidUrl(
|
||||
str,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import mermaid from '../../dist/mermaid.core';
|
||||
import mermaid from '../../src/mermaid';
|
||||
|
||||
let code = `flowchart LR
|
||||
Power_Supply --> Transmitter_A
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- <meta charset="iso-8859-15"/> -->
|
||||
<script src="/e2e.js"></script>
|
||||
<script src="./viewer.js" type="module" />
|
||||
<!-- <link href="https://fonts.googleapis.com/css?family=Mansalva&display=swap" rel="stylesheet" /> -->
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"
|
||||
@@ -37,7 +37,7 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="./mermaid.js"></script>
|
||||
<!-- <script src="./mermaid.js"></script> -->
|
||||
<script>
|
||||
// Notice startOnLoad=false
|
||||
// This prevents default handling in mermaid from render before the e2e logic is applied
|
||||
|
@@ -38,13 +38,17 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
flowchart LR
|
||||
a ---
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 50%">
|
||||
flowchart LR
|
||||
a2 ---
|
||||
subgraph one
|
||||
direction LR
|
||||
A[myClass1] --> B[default]
|
||||
subgraph two
|
||||
direction BT
|
||||
C[myClass2] --> D[default]
|
||||
end
|
||||
end
|
||||
|
||||
</pre>
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
flowchart LR
|
||||
@@ -79,7 +83,7 @@ flowchart TD
|
||||
end
|
||||
end
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 50%">
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
flowchart TD
|
||||
|
||||
release-branch[Create Release Branch]:::relClass
|
||||
@@ -131,7 +135,7 @@ flowchart TD
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 50%">
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
sequenceDiagram
|
||||
title: My Sequence Diagram Title
|
||||
accTitle: My Acc Sequence Diagram
|
||||
@@ -141,14 +145,14 @@ flowchart TD
|
||||
John-->>Alice: Great!
|
||||
Alice-)John: See you later!
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 50%">
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
graph TD
|
||||
A -->|000| B
|
||||
B -->|111| C
|
||||
|
||||
linkStyle 1 stroke:#ff3,stroke-width:4px,color:red;
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
journey
|
||||
accTitle: My User Journey Diagram
|
||||
accDescr: My User Journey Diagram Description
|
||||
@@ -162,10 +166,10 @@ graph TD
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 5: Me
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
info
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
requirementDiagram
|
||||
accTitle: My req Diagram
|
||||
accDescr: My req Diagram Description
|
||||
@@ -206,7 +210,7 @@ requirementDiagram
|
||||
test_req - contains -> test_req3
|
||||
test_req <- copies - test_entity2
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Adding GANTT diagram functionality to mermaid
|
||||
@@ -238,7 +242,7 @@ gantt
|
||||
Add gantt diagram to demo page :20h
|
||||
Add another diagram to demo page :48h
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
stateDiagram
|
||||
state Active {
|
||||
Idle
|
||||
@@ -266,7 +270,7 @@ stateDiagram
|
||||
end
|
||||
B ->> A: Return
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
classDiagram
|
||||
accTitle: My class diagram
|
||||
accDescr: My class diagram Description
|
||||
@@ -291,7 +295,7 @@ class Class10 {
|
||||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
gitGraph
|
||||
commit id: "ZERO"
|
||||
branch develop
|
||||
@@ -320,7 +324,7 @@ flowchart TD
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
classDiagram
|
||||
Animal "1" <|-- Duck
|
||||
Animal <|-- Fish
|
||||
@@ -343,7 +347,7 @@ flowchart TD
|
||||
+run()
|
||||
}
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
erDiagram
|
||||
CAR ||--o{ NAMED-DRIVER : allows
|
||||
CAR {
|
||||
|
@@ -1,16 +1,20 @@
|
||||
import { Base64 } from 'js-base64';
|
||||
import mermaid2 from '../../src/mermaid';
|
||||
|
||||
function b64ToUtf8(str) {
|
||||
return decodeURIComponent(escape(window.atob(str)));
|
||||
}
|
||||
|
||||
/**
|
||||
* ##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 page.
|
||||
* configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the
|
||||
* page.
|
||||
*/
|
||||
const contentLoaded = function () {
|
||||
let pos = document.location.href.indexOf('?graph=');
|
||||
if (pos > 0) {
|
||||
pos = pos + 7;
|
||||
const graphBase64 = document.location.href.substr(pos);
|
||||
const graphObj = JSON.parse(Base64.decode(graphBase64));
|
||||
const graphObj = JSON.parse(b64ToUtf8(graphBase64));
|
||||
if (graphObj.mermaid && graphObj.mermaid.theme === 'dark') {
|
||||
document.body.style.background = '#3f3f3f';
|
||||
}
|
||||
@@ -32,8 +36,8 @@ const contentLoaded = function () {
|
||||
document.getElementsByTagName('body')[0].appendChild(div);
|
||||
}
|
||||
|
||||
global.mermaid.initialize(graphObj.mermaid);
|
||||
global.mermaid.init();
|
||||
mermaid2.initialize(graphObj.mermaid);
|
||||
mermaid2.init();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -66,7 +70,7 @@ const contentLoadedApi = function () {
|
||||
if (pos > 0) {
|
||||
pos = pos + 7;
|
||||
const graphBase64 = document.location.href.substr(pos);
|
||||
const graphObj = JSON.parse(Base64.decode(graphBase64));
|
||||
const graphObj = JSON.parse(b64ToUtf8(graphBase64));
|
||||
// const graph = 'hello'
|
||||
if (Array.isArray(graphObj.code)) {
|
||||
const numCodes = graphObj.code.length;
|
||||
|
@@ -12,6 +12,8 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="graph-to-be"></div>
|
||||
<script src="./bundle-test.js" charset="utf-8"></script>
|
||||
<script type="module" charset="utf-8">
|
||||
import './bundle-test.js';
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="/e2e.js"></script>
|
||||
<script src="./viewer.js" type="module"></script>
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
.malware {
|
||||
|
299
demos/c4context.html
Normal file
299
demos/c4context.html
Normal file
@@ -0,0 +1,299 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>C4 Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||
<style>
|
||||
div.mermaid {
|
||||
/* font-family: 'trebuchet ms', verdana, arial; */
|
||||
/*font-family: 'Courier New', Courier, monospace !important;*/
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
C4Context
|
||||
accTitle: C4 context demo
|
||||
accDescr: Many large C4 diagrams
|
||||
|
||||
title System Context diagram for Internet Banking System
|
||||
|
||||
Enterprise_Boundary(b0, "BankBoundary0") {
|
||||
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
|
||||
Person(customerB, "Banking Customer B")
|
||||
Person_Ext(customerC, "Banking Customer C", "desc")
|
||||
|
||||
Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")
|
||||
|
||||
System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
|
||||
|
||||
Enterprise_Boundary(b1, "BankBoundary") {
|
||||
|
||||
SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
|
||||
|
||||
System_Boundary(b2, "BankBoundary2") {
|
||||
System(SystemA, "Banking System A")
|
||||
System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts. next line.")
|
||||
}
|
||||
|
||||
System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
|
||||
SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")
|
||||
|
||||
Boundary(b3, "BankBoundary3", "boundary") {
|
||||
SystemQueue(SystemF, "Banking System F Queue", "A system of the bank.")
|
||||
SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BiRel(customerA, SystemAA, "Uses")
|
||||
BiRel(SystemAA, SystemE, "Uses")
|
||||
Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
|
||||
Rel(SystemC, customerA, "Sends e-mails to")
|
||||
|
||||
UpdateElementStyle(customerA, $fontColor="red", $bgColor="grey", $borderColor="red")
|
||||
UpdateRelStyle(customerA, SystemAA, $textColor="blue", $lineColor="blue", $offsetX="5")
|
||||
UpdateRelStyle(SystemAA, SystemE, $textColor="blue", $lineColor="blue", $offsetY="-10")
|
||||
UpdateRelStyle(SystemAA, SystemC, $textColor="blue", $lineColor="blue", $offsetY="-40", $offsetX="-50")
|
||||
UpdateRelStyle(SystemC, customerA, $textColor="red", $lineColor="red", $offsetX="-50", $offsetY="20")
|
||||
|
||||
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
|
||||
</pre>
|
||||
|
||||
<pre class="mermaid">
|
||||
C4Container
|
||||
title Container diagram for Internet Banking System
|
||||
|
||||
System_Ext(email_system, "E-Mail System", "The internal Microsoft Exchange system", $tags="v1.0")
|
||||
Person(customer, Customer, "A customer of the bank, with personal bank accounts", $tags="v1.0")
|
||||
|
||||
Container_Boundary(c1, "Internet Banking") {
|
||||
Container(spa, "Single-Page App", "JavaScript, Angular", "Provides all the Internet banking functionality to customers via their web browser")
|
||||
Container_Ext(mobile_app, "Mobile App", "C#, Xamarin", "Provides a limited subset of the Internet banking functionality to customers via their mobile device")
|
||||
Container(web_app, "Web Application", "Java, Spring MVC", "Delivers the static content and the Internet banking SPA")
|
||||
ContainerDb(database, "Database", "SQL Database", "Stores user registration information, hashed auth credentials, access logs, etc.")
|
||||
ContainerDb_Ext(backend_api, "API Application", "Java, Docker Container", "Provides Internet banking functionality via API")
|
||||
|
||||
}
|
||||
|
||||
System_Ext(banking_system, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
|
||||
|
||||
Rel(customer, web_app, "Uses", "HTTPS")
|
||||
UpdateRelStyle(customer, web_app, $offsetY="60", $offsetX="90")
|
||||
Rel(customer, spa, "Uses", "HTTPS")
|
||||
UpdateRelStyle(customer, spa, $offsetY="-40")
|
||||
Rel(customer, mobile_app, "Uses")
|
||||
UpdateRelStyle(customer, mobile_app, $offsetY="-30")
|
||||
|
||||
Rel(web_app, spa, "Delivers")
|
||||
UpdateRelStyle(web_app, spa, $offsetX="130")
|
||||
Rel(spa, backend_api, "Uses", "async, JSON/HTTPS")
|
||||
Rel(mobile_app, backend_api, "Uses", "async, JSON/HTTPS")
|
||||
Rel_Back(database, backend_api, "Reads from and writes to", "sync, JDBC")
|
||||
|
||||
Rel(email_system, customer, "Sends e-mails to")
|
||||
UpdateRelStyle(email_system, customer, $offsetX="-45")
|
||||
Rel(backend_api, email_system, "Sends e-mails using", "sync, SMTP")
|
||||
UpdateRelStyle(backend_api, email_system, $offsetY="-60")
|
||||
Rel(backend_api, banking_system, "Uses", "sync/async, XML/HTTPS")
|
||||
UpdateRelStyle(backend_api, banking_system, $offsetY="-50", $offsetX="-140")
|
||||
</pre>
|
||||
|
||||
<pre class="mermaid">
|
||||
C4Component
|
||||
title Component diagram for Internet Banking System - API Application
|
||||
|
||||
Container(spa, "Single Page Application", "javascript and angular", "Provides all the internet banking functionality to customers via their web browser.")
|
||||
Container(ma, "Mobile App", "Xamarin", "Provides a limited subset ot the internet banking functionality to customers via their mobile mobile device.")
|
||||
ContainerDb(db, "Database", "Relational Database Schema", "Stores user registration information, hashed authentication credentials, access logs, etc.")
|
||||
System_Ext(mbs, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
|
||||
|
||||
Container_Boundary(api, "API Application") {
|
||||
Component(sign, "Sign In Controller", "MVC Rest Controller", "Allows users to sign in to the internet banking system")
|
||||
Component(accounts, "Accounts Summary Controller", "MVC Rest Controller", "Provides customers with a summary of their bank accounts")
|
||||
Component(security, "Security Component", "Spring Bean", "Provides functionality related to singing in, changing passwords, etc.")
|
||||
Component(mbsfacade, "Mainframe Banking System Facade", "Spring Bean", "A facade onto the mainframe banking system.")
|
||||
|
||||
Rel(sign, security, "Uses")
|
||||
Rel(accounts, mbsfacade, "Uses")
|
||||
Rel(security, db, "Read & write to", "JDBC")
|
||||
Rel(mbsfacade, mbs, "Uses", "XML/HTTPS")
|
||||
}
|
||||
|
||||
Rel_Back(spa, sign, "Uses", "JSON/HTTPS")
|
||||
Rel(spa, accounts, "Uses", "JSON/HTTPS")
|
||||
|
||||
Rel(ma, sign, "Uses", "JSON/HTTPS")
|
||||
Rel(ma, accounts, "Uses", "JSON/HTTPS")
|
||||
|
||||
UpdateRelStyle(spa, sign, $offsetY="-40")
|
||||
UpdateRelStyle(spa, accounts, $offsetX="40", $offsetY="40")
|
||||
|
||||
UpdateRelStyle(ma, sign, $offsetX="-90", $offsetY="40")
|
||||
UpdateRelStyle(ma, accounts, $offsetY="-40")
|
||||
|
||||
UpdateRelStyle(sign, security, $offsetX="-160", $offsetY="10")
|
||||
UpdateRelStyle(accounts, mbsfacade, $offsetX="140", $offsetY="10")
|
||||
UpdateRelStyle(security, db, $offsetY="-40")
|
||||
UpdateRelStyle(mbsfacade, mbs, $offsetY="-40")
|
||||
</pre>
|
||||
|
||||
<pre class="mermaid">
|
||||
C4Dynamic
|
||||
title Dynamic diagram for Internet Banking System - API Application
|
||||
|
||||
ContainerDb(c4, "Database", "Relational Database Schema", "Stores user registration information, hashed authentication credentials, access logs, etc.")
|
||||
Container(c1, "Single-Page Application", "JavaScript and Angular", "Provides all of the Internet banking functionality to customers via their web browser.")
|
||||
Container_Boundary(b, "API Application") {
|
||||
Component(c3, "Security Component", "Spring Bean", "Provides functionality Related to signing in, changing passwords, etc.")
|
||||
Component(c2, "Sign In Controller", "Spring MVC Rest Controller", "Allows users to sign in to the Internet Banking System.")
|
||||
}
|
||||
Rel(c1, c2, "Submits credentials to", "JSON/HTTPS")
|
||||
Rel(c2, c3, "Calls isAuthenticated() on")
|
||||
Rel(c3, c4, "select * from users where username = ?", "JDBC")
|
||||
|
||||
UpdateRelStyle(c1, c2, $textColor="red", $offsetY="-40")
|
||||
UpdateRelStyle(c2, c3, $textColor="red", $offsetX="-40", $offsetY="60")
|
||||
UpdateRelStyle(c3, c4, $textColor="red", $offsetY="-40", $offsetX="10")
|
||||
</pre>
|
||||
|
||||
<pre class="mermaid">
|
||||
C4Deployment
|
||||
title Deployment Diagram for Internet Banking System - Live
|
||||
|
||||
Deployment_Node(mob, "Customer's mobile device", "Apple IOS or Android"){
|
||||
Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile device.")
|
||||
}
|
||||
|
||||
Deployment_Node(comp, "Customer's computer", "Mircosoft Windows or Apple macOS"){
|
||||
Deployment_Node(browser, "Web Browser", "Google Chrome, Mozilla Firefox,<br/> Apple Safari or Microsoft Edge"){
|
||||
Container(spa, "Single Page Application", "JavaScript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.")
|
||||
}
|
||||
}
|
||||
|
||||
Deployment_Node(plc, "Big Bank plc", "Big Bank plc data center"){
|
||||
Deployment_Node(dn, "bigbank-api*** x8", "Ubuntu 16.04 LTS"){
|
||||
Deployment_Node(apache, "Apache Tomcat", "Apache Tomcat 8.x"){
|
||||
Container(api, "API Application", "Java and Spring MVC", "Provides Internet Banking functionality via a JSON/HTTPS API.")
|
||||
}
|
||||
}
|
||||
Deployment_Node(bb2, "bigbank-web*** x4", "Ubuntu 16.04 LTS"){
|
||||
Deployment_Node(apache2, "Apache Tomcat", "Apache Tomcat 8.x"){
|
||||
Container(web, "Web Application", "Java and Spring MVC", "Delivers the static content and the Internet Banking single page application.")
|
||||
}
|
||||
}
|
||||
Deployment_Node(bigbankdb01, "bigbank-db01", "Ubuntu 16.04 LTS"){
|
||||
Deployment_Node(oracle, "Oracle - Primary", "Oracle 12c"){
|
||||
ContainerDb(db, "Database", "Relational Database Schema", "Stores user registration information, hashed authentication credentials, access logs, etc.")
|
||||
}
|
||||
}
|
||||
Deployment_Node(bigbankdb02, "bigbank-db02", "Ubuntu 16.04 LTS") {
|
||||
Deployment_Node(oracle2, "Oracle - Secondary", "Oracle 12c") {
|
||||
ContainerDb(db2, "Database", "Relational Database Schema", "Stores user registration information, hashed authentication credentials, access logs, etc.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rel(mobile, api, "Makes API calls to", "json/HTTPS")
|
||||
Rel(spa, api, "Makes API calls to", "json/HTTPS")
|
||||
Rel_U(web, spa, "Delivers to the customer's web browser")
|
||||
Rel(api, db, "Reads from and writes to", "JDBC")
|
||||
Rel(api, db2, "Reads from and writes to", "JDBC")
|
||||
Rel_R(db, db2, "Replicates data to")
|
||||
|
||||
UpdateRelStyle(spa, api, $offsetY="-40")
|
||||
UpdateRelStyle(web, spa, $offsetY="-40")
|
||||
UpdateRelStyle(api, db, $offsetY="-20", $offsetX="5")
|
||||
UpdateRelStyle(api, db2, $offsetX="-40", $offsetY="-20")
|
||||
UpdateRelStyle(db, db2, $offsetY="-10")
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
const ALLOWED_TAGS = [
|
||||
'a',
|
||||
'b',
|
||||
'blockquote',
|
||||
'br',
|
||||
'dd',
|
||||
'div',
|
||||
'dl',
|
||||
'dt',
|
||||
'em',
|
||||
'foreignObject',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'h7',
|
||||
'h8',
|
||||
'hr',
|
||||
'i',
|
||||
'li',
|
||||
'ul',
|
||||
'ol',
|
||||
'p',
|
||||
'pre',
|
||||
'span',
|
||||
'strike',
|
||||
'strong',
|
||||
'table',
|
||||
'tbody',
|
||||
'td',
|
||||
'tfoot',
|
||||
'th',
|
||||
'thead',
|
||||
'tr',
|
||||
];
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
flowchart: { curve: 'basis' },
|
||||
gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50 },
|
||||
dompurifyConfig: {
|
||||
USE_PROFILES: {
|
||||
svg: true,
|
||||
},
|
||||
ADD_TAGS: ALLOWED_TAGS,
|
||||
ADD_ATTR: ['transform-origin'],
|
||||
},
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
function testClick(nodeId) {
|
||||
console.log('clicked', nodeId);
|
||||
var originalBgColor = document.querySelector('body').style.backgroundColor;
|
||||
document.querySelector('body').style.backgroundColor = 'yellow';
|
||||
setTimeout(function () {
|
||||
document.querySelector('body').style.backgroundColor = originalBgColor;
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
const testLineEndings = (test, input) => {
|
||||
try {
|
||||
mermaid.render(test, input, () => {
|
||||
//no-op
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Error in %s:\n\n%s', test, err);
|
||||
}
|
||||
};
|
||||
|
||||
testLineEndings('CR', 'graph LR\rsubgraph CR\rA --> B\rend');
|
||||
testLineEndings('LF', 'graph LR\nsubgraph LF\nA --> B\nend');
|
||||
testLineEndings('CRLF', 'graph LR\r\nsubgraph CRLF\r\nA --> B\r\nend');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<title>Class diagrams Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||
<style>
|
||||
div.mermaid {
|
||||
@@ -16,34 +16,125 @@
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
title Animal Diagram
|
||||
accDescription The animal class diagram
|
||||
Animal <|-- Duck
|
||||
Animal <|-- Fish
|
||||
Animal <|-- Zebra
|
||||
Animal : +int age
|
||||
Animal : +String gender
|
||||
Animal: +isMammal()
|
||||
Animal: +mate()
|
||||
class Duck{
|
||||
+String beakColor
|
||||
+swim()
|
||||
+quack()
|
||||
}
|
||||
class Fish{
|
||||
-int sizeInFeet
|
||||
-canEat()
|
||||
}
|
||||
class Zebra{
|
||||
+bool is_wild
|
||||
+run()
|
||||
}
|
||||
accTitle: Demo Class Diagram
|
||||
accDescr: This class diagram show the abstract Animal class, and 3 classes that inherit from it: Duck, Fish, and Zebra.
|
||||
|
||||
Animal <|-- Duck
|
||||
Animal <|-- Fish
|
||||
Animal <|-- Zebra
|
||||
Animal : +int age
|
||||
Animal : +String gender
|
||||
Animal: +isMammal()
|
||||
Animal: +mate()
|
||||
|
||||
class Duck{
|
||||
+String beakColor
|
||||
+swim()
|
||||
+quack()
|
||||
}
|
||||
class Fish{
|
||||
-int sizeInFeet
|
||||
-canEat()
|
||||
}
|
||||
class Zebra{
|
||||
+bool is_wild
|
||||
+run()
|
||||
}
|
||||
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
|
||||
<<interface>> Class01
|
||||
Class03 "0" *-- "0..n" Class04
|
||||
Class05 "1" o-- "many" Class06
|
||||
Class07 .. Class08
|
||||
Class09 "many" --> "1" C2 : Where am i?
|
||||
Class09 "0" --* "1..n" C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : #size()
|
||||
Class01 : -int chimp
|
||||
Class01 : +int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
</pre>
|
||||
<hr />
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
class Class01~T~
|
||||
Class01 : #size()
|
||||
Class01 : -int chimp
|
||||
Class01 : +int gorilla
|
||||
class Class10~T~ {
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
</pre>
|
||||
<hr />
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
Class01~T~ <|-- AveryLongClass : Cool
|
||||
<<interface>> Class01
|
||||
Class03~T~ "0" *-- "0..n" Class04
|
||||
Class05 "1" o-- "many" Class06
|
||||
Class07~T~ .. Class08
|
||||
Class09 "many" --> "1" C2 : Where am i?
|
||||
Class09 "0" --* "1..n" C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : #size()
|
||||
Class01 : -int chimp
|
||||
Class01 : +int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
class Class10 {
|
||||
<<service>>
|
||||
int id
|
||||
size()
|
||||
}
|
||||
</pre>
|
||||
<hr />
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
Interface1 ()-- Interface1Impl
|
||||
</pre>
|
||||
<hr />
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
direction LR
|
||||
Animal ()-- Dog
|
||||
Dog : bark()
|
||||
Dog : species()
|
||||
</pre>
|
||||
<hr />
|
||||
<pre class="mermaid">
|
||||
classDiagram
|
||||
direction RL
|
||||
Fruit ()-- Apple
|
||||
Apple : color()
|
||||
Apple : -int leafCount()
|
||||
Fruit ()-- Pineapple
|
||||
Pineapple : color()
|
||||
Pineapple : -int leafCount()
|
||||
Pineapple : -int spikeCount()
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
theme: 'default',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
|
@@ -16,6 +16,8 @@
|
||||
<h2>Data Flow Diagram Example</h2>
|
||||
<pre class="mermaid">
|
||||
flowchart LR
|
||||
accTitle: A simple linear flowchart.
|
||||
accDescr: A Database has input to a circle System has output to a square Customer.
|
||||
DataStore[|borders:tb|Database] -->|input| Process((System)) -->|output| Entity[Customer];
|
||||
</pre>
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<title>ER diagram | Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||
<style>
|
||||
div.mermaid {
|
||||
@@ -15,18 +15,31 @@
|
||||
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
erDiagram
|
||||
title This is a title
|
||||
accDescription Test a description
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
|
||||
erDiagram
|
||||
title: This is a title
|
||||
accDescription_ Test a description
|
||||
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
|
||||
|
||||
DELIVERY-ADDRESS {
|
||||
int customerId
|
||||
string addressLine1
|
||||
string addressLine2
|
||||
string city
|
||||
string county
|
||||
string state
|
||||
string region
|
||||
string country
|
||||
string postalCode
|
||||
}
|
||||
</pre>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
<script type="module">
|
||||
import mermaid from '../src/mermaid';
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
theme: 'base',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
|
@@ -19,6 +19,9 @@
|
||||
<h3>graph</h3>
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
accTitle: This is a complicated flow
|
||||
accDescr: This is the descriptoin for the complicated flow.
|
||||
|
||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
|
||||
|
||||
提交申请
|
||||
@@ -220,25 +223,25 @@
|
||||
<h3>graph</h3>
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
title What to buy
|
||||
accDescription Options of what to buy with Christmas money
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me thinksssssx<br/>sssssssssssssssssssuuu<br />tttsssssssssssssssssssssss}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
accTitle: What to buy
|
||||
accDescr: Options of what to buy with Christmas money
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me thinksssssx<br/>sssssssssssssssssssuuu<br />tttsssssssssssssssssssssss}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
</pre>
|
||||
|
||||
<h3>flowchart</h3>
|
||||
<pre class="mermaid">
|
||||
flowchart TD
|
||||
title What to buy
|
||||
accDescription Options of what to buy with Christmas money
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me thinksssssx<br/>sssssssssssssssssssuuu<br />tttsssssssssssssssssssssss}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
accTitle: What to buy
|
||||
accDescr: Options of what to buy with Christmas money
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me thinksssssx<br/>sssssssssssssssssssuuu<br />tttsssssssssssssssssssssss}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
@@ -1087,6 +1090,384 @@
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
|
||||
|
||||
提交申请
|
||||
熊大
|
||||
"];
|
||||
class sid-B3655226-6C29-4D00-B685-3D5C734DC7E1 node-executed;
|
||||
sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A["
|
||||
负责人审批
|
||||
强子
|
||||
"];
|
||||
class sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A node-executed;
|
||||
sid-E27C0367-E6D6-497F-9736-3CDC21FDE221["
|
||||
DBA审批
|
||||
强子
|
||||
"];
|
||||
class sid-E27C0367-E6D6-497F-9736-3CDC21FDE221 node-executed;
|
||||
sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD["
|
||||
SA审批
|
||||
阿美
|
||||
"];
|
||||
class sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD node-executed;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7["
|
||||
主管审批
|
||||
光头强
|
||||
"];
|
||||
class sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7 node-executed;
|
||||
sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89["
|
||||
DBA确认
|
||||
强子
|
||||
"];
|
||||
class sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89 node-executed;
|
||||
sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937["
|
||||
SA确认
|
||||
阿美
|
||||
"];
|
||||
class sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937 node-executed;
|
||||
sid-4FC27B48-A6F9-460A-A675-021F5854FE22["
|
||||
结束
|
||||
"];
|
||||
class sid-4FC27B48-A6F9-460A-A675-021F5854FE22 node-executed;
|
||||
sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E["
|
||||
SA执行1
|
||||
强子
|
||||
"];
|
||||
class sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E node-executed;
|
||||
sid-6C2120F3-D940-4958-A067-0903DCE879C4["
|
||||
SA执行2
|
||||
强子
|
||||
"];
|
||||
class sid-6C2120F3-D940-4958-A067-0903DCE879C4 node-executed;
|
||||
sid-9180E2A0-5C4B-435F-B42F-0D152470A338["
|
||||
DBA执行1
|
||||
强子
|
||||
"];
|
||||
class sid-9180E2A0-5C4B-435F-B42F-0D152470A338 node-executed;
|
||||
sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD["
|
||||
DBA执行3
|
||||
强子
|
||||
"];
|
||||
class sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD node-executed;
|
||||
sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756["
|
||||
DBA执行2
|
||||
强子
|
||||
"];
|
||||
class sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756 node-executed;
|
||||
sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93["
|
||||
DBA执行4
|
||||
强子
|
||||
"];
|
||||
class sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93 node-executed;
|
||||
sid-1897B30A-9C5C-4D5B-B80B-76A038785070["
|
||||
负责人确认
|
||||
梁静茹
|
||||
"];
|
||||
class sid-1897B30A-9C5C-4D5B-B80B-76A038785070 node-executed;
|
||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1-->sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7;
|
||||
sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A-->sid-1897B30A-9C5C-4D5B-B80B-76A038785070;
|
||||
sid-E27C0367-E6D6-497F-9736-3CDC21FDE221-->sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89;
|
||||
sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD-->sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937;
|
||||
sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E-->sid-6C2120F3-D940-4958-A067-0903DCE879C4;
|
||||
sid-9180E2A0-5C4B-435F-B42F-0D152470A338-->sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756;
|
||||
sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD-->sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93;
|
||||
sid-6C2120F3-D940-4958-A067-0903DCE879C4-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-1897B30A-9C5C-4D5B-B80B-76A038785070-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
|
||||
sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937-->sid-19DD9E9F-98C1-44EE-B604-842AFEE76F1E;
|
||||
sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89-->sid-9180E2A0-5C4B-435F-B42F-0D152470A338;
|
||||
sid-A1B3CD96-7697-4D7C-BEAA-73D187B1BE89-->sid-03A2C3AC-5337-48A5-B154-BB3FD0EC8DAD;
|
||||
sid-D5E1F2F4-306C-47A2-BF74-F66E3D769756-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-8C3F2F1D-F014-4F99-B966-095DC1A2BD93-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-BED98281-9585-4D1B-934E-BD1AC6AC0EFD;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-E27C0367-E6D6-497F-9736-3CDC21FDE221;
|
||||
sid-3E35A7FF-A2F4-4E07-9247-DBF884C81937-->sid-6C2120F3-D940-4958-A067-0903DCE879C4;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
|
||||
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me thinksssssx<br />sssssssssssssssssssuuu<br />tttsssssssssssssssssssssss}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
A[/Christmas\]
|
||||
A -->|Get money| B[\Go shopping/]
|
||||
B --> C{Let me thinksssss<br />ssssssssssssssssssssss<br />sssssssssssssssssssssssssss}
|
||||
C -->|One| D[/Laptop/]
|
||||
C -->|Two| E[\iPhone\]
|
||||
C -->|Three| F[Car]
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
47(SAM.CommonFA.FMESummary)-->48(SAM.CommonFA.CommonFAFinanceBudget)
|
||||
37(SAM.CommonFA.BudgetSubserviceLineVolume)-->48(SAM.CommonFA.CommonFAFinanceBudget)
|
||||
35(SAM.CommonFA.PopulationFME)-->47(SAM.CommonFA.FMESummary)
|
||||
41(SAM.CommonFA.MetricCost)-->47(SAM.CommonFA.FMESummary)
|
||||
44(SAM.CommonFA.MetricOutliers)-->47(SAM.CommonFA.FMESummary)
|
||||
46(SAM.CommonFA.MetricOpportunity)-->47(SAM.CommonFA.FMESummary)
|
||||
40(SAM.CommonFA.OPVisits)-->47(SAM.CommonFA.FMESummary)
|
||||
38(SAM.CommonFA.CommonFAFinanceRefund)-->47(SAM.CommonFA.FMESummary)
|
||||
43(SAM.CommonFA.CommonFAFinancePicuDays)-->47(SAM.CommonFA.FMESummary)
|
||||
42(SAM.CommonFA.CommonFAFinanceNurseryDays)-->47(SAM.CommonFA.FMESummary)
|
||||
45(SAM.CommonFA.MetricPreOpportunity)-->46(SAM.CommonFA.MetricOpportunity)
|
||||
35(SAM.CommonFA.PopulationFME)-->45(SAM.CommonFA.MetricPreOpportunity)
|
||||
41(SAM.CommonFA.MetricCost)-->45(SAM.CommonFA.MetricPreOpportunity)
|
||||
41(SAM.CommonFA.MetricCost)-->44(SAM.CommonFA.MetricOutliers)
|
||||
39(SAM.CommonFA.ChargeDetails)-->43(SAM.CommonFA.CommonFAFinancePicuDays)
|
||||
39(SAM.CommonFA.ChargeDetails)-->42(SAM.CommonFA.CommonFAFinanceNurseryDays)
|
||||
39(SAM.CommonFA.ChargeDetails)-->41(SAM.CommonFA.MetricCost)
|
||||
39(SAM.CommonFA.ChargeDetails)-->40(SAM.CommonFA.OPVisits)
|
||||
35(SAM.CommonFA.PopulationFME)-->39(SAM.CommonFA.ChargeDetails)
|
||||
36(SAM.CommonFA.PremetricCost)-->39(SAM.CommonFA.ChargeDetails)
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002("fa:fa-creative-commons My System | Test Environment")
|
||||
82072290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Business Logic Server:Service 1")
|
||||
db052290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Business Logic Server:Service 2")
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Report Server:Service 1")
|
||||
30122290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Shared Report Server:Service 2")
|
||||
5e112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Dedicated Test Business Logic Server:Service 1")
|
||||
c1112290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs Dedicated Test Business Logic Server:Service 2")
|
||||
b7042290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\SharedDbInstance].[SupportDb]")
|
||||
8f102290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\SharedDbInstance].[DevelopmentDb]")
|
||||
0e102290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\SharedDbInstance].[TestDb]")
|
||||
07132290_1ec3_e711_8c5a_005056ad0002("fa:fa-circle [DBServer\SharedDbInstance].[SharedReportingDb]")
|
||||
c7072290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Shared Business Logic Server")
|
||||
ca122290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Shared Report Server")
|
||||
68102290_1ec3_e711_8c5a_005056ad0002("fa:fa-server Dedicated Test Business Logic Server")
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002("fa:fa-database [DBServer\SharedDbInstance]")
|
||||
d6072290_1ec3_e711_8c5a_005056ad0002("fa:fa-server DBServer")
|
||||
71082290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\:MSSQLSERVER")
|
||||
c0102290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\:SQLAgent")
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002("fa:fa-cogs DBServer\:SQLBrowser")
|
||||
1d0a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost1")
|
||||
200a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost2")
|
||||
1c0a2290_1ec3_e711_8c5a_005056ad0002("fa:fa-server VmHost3")
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->82072290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->db052290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->4e112290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->30122290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->5e112290_1ec3_e711_8c5a_005056ad0002
|
||||
9e122290_1ec3_e711_8c5a_005056ad0002-->c1112290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->b7042290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->0e102290_1ec3_e711_8c5a_005056ad0002
|
||||
82072290_1ec3_e711_8c5a_005056ad0002-->c7072290_1ec3_e711_8c5a_005056ad0002
|
||||
db052290_1ec3_e711_8c5a_005056ad0002-->c7072290_1ec3_e711_8c5a_005056ad0002
|
||||
db052290_1ec3_e711_8c5a_005056ad0002-->82072290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->b7042290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->0e102290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->07132290_1ec3_e711_8c5a_005056ad0002
|
||||
4e112290_1ec3_e711_8c5a_005056ad0002-->ca122290_1ec3_e711_8c5a_005056ad0002
|
||||
30122290_1ec3_e711_8c5a_005056ad0002-->ca122290_1ec3_e711_8c5a_005056ad0002
|
||||
30122290_1ec3_e711_8c5a_005056ad0002-->4e112290_1ec3_e711_8c5a_005056ad0002
|
||||
5e112290_1ec3_e711_8c5a_005056ad0002-->8f102290_1ec3_e711_8c5a_005056ad0002
|
||||
5e112290_1ec3_e711_8c5a_005056ad0002-->68102290_1ec3_e711_8c5a_005056ad0002
|
||||
c1112290_1ec3_e711_8c5a_005056ad0002-->68102290_1ec3_e711_8c5a_005056ad0002
|
||||
c1112290_1ec3_e711_8c5a_005056ad0002-->5e112290_1ec3_e711_8c5a_005056ad0002
|
||||
b7042290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
8f102290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
0e102290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
07132290_1ec3_e711_8c5a_005056ad0002-->f4112290_1ec3_e711_8c5a_005056ad0002
|
||||
c7072290_1ec3_e711_8c5a_005056ad0002-->1d0a2290_1ec3_e711_8c5a_005056ad0002
|
||||
ca122290_1ec3_e711_8c5a_005056ad0002-->200a2290_1ec3_e711_8c5a_005056ad0002
|
||||
68102290_1ec3_e711_8c5a_005056ad0002-->1c0a2290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->c0102290_1ec3_e711_8c5a_005056ad0002
|
||||
f4112290_1ec3_e711_8c5a_005056ad0002-->9a072290_1ec3_e711_8c5a_005056ad0002
|
||||
d6072290_1ec3_e711_8c5a_005056ad0002-->1c0a2290_1ec3_e711_8c5a_005056ad0002
|
||||
71082290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
c0102290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
c0102290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
|
||||
9a072290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TB
|
||||
subgraph One
|
||||
a1-->a2
|
||||
end
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TB
|
||||
A
|
||||
B
|
||||
subgraph foo[Foo SubGraph]
|
||||
C
|
||||
D
|
||||
end
|
||||
subgraph bar[Bar SubGraph]
|
||||
E
|
||||
F
|
||||
end
|
||||
G
|
||||
|
||||
A-->B
|
||||
B-->C
|
||||
C-->D
|
||||
B-->D
|
||||
D-->E
|
||||
E-->A
|
||||
E-->F
|
||||
F-->D
|
||||
F-->G
|
||||
B-->G
|
||||
G-->D
|
||||
|
||||
style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
|
||||
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
456ac9b0d15a8b7f1e71073221059886[1051 AAA fa:fa-check]
|
||||
f7f580e11d00a75814d2ded41fe8e8fe[1141 BBB fa:fa-check]
|
||||
81dc9bdb52d04dc20036dbd8313ed055[1234 CCC fa:fa-check]
|
||||
456ac9b0d15a8b7f1e71073221059886 -->|Node| f7f580e11d00a75814d2ded41fe8e8fe
|
||||
f7f580e11d00a75814d2ded41fe8e8fe -->|Node| 81dc9bdb52d04dc20036dbd8313ed055
|
||||
click 456ac9b0d15a8b7f1e71073221059886 "/admin/user/view?id=1051" "AAA
|
||||
6000"
|
||||
click f7f580e11d00a75814d2ded41fe8e8fe "/admin/user/view?id=1141" "BBB
|
||||
600"
|
||||
click 81dc9bdb52d04dc20036dbd8313ed055 "/admin/user/view?id=1234" "CCC
|
||||
3000"
|
||||
style 456ac9b0d15a8b7f1e71073221059886 fill:#f9f,stroke:#333,stroke-width:4px
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{{Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?}}
|
||||
C -->|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[Car]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
A([stadium shape test])
|
||||
A -->|Get money| B([Go shopping])
|
||||
B --> C([Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?])
|
||||
C -->|One| D([Laptop])
|
||||
C -->|Two| E([iPhone])
|
||||
C -->|Three| F([Car<br />wroom wroom])
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
A[[subroutine shape test]]
|
||||
A -->|Get money| B[[Go shopping]]
|
||||
B --> C[[Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?]]
|
||||
C -->|One| D[[Laptop]]
|
||||
C -->|Two| E[[iPhone]]
|
||||
C -->|Three| F[[Car<br />wroom wroom]]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
A[(cylindrical<br />shape<br />test)]
|
||||
A -->|Get money| B1[(Go shopping 1)]
|
||||
A -->|Get money| B2[(Go shopping 2)]
|
||||
A -->|Get money| B3[(Go shopping 3)]
|
||||
C[(Let me think...<br />Do I want something for work,<br />something to spend every free second with,<br />or something to get around?)]
|
||||
B1 --> C
|
||||
B2 --> C
|
||||
B3 --> C
|
||||
C -->|One| D[(Laptop)]
|
||||
C -->|Two| E[(iPhone)]
|
||||
C -->|Three| F[(Car)]
|
||||
click A "index.html#link-clicked" "link test"
|
||||
click B testClick "click test"
|
||||
classDef someclass fill:#f96;
|
||||
class A someclass;
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
A1[Multi<br>Line] -->|Multi<br>Line| B1(Multi<br>Line)
|
||||
C1[Multi<br />Line] -->|Multi<br />Line| D1(Multi<br />Line)
|
||||
E1[Multi<br />Line] -->|Multi<br />Line| F1(Multi<br />Line)
|
||||
A2[Multi<br>Line] -->|Multi<br>Line| B2(Multi<br>Line)
|
||||
C2[Multi<br />Line] -->|Multi<br />Line| D2(Multi<br />Line)
|
||||
E2[Multi<br />Line] -->|Multi<br />Line| F2(Multi<br />Line)
|
||||
linkStyle 0 stroke:DarkGray,stroke-width:2px
|
||||
linkStyle 1 stroke:DarkGray,stroke-width:2px
|
||||
linkStyle 2 stroke:DarkGray,stroke-width:2px
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
A(( )) -->|step 1| B(( ))
|
||||
B(( )) -->|step 2| C(( ))
|
||||
C(( )) -->|step 3| D(( ))
|
||||
linkStyle 1 stroke:greenyellow,stroke-width:2px
|
||||
style C fill:greenyellow,stroke:green,stroke-width:4px
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TB
|
||||
TITLE["Link Click Events<br>(click the nodes below)"]
|
||||
A["link test (open in same tab)"]
|
||||
B["link test (open in new tab)"]
|
||||
C[anchor test]
|
||||
D[mailto test]
|
||||
E[other protocol test]
|
||||
F[script test]
|
||||
TITLE --> A & B & C & D & E & F
|
||||
click A "https://mermaid-js.github.io/mermaid/#/" "link test (open in same tab)"
|
||||
click B "https://mermaid-js.github.io/mermaid/#/" "link test (open in new tab)" _blank
|
||||
click C "#link-clicked"
|
||||
click D "mailto:user@user.user" "mailto test"
|
||||
click E "notes://do-your-thing/id" "other protocol test"
|
||||
click F "javascript:alert('test')" "script test"
|
||||
</pre>
|
||||
<hr />
|
||||
<pre class="mermaid">
|
||||
graph LR
|
||||
A[red<br>text] -->|red<br>text| B(blue<br>text)
|
||||
C[/red<br />text/] -->|blue<br />text| D{blue<br />text}
|
||||
E{{default<br />style}} -->|default<br />style| F([default<br />style])
|
||||
linkStyle default color:Sienna;
|
||||
linkStyle 0 color:red;
|
||||
linkStyle 1 stroke:DarkGray,stroke-width:2px,color:#0000ff
|
||||
style A color:red;
|
||||
style B color:blue;
|
||||
style C stroke:#ff0000,fill:#ffcccc,color:#ff0000
|
||||
style D stroke:#0000ff,fill:#ccccff,color:#0000ff
|
||||
click B "index.html#link-clicked" "link test"
|
||||
click D testClick "click test"
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
graph TD
|
||||
A[myClass1] --> B[default] & C[default]
|
||||
B[default] & C[default] --> D[myClass2]
|
||||
classDef default stroke-width:2px,fill:none,stroke:silver
|
||||
classDef node color:red
|
||||
classDef myClass1 color:#0000ff
|
||||
classDef myClass2 stroke:#0000ff,fill:#ccccff
|
||||
class A myClass1
|
||||
class D myClass2
|
||||
</pre>
|
||||
|
||||
<h1 id="link-clicked">Anchor for "link-clicked" test</h1>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
|
163
demos/gantt.html
163
demos/gantt.html
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<title>Gantt | Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||
<style>
|
||||
div.mermaid {
|
||||
@@ -15,21 +15,158 @@
|
||||
<body>
|
||||
<!-- accDescription Tasks for Q4 -->
|
||||
<pre class="mermaid">
|
||||
gantt
|
||||
title A Gantt Diagram
|
||||
accDescription Remaining Q4 Tasks
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
gantt
|
||||
title A Gantt Diagram
|
||||
accTitle: A simple sample gantt diagram
|
||||
accDescr: 2 sections with 2 tasks each, from 2014
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
</pre>
|
||||
|
||||
<pre class="mermaid">
|
||||
gantt
|
||||
title Airworks roadmap
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %m-%d %a
|
||||
excludes weekends, 2021-10-01,2021-10-04,2021-10-05,2021-10-06,2021-10-07
|
||||
includes 2021-10-09
|
||||
|
||||
</pre
|
||||
>
|
||||
section Airworks 3.4.1
|
||||
开发 :b, 2021-10-07, 5d
|
||||
测试 :after b, 4d
|
||||
OK :milestore
|
||||
section Airworks 3.4.2
|
||||
开发 :a, 2021-10-09, 4d
|
||||
测试 :after a, 4d
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
gantt
|
||||
title Exclusive end dates (Manual date should end on 3d)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d
|
||||
section Section1
|
||||
2 Days: 1, 2019-01-01,2d
|
||||
Manual Date: 2, 2019-01-01,2019-01-03
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
gantt
|
||||
title Inclusive end dates (Manual date should end on 4th)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d
|
||||
inclusiveEndDates
|
||||
section Section1
|
||||
2 Days: 1, 2019-01-01,2d
|
||||
Manual Date: 2, 2019-01-01,2019-01-03
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
gantt
|
||||
title Hide today marker (vertical line should not be visible)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d
|
||||
todayMarker off
|
||||
section Section1
|
||||
Today: 1, -1h
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
gantt
|
||||
title Style today marker (vertical line should be 5px wide and half-transparent blue)
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d
|
||||
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5
|
||||
section Section1
|
||||
Today: 1, -1h
|
||||
</pre>
|
||||
|
||||
<pre class="mermaid">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title Adding GANTT diagram to mermaid
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks
|
||||
Completed task in the critical line :crit, done, 2014-01-06,24h
|
||||
Implement parser and jison :crit, done, after des1, 2d
|
||||
Create tests for parser :crit, active, 3d
|
||||
Future task in critical line :crit, 5d
|
||||
Create tests for renderer :2d
|
||||
Add to mermaid :1d
|
||||
|
||||
section Documentation
|
||||
Describe gantt syntax :active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page :after a1 , 20h
|
||||
Add another diagram to demo page :doc1, after a1 , 48h
|
||||
|
||||
section Clickable
|
||||
Visit mermaidjs :active, cl1, 2014-01-07,2014-01-10
|
||||
Calling a Callback (look at the console log) :cl2, after cl1, 3d
|
||||
|
||||
click cl1 href "https://mermaidjs.github.io/"
|
||||
click cl2 call ganttTestClick("test", test, test)
|
||||
|
||||
section Last section
|
||||
Describe gantt syntax :after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
title GANTT diagram with multiline section titles
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section<br>multiline
|
||||
Completed task : done, des1, 2014-01-06,2014-01-08
|
||||
Active task : active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
|
||||
section Critical tasks<br />multiline
|
||||
Completed task in the critical line : crit, done, 2014-01-06, 24h
|
||||
Implement parser and jison : crit, done, after des1, 2d
|
||||
Create tests for parser : crit, active, 3d
|
||||
Future task in critical line : crit, 5d
|
||||
Create tests for renderer : 2d
|
||||
Add to mermaid : 1d
|
||||
|
||||
section Documentation<br />multiline
|
||||
Describe gantt syntax : active, a1, after des1, 3d
|
||||
Add gantt diagram to demo page : after a1, 20h
|
||||
Add another diagram to demo page : doc1, after a1, 48h
|
||||
|
||||
section Last section<br />multiline
|
||||
Describe gantt syntax : after doc1, 3d
|
||||
Add gantt diagram to demo page : 20h
|
||||
Add another diagram to demo page : 48h
|
||||
</pre>
|
||||
|
||||
<script>
|
||||
function ganttTestClick(a, b, c) {
|
||||
console.log('a:', a);
|
||||
console.log('b:', b);
|
||||
console.log('c:', c);
|
||||
}
|
||||
function testClick(nodeId) {
|
||||
console.log('clicked', nodeId);
|
||||
var originalBgColor = document.querySelector('body').style.backgroundColor;
|
||||
document.querySelector('body').style.backgroundColor = 'yellow';
|
||||
setTimeout(function () {
|
||||
document.querySelector('body').style.backgroundColor = originalBgColor;
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
|
94
demos/git.html
Normal file
94
demos/git.html
Normal file
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Git Graphs Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||
<style>
|
||||
div.mermaid {
|
||||
/* font-family: 'trebuchet ms', verdana, arial; */
|
||||
font-family: 'Courier New', Courier, monospace !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
gitGraph:
|
||||
options
|
||||
{
|
||||
"nodeSpacing": 50,
|
||||
"nodeRadius": 5
|
||||
}
|
||||
end
|
||||
branch master
|
||||
commit
|
||||
branch newbranch
|
||||
checkout newbranch
|
||||
commit
|
||||
commit
|
||||
checkout master
|
||||
commit
|
||||
commit
|
||||
merge newbranch
|
||||
</pre>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
const ALLOWED_TAGS = [
|
||||
'a',
|
||||
'b',
|
||||
'blockquote',
|
||||
'br',
|
||||
'dd',
|
||||
'div',
|
||||
'dl',
|
||||
'dt',
|
||||
'em',
|
||||
'foreignObject',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'h7',
|
||||
'h8',
|
||||
'hr',
|
||||
'i',
|
||||
'li',
|
||||
'ul',
|
||||
'ol',
|
||||
'p',
|
||||
'pre',
|
||||
'span',
|
||||
'strike',
|
||||
'strong',
|
||||
'table',
|
||||
'tbody',
|
||||
'td',
|
||||
'tfoot',
|
||||
'th',
|
||||
'thead',
|
||||
'tr',
|
||||
];
|
||||
mermaid.initialize({
|
||||
theme: 'default',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
flowchart: { curve: 'basis' },
|
||||
gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50 },
|
||||
dompurifyConfig: {
|
||||
USE_PROFILES: {
|
||||
svg: true,
|
||||
},
|
||||
ADD_TAGS: ALLOWED_TAGS,
|
||||
ADD_ATTR: ['transform-origin'],
|
||||
},
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
1030
demos/index.html
1030
demos/index.html
File diff suppressed because it is too large
Load Diff
@@ -15,16 +15,18 @@
|
||||
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
journey
|
||||
title My day
|
||||
accDescription A user journey diagram of a typical day in my life
|
||||
section Go to work
|
||||
Make tea: 5: Me
|
||||
Go upstairs: 3: Me
|
||||
Do work: 1: Me, Cat
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 5: Me
|
||||
journey
|
||||
title My working day
|
||||
accTitle: Very simple journey demo
|
||||
accDescr: 2 main sections: work and home, each with just a few tasks
|
||||
|
||||
section Go to work
|
||||
Make tea: 5: Me
|
||||
Go upstairs: 3: Me
|
||||
Do work: 1: Me, Cat
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 3: Me
|
||||
</pre>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
|
51
demos/pie.html
Normal file
51
demos/pie.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<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: 'trebuchet ms', verdana, arial; */
|
||||
font-family: 'Courier New', Courier, monospace !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
pie title Pets adopted by volunteers
|
||||
accTitle: simple pie char demo
|
||||
accDescr: pie chart with 3 sections: dogs, cats, rats. Most are dogs.
|
||||
"Dogs" : 386
|
||||
"Cats" : 85
|
||||
"Rats" : 15
|
||||
</pre>
|
||||
|
||||
<pre class="mermaid">
|
||||
pie
|
||||
title Key elements in Product X
|
||||
accTitle: Key elements in Product X
|
||||
accDescr: This is a pie chart showing the key elements in Product X.
|
||||
"Calcium" : 42.96
|
||||
"Potassium" : 50.05
|
||||
"Magnesium" : 10.01
|
||||
"Iron" : 5
|
||||
</pre>
|
||||
|
||||
<script type="module">
|
||||
import mermaid from '../src/mermaid';
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
// flowchart: { curve: 'basis' },
|
||||
// gantt: { axisFormat: '%m/%d/%Y' },
|
||||
sequence: { actorMargin: 50 },
|
||||
// sequenceDiagram: { actorMargin: 300 } // deprecated
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<title>Requirements Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||
<style>
|
||||
div.mermaid {
|
||||
@@ -16,7 +16,9 @@
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
requirementDiagram
|
||||
title This is a title
|
||||
accTitle: Requirments demo in black and white
|
||||
accDescr: A series of requirement boxes showing relationships among them. Has meaningless task names
|
||||
|
||||
requirement test_req {
|
||||
id: 1
|
||||
text: the test text.
|
||||
@@ -84,11 +86,82 @@
|
||||
test_req <- copies - test_entity2
|
||||
</pre
|
||||
>
|
||||
<hr />
|
||||
|
||||
<pre class="mermaid">
|
||||
requirementDiagram
|
||||
|
||||
requirement An Example {
|
||||
id: 1
|
||||
text: the test text.
|
||||
risk: high
|
||||
verifymethod: test
|
||||
}
|
||||
|
||||
functionalRequirement Random Name {
|
||||
id: 1.1
|
||||
text: the second test text.
|
||||
risk: low
|
||||
verifymethod: inspection
|
||||
}
|
||||
|
||||
performanceRequirement Something Else {
|
||||
id: 1.2
|
||||
text: the third test text.
|
||||
risk: medium
|
||||
verifymethod: demonstration
|
||||
}
|
||||
|
||||
interfaceRequirement test_req4 {
|
||||
id: 1.2.1
|
||||
text: the fourth test text.
|
||||
risk: medium
|
||||
verifymethod: analysis
|
||||
}
|
||||
|
||||
physicalRequirement test_req5 {
|
||||
id: 1.2.2
|
||||
text: the fifth test text.
|
||||
risk: medium
|
||||
verifymethod: analysis
|
||||
}
|
||||
|
||||
designConstraint test_req6 {
|
||||
id: 1.2.3
|
||||
text: really long text to test overflow. really long text to test overflow. really long text to test overflow.
|
||||
risk: medium
|
||||
verifymethod: analysis
|
||||
}
|
||||
|
||||
element test_entity {
|
||||
type: simulation
|
||||
}
|
||||
|
||||
element test_entity2 {
|
||||
type: word doc
|
||||
docRef: reqs/test_entity
|
||||
}
|
||||
|
||||
element test_entity3 {
|
||||
type: "test suite"
|
||||
docRef: github.com/all_the_tests
|
||||
}
|
||||
|
||||
|
||||
test_entity - satisfies -> Random Name
|
||||
An Example - traces -> Random Name
|
||||
An Example - contains -> Something Else
|
||||
Something Else - contains -> test_req4
|
||||
test_req4 - derives -> test_req5
|
||||
test_req5 - refines -> test_req6
|
||||
test_entity3 - verifies -> test_req5
|
||||
An Example <- copies - test_entity2
|
||||
</pre>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
theme: 'neutral',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
|
@@ -16,49 +16,116 @@
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
sequenceDiagram
|
||||
title: FancySequenceDiagram
|
||||
accDescription Test a description
|
||||
participant Alice
|
||||
participant Bob
|
||||
participant John as John<br />Second Line
|
||||
autonumber 10 10
|
||||
rect rgb(200, 220, 100)
|
||||
rect rgb(200, 255, 200)
|
||||
Alice ->> Bob: Hello Bob, how are you?
|
||||
Bob-->>John: How about you John?
|
||||
end
|
||||
Bob--x Alice: I am good thanks!
|
||||
Bob-x John: I am good thanks!
|
||||
Note right of John: John thinks a long<br />long time, so long<br />that the text does<br />not fit on a row.
|
||||
Bob-->Alice: Checking with John...
|
||||
Note over John:wrap: John looks like he's still thinking, so Bob prods him a bit.
|
||||
Bob-x John: Hey John - we're still waiting to know<br />how you're doing
|
||||
Note over John:nowrap: John's trying hard not to break his train of thought.
|
||||
Bob-x John:wrap: John! Are you still debating about how you're doing? How long does it take??
|
||||
Note over John: After a few more moments, John<br />finally snaps out of it.
|
||||
end
|
||||
autonumber off
|
||||
alt either this
|
||||
Alice->>+John: Yes
|
||||
John-->>-Alice: OK
|
||||
else or this
|
||||
autonumber
|
||||
Alice->>John: No
|
||||
else or this will happen
|
||||
Alice->John: Maybe
|
||||
end
|
||||
autonumber 200
|
||||
par this happens in parallel
|
||||
Alice -->> Bob: Parallel message 1
|
||||
and
|
||||
Alice -->> John: Parallel message 2
|
||||
end
|
||||
accTitle: test the accTitle
|
||||
accDescr: Test a description
|
||||
|
||||
participant Alice
|
||||
participant Bob
|
||||
participant John as John<br />Second Line
|
||||
autonumber 10 10
|
||||
rect rgb(200, 220, 100)
|
||||
rect rgb(200, 255, 200)
|
||||
|
||||
Alice ->> Bob: Hello Bob, how are you?
|
||||
Bob-->>John: How about you John?
|
||||
end
|
||||
|
||||
Bob--x Alice: I am good thanks!
|
||||
Bob-x John: I am good thanks!
|
||||
Note right of John: John thinks a long<br />long time, so long<br />that the text does<br />not fit on a row.
|
||||
|
||||
Bob-->Alice: Checking with John...
|
||||
Note over John:wrap: John looks like he's still thinking, so Bob prods him a bit.
|
||||
Bob-x John: Hey John - we're still waiting to know<br />how you're doing
|
||||
Note over John:nowrap: John's trying hard not to break his train of thought.
|
||||
Bob-x John:wrap: John! Are you still debating about how you're doing? How long does it take??
|
||||
Note over John: After a few more moments, John<br />finally snaps out of it.
|
||||
end
|
||||
|
||||
autonumber off
|
||||
alt either this
|
||||
Alice->>+John: Yes
|
||||
John-->>-Alice: OK
|
||||
else or this
|
||||
autonumber
|
||||
Alice->>John: No
|
||||
else or this will happen
|
||||
Alice->John: Maybe
|
||||
end
|
||||
autonumber 200
|
||||
par this happens in parallel
|
||||
Alice -->> Bob: Parallel message 1
|
||||
and
|
||||
Alice -->> John: Parallel message 2
|
||||
end
|
||||
</pre>
|
||||
|
||||
<pre class="mermaid">
|
||||
sequenceDiagram
|
||||
accTitle: Sequence diagram title is here
|
||||
accDescr: Hello friends
|
||||
|
||||
participant Alice
|
||||
participant Bob
|
||||
participant John as John<br />Second Line
|
||||
rect rgb(200, 220, 100)
|
||||
rect rgb(200, 255, 200)
|
||||
Alice ->> Bob: Hello Bob, how are you?
|
||||
Bob-->>John: How about you John?
|
||||
end
|
||||
Bob--x Alice: I am good thanks!
|
||||
Bob-x John: I am good thanks!
|
||||
Note right of John: John thinks a long<br />long time, so long<br />that the text does<br />not fit on a row.
|
||||
Bob-->Alice: Checking with John...
|
||||
Note over John:wrap: John looks like he's still thinking, so Bob prods him a bit.
|
||||
Bob-x John: Hey John - we're still waiting to know<br />how you're doing
|
||||
Note over John:nowrap: John's trying hard not to break his train of thought.
|
||||
Bob-x John:wrap: John! Are you still debating about how you're doing? How long does it take??
|
||||
Note over John: After a few more moments, John<br />finally snaps out of it.
|
||||
end
|
||||
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
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
sequenceDiagram
|
||||
participant 1 as multiline<br>using #lt;br#gt;
|
||||
participant 2 as multiline<br />using #lt;br/#gt;
|
||||
participant 3 as multiline<br />using #lt;br /#gt;
|
||||
participant 4 as multiline<br />using #lt;br /#gt;
|
||||
1->>2: multiline<br>using #lt;br#gt;
|
||||
note right of 2: multiline<br>using #lt;br#gt;
|
||||
2->>3: multiline<br />using #lt;br/#gt;
|
||||
note right of 3: multiline<br />using #lt;br/#gt;
|
||||
3->>4: multiline<br />using #lt;br /#gt;
|
||||
note right of 4: multiline<br />using #lt;br /#gt;
|
||||
4->>1: multiline<br />using #lt;br /#gt;
|
||||
note right of 1: multiline<br />using #lt;br /#gt;
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
Alice->>John: Hello John,<br>how are you?
|
||||
autonumber 50 10
|
||||
Alice->>John: John,<br />can you hear me?
|
||||
John-->>Alice: Hi Alice,<br />I can hear you!
|
||||
autonumber off
|
||||
John-->>Alice: I feel great!
|
||||
</pre>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
theme: 'base',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<title>States Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||
<style>
|
||||
div.mermaid {
|
||||
@@ -16,22 +16,66 @@
|
||||
<body>
|
||||
<pre class="mermaid">
|
||||
stateDiagram
|
||||
title This is a title
|
||||
accDescription This is an accessible description
|
||||
State1
|
||||
accTitle: This is the accessible title
|
||||
accDescr:This is an accessible description
|
||||
State1 --> State2
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<pre class="mermaid">
|
||||
stateDiagram-v2
|
||||
title This is a title
|
||||
accDescription This is an accessible description
|
||||
State1
|
||||
accTitle: This is the accessible title
|
||||
accDescr: This is an accessible description
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<pre class="mermaid">
|
||||
stateDiagram
|
||||
accTitle: very very simple state
|
||||
accDescr: This is a state diagram showing one state
|
||||
State1
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<pre class="mermaid">
|
||||
stateDiagram
|
||||
[*] --> First
|
||||
state First {
|
||||
[*] --> second
|
||||
second --> [*]
|
||||
}
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
stateDiagram
|
||||
State1: The state with a note
|
||||
note right of State1
|
||||
Important information! You can write
|
||||
notes.
|
||||
end note
|
||||
State1 --> State2
|
||||
note left of State2 : This is the note to the left.
|
||||
</pre>
|
||||
<pre class="mermaid">
|
||||
stateDiagram
|
||||
State1
|
||||
note right of State1
|
||||
Line1<br>Line2<br />Line3<br />Line4<br />Line5
|
||||
end note
|
||||
</pre>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
theme: 'forest',
|
||||
theme: 'base',
|
||||
// themeCSS: '.node rect { fill: red; }',
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
|
@@ -77,7 +77,19 @@ When deployed within code, init is called before the graph/diagram description.
|
||||
|
||||
**for example**:
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
%%{init: {"theme": "default", "logLevel": 1 }}%%
|
||||
graph LR
|
||||
a-->b
|
||||
b-->c
|
||||
c-->d
|
||||
d-->e
|
||||
e-->f
|
||||
f-->g
|
||||
g-->
|
||||
```
|
||||
|
||||
```mermaid
|
||||
%%{init: {"theme": "default", "logLevel": 1 }}%%
|
||||
graph LR
|
||||
a-->b
|
||||
|
@@ -42,7 +42,13 @@ It is also possible to override site-wide theme settings locally, for a specific
|
||||
|
||||
**Following is an example:**
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
%%{init: {'theme':'base'}}%%
|
||||
graph TD
|
||||
a --> b
|
||||
```
|
||||
|
||||
```mermaid
|
||||
%%{init: {'theme':'base'}}%%
|
||||
graph TD
|
||||
a --> b
|
||||
@@ -58,7 +64,25 @@ The easiest way to make a custom theme is to start with the base theme, and just
|
||||
|
||||
Here is an example of overriding `primaryColor` and giving everything a different look, using `%%init%%`.
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
```
|
||||
|
||||
```mermaid
|
||||
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#ff0000'}}}%%
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
|
@@ -49,7 +49,15 @@ In our release process we rely heavily on visual regression tests using [applito
|
||||
|
||||
### [Flowchart](./flowchart.md?id=flowcharts-basic-syntax)
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
```
|
||||
|
||||
```mermaid
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
@@ -61,7 +69,21 @@ graph TD;
|
||||
|
||||
### [Sequence diagram](./sequenceDiagram.md)
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant Bob
|
||||
Alice->>John: Hello John, how are you?
|
||||
loop Healthcheck
|
||||
John->>John: Fight against hypochondria
|
||||
end
|
||||
Note right of John: Rational thoughts <br/>prevail!
|
||||
John-->>Alice: Great!
|
||||
John->>Bob: How about you?
|
||||
Bob-->>John: Jolly good!
|
||||
```
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant Bob
|
||||
@@ -79,7 +101,20 @@ sequenceDiagram
|
||||
|
||||
### [Gantt diagram](./gantt.md)
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Adding GANTT diagram to mermaid
|
||||
excludes weekdays 2014-01-10
|
||||
|
||||
section A section
|
||||
Completed task :done, des1, 2014-01-06,2014-01-08
|
||||
Active task :active, des2, 2014-01-09, 3d
|
||||
Future task : des3, after des2, 5d
|
||||
Future task2 : des4, after des3, 5d
|
||||
```
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Adding GANTT diagram to mermaid
|
||||
@@ -96,7 +131,24 @@ Future task2 : des4, after des3, 5d
|
||||
|
||||
### [Class diagram](./classDiagram.md)
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
Class03 *-- Class04
|
||||
Class05 o-- Class06
|
||||
Class07 .. Class08
|
||||
Class09 --> C2 : Where am i?
|
||||
Class09 --* C3
|
||||
Class09 --|> Class07
|
||||
Class07 : equals()
|
||||
Class07 : Object[] elementData
|
||||
Class01 : size()
|
||||
Class01 : int chimp
|
||||
Class01 : int gorilla
|
||||
Class08 <--> C2: Cool label
|
||||
```
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
Class01 <|-- AveryLongClass : Cool
|
||||
Class03 *-- Class04
|
||||
@@ -145,7 +197,15 @@ Class08 <--> C2: Cool label
|
||||
|
||||
### [Entity Relationship Diagram - :exclamation: experimental](./entityRelationshipDiagram.md)
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
erDiagram
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
|
||||
|
||||
```
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
ORDER ||--|{ LINE-ITEM : contains
|
||||
@@ -157,7 +217,19 @@ erDiagram
|
||||
|
||||
### [User Journey Diagram](./user-journey.md)
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
Make tea: 5: Me
|
||||
Go upstairs: 3: Me
|
||||
Do work: 1: Me, Cat
|
||||
section Go home
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 5: Me
|
||||
```
|
||||
|
||||
```mermaid
|
||||
journey
|
||||
title My working day
|
||||
section Go to work
|
||||
|
@@ -336,7 +336,12 @@ classE o-- classF : aggregation
|
||||
|
||||
Relations can logically represent an N:M association:
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
Animal <|--|> Zebra
|
||||
```
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
Animal <|--|> Zebra
|
||||
```
|
||||
@@ -468,7 +473,17 @@ class Color{
|
||||
|
||||
Comments can be entered within a class diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text until the next newline will be treated as a comment, including any class diagram syntax.
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
%% This whole line is a comment classDiagram class Shape <<interface>>
|
||||
class Shape{
|
||||
<<interface>>
|
||||
noOfVertices
|
||||
draw()
|
||||
}
|
||||
```
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
%% This whole line is a comment classDiagram class Shape <<interface>>
|
||||
class Shape{
|
||||
@@ -538,7 +553,15 @@ You would define these actions on a separate line after all classes have been de
|
||||
|
||||
_URL Link:_
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
class Shape
|
||||
link Shape "https://www.github.com" "This is a tooltip for a link"
|
||||
class Shape2
|
||||
click Shape2 href "https://www.github.com" "This is a tooltip for a link"
|
||||
```
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Shape
|
||||
link Shape "https://www.github.com" "This is a tooltip for a link"
|
||||
@@ -548,7 +571,15 @@ click Shape2 href "https://www.github.com" "This is a tooltip for a link"
|
||||
|
||||
_Callback:_
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
class Shape
|
||||
callback Shape "callbackFunction" "This is a tooltip for a callback"
|
||||
class Shape2
|
||||
click Shape2 call callbackFunction() "This is a tooltip for a callback"
|
||||
```
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Shape
|
||||
callback Shape "callbackFunction" "This is a tooltip for a callback"
|
||||
@@ -660,14 +691,27 @@ It is also possible to attach a class to a list of nodes in one statement:
|
||||
|
||||
A shorter form of adding a class is to attach the classname to the node using the `:::` operator:
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
class Animal:::cssClass
|
||||
```
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Animal:::cssClass
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
class Animal:::cssClass {
|
||||
-int sizeInFeet
|
||||
-canEat()
|
||||
}
|
||||
```
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Animal:::cssClass {
|
||||
-int sizeInFeet
|
||||
|
@@ -397,7 +397,15 @@ graph TB
|
||||
|
||||
If you describe the same diagram using the the basic syntax, it will take four lines:
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
graph TB
|
||||
A --> C
|
||||
A --> D
|
||||
B --> C
|
||||
B --> D
|
||||
```
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A --> C
|
||||
A --> D
|
||||
@@ -740,7 +748,13 @@ Beginner's tip—here's a full example of using interactive links in HTML:
|
||||
|
||||
Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text until the next newline will be treated as a comment, including all punctuation and any flow syntax.
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
graph LR
|
||||
%% this is a comment A -- text --> B{node}
|
||||
A -- text --> B -- text2 --> C
|
||||
```
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
%% this is a comment A -- text --> B{node}
|
||||
A -- text --> B -- text2 --> C
|
||||
|
@@ -114,7 +114,13 @@ Cardinality is a property that describes how many elements of another entity can
|
||||
|
||||
Relationships may be classified as either _identifying_ or _non-identifying_ and these are rendered with either solid or dashed lines respectively. This is relevant when one of the entities in question can not have independent existence without the other. For example a firm that insures people to drive cars might need to store data on `NAMED-DRIVER`s. In modelling this we might start out by observing that a `CAR` can be driven by many `PERSON` instances, and a `PERSON` can drive many `CAR`s - both entities can exist without the other, so this is a non-identifying relationship that we might specify in Mermaid as: `PERSON }|..|{ CAR : "driver"`. Note the two dots in the middle of the relationship that will result in a dashed line being drawn between the two entities. But when this many-to-many relationship is resolved into two one-to-many relationships, we observe that a `NAMED-DRIVER` cannot exist without both a `PERSON` and a `CAR` - the relationships become identifying and would be specified using hyphens, which translate to a solid line:
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
erDiagram
|
||||
CAR ||--o{ NAMED-DRIVER : allows
|
||||
PERSON ||--o{ NAMED-DRIVER : is
|
||||
```
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
CAR ||--o{ NAMED-DRIVER : allows
|
||||
PERSON ||--o{ NAMED-DRIVER : is
|
||||
|
@@ -403,7 +403,15 @@ word of warning, one could go overboard with this making the flowchart harder to
|
||||
markdown form. The Swedish word `lagom` comes to mind. It means, not too much and not too little.
|
||||
This goes for expressive syntaxes as well.
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
flowchart TB
|
||||
A --> C
|
||||
A --> D
|
||||
B --> C
|
||||
B --> D
|
||||
```
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
A --> C
|
||||
A --> D
|
||||
@@ -671,6 +679,8 @@ flowchart LR
|
||||
B1 --> B2
|
||||
```
|
||||
|
||||
**A clarification is in order here.** The direction statement affects the layout of a subgraph but only as long as it does not have any links leading in or out of it. The reason for this is that if you have links in or out then the graph of nodes is not longer the set of nodes in the subgraph but actually the set of nodes of the parent including the ones in the subgraph. One can see it as that the direction of the container gets injected in the subgraph with a link.
|
||||
|
||||
## Interaction
|
||||
|
||||
It is possible to bind a click event to a node, the click can lead to either a javascript callback or to a link which will be opened in a new browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`.
|
||||
@@ -778,7 +788,13 @@ Beginner's tip—a full example using interactive links in a html context:
|
||||
|
||||
Comments can be entered within a flow diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any flow syntax
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
flowchart LR
|
||||
%% this is a comment A -- text --> B{node}
|
||||
A -- text --> B -- text2 --> C
|
||||
```
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
%% this is a comment A -- text --> B{node}
|
||||
A -- text --> B -- text2 --> C
|
||||
|
@@ -234,7 +234,21 @@ More info in: https://github.com/mbostock/d3/wiki/Time-Formatting
|
||||
|
||||
Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
gantt
|
||||
title A Gantt Diagram
|
||||
%% this is a comment
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
|
||||
```
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
title A Gantt Diagram
|
||||
%% this is a comment
|
||||
|
@@ -393,44 +393,6 @@ Let see an example:
|
||||
commit id:"C"
|
||||
```
|
||||
|
||||
By default, the cherry-picked commit from commit with id `A` will be labeled `cherry-pick:A`. You can provide your own custom tag instead to override this behavior, using the same syntax as the `commit` keyword:
|
||||
|
||||
```mermaid-example
|
||||
gitGraph
|
||||
commit id: "ZERO"
|
||||
branch develop
|
||||
commit id:"A"
|
||||
checkout main
|
||||
commit id:"ONE"
|
||||
checkout develop
|
||||
commit id:"B"
|
||||
checkout main
|
||||
commit id:"TWO"
|
||||
cherry-pick id:"A" tag:"fix"
|
||||
commit id:"THREE"
|
||||
checkout develop
|
||||
commit id:"C"
|
||||
```
|
||||
|
||||
```mermaid
|
||||
gitGraph
|
||||
commit id: "ZERO"
|
||||
branch develop
|
||||
commit id:"A"
|
||||
checkout main
|
||||
commit id:"ONE"
|
||||
checkout develop
|
||||
commit id:"B"
|
||||
checkout main
|
||||
commit id:"TWO"
|
||||
cherry-pick id:"A" tag:"fix"
|
||||
commit id:"THREE"
|
||||
checkout develop
|
||||
commit id:"C"
|
||||
```
|
||||
|
||||
To suppress the tag entirely, use `tag:""` (empty string).
|
||||
|
||||
## Gitgraph specific configuration options
|
||||
|
||||
In Mermaid, you have the option to configure the gitgraph diagram. You can configure the following options:
|
||||
|
@@ -19,6 +19,7 @@ They also serve as proof of concept, for the variety of things that can be built
|
||||
- [Joplin](https://joplinapp.org) (**Native support**)
|
||||
- [Notion](https://notion.so) (**Native support**)
|
||||
- [Observable](https://observablehq.com/@observablehq/mermaid) (**Native support**)
|
||||
- [Obsidian](https://help.obsidian.md/How+to/Format+your+notes#Diagram) (**Native support**)
|
||||
- [GitBook](https://gitbook.com)
|
||||
- [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
|
||||
- [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
|
||||
@@ -51,6 +52,8 @@ They also serve as proof of concept, for the variety of things that can be built
|
||||
|
||||
## CMS
|
||||
|
||||
- [VitePress](https://vitepress.vuejs.org/)
|
||||
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
|
||||
- [VuePress](https://vuepress.vuejs.org/)
|
||||
- [Plugin for Mermaid.js](https://github.com/eFrane/vuepress-plugin-mermaidjs)
|
||||
- [Grav CMS](https://getgrav.org/)
|
||||
|
@@ -481,7 +481,14 @@ sequenceDiagram
|
||||
|
||||
Comments can be entered within a sequence diagram, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
sequenceDiagram
|
||||
Alice->>John: Hello John, how are you?
|
||||
%% this is a comment
|
||||
John-->>Alice: Great!
|
||||
```
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
Alice->>John: Hello John, how are you?
|
||||
%% this is a comment
|
||||
@@ -554,7 +561,20 @@ This can be configured by adding one or more link lines with the format:
|
||||
|
||||
link <actor>: <link-label> @ <link-url>
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant John
|
||||
link Alice: Dashboard @ https://dashboard.contoso.com/alice
|
||||
link Alice: Wiki @ https://wiki.contoso.com/alice
|
||||
link John: Dashboard @ https://dashboard.contoso.com/john
|
||||
link John: Wiki @ https://wiki.contoso.com/john
|
||||
Alice->>John: Hello John, how are you?
|
||||
John-->>Alice: Great!
|
||||
Alice-)John: See you later!
|
||||
```
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Alice
|
||||
participant John
|
||||
|
@@ -403,7 +403,18 @@ stateDiagram
|
||||
|
||||
Comments can be entered within a state diagram chart, which will be ignored by the parser. Comments need to be on their own line, and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
stateDiagram-v2
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
%% this is a comment
|
||||
Still --> Moving
|
||||
Moving --> Still %% another comment
|
||||
Moving --> Crash
|
||||
Crash --> [*]
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
|
@@ -41,7 +41,13 @@ mermaidAPI.initialize({
|
||||
|
||||
When Generating a diagram using on a webpage that supports mermaid. It is also possible to override site-wide theme settings locally, for a specific diagram, using directives, as long as it is not prohibited by the `secure` array.
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
%%{init: {'theme':'base'}}%%
|
||||
graph TD
|
||||
a --> b
|
||||
```
|
||||
|
||||
```mermaid
|
||||
%%{init: {'theme':'base'}}%%
|
||||
graph TD
|
||||
a --> b
|
||||
@@ -329,7 +335,25 @@ In the following examples, the directive `init` is used, with the `theme` being
|
||||
|
||||
### Flowchart
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
B --> C{Let me think}
|
||||
B --> G[/Another/]
|
||||
C ==>|One| D[Laptop]
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
subgraph section
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
end
|
||||
```
|
||||
|
||||
```mermaid
|
||||
%%{init: {'securityLevel': 'loose', 'theme':'base'}}%%
|
||||
graph TD
|
||||
A[Christmas] -->|Get money| B(Go shopping)
|
||||
|
@@ -1,24 +0,0 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const path = require('path');
|
||||
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
||||
module.exports = {
|
||||
testEnvironment: 'jsdom',
|
||||
preset: 'ts-jest',
|
||||
transform: {
|
||||
'^.+\\.[jt]sx?$': 'esbuild-jest',
|
||||
'^.+\\.jison$': [
|
||||
path.resolve(__dirname, './src/jison/transformer.js'),
|
||||
{ 'token-stack': true },
|
||||
],
|
||||
},
|
||||
coveragePathIgnorePatterns: [
|
||||
'/node_modules/',
|
||||
'^.+\\.jison$', // might be able to fix in future if .jison adds source-map support
|
||||
],
|
||||
transformIgnorePatterns: ['/node_modules/(?!dagre-d3-renderer/lib|khroma).*\\.js'],
|
||||
testPathIgnorePatterns: ['/node_modules/', '.cache', './cypress'],
|
||||
moduleNameMapper: {
|
||||
'\\.(css|scss)$': 'identity-obj-proxy',
|
||||
},
|
||||
moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx', 'node', 'jison'],
|
||||
};
|
66
package.json
66
package.json
@@ -1,10 +1,11 @@
|
||||
{
|
||||
"name": "mermaid",
|
||||
"version": "9.2.0-rc1",
|
||||
"version": "9.2.0-rc2",
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "dist/mermaid.core.mjs",
|
||||
"module": "dist/mermaid.core.mjs",
|
||||
"types": "dist/mermaid.d.ts",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./dist/mermaid.min.js",
|
||||
@@ -24,27 +25,24 @@
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build:code": "node .esbuild/esbuild.cjs",
|
||||
"build:vite": "ts-node-esm --transpileOnly --project=.vite/tsconfig.json .vite/build.ts",
|
||||
"build:types": "tsc -p ./tsconfig.json --emitDeclarationOnly",
|
||||
"build:webpack": "webpack --mode production --progress --color",
|
||||
"build:watch": "yarn build:code --watch",
|
||||
"build:new": "concurrently \"yarn build:code\" \"yarn build:types\"",
|
||||
"build": "yarn clean; yarn build:webpack",
|
||||
"docs:build": "ts-node-esm src/docs.mts",
|
||||
"docs:verify": "ts-node-esm src/docs.mts --verify",
|
||||
"postbuild": "documentation build src/mermaidAPI.ts src/config.ts src/defaultConfig.ts --shallow -f md --markdown-toc false > src/docs/Setup.md && prettier --write src/docs/Setup.md && yarn docs:build",
|
||||
"build": "yarn clean; concurrently \"yarn build:vite\" \"yarn build:types\"",
|
||||
"dev": "concurrently \"yarn build:vite --watch\" \"ts-node-esm .vite/server\"",
|
||||
"docs:build": "ts-node-esm --transpileOnly src/docs.mts",
|
||||
"docs:verify": "yarn docs:build --verify",
|
||||
"postbuild": "documentation build src/mermaidAPI.ts src/config.ts src/defaultConfig.ts --shallow -f md --markdown-toc false > src/docs/Setup.md && prettier --write src/docs/Setup.md",
|
||||
"release": "yarn build",
|
||||
"lint": "eslint --cache --ignore-path .gitignore . && prettier --check .",
|
||||
"lint": "eslint --cache --ignore-path .gitignore . && yarn lint:jison && prettier --check .",
|
||||
"lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .",
|
||||
"e2e:depr": "yarn lint && jest e2e --config e2e/jest.config.js",
|
||||
"lint:jison": "ts-node-esm --transpileOnly src/jison/lint.mts",
|
||||
"cypress": "cypress run",
|
||||
"cypress:open": "cypress open",
|
||||
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
|
||||
"e2e-upd": "yarn lint && jest e2e -u --config e2e/jest.config.js",
|
||||
"dev": "webpack serve --config ./.webpack/webpack.config.e2e.babel.js",
|
||||
"ci": "jest src/.*",
|
||||
"test": "yarn lint && jest src/.*",
|
||||
"test:watch": "jest --watch src",
|
||||
"ci": "vitest run",
|
||||
"test": "yarn lint && vitest run",
|
||||
"test:watch": "vitest --coverage --watch",
|
||||
"prepublishOnly": "yarn build && yarn test",
|
||||
"prepare": "concurrently \"husky install\" \"yarn build\"",
|
||||
"pre-commit": "lint-staged"
|
||||
@@ -81,30 +79,26 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@applitools/eyes-cypress": "^3.25.7",
|
||||
"@babel/core": "^7.19.0",
|
||||
"@babel/eslint-parser": "^7.14.7",
|
||||
"@babel/preset-env": "^7.19.0",
|
||||
"@babel/register": "^7.14.5",
|
||||
"@commitlint/cli": "^17.1.2",
|
||||
"@commitlint/config-conventional": "^17.0.0",
|
||||
"@types/d3": "^7.4.0",
|
||||
"@types/dompurify": "^2.3.4",
|
||||
"@types/jest": "^28.1.7",
|
||||
"@types/lodash": "^4.14.184",
|
||||
"@types/eslint": "^8.4.6",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/jsdom": "^20.0.0",
|
||||
"@types/lodash": "^4.14.185",
|
||||
"@types/prettier": "^2.7.1",
|
||||
"@types/stylis": "^4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.37.0",
|
||||
"@typescript-eslint/parser": "^5.37.0",
|
||||
"babel-jest": "^29.0.3",
|
||||
"babel-loader": "^8.2.2",
|
||||
"@vitest/coverage-c8": "^0.23.2",
|
||||
"@vitest/ui": "^0.23.2",
|
||||
"concurrently": "^7.4.0",
|
||||
"css-to-string-loader": "^0.1.3",
|
||||
"coveralls": "^3.1.1",
|
||||
"cypress": "^10.0.0",
|
||||
"cypress-image-snapshot": "^4.0.1",
|
||||
"documentation": "13.2.0",
|
||||
"esbuild": "^0.15.6",
|
||||
"esbuild-jest": "^0.5.0",
|
||||
"esbuild-loader": "^2.19.0",
|
||||
"eslint": "^8.23.1",
|
||||
"eslint": "^8.24.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-html": "^7.1.0",
|
||||
@@ -112,13 +106,12 @@
|
||||
"eslint-plugin-jsdoc": "^39.3.6",
|
||||
"eslint-plugin-json": "^3.1.0",
|
||||
"eslint-plugin-markdown": "^3.0.0",
|
||||
"express": "^4.18.1",
|
||||
"globby": "^13.1.2",
|
||||
"husky": "^8.0.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^28.0.3",
|
||||
"jest-environment-jsdom": "^29.0.3",
|
||||
"jison": "^0.4.18",
|
||||
"js-base64": "3.7.2",
|
||||
"jsdom": "^20.0.0",
|
||||
"lint-staged": "^13.0.0",
|
||||
"moment": "^2.23.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
@@ -126,18 +119,13 @@
|
||||
"prettier-plugin-jsdoc": "^0.4.2",
|
||||
"remark": "^14.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.79.1",
|
||||
"start-server-and-test": "^1.12.6",
|
||||
"terser-webpack-plugin": "^5.3.6",
|
||||
"ts-jest": "^28.0.8",
|
||||
"ts-loader": "^9.3.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.3",
|
||||
"unist-util-flatmap": "^1.0.0",
|
||||
"webpack": "^5.53.0",
|
||||
"webpack-cli": "^4.7.2",
|
||||
"webpack-dev-server": "^4.11.0",
|
||||
"webpack-merge": "^5.8.0",
|
||||
"webpack-node-externals": "^3.0.0"
|
||||
"vite": "^3.0.9",
|
||||
"vitest": "^0.23.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"d3": "^7.0.0"
|
||||
|
@@ -1,3 +0,0 @@
|
||||
module.exports = function (txt) {
|
||||
return txt;
|
||||
};
|
@@ -1,18 +1,15 @@
|
||||
/**
|
||||
* Mocks for `./mermaidAPI`.
|
||||
*
|
||||
* We can't easily use `jest.spyOn(mermaidAPI, "function")` since the object is frozen with `Object.freeze()`.
|
||||
* We can't easily use `vi.spyOn(mermaidAPI, "function")` since the object is frozen with `Object.freeze()`.
|
||||
*/
|
||||
import * as configApi from '../config';
|
||||
|
||||
import { vi } from 'vitest';
|
||||
import { addDiagrams } from '../diagram-api/diagram-orchestration';
|
||||
import Diagram from '../Diagram';
|
||||
|
||||
// Normally, we could just do the following to get the original `parse()`
|
||||
// implementation, however, requireActual isn't currently supported in Jest
|
||||
// for ESM, see https://github.com/facebook/jest/issues/9430
|
||||
// and https://github.com/facebook/jest/pull/10976
|
||||
// const {parse} = jest.requireActual("./mermaidAPI");
|
||||
// implementation, however, requireActual returns a promise and it's not documented how to use withing mock file.
|
||||
|
||||
let hasLoadedDiagrams = false;
|
||||
/**
|
||||
@@ -31,10 +28,10 @@ function parse(text: string, parseError?: Function): boolean {
|
||||
|
||||
// original version cannot be modified since it was frozen with `Object.freeze()`
|
||||
export const mermaidAPI = {
|
||||
render: jest.fn(),
|
||||
render: vi.fn(),
|
||||
parse,
|
||||
parseDirective: jest.fn(),
|
||||
initialize: jest.fn(),
|
||||
parseDirective: vi.fn(),
|
||||
initialize: vi.fn(),
|
||||
getConfig: configApi.getConfig,
|
||||
setConfig: configApi.setConfig,
|
||||
getSiteConfig: configApi.getSiteConfig,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { parser } from './parser/classDiagram';
|
||||
import classDb from './classDb';
|
||||
|
||||
const spyOn = jest.spyOn;
|
||||
import { vi } from 'vitest';
|
||||
const spyOn = vi.spyOn;
|
||||
|
||||
describe('class diagram, ', function () {
|
||||
describe('when parsing an info graph it', function () {
|
||||
@@ -14,7 +14,7 @@ describe('class diagram, ', function () {
|
||||
|
||||
parser.parse(str);
|
||||
});
|
||||
xit('should handle a leading newline axa', function () {
|
||||
it.skip('should handle a leading newline axa', function () {
|
||||
const str = '\nclassDiagram\n' + 'class Car';
|
||||
|
||||
try {
|
||||
|
@@ -6,12 +6,12 @@ const getStyles = (options) =>
|
||||
}
|
||||
|
||||
.attributeBoxOdd {
|
||||
fill: #ffffff;
|
||||
fill: ${options.attributeBackgroundColorOdd};
|
||||
stroke: ${options.nodeBorder};
|
||||
}
|
||||
|
||||
.attributeBoxEven {
|
||||
fill: #f2f2f2;
|
||||
fill: ${options.attributeBackgroundColorEven};
|
||||
stroke: ${options.nodeBorder};
|
||||
}
|
||||
|
||||
|
@@ -4,9 +4,6 @@ import flowRenderer from './flowRenderer';
|
||||
import Diagram from '../../Diagram';
|
||||
import { addDiagrams } from '../../diagram-api/diagram-orchestration';
|
||||
addDiagrams();
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when using mermaid and ', function () {
|
||||
describe('when calling addEdges ', function () {
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import flowDb from '../flowDb';
|
||||
import flow from './flow';
|
||||
import { setConfig } from '../../../config';
|
||||
|
||||
const spyOn = jest.spyOn;
|
||||
import { vi } from 'vitest';
|
||||
const spyOn = vi.spyOn;
|
||||
|
||||
setConfig({
|
||||
securityLevel: 'strict',
|
||||
|
@@ -284,7 +284,7 @@ describe('[Text] when parsing', () => {
|
||||
|
||||
expect(edges[0].text).toBe('text including graph space and v');
|
||||
});
|
||||
// xit('should handle text on open links',function(){
|
||||
// it.skip('should handle text on open links',function(){
|
||||
// const res = flow.parser.parse('graph TD;A-- text including graph space --B');
|
||||
//
|
||||
// const vert = flow.parser.yy.getVertices();
|
||||
@@ -324,7 +324,7 @@ describe('[Text] when parsing', () => {
|
||||
expect(vert['C'].type).toBe('round');
|
||||
expect(vert['C'].text).toBe('Chimpansen hoppar åäö <br> - ÅÄÖ');
|
||||
});
|
||||
// xit('should handle åäö, minus and space and br',function(){
|
||||
// it.skip('should handle åäö, minus and space and br',function(){
|
||||
// const res = flow.parser.parse('graph TD; A[Object(foo,bar)]-->B(Thing);');
|
||||
//
|
||||
// const vert = flow.parser.yy.getVertices();
|
||||
|
@@ -62,7 +62,7 @@ describe('when parsing subgraphs', function () {
|
||||
expect(subgraph.id).toBe('some-id');
|
||||
});
|
||||
|
||||
xit('should handle subgraph without id and space in title', function () {
|
||||
it.skip('should handle subgraph without id and space in title', function () {
|
||||
const res = flow.parser.parse('graph TB\nsubgraph Some Title\n\ta1-->a2\nend');
|
||||
const subgraphs = flow.parser.yy.getSubGraphs();
|
||||
expect(subgraphs.length).toBe(1);
|
||||
|
@@ -1,5 +1,8 @@
|
||||
// @ts-nocheck TODO: Fix TS
|
||||
import moment from 'moment-mini';
|
||||
import ganttDb from './ganttDb';
|
||||
import { it, describe } from 'vitest';
|
||||
import { convert } from '../../tests/util';
|
||||
|
||||
describe('when using the ganttDb', function () {
|
||||
beforeEach(function () {
|
||||
@@ -7,14 +10,23 @@ describe('when using the ganttDb', function () {
|
||||
});
|
||||
|
||||
describe('when using duration', function () {
|
||||
it.each`
|
||||
it.each([{ str: '1d', expected: moment.duration(1, 'd') }])(
|
||||
'should %s resulting in $o duration',
|
||||
({ str, expected }) => {
|
||||
expect(ganttDb.parseDuration(str)).toEqual(expected);
|
||||
}
|
||||
);
|
||||
|
||||
it.each(
|
||||
convert`
|
||||
str | expected
|
||||
${'1d'} | ${moment.duration(1, 'd')}
|
||||
${'2w'} | ${moment.duration(2, 'w')}
|
||||
${'1ms'} | ${moment.duration(1, 'ms')}
|
||||
${'0.1s'} | ${moment.duration(100, 'ms')}
|
||||
${'1f'} | ${moment.duration.invalid()}
|
||||
`('should $str resulting in $expected duration', ({ str, expected }) => {
|
||||
`
|
||||
)('should $str resulting in $expected duration', ({ str, expected }) => {
|
||||
expect(ganttDb.parseDuration(str)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
@@ -31,7 +43,7 @@ describe('when using the ganttDb', function () {
|
||||
ganttDb.clear();
|
||||
});
|
||||
|
||||
it.each`
|
||||
it.each(convert`
|
||||
fn | expected
|
||||
${'getTasks'} | ${[]}
|
||||
${'getAccTitle'} | ${''}
|
||||
@@ -42,12 +54,13 @@ describe('when using the ganttDb', function () {
|
||||
${'getExcludes'} | ${[]}
|
||||
${'getSections'} | ${[]}
|
||||
${'endDatesAreInclusive'} | ${false}
|
||||
`('should clear $fn', ({ fn, expected }) => {
|
||||
`)('should clear $fn', ({ fn, expected }) => {
|
||||
expect(ganttDb[fn]()).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it.each`
|
||||
// prettier-ignore
|
||||
it.each(convert`
|
||||
testName | section | taskName | taskData | expStartDate | expEndDate | expId | expTask
|
||||
${'should handle fixed dates'} | ${'testa1'} | ${'test1'} | ${'id1,2013-01-01,2013-01-12'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 12)} | ${'id1'} | ${'test1'}
|
||||
${'should handle duration (days) instead of fixed date to determine end date'} | ${'testa1'} | ${'test1'} | ${'id1,2013-01-01,2d'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 3)} | ${'id1'} | ${'test1'}
|
||||
@@ -57,7 +70,7 @@ describe('when using the ganttDb', function () {
|
||||
${'should handle duration (weeks) instead of fixed date to determine end date'} | ${'testa1'} | ${'test1'} | ${'id1,2013-01-01,2w'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 15)} | ${'id1'} | ${'test1'}
|
||||
${'should handle fixed dates without id'} | ${'testa1'} | ${'test1'} | ${'2013-01-01,2013-01-12'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 12)} | ${'task1'} | ${'test1'}
|
||||
${'should handle duration instead of a fixed date to determine end date without id'} | ${'testa1'} | ${'test1'} | ${'2013-01-01,4d'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 5)} | ${'task1'} | ${'test1'}
|
||||
`('$testName', ({ section, taskName, taskData, expStartDate, expEndDate, expId, expTask }) => {
|
||||
`)('$testName', ({ section, taskName, taskData, expStartDate, expEndDate, expId, expTask }) => {
|
||||
ganttDb.setDateFormat('YYYY-MM-DD');
|
||||
ganttDb.addSection(section);
|
||||
ganttDb.addTask(taskName, taskData);
|
||||
@@ -68,14 +81,15 @@ describe('when using the ganttDb', function () {
|
||||
expect(tasks[0].task).toEqual(expTask);
|
||||
});
|
||||
|
||||
it.each`
|
||||
// prettier-ignore
|
||||
it.each(convert`
|
||||
section | taskName1 | taskName2 | taskData1 | taskData2 | expStartDate2 | expEndDate2 | expId2 | expTask2
|
||||
${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'id2,after id1,1d'} | ${new Date(2013, 0, 15)} | ${undefined} | ${'id2'} | ${'test2'}
|
||||
${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'id2,after id3,1d'} | ${new Date(new Date().setHours(0, 0, 0, 0))} | ${undefined} | ${'id2'} | ${'test2'}
|
||||
${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'after id1,1d'} | ${new Date(2013, 0, 15)} | ${undefined} | ${'task1'} | ${'test2'}
|
||||
${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'2013-01-26'} | ${new Date(2013, 0, 15)} | ${new Date(2013, 0, 26)} | ${'task1'} | ${'test2'}
|
||||
${'testa1'} | ${'test1'} | ${'test2'} | ${'id1,2013-01-01,2w'} | ${'2d'} | ${new Date(2013, 0, 15)} | ${new Date(2013, 0, 17)} | ${'task1'} | ${'test2'}
|
||||
`(
|
||||
`)(
|
||||
'$testName',
|
||||
({
|
||||
section,
|
||||
@@ -381,11 +395,11 @@ describe('when using the ganttDb', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it.each`
|
||||
it.each(convert`
|
||||
type | expected
|
||||
${'hide'} | ${'off'}
|
||||
${'style'} | ${'stoke:stroke-width:5px,stroke:#00f,opacity:0.5'}
|
||||
`('should ${type} today marker', ({ expected }) => {
|
||||
`)('should ${type} today marker', ({ expected }) => {
|
||||
ganttDb.setTodayMarker(expected);
|
||||
expect(ganttDb.getTodayMarker()).toEqual(expected);
|
||||
});
|
@@ -1,7 +1,8 @@
|
||||
import { parser } from './gantt';
|
||||
import ganttDb from '../ganttDb';
|
||||
|
||||
const spyOn = jest.spyOn;
|
||||
import { convert } from '../../../tests/util';
|
||||
import { vi } from 'vitest';
|
||||
const spyOn = vi.spyOn;
|
||||
const parserFnConstructor = (str) => {
|
||||
return () => {
|
||||
parser.parse(str);
|
||||
@@ -92,14 +93,14 @@ describe('when parsing a gantt diagram it', function () {
|
||||
expect(tasks[0].id).toEqual('des1');
|
||||
expect(tasks[0].task).toEqual('Design jison grammar');
|
||||
});
|
||||
it.each`
|
||||
it.each(convert`
|
||||
tags | milestone | done | crit | active
|
||||
${'milestone'} | ${true} | ${false} | ${false} | ${false}
|
||||
${'done'} | ${false} | ${true} | ${false} | ${false}
|
||||
${'crit'} | ${false} | ${false} | ${true} | ${false}
|
||||
${'active'} | ${false} | ${false} | ${false} | ${true}
|
||||
${'crit,milestone,done'} | ${true} | ${true} | ${true} | ${false}
|
||||
`('should handle a task with tags $tags', ({ tags, milestone, done, crit, active }) => {
|
||||
`)('should handle a task with tags $tags', ({ tags, milestone, done, crit, active }) => {
|
||||
const str =
|
||||
'gantt\n' +
|
||||
'dateFormat YYYY-MM-DD\n' +
|
||||
|
@@ -25,15 +25,15 @@ describe('more than one sequence diagram', () => {
|
||||
Alice->Bob:Hello Bob, how are you?
|
||||
Bob-->Alice: I am good thanks!`);
|
||||
expect(diagram1.db.getMessages()).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
[
|
||||
{
|
||||
"from": "Alice",
|
||||
"message": "Hello Bob, how are you?",
|
||||
"to": "Bob",
|
||||
"type": 5,
|
||||
"wrap": false,
|
||||
},
|
||||
Object {
|
||||
{
|
||||
"from": "Bob",
|
||||
"message": "I am good thanks!",
|
||||
"to": "Alice",
|
||||
@@ -48,15 +48,15 @@ describe('more than one sequence diagram', () => {
|
||||
Bob-->Alice: I am good thanks!`);
|
||||
|
||||
expect(diagram2.db.getMessages()).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
[
|
||||
{
|
||||
"from": "Alice",
|
||||
"message": "Hello Bob, how are you?",
|
||||
"to": "Bob",
|
||||
"type": 5,
|
||||
"wrap": false,
|
||||
},
|
||||
Object {
|
||||
{
|
||||
"from": "Bob",
|
||||
"message": "I am good thanks!",
|
||||
"to": "Alice",
|
||||
@@ -73,15 +73,15 @@ describe('more than one sequence diagram', () => {
|
||||
John-->Alice: I am good thanks!`);
|
||||
|
||||
expect(diagram3.db.getMessages()).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
[
|
||||
{
|
||||
"from": "Alice",
|
||||
"message": "Hello John, how are you?",
|
||||
"to": "John",
|
||||
"type": 5,
|
||||
"wrap": false,
|
||||
},
|
||||
Object {
|
||||
{
|
||||
"from": "John",
|
||||
"message": "I am good thanks!",
|
||||
"to": "Alice",
|
||||
|
@@ -389,7 +389,7 @@ describe('state diagram, ', function () {
|
||||
});
|
||||
});
|
||||
describe('when parsing an ignored info graph it', function () {
|
||||
xit('should handle if statements', function () {
|
||||
it.skip('should handle if statements', function () {
|
||||
const str = `stateDiagram\n
|
||||
[*] --> "Order Submitted"
|
||||
if "Payment Accepted" then
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import journeyDb from './journeyDb';
|
||||
import { convert } from '../../tests/util';
|
||||
|
||||
describe('when using the journeyDb', function () {
|
||||
beforeEach(function () {
|
||||
@@ -13,13 +14,13 @@ describe('when using the journeyDb', function () {
|
||||
journeyDb.clear();
|
||||
});
|
||||
|
||||
it.each`
|
||||
it.each(convert`
|
||||
fn | expected
|
||||
${'getTasks'} | ${[]}
|
||||
${'getAccTitle'} | ${''}
|
||||
${'getSections'} | ${[]}
|
||||
${'getActors'} | ${[]}
|
||||
`('should clear $fn', ({ fn, expected }) => {
|
||||
`)('should clear $fn', ({ fn, expected }) => {
|
||||
expect(journeyDb[fn]()).toEqual(expected);
|
||||
});
|
||||
});
|
||||
@@ -31,18 +32,18 @@ describe('when using the journeyDb', function () {
|
||||
journeyDb.addTask('test2', '1: id2');
|
||||
journeyDb.clear();
|
||||
});
|
||||
it.each`
|
||||
it.each(convert`
|
||||
fn | expected
|
||||
${'getTasks'} | ${[]}
|
||||
${'getAccTitle'} | ${''}
|
||||
${'getAccDescription'} | ${''}
|
||||
${'getSections'} | ${[]}
|
||||
`('should clear $fn', ({ fn, expected }) => {
|
||||
`)('should clear $fn', ({ fn, expected }) => {
|
||||
expect(journeyDb[fn]()).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tasks and actors should be added', function () {
|
||||
it('tasks and actors should be added', function () {
|
||||
journeyDb.setAccTitle('Shopping');
|
||||
journeyDb.setAccDescription('A user journey for family shopping');
|
||||
journeyDb.addSection('Journey to the shops');
|
||||
|
@@ -132,8 +132,6 @@ const getStyles = (options) =>
|
||||
.actor-5 {
|
||||
${options.actor5 ? `fill: ${options.actor5}` : ''};
|
||||
}
|
||||
|
||||
}
|
||||
`;
|
||||
|
||||
export default getStyles;
|
||||
|
74
src/docs.mts
74
src/docs.mts
@@ -1,11 +1,10 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
/**
|
||||
* @file Transform documentation source files into files suitable for publishing
|
||||
* and optionally copy the transformed files from the source directory to the
|
||||
* directory used for the final, published documentation directory. The list
|
||||
* of files transformed and copied to final documentation directory are logged
|
||||
* to the console. If a file in the source directory has the same contents in
|
||||
* @file Transform documentation source files into files suitable for publishing and optionally copy
|
||||
* the transformed files from the source directory to the directory used for the final, published
|
||||
* documentation directory. The list of files transformed and copied to final documentation
|
||||
* directory are logged to the console. If a file in the source directory has the same contents in
|
||||
* the final directory, nothing is done (the final directory is up-to-date).
|
||||
* @example
|
||||
* docs
|
||||
@@ -24,12 +23,12 @@
|
||||
* If the --git option is used, the command `git add docs` will be run after all transformations (and/or verifications) have completed successfully
|
||||
* If not files were transformed, the git command is not run.
|
||||
*
|
||||
* @todo Ensure that the documentation source and final paths are correct by
|
||||
* using process.cwd() to get their absolute paths. Ensures that the location
|
||||
* of those 2 directories is not dependent on where this file resides.
|
||||
* @todo Ensure that the documentation source and final paths are correct by using process.cwd() to
|
||||
* get their absolute paths. Ensures that the location of those 2 directories is not dependent on
|
||||
* where this file resides.
|
||||
*
|
||||
* @todo Write a test file for this. (Will need to be able to deal .mts file.
|
||||
* Jest has trouble with it.)
|
||||
* @todo Write a test file for this. (Will need to be able to deal .mts file. Jest has trouble with
|
||||
* it.)
|
||||
*/
|
||||
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
||||
import { exec } from 'child_process';
|
||||
@@ -68,14 +67,13 @@ const prettierConfig: prettier.Config = {
|
||||
let filesWereTransformed = false;
|
||||
|
||||
/**
|
||||
* Given a source file name and path, return the documentation destination full
|
||||
* path and file name Create the destination path if it does not already exist.
|
||||
* Given a source file name and path, return the documentation destination full path and file name
|
||||
* Create the destination path if it does not already exist.
|
||||
*
|
||||
* @param {string} file - Name of the file (including full path)
|
||||
* @returns {string} Name of the file with the path changed from the source
|
||||
* directory to final documentation directory
|
||||
* @todo Possible Improvement: combine with lint-staged to only copy files that
|
||||
* have changed
|
||||
* @returns {string} Name of the file with the path changed from the source directory to final
|
||||
* documentation directory
|
||||
* @todo Possible Improvement: combine with lint-staged to only copy files that have changed
|
||||
*/
|
||||
const changeToFinalDocDir = (file: string): string => {
|
||||
const newDir = file.replace(SOURCE_DOCS_DIR, FINAL_DOCS_DIR);
|
||||
@@ -84,8 +82,8 @@ const changeToFinalDocDir = (file: string): string => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Log messages to the console showing if the transformed file copied to the
|
||||
* final documentation directory or still needs to be copied.
|
||||
* Log messages to the console showing if the transformed file copied to the final documentation
|
||||
* directory or still needs to be copied.
|
||||
*
|
||||
* @param {string} filename Name of the file that was transformed
|
||||
* @param {boolean} wasCopied Whether or not the file was copied
|
||||
@@ -101,14 +99,13 @@ const logWasOrShouldBeTransformed = (filename: string, wasCopied: boolean) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* If the file contents were transformed, set the _filesWereTransformed_ flag to
|
||||
* true and copy the transformed contents to the final documentation directory
|
||||
* if the doCopy flag is true. Log messages to the console.
|
||||
* If the file contents were transformed, set the _filesWereTransformed_ flag to true and copy the
|
||||
* transformed contents to the final documentation directory if the doCopy flag is true. Log
|
||||
* messages to the console.
|
||||
*
|
||||
* @param {string} filename Name of the file that will be verified
|
||||
* @param {boolean} [doCopy=false] Whether we should copy that
|
||||
* transformedContents to the final documentation directory. Default is
|
||||
* `false`. Default is `false`
|
||||
* @param {boolean} [doCopy=false] Whether we should copy that transformedContents to the final
|
||||
* documentation directory. Default is `false`
|
||||
* @param {string} [transformedContent] New contents for the file
|
||||
*/
|
||||
const copyTransformedContents = (filename: string, doCopy = false, transformedContent?: string) => {
|
||||
@@ -133,15 +130,14 @@ const readSyncedUTF8file = (filename: string): string => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform a markdown file and write the transformed file to the directory for
|
||||
* published documentation
|
||||
* Transform a markdown file and write the transformed file to the directory for published
|
||||
* documentation
|
||||
*
|
||||
* 1. Add a `mermaid-example` block before every `mermaid` or `mmd` block On the
|
||||
* docsify site (one place where the documentation is published), this will
|
||||
* show the code used for the mermaid diagram
|
||||
* 1. Add a `mermaid-example` block before every `mermaid` or `mmd` block On the docsify site (one
|
||||
* place where the documentation is published), this will show the code used for the mermaid
|
||||
* diagram
|
||||
* 2. Add the text that says the file is automatically generated
|
||||
* 3. Use prettier to format the file Verify that the file has been changed and
|
||||
* write out the changes
|
||||
* 3. Use prettier to format the file Verify that the file has been changed and write out the changes
|
||||
*
|
||||
* @param file {string} name of the file that will be verified
|
||||
*/
|
||||
@@ -149,12 +145,15 @@ const transformMarkdown = (file: string) => {
|
||||
const doc = readSyncedUTF8file(file);
|
||||
const ast: Root = remark.parse(doc);
|
||||
const out = flatmap(ast, (c: Code) => {
|
||||
if (c.type !== 'code' || !c.lang?.startsWith('mermaid')) {
|
||||
if (c.type !== 'code') {
|
||||
return [c];
|
||||
}
|
||||
if (c.lang === 'mermaid' || c.lang === 'mmd') {
|
||||
c.lang = 'mermaid-example';
|
||||
}
|
||||
if (c.lang !== 'mermaid-example') {
|
||||
return [c];
|
||||
}
|
||||
return [c, Object.assign({}, c, { lang: 'mermaid' })];
|
||||
});
|
||||
|
||||
@@ -168,11 +167,11 @@ const transformMarkdown = (file: string) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Transform an HTML file and write the transformed file to the directory for
|
||||
* published documentation
|
||||
* Transform an HTML file and write the transformed file to the directory for published
|
||||
* documentation
|
||||
*
|
||||
* - Add the text that says the file is automatically generated Verify that the
|
||||
* file has been changed and write out the changes
|
||||
* - Add the text that says the file is automatically generated Verify that the file has been changed
|
||||
* and write out the changes
|
||||
*
|
||||
* @param filename {string} name of the HTML file to transform
|
||||
*/
|
||||
@@ -204,6 +203,9 @@ const transformHtml = (filename: string) => {
|
||||
|
||||
/** Main method (entry point) */
|
||||
(async () => {
|
||||
if (verifyOnly) {
|
||||
console.log('Verifying that all files are in sync with the source files');
|
||||
}
|
||||
const sourceDirGlob = join('.', SOURCE_DOCS_DIR, '**');
|
||||
const includeFilesStartingWithDot = true;
|
||||
|
||||
|
@@ -493,14 +493,14 @@ It is also possible to attach a class to a list of nodes in one statement:
|
||||
|
||||
A shorter form of adding a class is to attach the classname to the node using the `:::` operator:
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
class Animal:::cssClass
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```mmd
|
||||
```mermaid-example
|
||||
classDiagram
|
||||
class Animal:::cssClass {
|
||||
-int sizeInFeet
|
||||
|
@@ -424,6 +424,8 @@ flowchart LR
|
||||
B1 --> B2
|
||||
```
|
||||
|
||||
**A clarification is in order here.** The direction statement affects the layout of a subgraph but only as long as it does not have any links leading in or out of it. The reason for this is that if you have links in or out then the graph of nodes is not longer the set of nodes in the subgraph but actually the set of nodes of the parent including the ones in the subgraph. One can see it as that the direction of the container gets injected in the subgraph with a link.
|
||||
|
||||
## Interaction
|
||||
|
||||
It is possible to bind a click event to a node, the click can lead to either a javascript callback or to a link which will be opened in a new browser tab. **Note**: This functionality is disabled when using `securityLevel='strict'` and enabled when using `securityLevel='loose'`.
|
||||
|
@@ -17,6 +17,7 @@ They also serve as proof of concept, for the variety of things that can be built
|
||||
- [Joplin](https://joplinapp.org) (**Native support**)
|
||||
- [Notion](https://notion.so) (**Native support**)
|
||||
- [Observable](https://observablehq.com/@observablehq/mermaid) (**Native support**)
|
||||
- [Obsidian](https://help.obsidian.md/How+to/Format+your+notes#Diagram) (**Native support**)
|
||||
- [GitBook](https://gitbook.com)
|
||||
- [Mermaid Plugin](https://github.com/JozoVilcek/gitbook-plugin-mermaid)
|
||||
- [Markdown with Mermaid CLI](https://github.com/miao1007/gitbook-plugin-mermaid-cli)
|
||||
@@ -49,6 +50,8 @@ They also serve as proof of concept, for the variety of things that can be built
|
||||
|
||||
## CMS
|
||||
|
||||
- [VitePress](https://vitepress.vuejs.org/)
|
||||
- [Plugin for Mermaid.js](https://emersonbottero.github.io/vitepress-plugin-mermaid/)
|
||||
- [VuePress](https://vuepress.vuejs.org/)
|
||||
- [Plugin for Mermaid.js](https://github.com/eFrane/vuepress-plugin-mermaidjs)
|
||||
- [Grav CMS](https://getgrav.org/)
|
||||
|
31
src/jison/lint.mts
Normal file
31
src/jison/lint.mts
Normal file
@@ -0,0 +1,31 @@
|
||||
/* eslint-disable no-console */
|
||||
import { readFile } from 'fs/promises';
|
||||
import { globby } from 'globby';
|
||||
import { ESLint } from 'eslint';
|
||||
// @ts-ignore no typings
|
||||
import jison from 'jison';
|
||||
|
||||
const linter = new ESLint({
|
||||
overrideConfig: { rules: { 'no-console': 'error' }, parser: '@typescript-eslint/parser' },
|
||||
useEslintrc: false,
|
||||
});
|
||||
|
||||
const lint = async (file: string): Promise<boolean> => {
|
||||
const jisonCode = await readFile(file, 'utf8');
|
||||
// @ts-ignore no typings
|
||||
const jsCode = new jison.Generator(jisonCode, { moduleType: 'amd' }).generate();
|
||||
const [result] = await linter.lintText(jsCode);
|
||||
if (result.errorCount > 0) {
|
||||
console.error(`Linting failed for ${file}`);
|
||||
console.error(result.messages);
|
||||
}
|
||||
return result.errorCount === 0;
|
||||
};
|
||||
|
||||
(async () => {
|
||||
const jisonFiles = await globby(['./src/**/*.jison'], { dot: true });
|
||||
const lintResults = await Promise.all(jisonFiles.map(lint));
|
||||
if (lintResults.some((result) => result === false)) {
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
@@ -1,8 +0,0 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { Generator } = require('jison');
|
||||
|
||||
module.exports = {
|
||||
process(sourceText, sourcePath, options) {
|
||||
return { code: new Generator(sourceText, options.transformerConfig).generate() };
|
||||
},
|
||||
};
|
@@ -1,19 +1,12 @@
|
||||
// mocks the mermaidAPI.render function (see `./__mocks__/mermaidAPI`)
|
||||
jest.mock('./mermaidAPI');
|
||||
// jest.mock only works well with CJS, see https://github.com/facebook/jest/issues/9430
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { default: mermaid } = require('./mermaid');
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { mermaidAPI } = require('./mermaidAPI');
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { default: flowDb } = require('./diagrams/flowchart/flowDb');
|
||||
import mermaid from './mermaid';
|
||||
import { mermaidAPI } from './mermaidAPI';
|
||||
import { vi, describe, it, beforeEach, afterEach, expect } from 'vitest';
|
||||
const spyOn = vi.spyOn;
|
||||
|
||||
import flowParser from './diagrams/flowchart/parser/flow';
|
||||
|
||||
const spyOn = jest.spyOn;
|
||||
vi.mock('./mermaidAPI');
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when using mermaid and ', function () {
|
||||
@@ -63,11 +56,6 @@ describe('when using mermaid and ', function () {
|
||||
});
|
||||
|
||||
describe('checking validity of input ', function () {
|
||||
beforeEach(function () {
|
||||
flowParser.parser.yy = flowDb;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
});
|
||||
it('should throw for an invalid definition', function () {
|
||||
expect(() => mermaid.parse('this is not a mermaid diagram definition')).toThrow();
|
||||
});
|
@@ -1,4 +1,3 @@
|
||||
'use strict';
|
||||
/**
|
||||
* Web page integration module for the mermaid framework. It uses the mermaidAPI for mermaid
|
||||
* functionality and to render the diagrams to svg code.
|
||||
|
3
src/tests/setup.ts
Normal file
3
src/tests/setup.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { vi } from 'vitest';
|
||||
vi.mock('d3');
|
||||
vi.mock('dagre-d3');
|
44
src/tests/util.ts
Normal file
44
src/tests/util.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Used to convert jest's Tagged Template literals to object arrays as required by vitest.
|
||||
|
||||
Example:
|
||||
|
||||
Jest code
|
||||
```ts
|
||||
it.each`
|
||||
str | expected
|
||||
${'1d'} | ${moment.duration(1, 'd')}
|
||||
${'2w'} | ${moment.duration(2, 'w')}
|
||||
`('should parse $str to $expected duration', ({ str, expected }) => {
|
||||
expect(yourFunction(str)).toEqual(expected);
|
||||
});
|
||||
```
|
||||
|
||||
Vitest code
|
||||
```ts
|
||||
it.each(convert`
|
||||
str | expected
|
||||
${'1d'} | ${moment.duration(1, 'd')}
|
||||
${'2w'} | ${moment.duration(2, 'w')}
|
||||
`)('should parse $str to $expected duration', ({ str, expected }) => {
|
||||
expect(yourFunction(str)).toEqual(expected);
|
||||
});
|
||||
```
|
||||
*/
|
||||
|
||||
export const convert = (template: TemplateStringsArray, ...params: any[]) => {
|
||||
const header = template[0]
|
||||
.trim()
|
||||
.split('|')
|
||||
.map((s) => s.trim());
|
||||
if (header.length === 0 || params.length % header.length !== 0) {
|
||||
throw new Error('Table column count mismatch');
|
||||
}
|
||||
const chunkSize = header.length;
|
||||
const out = [];
|
||||
for (let i = 0; i < params.length; i += chunkSize) {
|
||||
const chunk = params.slice(i, i + chunkSize);
|
||||
out.push(Object.fromEntries(chunk.map((v, i) => [header[i], v])));
|
||||
}
|
||||
return out;
|
||||
};
|
7
src/themes/erDiagram-oldHardcodedValues.ts
Normal file
7
src/themes/erDiagram-oldHardcodedValues.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* @file Values that have been hardcoded in src/diagrams/er/styles.js. These can be used by
|
||||
* theme-_._ files to maintain display styles until themes, styles, renderers are revised. --
|
||||
* 2022-09-22
|
||||
*/
|
||||
export const oldAttributeBackgroundColorOdd = '#ffffff';
|
||||
export const oldAttributeBackgroundColorEven = '#f2f2f2';
|
@@ -1,5 +1,10 @@
|
||||
import { darken, lighten, adjust, invert } from 'khroma';
|
||||
import { mkBorder } from './theme-helpers';
|
||||
import {
|
||||
oldAttributeBackgroundColorEven,
|
||||
oldAttributeBackgroundColorOdd,
|
||||
} from './erDiagram-oldHardcodedValues';
|
||||
|
||||
class Theme {
|
||||
constructor() {
|
||||
/** # Base variables */
|
||||
@@ -219,6 +224,15 @@ class Theme {
|
||||
this.commitLabelColor = this.commitLabelColor || this.secondaryTextColor;
|
||||
this.commitLabelBackground = this.commitLabelBackground || this.secondaryColor;
|
||||
this.commitLabelFontSize = this.commitLabelFontSize || '10px';
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
/* EntityRelationship diagrams */
|
||||
|
||||
this.attributeBackgroundColorOdd =
|
||||
this.attributeBackgroundColorOdd || oldAttributeBackgroundColorOdd;
|
||||
this.attributeBackgroundColorEven =
|
||||
this.attributeBackgroundColorEven || oldAttributeBackgroundColorEven;
|
||||
/* -------------------------------------------------- */
|
||||
}
|
||||
calculate(overrides) {
|
||||
if (typeof overrides !== 'object') {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { invert, lighten, darken, rgba, adjust } from 'khroma';
|
||||
import { mkBorder } from './theme-helpers';
|
||||
|
||||
class Theme {
|
||||
constructor() {
|
||||
this.background = '#333';
|
||||
@@ -28,8 +29,8 @@ class Theme {
|
||||
this.fontSize = '16px';
|
||||
this.labelBackground = '#181818';
|
||||
this.textColor = '#ccc';
|
||||
/* Flowchart variables */
|
||||
|
||||
/* Flowchart variables */
|
||||
this.nodeBkg = 'calculated';
|
||||
this.nodeBorder = 'calculated';
|
||||
this.clusterBkg = 'calculated';
|
||||
@@ -218,6 +219,15 @@ class Theme {
|
||||
this.commitLabelColor = this.commitLabelColor || this.secondaryTextColor;
|
||||
this.commitLabelBackground = this.commitLabelBackground || this.secondaryColor;
|
||||
this.commitLabelFontSize = this.commitLabelFontSize || '10px';
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
/* EntityRelationship diagrams */
|
||||
|
||||
this.attributeBackgroundColorOdd =
|
||||
this.attributeBackgroundColorOdd || lighten(this.background, 12);
|
||||
this.attributeBackgroundColorEven =
|
||||
this.attributeBackgroundColorEven || lighten(this.background, 2);
|
||||
/* -------------------------------------------------- */
|
||||
}
|
||||
calculate(overrides) {
|
||||
if (typeof overrides !== 'object') {
|
||||
|
@@ -1,5 +1,9 @@
|
||||
import { invert, lighten, rgba, adjust, darken } from 'khroma';
|
||||
import { mkBorder } from './theme-helpers';
|
||||
import {
|
||||
oldAttributeBackgroundColorEven,
|
||||
oldAttributeBackgroundColorOdd,
|
||||
} from './erDiagram-oldHardcodedValues';
|
||||
|
||||
class Theme {
|
||||
constructor() {
|
||||
@@ -257,6 +261,15 @@ class Theme {
|
||||
this.commitLabelColor = this.commitLabelColor || this.secondaryTextColor;
|
||||
this.commitLabelBackground = this.commitLabelBackground || this.secondaryColor;
|
||||
this.commitLabelFontSize = this.commitLabelFontSize || '10px';
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
/* EntityRelationship diagrams */
|
||||
|
||||
this.attributeBackgroundColorOdd =
|
||||
this.attributeBackgroundColorOdd || oldAttributeBackgroundColorOdd;
|
||||
this.attributeBackgroundColorEven =
|
||||
this.attributeBackgroundColorEven || oldAttributeBackgroundColorEven;
|
||||
/* -------------------------------------------------- */
|
||||
}
|
||||
calculate(overrides) {
|
||||
if (typeof overrides !== 'object') {
|
||||
|
@@ -1,5 +1,10 @@
|
||||
import { darken, lighten, adjust, invert } from 'khroma';
|
||||
import { mkBorder } from './theme-helpers';
|
||||
import {
|
||||
oldAttributeBackgroundColorEven,
|
||||
oldAttributeBackgroundColorOdd,
|
||||
} from './erDiagram-oldHardcodedValues';
|
||||
|
||||
class Theme {
|
||||
constructor() {
|
||||
/* Base vales */
|
||||
@@ -219,6 +224,15 @@ class Theme {
|
||||
this.commitLabelColor = this.commitLabelColor || this.secondaryTextColor;
|
||||
this.commitLabelBackground = this.commitLabelBackground || this.secondaryColor;
|
||||
this.commitLabelFontSize = this.commitLabelFontSize || '10px';
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
/* EntityRelationship diagrams */
|
||||
|
||||
this.attributeBackgroundColorOdd =
|
||||
this.attributeBackgroundColorOdd || oldAttributeBackgroundColorOdd;
|
||||
this.attributeBackgroundColorEven =
|
||||
this.attributeBackgroundColorEven || oldAttributeBackgroundColorEven;
|
||||
/* -------------------------------------------------- */
|
||||
}
|
||||
calculate(overrides) {
|
||||
if (typeof overrides !== 'object') {
|
||||
|
@@ -1,5 +1,9 @@
|
||||
import { invert, darken, lighten, adjust } from 'khroma';
|
||||
import { mkBorder } from './theme-helpers';
|
||||
import {
|
||||
oldAttributeBackgroundColorEven,
|
||||
oldAttributeBackgroundColorOdd,
|
||||
} from './erDiagram-oldHardcodedValues';
|
||||
|
||||
// const Color = require ( 'khroma/dist/color' ).default
|
||||
// Color.format.hex.stringify(Color.parse('hsl(210, 66.6666666667%, 95%)')); // => "#EAF2FB"
|
||||
@@ -261,6 +265,15 @@ class Theme {
|
||||
this.commitLabelColor = this.commitLabelColor || this.secondaryTextColor;
|
||||
this.commitLabelBackground = this.commitLabelBackground || this.secondaryColor;
|
||||
this.commitLabelFontSize = this.commitLabelFontSize || '10px';
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
/* EntityRelationship diagrams */
|
||||
|
||||
this.attributeBackgroundColorOdd =
|
||||
this.attributeBackgroundColorOdd || oldAttributeBackgroundColorOdd;
|
||||
this.attributeBackgroundColorEven =
|
||||
this.attributeBackgroundColorEven || oldAttributeBackgroundColorEven;
|
||||
/* -------------------------------------------------- */
|
||||
}
|
||||
calculate(overrides) {
|
||||
if (typeof overrides !== 'object') {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import utils from './utils';
|
||||
import assignWithDepth from './assignWithDepth';
|
||||
import { detectType } from './diagram-api/detectType';
|
||||
@@ -303,14 +304,22 @@ describe('when formatting urls', function () {
|
||||
});
|
||||
|
||||
describe('when initializing the id generator', function () {
|
||||
it('should return a random number generator based on Date', function (done) {
|
||||
beforeEach(() => {
|
||||
// tell vitest we use mocked time
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// restoring date after each test run
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('should return a random number generator based on Date', function () {
|
||||
const idGenerator = new utils.initIdGenerator(false);
|
||||
expect(typeof idGenerator.next).toEqual('function');
|
||||
const lastId = idGenerator.next();
|
||||
setTimeout(() => {
|
||||
expect(idGenerator.next() > lastId).toBe(true);
|
||||
done();
|
||||
}, 5);
|
||||
vi.advanceTimersByTime(1000);
|
||||
expect(idGenerator.next() > lastId).toBe(true);
|
||||
});
|
||||
|
||||
it('should return a non random number generator', function () {
|
||||
|
@@ -11,10 +11,10 @@
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
"target": "ES6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
"lib": [
|
||||
"ES2021",
|
||||
"DOM"
|
||||
"DOM",
|
||||
"ES2021"
|
||||
] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
@@ -34,7 +34,10 @@
|
||||
// "paths": {} /* Specify a set of entries that re-map imports to additional lookup locations. */,
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [] /* Specify multiple folders that act like `./node_modules/@types`. */,
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
"types": [
|
||||
"vitest/globals"
|
||||
] /* Specify type package names to be included without being referenced in a source file. */,
|
||||
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
"resolveJsonModule": true /* Enable importing .json files */,
|
||||
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
||||
|
17
vite.config.ts
Normal file
17
vite.config.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import jison from './.vite/jisonPlugin';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
extensions: ['.jison', '.js', '.ts', '.json'],
|
||||
},
|
||||
plugins: [jison()],
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
globals: true,
|
||||
setupFiles: ['src/tests/setup.ts'],
|
||||
coverage: {
|
||||
reporter: ['text', 'json', 'html', 'lcov'],
|
||||
},
|
||||
},
|
||||
});
|
Reference in New Issue
Block a user