mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-05 15:19:36 +02:00
Merge branch 'develop' of github.com:yari-dewalt/mermaid into fix/could_not_find_a_suitable_point_for_the_given_distance
This commit is contained in:
@@ -37,14 +37,14 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^7.0.0",
|
||||
"@braintree/sanitize-url": "^7.0.4",
|
||||
"d3": "^7.9.0",
|
||||
"khroma": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^8.2.2",
|
||||
"concurrently": "^9.1.2",
|
||||
"mermaid": "workspace:*",
|
||||
"rimraf": "^5.0.5"
|
||||
"rimraf": "^6.0.1"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
@@ -37,7 +37,7 @@
|
||||
"mermaid": "workspace:^"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"mermaid": "^11.0.0"
|
||||
"mermaid": "^11.0.2"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
@@ -33,7 +33,7 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@zenuml/core": "^3.23.27"
|
||||
"@zenuml/core": "^3.23.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mermaid": "workspace:^"
|
||||
|
@@ -67,68 +67,67 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^7.0.1",
|
||||
"@iconify/utils": "^2.1.32",
|
||||
"@braintree/sanitize-url": "^7.0.4",
|
||||
"@iconify/utils": "^2.1.33",
|
||||
"@mermaid-js/parser": "workspace:^",
|
||||
"@types/d3": "^7.4.3",
|
||||
"cytoscape": "^3.29.2",
|
||||
"cytoscape": "^3.29.3",
|
||||
"cytoscape-cose-bilkent": "^4.1.0",
|
||||
"cytoscape-fcose": "^2.2.0",
|
||||
"d3": "^7.9.0",
|
||||
"d3-sankey": "^0.12.3",
|
||||
"dagre-d3-es": "7.0.11",
|
||||
"dayjs": "^1.11.10",
|
||||
"dayjs": "^1.11.13",
|
||||
"dompurify": "^3.2.1",
|
||||
"katex": "^0.16.9",
|
||||
"khroma": "^2.1.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"marked": "^13.0.2",
|
||||
"marked": "^15.0.7",
|
||||
"roughjs": "^4.6.6",
|
||||
"stylis": "^4.3.1",
|
||||
"stylis": "^4.3.6",
|
||||
"ts-dedent": "^2.2.0",
|
||||
"uuid": "^9.0.1"
|
||||
"uuid": "^11.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@adobe/jsonschema2md": "^8.0.0",
|
||||
"@adobe/jsonschema2md": "^8.0.2",
|
||||
"@iconify/types": "^2.0.0",
|
||||
"@types/cytoscape": "^3.21.4",
|
||||
"@types/cytoscape": "^3.21.9",
|
||||
"@types/cytoscape-fcose": "^2.2.4",
|
||||
"@types/d3-sankey": "^0.12.4",
|
||||
"@types/d3-scale": "^4.0.8",
|
||||
"@types/d3-scale-chromatic": "^3.0.3",
|
||||
"@types/d3-selection": "^3.0.10",
|
||||
"@types/d3-shape": "^3.1.6",
|
||||
"@types/jsdom": "^21.1.6",
|
||||
"@types/d3-scale": "^4.0.9",
|
||||
"@types/d3-scale-chromatic": "^3.1.0",
|
||||
"@types/d3-selection": "^3.0.11",
|
||||
"@types/d3-shape": "^3.1.7",
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"@types/katex": "^0.16.7",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/micromatch": "^4.0.6",
|
||||
"@types/prettier": "^3.0.0",
|
||||
"@types/stylis": "^4.2.5",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"ajv": "^8.12.0",
|
||||
"chokidar": "^3.6.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"csstree-validator": "^3.0.0",
|
||||
"globby": "^14.0.1",
|
||||
"@types/micromatch": "^4.0.9",
|
||||
"@types/stylis": "^4.2.7",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"ajv": "^8.17.1",
|
||||
"chokidar": "^4.0.3",
|
||||
"concurrently": "^9.1.2",
|
||||
"csstree-validator": "^4.0.1",
|
||||
"globby": "^14.0.2",
|
||||
"jison": "^0.4.18",
|
||||
"js-base64": "^3.7.7",
|
||||
"jsdom": "^24.0.0",
|
||||
"json-schema-to-typescript": "^13.1.2",
|
||||
"micromatch": "^4.0.5",
|
||||
"jsdom": "^26.0.0",
|
||||
"json-schema-to-typescript": "^15.0.4",
|
||||
"micromatch": "^4.0.8",
|
||||
"path-browserify": "^1.0.1",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier": "^3.5.2",
|
||||
"remark": "^15.0.1",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"rimraf": "^5.0.5",
|
||||
"start-server-and-test": "^2.0.3",
|
||||
"type-fest": "^4.13.1",
|
||||
"typedoc": "^0.25.12",
|
||||
"typedoc-plugin-markdown": "^3.17.1",
|
||||
"typescript": "~5.4.3",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"rimraf": "^6.0.1",
|
||||
"start-server-and-test": "^2.0.10",
|
||||
"type-fest": "^4.35.0",
|
||||
"typedoc": "^0.27.8",
|
||||
"typedoc-plugin-markdown": "^4.4.2",
|
||||
"typescript": "~5.7.3",
|
||||
"unist-util-flatmap": "^1.0.0",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"vitepress": "^1.0.1",
|
||||
"vitepress": "^1.0.2",
|
||||
"vitepress-plugin-search": "1.0.4-alpha.22"
|
||||
},
|
||||
"files": [
|
||||
|
@@ -230,7 +230,7 @@ const ConfigWarning = {
|
||||
} as const;
|
||||
|
||||
type ConfigWarningStrings = keyof typeof ConfigWarning;
|
||||
const issuedWarnings: { [key in ConfigWarningStrings]?: boolean } = {};
|
||||
const issuedWarnings: Partial<Record<ConfigWarningStrings, boolean>> = {};
|
||||
const issueWarning = (warning: ConfigWarningStrings) => {
|
||||
if (issuedWarnings[warning]) {
|
||||
return;
|
||||
|
@@ -106,9 +106,7 @@ export const isValidArchitectureDirectionPair = function (
|
||||
return x !== 'LL' && x !== 'RR' && x !== 'TT' && x !== 'BB';
|
||||
};
|
||||
|
||||
export type ArchitectureDirectionPairMap = {
|
||||
[key in ArchitectureDirectionPair]?: string;
|
||||
};
|
||||
export type ArchitectureDirectionPairMap = Partial<Record<ArchitectureDirectionPair, string>>;
|
||||
|
||||
/**
|
||||
* Creates a pair of the directions of each side of an edge. This function should be used instead of manually creating it to ensure that the source is always the first character.
|
||||
|
@@ -84,7 +84,7 @@ describe('when parsing a gitGraph', function () {
|
||||
const commits = db.getCommits();
|
||||
|
||||
expect(commits.size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('a commit');
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
});
|
||||
@@ -246,7 +246,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('');
|
||||
expect(commits.get(key)?.id).not.toBeNull();
|
||||
expect(commits.get(key)?.tags).toStrictEqual([]);
|
||||
@@ -263,7 +263,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('');
|
||||
expect(commits.get(key)?.id).toBe('1111');
|
||||
expect(commits.get(key)?.tags).toStrictEqual([]);
|
||||
@@ -281,7 +281,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('');
|
||||
expect(commits.get(key)?.id).not.toBeNull();
|
||||
expect(commits.get(key)?.tags).toStrictEqual(['test']);
|
||||
@@ -299,7 +299,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('');
|
||||
expect(commits.get(key)?.id).not.toBeNull();
|
||||
expect(commits.get(key)?.tags).toStrictEqual([]);
|
||||
@@ -317,7 +317,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('');
|
||||
expect(commits.get(key)?.id).not.toBeNull();
|
||||
expect(commits.get(key)?.tags).toStrictEqual([]);
|
||||
@@ -335,7 +335,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('');
|
||||
expect(commits.get(key)?.id).not.toBeNull();
|
||||
expect(commits.get(key)?.tags).toStrictEqual([]);
|
||||
@@ -353,7 +353,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('test commit');
|
||||
expect(commits.get(key)?.id).not.toBeNull();
|
||||
expect(commits.get(key)?.tags).toStrictEqual([]);
|
||||
@@ -371,7 +371,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('test commit');
|
||||
expect(commits.get(key)?.id).not.toBeNull();
|
||||
expect(commits.get(key)?.tags).toStrictEqual([]);
|
||||
@@ -389,7 +389,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('');
|
||||
expect(commits.get(key)?.id).toBe('1111');
|
||||
expect(commits.get(key)?.tags).toStrictEqual(['test tag']);
|
||||
@@ -407,7 +407,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('');
|
||||
expect(commits.get(key)?.id).not.toBeNull();
|
||||
expect(commits.get(key)?.tags).toStrictEqual(['test tag']);
|
||||
@@ -425,7 +425,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('');
|
||||
expect(commits.get(key)?.id).not.toBeNull();
|
||||
expect(commits.get(key)?.tags).toStrictEqual(['test tag']);
|
||||
@@ -443,7 +443,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('');
|
||||
expect(commits.get(key)?.id).toBe('1111');
|
||||
expect(commits.get(key)?.tags).toStrictEqual(['test tag']);
|
||||
@@ -461,7 +461,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('test msg');
|
||||
expect(commits.get(key)?.id).toBe('1111');
|
||||
expect(commits.get(key)?.tags).toStrictEqual(['test tag']);
|
||||
@@ -480,7 +480,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('test msg');
|
||||
expect(commits.get(key)?.id).toBe('1111');
|
||||
expect(commits.get(key)?.tags).toStrictEqual(['test tag']);
|
||||
@@ -498,7 +498,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('test msg');
|
||||
expect(commits.get(key)?.id).toBe('1111');
|
||||
expect(commits.get(key)?.tags).toStrictEqual(['test tag']);
|
||||
@@ -516,7 +516,7 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(db.getCurrentBranch()).toBe('main');
|
||||
expect(db.getDirection()).toBe('LR');
|
||||
expect(db.getBranches().size).toBe(1);
|
||||
const key = commits.keys().next().value;
|
||||
const key = commits.keys().next().value!;
|
||||
expect(commits.get(key)?.message).toBe('test msg');
|
||||
expect(commits.get(key)?.id).toBe('1111');
|
||||
expect(commits.get(key)?.tags).toStrictEqual(['test tag']);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import type { InfoFields, InfoDB } from './infoTypes.js';
|
||||
import { version } from '../../../package.json';
|
||||
import packageJson from '../../../package.json' assert { type: 'json' };
|
||||
|
||||
export const DEFAULT_INFO_DB: InfoFields = { version } as const;
|
||||
export const DEFAULT_INFO_DB: InfoFields = { version: packageJson.version } as const;
|
||||
|
||||
export const getVersion = (): string => DEFAULT_INFO_DB.version;
|
||||
|
||||
|
@@ -9,7 +9,7 @@ const parserFnConstructor = (str: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
const mockDB: Record<string, Mock<any, any>> = {
|
||||
const mockDB: Record<string, Mock<any>> = {
|
||||
setQuadrant1Text: vi.fn(),
|
||||
setQuadrant2Text: vi.fn(),
|
||||
setQuadrant3Text: vi.fn(),
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,26 @@
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/sequenceDiagram.jison';
|
||||
import db from './sequenceDb.js';
|
||||
import { SequenceDB } from './sequenceDb.js';
|
||||
import styles from './styles.js';
|
||||
import { setConfig } from '../../diagram-api/diagramAPI.js';
|
||||
import renderer from './sequenceRenderer.js';
|
||||
import type { MermaidConfig } from '../../config.type.js';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
get db() {
|
||||
return new SequenceDB();
|
||||
},
|
||||
renderer,
|
||||
styles,
|
||||
init: ({ wrap }) => {
|
||||
db.setWrap(wrap);
|
||||
init: (cnf: MermaidConfig) => {
|
||||
if (!cnf.sequence) {
|
||||
cnf.sequence = {};
|
||||
}
|
||||
if (cnf.wrap) {
|
||||
cnf.sequence.wrap = cnf.wrap;
|
||||
setConfig({ sequence: { wrap: cnf.wrap } });
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@@ -1538,7 +1538,6 @@ const calculateLoopBounds = async function (messages, actors, _maxWidthPerActor,
|
||||
let current, noteModel, msgModel;
|
||||
|
||||
for (const msg of messages) {
|
||||
msg.id = utils.random({ length: 10 });
|
||||
switch (msg.type) {
|
||||
case diagObj.db.LINETYPE.LOOP_START:
|
||||
case diagObj.db.LINETYPE.ALT_START:
|
||||
|
@@ -20,6 +20,7 @@ export interface Actor {
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
id: string;
|
||||
from?: string;
|
||||
to?: string;
|
||||
message:
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import stateDb from '../stateDb.js';
|
||||
import { StateDB } from '../stateDb.js';
|
||||
import stateDiagram from './stateDiagram.jison';
|
||||
import { setConfig } from '../../../config.js';
|
||||
|
||||
@@ -7,7 +7,9 @@ setConfig({
|
||||
});
|
||||
|
||||
describe('state parser can parse...', () => {
|
||||
let stateDb;
|
||||
beforeEach(function () {
|
||||
stateDb = new StateDB(2);
|
||||
stateDiagram.parser.yy = stateDb;
|
||||
stateDiagram.parser.yy.clear();
|
||||
});
|
||||
@@ -18,7 +20,6 @@ describe('state parser can parse...', () => {
|
||||
const diagramText = `stateDiagram-v2
|
||||
state "Small State 1" as namedState1`;
|
||||
stateDiagram.parser.parse(diagramText);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
expect(states.get('namedState1')).not.toBeUndefined();
|
||||
@@ -31,7 +32,6 @@ describe('state parser can parse...', () => {
|
||||
const diagramText = `stateDiagram-v2
|
||||
namedState1 : Small State 1`;
|
||||
stateDiagram.parser.parse(diagramText);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
expect(states.get('namedState1')).not.toBeUndefined();
|
||||
@@ -42,7 +42,6 @@ describe('state parser can parse...', () => {
|
||||
const diagramText = `stateDiagram-v2
|
||||
namedState1:Small State 1`;
|
||||
stateDiagram.parser.parse(diagramText);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
expect(states.get('namedState1')).not.toBeUndefined();
|
||||
@@ -60,7 +59,6 @@ describe('state parser can parse...', () => {
|
||||
state assemblies
|
||||
`;
|
||||
stateDiagram.parser.parse(diagramText);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
expect(states.get('assemble')).not.toBeUndefined();
|
||||
expect(states.get('assemblies')).not.toBeUndefined();
|
||||
@@ -71,7 +69,6 @@ describe('state parser can parse...', () => {
|
||||
state "as" as as
|
||||
`;
|
||||
stateDiagram.parser.parse(diagramText);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
expect(states.get('as')).not.toBeUndefined();
|
||||
expect(states.get('as').descriptions.join(' ')).toEqual('as');
|
||||
@@ -96,7 +93,6 @@ describe('state parser can parse...', () => {
|
||||
namedState2 --> bigState2: should point to \\nbigState2 container`;
|
||||
|
||||
stateDiagram.parser.parse(diagramText);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
expect(states.get('namedState1')).not.toBeUndefined();
|
||||
@@ -120,7 +116,6 @@ describe('state parser can parse...', () => {
|
||||
inner1 --> inner2
|
||||
}`;
|
||||
stateDiagram.parser.parse(diagramText);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
expect(states.get('bigState1')).not.toBeUndefined();
|
||||
@@ -137,7 +132,6 @@ describe('state parser can parse...', () => {
|
||||
stateDiagram-v2
|
||||
[*] --> ${prop}
|
||||
${prop} --> [*]`);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
expect(states.get(prop)).not.toBeUndefined();
|
||||
});
|
||||
|
@@ -1,13 +1,15 @@
|
||||
import stateDb from '../stateDb.js';
|
||||
import stateDiagram from './stateDiagram.jison';
|
||||
import { setConfig } from '../../../config.js';
|
||||
import { StateDB } from '../stateDb.js';
|
||||
import stateDiagram from './stateDiagram.jison';
|
||||
|
||||
setConfig({
|
||||
securityLevel: 'strict',
|
||||
});
|
||||
|
||||
describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
let stateDb;
|
||||
beforeEach(function () {
|
||||
stateDb = new StateDB(2);
|
||||
stateDiagram.parser.yy = stateDb;
|
||||
stateDiagram.parser.yy.clear();
|
||||
});
|
||||
@@ -16,7 +18,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
describe('defining (classDef)', () => {
|
||||
it('has "classDef" as a keyword, an id, and can set a css style attribute', function () {
|
||||
stateDiagram.parser.parse('stateDiagram-v2\n classDef exampleClass background:#bbb;');
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const styleClasses = stateDb.getClasses();
|
||||
expect(styleClasses.get('exampleClass').styles.length).toEqual(1);
|
||||
@@ -27,7 +28,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
stateDiagram.parser.parse(
|
||||
'stateDiagram-v2\n classDef exampleClass background:#bbb, font-weight:bold, font-style:italic;'
|
||||
);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const styleClasses = stateDb.getClasses();
|
||||
expect(styleClasses.get('exampleClass').styles.length).toEqual(3);
|
||||
@@ -41,7 +41,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
stateDiagram.parser.parse(
|
||||
'stateDiagram-v2\n classDef exampleStyleClass background:#bbb,border:1.5px solid red;'
|
||||
);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const classes = stateDiagram.parser.yy.getClasses();
|
||||
expect(classes.get('exampleStyleClass').styles.length).toBe(2);
|
||||
@@ -53,7 +52,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
stateDiagram.parser.parse(
|
||||
'stateDiagram-v2\n classDef exampleStyleClass background: #bbb,border:1.5px solid red;'
|
||||
);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const classes = stateDiagram.parser.yy.getClasses();
|
||||
expect(classes.get('exampleStyleClass').styles.length).toBe(2);
|
||||
@@ -65,7 +63,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
stateDiagram.parser.parse(
|
||||
'stateDiagram-v2\n classDef __proto__ background:#bbb,border:1.5px solid red;\n classDef constructor background:#bbb,border:1.5px solid red;'
|
||||
);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const classes = stateDiagram.parser.yy.getClasses();
|
||||
expect(classes.get('__proto__').styles.length).toBe(2);
|
||||
expect(classes.get('constructor').styles.length).toBe(2);
|
||||
@@ -81,7 +78,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
diagram += 'class a exampleStyleClass';
|
||||
|
||||
stateDiagram.parser.parse(diagram);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const classes = stateDb.getClasses();
|
||||
expect(classes.get('exampleStyleClass').styles.length).toEqual(2);
|
||||
@@ -102,7 +98,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
diagram += 'class a_a exampleStyleClass';
|
||||
|
||||
stateDiagram.parser.parse(diagram);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const classes = stateDiagram.parser.yy.getClasses();
|
||||
expect(classes.get('exampleStyleClass').styles.length).toBe(2);
|
||||
@@ -122,7 +117,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
diagram += 'a --> b:::exampleStyleClass' + '\n';
|
||||
|
||||
stateDiagram.parser.parse(diagram);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
const classes = stateDiagram.parser.yy.getClasses();
|
||||
@@ -141,7 +135,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
diagram += '[*]:::exampleStyleClass --> b\n';
|
||||
|
||||
stateDiagram.parser.parse(diagram);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
const classes = stateDiagram.parser.yy.getClasses();
|
||||
@@ -161,7 +154,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
diagram += 'class a,b exampleStyleClass';
|
||||
|
||||
stateDiagram.parser.parse(diagram);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
let classes = stateDiagram.parser.yy.getClasses();
|
||||
let states = stateDiagram.parser.yy.getStates();
|
||||
|
||||
@@ -180,7 +172,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
diagram += 'class a,b,c, d, e exampleStyleClass';
|
||||
|
||||
stateDiagram.parser.parse(diagram);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const classes = stateDiagram.parser.yy.getClasses();
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
|
||||
@@ -208,7 +199,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
diagram += '}\n';
|
||||
|
||||
stateDiagram.parser.parse(diagram);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const states = stateDiagram.parser.yy.getStates();
|
||||
|
||||
@@ -224,7 +214,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
stateDiagram.parser.parse(`stateDiagram-v2
|
||||
id1
|
||||
style id1 background:#bbb`);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const data4Layout = stateDiagram.parser.yy.getData();
|
||||
|
||||
expect(data4Layout.nodes[0].cssStyles).toEqual(['background:#bbb']);
|
||||
@@ -234,7 +223,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
id1
|
||||
id2
|
||||
style id1,id2 background:#bbb`);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const data4Layout = stateDiagram.parser.yy.getData();
|
||||
|
||||
expect(data4Layout.nodes[0].cssStyles).toEqual(['background:#bbb']);
|
||||
@@ -247,7 +235,6 @@ describe('ClassDefs and classes when parsing a State diagram', () => {
|
||||
id2
|
||||
style id1,id2 background:#bbb, font-weight:bold, font-style:italic;`);
|
||||
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
const data4Layout = stateDiagram.parser.yy.getData();
|
||||
|
||||
expect(data4Layout.nodes[0].cssStyles).toEqual([
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { line, curveBasis } from 'd3';
|
||||
import idCache from './id-cache.js';
|
||||
import stateDb from './stateDb.js';
|
||||
import { StateDB } from './stateDb.js';
|
||||
import utils from '../../utils.js';
|
||||
import common from '../common/common.js';
|
||||
import { getConfig } from '../../diagram-api/diagramAPI.js';
|
||||
@@ -414,13 +414,13 @@ let edgeCount = 0;
|
||||
export const drawEdge = function (elem, path, relation) {
|
||||
const getRelationType = function (type) {
|
||||
switch (type) {
|
||||
case stateDb.relationType.AGGREGATION:
|
||||
case StateDB.relationType.AGGREGATION:
|
||||
return 'aggregation';
|
||||
case stateDb.relationType.EXTENSION:
|
||||
case StateDB.relationType.EXTENSION:
|
||||
return 'extension';
|
||||
case stateDb.relationType.COMPOSITION:
|
||||
case StateDB.relationType.COMPOSITION:
|
||||
return 'composition';
|
||||
case stateDb.relationType.DEPENDENCY:
|
||||
case StateDB.relationType.DEPENDENCY:
|
||||
return 'dependency';
|
||||
}
|
||||
};
|
||||
@@ -459,7 +459,7 @@ export const drawEdge = function (elem, path, relation) {
|
||||
|
||||
svgPath.attr(
|
||||
'marker-end',
|
||||
'url(' + url + '#' + getRelationType(stateDb.relationType.DEPENDENCY) + 'End' + ')'
|
||||
'url(' + url + '#' + getRelationType(StateDB.relationType.DEPENDENCY) + 'End' + ')'
|
||||
);
|
||||
|
||||
if (relation.title !== undefined) {
|
||||
|
@@ -3,11 +3,14 @@
|
||||
*/
|
||||
|
||||
// default diagram direction
|
||||
export const DEFAULT_DIAGRAM_DIRECTION = 'LR';
|
||||
export const DEFAULT_DIAGRAM_DIRECTION = 'TB';
|
||||
|
||||
// default direction for any nested documents (composites)
|
||||
export const DEFAULT_NESTED_DOC_DIR = 'TB';
|
||||
|
||||
// parsed statement type for a direction
|
||||
export const STMT_DIRECTION = 'dir';
|
||||
|
||||
// parsed statement type for a state
|
||||
export const STMT_STATE = 'state';
|
||||
// parsed statement type for a relation
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,9 @@
|
||||
import stateDb from './stateDb.js';
|
||||
import { StateDB } from './stateDb.js';
|
||||
|
||||
describe('State Diagram stateDb', () => {
|
||||
let stateDb;
|
||||
beforeEach(() => {
|
||||
stateDb.clear();
|
||||
stateDb = new StateDB(1);
|
||||
});
|
||||
|
||||
describe('addStyleClass', () => {
|
||||
@@ -20,8 +21,9 @@ describe('State Diagram stateDb', () => {
|
||||
});
|
||||
|
||||
describe('addDescription to a state', () => {
|
||||
let stateDb;
|
||||
beforeEach(() => {
|
||||
stateDb.clear();
|
||||
stateDb = new StateDB(1);
|
||||
stateDb.addState('state1');
|
||||
});
|
||||
|
||||
@@ -73,3 +75,25 @@ describe('State Diagram stateDb', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('state db class', () => {
|
||||
let stateDb;
|
||||
beforeEach(() => {
|
||||
stateDb = new StateDB(1);
|
||||
});
|
||||
// This is to ensure that functions used in state JISON are exposed as function from StateDb
|
||||
it('should have functions used in flow JISON as own property', () => {
|
||||
const functionsUsedInParser = [
|
||||
'setRootDoc',
|
||||
'trimColon',
|
||||
'getDividerId',
|
||||
'setAccTitle',
|
||||
'setAccDescription',
|
||||
'setDirection',
|
||||
];
|
||||
|
||||
for (const fun of functionsUsedInParser) {
|
||||
expect(Object.hasOwn(stateDb, fun)).toBe(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@@ -1,11 +1,13 @@
|
||||
import { parser } from './parser/stateDiagram.jison';
|
||||
import stateDb from './stateDb.js';
|
||||
import stateDiagram from './parser/stateDiagram.jison';
|
||||
import stateDiagram, { parser } from './parser/stateDiagram.jison';
|
||||
import { DEFAULT_DIAGRAM_DIRECTION } from './stateCommon.js';
|
||||
import { StateDB } from './stateDb.js';
|
||||
|
||||
describe('state diagram V2, ', function () {
|
||||
// TODO - these examples should be put into ./parser/stateDiagram.spec.js
|
||||
describe('when parsing an info graph it', function () {
|
||||
let stateDb;
|
||||
beforeEach(function () {
|
||||
stateDb = new StateDB(2);
|
||||
parser.yy = stateDb;
|
||||
stateDiagram.parser.yy = stateDb;
|
||||
stateDiagram.parser.yy.clear();
|
||||
@@ -127,7 +129,6 @@ describe('state diagram V2, ', function () {
|
||||
`;
|
||||
|
||||
stateDiagram.parser.parse(diagram);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const rels = stateDb.getRelations();
|
||||
const rel_1_2 = rels.find((rel) => rel.id1 === 'State1' && rel.id2 === 'State2');
|
||||
@@ -402,7 +403,6 @@ describe('state diagram V2, ', function () {
|
||||
`;
|
||||
|
||||
stateDiagram.parser.parse(diagram);
|
||||
stateDiagram.parser.yy.extract(stateDiagram.parser.yy.getRootDocV2());
|
||||
|
||||
const states = stateDb.getStates();
|
||||
expect(states.get('Active').doc[0].id).toEqual('Idle');
|
||||
@@ -413,5 +413,34 @@ describe('state diagram V2, ', function () {
|
||||
const rel_Active_Active = rels.find((rel) => rel.id1 === 'Active' && rel.id2 === 'Active');
|
||||
expect(rel_Active_Active.relationTitle).toEqual('LOG');
|
||||
});
|
||||
|
||||
it('should check default diagram direction', () => {
|
||||
const diagram = `
|
||||
stateDiagram
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
`;
|
||||
|
||||
parser.parse(diagram);
|
||||
|
||||
// checking default direction if no direction is specified
|
||||
const defaultDir = stateDb.getDirection();
|
||||
expect(defaultDir).toEqual(DEFAULT_DIAGRAM_DIRECTION);
|
||||
});
|
||||
|
||||
it('retrieve the diagram direction correctly', () => {
|
||||
const diagram = `
|
||||
stateDiagram
|
||||
direction LR
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
`;
|
||||
|
||||
parser.parse(diagram);
|
||||
|
||||
//retrieve the diagram direction
|
||||
const currentDirection = stateDb.getDirection();
|
||||
expect(currentDirection).toEqual('LR');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,13 +1,15 @@
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/stateDiagram.jison';
|
||||
import db from './stateDb.js';
|
||||
import { StateDB } from './stateDb.js';
|
||||
import styles from './styles.js';
|
||||
import renderer from './stateRenderer-v3-unified.js';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
get db() {
|
||||
return new StateDB(2);
|
||||
},
|
||||
renderer,
|
||||
styles,
|
||||
init: (cnf) => {
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import { parser } from './parser/stateDiagram.jison';
|
||||
import stateDb from './stateDb.js';
|
||||
import { StateDB } from './stateDb.js';
|
||||
|
||||
describe('state diagram, ', function () {
|
||||
describe('when parsing an info graph it', function () {
|
||||
let stateDb;
|
||||
beforeEach(function () {
|
||||
stateDb = new StateDB(1);
|
||||
parser.yy = stateDb;
|
||||
});
|
||||
|
||||
|
@@ -1,13 +1,15 @@
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/stateDiagram.jison';
|
||||
import db from './stateDb.js';
|
||||
import { StateDB } from './stateDb.js';
|
||||
import styles from './styles.js';
|
||||
import renderer from './stateRenderer.js';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser,
|
||||
db,
|
||||
get db() {
|
||||
return new StateDB(1);
|
||||
},
|
||||
renderer,
|
||||
styles,
|
||||
init: (cnf) => {
|
||||
|
@@ -36,7 +36,6 @@ export const getClasses = function (
|
||||
text: string,
|
||||
diagramObj: any
|
||||
): Map<string, DiagramStyleClassDef> {
|
||||
diagramObj.db.extract(diagramObj.db.getRootDocV2());
|
||||
return diagramObj.db.getClasses();
|
||||
};
|
||||
|
||||
|
@@ -136,7 +136,6 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) =
|
||||
return {};
|
||||
});
|
||||
|
||||
diagObj.db.extract(doc);
|
||||
const states = diagObj.db.getStates();
|
||||
const relations = diagObj.db.getRelations();
|
||||
|
||||
|
@@ -9,7 +9,7 @@ const parserFnConstructor = (str: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
const mockDB: Record<string, Mock<any, any>> = {
|
||||
const mockDB: Record<string, Mock<any>> = {
|
||||
setOrientation: vi.fn(),
|
||||
setDiagramTitle: vi.fn(),
|
||||
setXAxisTitle: vi.fn(),
|
||||
|
@@ -16,7 +16,7 @@ import { teamMembers } from '../contributors';
|
||||
<p text-lg max-w-200 text-center leading-7>
|
||||
<Contributors />
|
||||
<br />
|
||||
<a href="https://discord.gg/AgrbSrBer3" rel="noopener noreferrer">Join the community</a>
|
||||
<a href="https://discord.gg/sKeNQX4Wtj" rel="noopener noreferrer">Join the community</a>
|
||||
and get involved!
|
||||
</p>
|
||||
</div>
|
||||
|
@@ -1,40 +1,114 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
|
||||
interface Taglines {
|
||||
label: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
const taglines: Taglines[] = [
|
||||
{
|
||||
label: 'Explore the Mermaid Whiteboard from the creators of Mermaid',
|
||||
url: 'https://www.mermaidchart.com/whiteboard?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=whiteboard',
|
||||
const allTaglines: { [key: string]: { design: number; taglines: Taglines[] } } = {
|
||||
A: {
|
||||
design: 1,
|
||||
taglines: [
|
||||
{
|
||||
label: 'Replace ChatGPT Pro, Mermaid.live, and Lucid Chart with Mermaid Chart',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=AIbundle_A',
|
||||
},
|
||||
{
|
||||
label: 'Diagram live with teammates in Mermaid Chart',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=teams_A',
|
||||
},
|
||||
{
|
||||
label: 'Use the Visual Editor in Mermaid Chart to design and build diagrams',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=visual_editor_A',
|
||||
},
|
||||
{
|
||||
label: 'Explore the Mermaid Whiteboard from the creators of Mermaid',
|
||||
url: 'https://www.mermaidchart.com/whiteboard?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=whiteboard_A',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Use the Visual Editor in Mermaid Chart to design and build diagrams',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=visual_editor',
|
||||
B: {
|
||||
design: 2,
|
||||
taglines: [
|
||||
{
|
||||
label: 'Replace ChatGPT Pro, Mermaid.live, and Lucid Chart with Mermaid Chart',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=AIbundle_B',
|
||||
},
|
||||
{
|
||||
label: 'Diagram live with teammates in Mermaid Chart',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=teams_B',
|
||||
},
|
||||
{
|
||||
label: 'Use the Visual Editor in Mermaid Chart to design and build diagrams',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=visual_editor_B',
|
||||
},
|
||||
{
|
||||
label: 'Explore the Mermaid Whiteboard from the creators of Mermaid',
|
||||
url: 'https://www.mermaidchart.com/whiteboard?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=whiteboard_B',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Diagram live with teammates in Mermaid Chart',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=teams',
|
||||
C: {
|
||||
design: 1,
|
||||
taglines: [
|
||||
{
|
||||
label: 'Replace ChatGPT Pro, Mermaid.live, and Lucid Chart with Mermaid Pro',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=AIbundle_C',
|
||||
},
|
||||
{
|
||||
label: 'Diagram live with teammates in Mermaid Pro',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=teams_C',
|
||||
},
|
||||
{
|
||||
label: 'Use the Visual Editor in Mermaid Pro to design and build diagrams',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=visual_editor_C',
|
||||
},
|
||||
{
|
||||
label: 'Explore the Mermaid Whiteboard from the creators of Mermaid',
|
||||
url: 'https://www.mermaidchart.com/whiteboard?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=whiteboard_A',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Replace ChatGPT Pro, Mermaid.live, and LucidChart with Mermaid Pro',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=AIbundle',
|
||||
D: {
|
||||
design: 2,
|
||||
taglines: [
|
||||
{
|
||||
label: 'Replace ChatGPT Pro, Mermaid.live, and Lucid Chart with Mermaid Pro',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=AIbundle_D',
|
||||
},
|
||||
{
|
||||
label: 'Diagram live with teammates in Mermaid Pro',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=teams_D',
|
||||
},
|
||||
{
|
||||
label: 'Use the Visual Editor in Mermaid Pro to design and build diagrams',
|
||||
url: 'https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=visual_editor_D',
|
||||
},
|
||||
{
|
||||
label: 'Explore the Mermaid Whiteboard from the creators of Mermaid',
|
||||
url: 'https://www.mermaidchart.com/whiteboard?utm_source=mermaid_js&utm_medium=banner_ad&utm_campaign=whiteboard_B',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const { design, taglines } =
|
||||
Object.values(allTaglines)[Math.floor(Math.random() * Object.values(allTaglines).length)];
|
||||
|
||||
let index = ref(Math.floor(Math.random() * taglines.length));
|
||||
onMounted(() => {
|
||||
setInterval(() => {
|
||||
index.value = (index.value + 1) % taglines.length;
|
||||
}, 40_000);
|
||||
}, 5_000);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mb-4 w-full top-bar bg-gradient-to-r from-[#bd34fe] to-[#ff3670] flex p-1">
|
||||
<div
|
||||
:class="[design === 1 ? 'bg-gradient-to-r from-[#bd34fe] to-[#ff3670] ' : 'bg-[#E0095F]']"
|
||||
class="mb-4 w-full top-bar flex p-2"
|
||||
>
|
||||
<p class="w-full tracking-wide fade-text">
|
||||
<transition name="fade" mode="out-in">
|
||||
<a
|
||||
@@ -44,7 +118,7 @@ onMounted(() => {
|
||||
class="unstyled flex justify-center items-center gap-4 text-white tracking-wide plausible-event-name=bannerClick"
|
||||
>
|
||||
<span class="font-semibold">{{ taglines[index].label }}</span>
|
||||
<button class="rounded bg-[#111113] p-1 px-2 text-sm font-semibold tracking-wide">
|
||||
<button class="bg-[#1E1A2E] rounded-lg p-1.5 px-4 font-semibold tracking-wide">
|
||||
Try now
|
||||
</button>
|
||||
</a>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import type { MarkdownOptions } from 'vitepress';
|
||||
import { defineConfig } from 'vitepress';
|
||||
import { version } from '../../../package.json';
|
||||
import packageJson from '../../../package.json' assert { type: 'json' };
|
||||
import MermaidExample from './mermaid-markdown-all.js';
|
||||
|
||||
const allMarkdownTransformers: MarkdownOptions = {
|
||||
@@ -58,7 +58,7 @@ export default defineConfig({
|
||||
{ icon: 'github', link: 'https://github.com/mermaid-js/mermaid' },
|
||||
{
|
||||
icon: 'discord',
|
||||
link: 'https://discord.gg/AgrbSrBer3',
|
||||
link: 'https://discord.gg/sKeNQX4Wtj',
|
||||
},
|
||||
{
|
||||
icon: {
|
||||
@@ -95,7 +95,7 @@ function nav() {
|
||||
activeMatch: '/announcements',
|
||||
},
|
||||
{
|
||||
text: version,
|
||||
text: packageJson.version,
|
||||
items: [
|
||||
{
|
||||
text: 'Changelog',
|
||||
|
@@ -39,7 +39,7 @@ Where to start:
|
||||
- You could work on a new feature! [These](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Area%3A+Development%22+label%3A%22Type%3A+Enhancement%22+label%3A%22Status%3A+Approved%22+) are some ideas!
|
||||
- You could confirm the bugs in [these issues](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Status%3A+Triage%22++label%3A%22Type%3A+Bug+%2F+Error%22).
|
||||
|
||||
[You can join our Discord server if you want closer contact!](https://discord.gg/AgrbSrBer3)
|
||||
[You can join our Discord server if you want closer contact!](https://discord.gg/sKeNQX4Wtj)
|
||||
|
||||
## A Question Or a Suggestion?
|
||||
|
||||
@@ -53,6 +53,6 @@ If you have faced a vulnerability [report it to us](./security.md).
|
||||
|
||||
Don't get daunted if it is hard in the beginning. We have a great community with only encouraging words. So, if you get stuck, ask for help and hints in the Slack forum. If you want to show off something good, show it off there.
|
||||
|
||||
[You can join our Discord server if you want closer contact!](https://discord.gg/AgrbSrBer3)
|
||||
[You can join our Discord server if you want closer contact!](https://discord.gg/sKeNQX4Wtj)
|
||||
|
||||

|
||||
|
Binary file not shown.
After Width: | Height: | Size: 256 KiB |
@@ -18,7 +18,7 @@ Currently pending [IANA](https://www.iana.org/) recognition.
|
||||
|
||||
### Mermaid Discord workspace
|
||||
|
||||
We would love to see what you create with Mermaid. Please share your creations with us in our [Discord](https://discord.gg/AgrbSrBer3) server [#showcase](https://discord.com/channels/1079455296289788015/1079502635054399649) channel.
|
||||
We would love to see what you create with Mermaid. Please share your creations with us in our [Discord](https://discord.gg/sKeNQX4Wtj) server [#showcase](https://discord.com/channels/1079455296289788015/1079502635054399649) channel.
|
||||
|
||||
### Add to Mermaid Ecosystem
|
||||
|
||||
|
@@ -42,7 +42,7 @@ Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an accoun
|
||||
|
||||
## Plans
|
||||
|
||||
- **Free** - A free plan that includes five diagrams.
|
||||
- **Free** - A free plan that includes three diagrams.
|
||||
|
||||
- **Pro** - A paid plan that includes unlimited diagrams, access to the collaboration feature, and more.
|
||||
|
||||
@@ -50,7 +50,7 @@ Try the Ultimate AI, Mermaid, and Visual Diagramming Suite by creating an accoun
|
||||
|
||||
To learn more, visit our [Pricing](https://mermaidchart.com/pricing) page.
|
||||
|
||||
Mermaid Chart is currently offering a 14-day free trial on our Pro and Enterprise tiers. Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up).
|
||||
Mermaid Chart is currently offering a 7-day free trial on our Pro and Enterprise tiers. Sign up for a free account at [Mermaid Chart](https://www.mermaidchart.com/app/sign-up).
|
||||
|
||||
## Mermaid JS contributions
|
||||
|
||||
|
@@ -46,28 +46,33 @@ https://codepen.io/Ryuno-Ki/pen/LNxwgR
|
||||
|
||||
[K8s.dev blog: Improve your documentation with Mermaid.js diagrams](https://www.kubernetes.dev/blog/2021/12/01/improve-your-documentation-with-mermaid.js-diagrams/)
|
||||
|
||||
## Jupyter Integration with mermaid-js
|
||||
## Jupyter / Python Integration with mermaid-js
|
||||
|
||||
Here's an example of Python integration with mermaid-js which uses the mermaid.ink service, that displays the graph in a Jupyter notebook.
|
||||
Here's an example of Python integration with mermaid-js which uses the mermaid.ink service, that displays the graph in a Jupyter notebook and save it as _.png_ image with the stated resolution (in this example, `dpi=1200`).
|
||||
|
||||
```python
|
||||
import base64
|
||||
import io, requests
|
||||
from IPython.display import Image, display
|
||||
from PIL import Image as im
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def mm(graph):
|
||||
graphbytes = graph.encode("utf8")
|
||||
base64_bytes = base64.urlsafe_b64encode(graphbytes)
|
||||
base64_string = base64_bytes.decode("ascii")
|
||||
display(Image(url="https://mermaid.ink/img/" + base64_string))
|
||||
img = im.open(io.BytesIO(requests.get('https://mermaid.ink/img/' + base64_string).content))
|
||||
plt.imshow(img)
|
||||
plt.axis('off') # allow to hide axis
|
||||
plt.savefig('image.png', dpi=1200)
|
||||
|
||||
mm("""
|
||||
graph LR;
|
||||
A--> B & C & D;
|
||||
B--> A & E;
|
||||
C--> A & E;
|
||||
D--> A & E;
|
||||
E--> B & C & D;
|
||||
A--> B & C & D
|
||||
B--> A & E
|
||||
C--> A & E
|
||||
D--> A & E
|
||||
E--> B & C & D
|
||||
""")
|
||||
```
|
||||
|
||||
@@ -75,4 +80,4 @@ graph LR;
|
||||
|
||||

|
||||
|
||||
<!--- cspell:ignore Elle Jaoude Neurodiverse graphbytes --->
|
||||
<!--- cspell:ignore Elle Jaoude Neurodiverse graphbytes imshow savefig --->
|
||||
|
@@ -16,7 +16,7 @@ It is a JavaScript based diagramming and charting tool that renders Markdown-ins
|
||||
[](https://coveralls.io/github/mermaid-js/mermaid?branch=master)
|
||||
[](https://www.jsdelivr.com/package/npm/mermaid)
|
||||
[](https://www.npmjs.com/package/mermaid)
|
||||
[](https://discord.gg/AgrbSrBer3)
|
||||
[](https://discord.gg/sKeNQX4Wtj)
|
||||
[](https://twitter.com/mermaidjs_)
|
||||
|
||||
</div>
|
||||
|
@@ -1,17 +1,35 @@
|
||||
# Blog
|
||||
|
||||
## [GUI for editing Mermaid Class Diagrams](https://docs.mermaidchart.com/blog/posts/gui-for-editing-mermaid-class-diagrams)
|
||||
|
||||
1/17/2025 • 5 mins
|
||||
|
||||
Discover how the latest update to the Mermaid Visual Editor transforms class diagramming. With new intuitive tools for creating and editing diagrams, dynamic relationship management, and customizable layouts, this feature-packed enhancement streamlines your diagramming experience like never before.
|
||||
|
||||
## [7 ER Diagram Examples For Database Modeling from Mermaid AI](https://docs.mermaidchart.com/blog/posts/7-er-diagram-examples-for-database-modeling-from-mermaid-ai)
|
||||
|
||||
1/16/2025 • 6 mins
|
||||
|
||||
Entity relationship (ER) diagrams are a cornerstone of database design, providing a blueprint for modeling your database and enabling clear communication across functions in your organization. As data volumes continue to soar and as AI models demand clean, well-organized data, ER diagrams have become more vital than ever. You can now quickly build ER diagrams with Mermaid Chart, Mermaid AI to Kickstart and fine tune your diagrams . From e-commerce payment flows to social media interactions and healthcare systems, ER diagrams are powering modern, data-driven environments.
|
||||
|
||||
## [Mermaid Whiteboard: Visual Collaboration Made Universal](https://docs.mermaidchart.com/blog/posts/mermaid-whiteboard-visual-collaboration-made-universal)
|
||||
|
||||
12/6/2024 • 2 mins
|
||||
|
||||
The Mermaid Whiteboard combines Mermaid syntax with a drag-and-drop interface, making it easier for teams to create, edit, and refine diagrams together. Whether you prefer working with code, visuals, Mermaid AI or all three, this tool adapts to your needs while keeping everything tied to Mermaid’s syntax. Key Features 1. Dual-Mode Editing Switch seamlessly between […]
|
||||
|
||||
## [Mermaid 11.4 is out: New Features and Kanban Diagramming](https://www.mermaidchart.com/blog/posts/mermaid-11-4-is-out-new-features-and-kanban-diagramming)
|
||||
|
||||
Mermaid 11.4 brings enhanced functionality with the introduction of Kanban diagrams, allowing users to create visual workflows with status columns and task details.
|
||||
|
||||
October 31, 2024 · 2 mins
|
||||
|
||||
Mermaid 11.4 brings enhanced functionality with the introduction of Kanban diagrams, allowing users to create visual workflows with status columns and task details.
|
||||
|
||||
## [How To Build an ER Diagram with Mermaid Chart](https://www.mermaidchart.com/blog/posts/how-to-build-an-er-diagram-with-mermaid-chart)
|
||||
|
||||
An entity relationship (ER) diagram acts like a blueprint for your database. This makes ER diagrams effective tools for anyone dealing with complex databases, data modeling, and AI model training.
|
||||
|
||||
October 24, 2024 · 4 mins
|
||||
|
||||
An entity relationship (ER) diagram acts like a blueprint for your database. This makes ER diagrams effective tools for anyone dealing with complex databases, data modeling, and AI model training.
|
||||
|
||||
## [Expanding the Horizons of Mermaid Flowcharts: Introducing 30 New Shapes!](https://www.mermaidchart.com/blog/posts/new-mermaid-flowchart-shapes/)
|
||||
|
||||
24 September 2024 · 5 mins
|
||||
|
@@ -16,26 +16,26 @@
|
||||
"fetch-contributors": "tsx .vitepress/scripts/fetch-contributors.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdi/font": "^7.0.0",
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"@mdi/font": "^7.4.47",
|
||||
"@vueuse/core": "^12.7.0",
|
||||
"font-awesome": "^4.7.0",
|
||||
"jiti": "^1.21.0",
|
||||
"jiti": "^2.4.2",
|
||||
"mermaid": "workspace:^",
|
||||
"vue": "^3.4.21"
|
||||
"vue": "^3.4.38"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/carbon": "^1.1.31",
|
||||
"@unocss/reset": "^0.59.0",
|
||||
"@vite-pwa/vitepress": "^0.4.0",
|
||||
"@vitejs/plugin-vue": "^5.0.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"@iconify-json/carbon": "^1.1.37",
|
||||
"@unocss/reset": "^66.0.0",
|
||||
"@vite-pwa/vitepress": "^0.5.3",
|
||||
"@vitejs/plugin-vue": "^5.0.5",
|
||||
"fast-glob": "^3.3.3",
|
||||
"https-localhost": "^4.7.1",
|
||||
"pathe": "^1.1.2",
|
||||
"unocss": "^0.59.0",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.0.0",
|
||||
"vite-plugin-pwa": "^0.19.7",
|
||||
"vitepress": "1.1.4",
|
||||
"workbox-window": "^7.0.0"
|
||||
"pathe": "^2.0.3",
|
||||
"unocss": "^66.0.0",
|
||||
"unplugin-vue-components": "^28.4.0",
|
||||
"vite": "^6.1.1",
|
||||
"vite-plugin-pwa": "^0.21.1",
|
||||
"vitepress": "1.6.3",
|
||||
"workbox-window": "^7.3.0"
|
||||
}
|
||||
}
|
||||
|
@@ -67,10 +67,12 @@ vi.mock('stylis', () => {
|
||||
|
||||
import { compile, serialize } from 'stylis';
|
||||
import { Diagram } from './Diagram.js';
|
||||
import { decodeEntities, encodeEntities } from './utils.js';
|
||||
import { toBase64 } from './utils/base64.js';
|
||||
import { ClassDB } from './diagrams/class/classDb.js';
|
||||
import { FlowDB } from './diagrams/flowchart/flowDb.js';
|
||||
import { SequenceDB } from './diagrams/sequence/sequenceDb.js';
|
||||
import { decodeEntities, encodeEntities } from './utils.js';
|
||||
import { toBase64 } from './utils/base64.js';
|
||||
import { StateDB } from './diagrams/state/stateDb.js';
|
||||
|
||||
/**
|
||||
* @see https://vitest.dev/guide/mocking.html Mock part of a module
|
||||
@@ -836,6 +838,31 @@ graph TD;A--x|text including URL space|B;`)
|
||||
});
|
||||
|
||||
it('should not modify db when rendering different diagrams', async () => {
|
||||
const stateDiagram1 = await mermaidAPI.getDiagramFromText(
|
||||
`stateDiagram
|
||||
direction LR
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]`
|
||||
);
|
||||
const stateDiagram2 = await mermaidAPI.getDiagramFromText(
|
||||
`stateDiagram
|
||||
direction TB
|
||||
[*] --> Still
|
||||
Still --> [*]
|
||||
Still --> Moving
|
||||
Moving --> Still
|
||||
Moving --> Crash
|
||||
Crash --> [*]`
|
||||
);
|
||||
expect(stateDiagram1.db).not.toBe(stateDiagram2.db);
|
||||
assert(stateDiagram1.db instanceof StateDB);
|
||||
assert(stateDiagram2.db instanceof StateDB);
|
||||
expect(stateDiagram1.db.getDirection()).not.toEqual(stateDiagram2.db.getDirection());
|
||||
|
||||
const flowDiagram1 = await mermaidAPI.getDiagramFromText(
|
||||
`flowchart LR
|
||||
A -- text --> B -- text2 --> C`
|
||||
@@ -899,28 +926,18 @@ graph TD;A--x|text including URL space|B;`)
|
||||
);
|
||||
const sequenceDiagram2 = await mermaidAPI.getDiagramFromText(
|
||||
`sequenceDiagram
|
||||
actor A1
|
||||
Alice->>+John: Hello John, how are you?
|
||||
Alice->>+John: John, can you hear me?
|
||||
John-->>-Alice: Hi Alice, I can hear you!
|
||||
John-->>-Alice: I feel great!`
|
||||
);
|
||||
// Since sequenceDiagram will return same Db object each time, we can compare the db to be same.
|
||||
expect(sequenceDiagram1.db).toBe(sequenceDiagram2.db);
|
||||
|
||||
// Since sequenceDiagram will return new Db object each time, we can compare the db to be different.
|
||||
expect(sequenceDiagram1.db).not.toBe(sequenceDiagram2.db);
|
||||
assert(sequenceDiagram1.db instanceof SequenceDB);
|
||||
assert(sequenceDiagram2.db instanceof SequenceDB);
|
||||
expect(sequenceDiagram1.db.getActors()).not.toEqual(sequenceDiagram2.db.getActors());
|
||||
});
|
||||
});
|
||||
|
||||
// Sequence Diagram currently uses a singleton DB, so this test will fail
|
||||
it.fails('should not modify db when rendering different sequence diagrams', async () => {
|
||||
const sequenceDiagram1 = await mermaidAPI.getDiagramFromText(
|
||||
`sequenceDiagram
|
||||
Alice->>Bob: Hello Bob, how are you?
|
||||
Bob-->>John: How about you John?`
|
||||
);
|
||||
const sequenceDiagram2 = await mermaidAPI.getDiagramFromText(
|
||||
`sequenceDiagram
|
||||
Alice->>Bob: Hello Bob, how are you?
|
||||
Bob-->>John: How about you John?`
|
||||
);
|
||||
expect(sequenceDiagram1.db).not.toBe(sequenceDiagram2.db);
|
||||
});
|
||||
});
|
||||
|
@@ -8,7 +8,7 @@ import { compile, serialize, stringify } from 'stylis';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import DOMPurify from 'dompurify';
|
||||
import isEmpty from 'lodash-es/isEmpty.js';
|
||||
import { version } from '../package.json';
|
||||
import packageJson from '../package.json' assert { type: 'json' };
|
||||
import { addSVGa11yTitleDescription, setA11yDiagramInfo } from './accessibility.js';
|
||||
import assignWithDepth from './assignWithDepth.js';
|
||||
import * as configApi from './config.js';
|
||||
@@ -422,12 +422,12 @@ const render = async function (
|
||||
// -------------------------------------------------------------------------------
|
||||
// Draw the diagram with the renderer
|
||||
try {
|
||||
await diag.renderer.draw(text, id, version, diag);
|
||||
await diag.renderer.draw(text, id, packageJson.version, diag);
|
||||
} catch (e) {
|
||||
if (config.suppressErrorRendering) {
|
||||
removeTempElements();
|
||||
} else {
|
||||
errorRenderer.draw(text, id, version);
|
||||
errorRenderer.draw(text, id, packageJson.version);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"$schema": "https://typedoc.org/schema.json",
|
||||
"plugin": ["typedoc-plugin-markdown"],
|
||||
"readme": "none",
|
||||
"githubPages": false,
|
||||
@@ -6,6 +7,5 @@
|
||||
"gitRevision": "master",
|
||||
"out": "src/docs/config/setup",
|
||||
"entryPointStrategy": "expand",
|
||||
"hideBreadcrumbs": true,
|
||||
"hideInPageTOC": true
|
||||
"hideBreadcrumbs": true
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@
|
||||
"ast"
|
||||
],
|
||||
"dependencies": {
|
||||
"langium": "3.0.0"
|
||||
"langium": "3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chevrotain": "^11.0.3"
|
||||
|
Reference in New Issue
Block a user