Compare commits

..

3 Commits

Author SHA1 Message Date
Yash Singh
9fd6a1396b fix: set root when globalThis is defined 2024-03-23 13:00:51 -07:00
Yash Singh
3df86ea1e6 Merge remote-tracking branch 'origin' into fix/5378 2024-03-23 12:17:21 -07:00
Yash Singh
7bc201673d fix: patch lodash to not use Function calls 2024-03-23 12:06:29 -07:00
120 changed files with 3106 additions and 3447 deletions

View File

@@ -1 +0,0 @@
.gitignore

11
.eslintignore Normal file
View File

@@ -0,0 +1,11 @@
dist/**
.github/**
docs/Setup.md
cypress.config.js
cypress/plugins/index.js
coverage
*.json
node_modules
# autogenereated by langium-cli
generated/

View File

@@ -53,7 +53,6 @@ module.exports = {
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/consistent-type-definitions': 'error',
'@typescript-eslint/ban-ts-comment': [
'error',
{

View File

@@ -37,13 +37,13 @@ jobs:
run: pnpm run build
- name: Upload Mermaid Build as Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: mermaid-build
path: packages/mermaid/dist
- name: Upload Mermaid Mindmap Build as Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: mermaid-mindmap-build
path: packages/mermaid-mindmap/dist

View File

@@ -33,7 +33,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v2
with:
config-file: ./.github/codeql/codeql-config.yml
languages: ${{ matrix.language }}
@@ -45,7 +45,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -59,4 +59,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v2

View File

@@ -17,4 +17,4 @@ jobs:
- name: 'Checkout Repository'
uses: actions/checkout@v4
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
uses: actions/dependency-review-action@v3

View File

@@ -106,7 +106,7 @@ jobs:
# These cached snapshots are downloaded, providing the reference snapshots.
- name: Cache snapshots
id: cache-snapshot
uses: actions/cache/restore@v4
uses: actions/cache/restore@v3
with:
path: ./cypress/snapshots
key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
@@ -148,7 +148,7 @@ jobs:
CYPRESS_COMMIT: ${{ github.sha }}
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v3
# Run step only pushes to develop and pull_requests
if: ${{ steps.cypress.conclusion == 'success' && (github.event_name == 'pull_request' || github.ref == 'refs/heads/develop')}}
with:
@@ -185,7 +185,7 @@ jobs:
- name: Save snapshots cache
id: cache-upload
if: ${{ github.event_name == 'push' && needs.e2e.result != 'failure' }}
uses: actions/cache/save@v4
uses: actions/cache/save@v3
with:
path: ./snapshots
key: ${{ runner.os }}-snapshots-${{ github.event.after }}

View File

@@ -29,7 +29,7 @@ jobs:
- uses: actions/checkout@v4
- name: Restore lychee cache
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: .lycheecache
key: cache-lychee-${{ github.sha }}

View File

@@ -22,7 +22,7 @@ jobs:
pull-requests: write # write permission is required to label PRs
steps:
- name: Label PR
uses: release-drafter/release-drafter@v6
uses: release-drafter/release-drafter@v5
with:
config-name: pr-labeler.yml
disable-autolabeler: false

View File

@@ -37,13 +37,13 @@ jobs:
run: pnpm install --frozen-lockfile
- name: Setup Pages
uses: actions/configure-pages@v4
uses: actions/configure-pages@v3
- name: Run Build
run: pnpm --filter mermaid run docs:build:vitepress
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
uses: actions/upload-pages-artifact@v1
with:
path: packages/mermaid/src/vitepress/.vitepress/dist
@@ -56,4 +56,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v2

View File

@@ -16,7 +16,7 @@ jobs:
pull-requests: read # required to read PR titles/labels
steps:
- name: Draft Release
uses: release-drafter/release-drafter@v6
uses: release-drafter/release-drafter@v5
with:
disable-autolabeler: true
env:

View File

@@ -39,7 +39,7 @@ jobs:
pnpm exec vitest run ./packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts --coverage
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v3
# Run step only pushes to develop and pull_requests
if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/develop' }}
with:

View File

@@ -19,7 +19,7 @@ jobs:
message: 'chore: update browsers list'
push: false
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
uses: peter-evans/create-pull-request@v5
with:
branch: update-browserslist
title: Update Browserslist

View File

@@ -1 +1 @@
20.12.2
v20.11.1

View File

@@ -1,2 +1,2 @@
FROM node:20.12.2-alpine3.19 AS base
FROM node:20.11.1-alpine3.19 AS base
RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.shrc" SHELL="$(which sh)" sh -

View File

@@ -1458,79 +1458,5 @@ gitGraph TB:
{ gitGraph: { parallelCommits: true } }
);
});
it('73: should render a simple gitgraph with three branches and tagged merge commit using switch instead of checkout', () => {
imgSnapshotTest(
`gitGraph
commit id: "1"
commit id: "2"
branch nice_feature
switch nice_feature
commit id: "3"
switch main
commit id: "4"
switch nice_feature
branch very_nice_feature
switch very_nice_feature
commit id: "5"
switch main
commit id: "6"
switch nice_feature
commit id: "7"
switch main
merge nice_feature id: "12345" tag: "my merge commit"
switch very_nice_feature
commit id: "8"
switch main
commit id: "9"
`,
{}
);
});
it('74: should render commits for more than 8 branches using switch instead of checkout', () => {
imgSnapshotTest(
`
gitGraph
switch main
%% Make sure to manually set the ID of all commits, for consistent visual tests
commit id: "1-abcdefg"
switch main
branch branch1
commit id: "2-abcdefg"
switch main
merge branch1
branch branch2
commit id: "3-abcdefg"
switch main
merge branch2
branch branch3
commit id: "4-abcdefg"
switch main
merge branch3
branch branch4
commit id: "5-abcdefg"
switch main
merge branch4
branch branch5
commit id: "6-abcdefg"
switch main
merge branch5
branch branch6
commit id: "7-abcdefg"
switch main
merge branch6
branch branch7
commit id: "8-abcdefg"
switch main
merge branch7
branch branch8
commit id: "9-abcdefg"
switch main
merge branch8
branch branch9
commit id: "10-abcdefg"
`,
{}
);
});
});
});

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.ts';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('Quadrant Chart', () => {
it('should render if only chart type is provided', () => {
@@ -226,52 +226,4 @@ describe('Quadrant Chart', () => {
);
cy.get('svg');
});
it('it should render data points with styles', () => {
imgSnapshotTest(
`
quadrantChart
title Reach and engagement of campaigns
x-axis Reach -->
y-axis Engagement -->
quadrant-1 We should expand
quadrant-2 Need to promote
quadrant-3 Re-evaluate
quadrant-4 May be improved
Campaign A: [0.3, 0.6] radius: 20
Campaign B: [0.45, 0.23] color: #ff0000
Campaign C: [0.57, 0.69] stroke-color: #ff00ff
Campaign D: [0.78, 0.34] stroke-width: 3px
Campaign E: [0.40, 0.34] radius: 20, color: #ff0000 , stroke-color : #ff00ff, stroke-width : 3px
Campaign F: [0.35, 0.78] stroke-width: 3px , color: #ff0000, radius: 20, stroke-color: #ff00ff
Campaign G: [0.22, 0.22] stroke-width: 3px , color: #309708 , radius : 20 , stroke-color: #5060ff
Campaign H: [0.22, 0.44]
`,
{}
);
cy.get('svg');
});
it('it should render data points with styles + classes', () => {
imgSnapshotTest(
`
quadrantChart
title Reach and engagement of campaigns
x-axis Reach -->
y-axis Engagement -->
quadrant-1 We should expand
quadrant-2 Need to promote
quadrant-3 Re-evaluate
quadrant-4 May be improved
Campaign A:::class1: [0.3, 0.6] radius: 20
Campaign B: [0.45, 0.23] color: #ff0000
Campaign C: [0.57, 0.69] stroke-color: #ff00ff
Campaign D:::class2: [0.78, 0.34] stroke-width: 3px
Campaign E:::class2: [0.40, 0.34] radius: 20, color: #ff0000, stroke-color: #ff00ff, stroke-width: 3px
Campaign F:::class1: [0.35, 0.78]
classDef class1 color: #908342, radius : 10, stroke-color: #310085, stroke-width: 10px
classDef class2 color: #f00fff, radius : 10
`
);
});
});

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css"

View File

@@ -3,7 +3,7 @@
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -3,7 +3,7 @@
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -3,7 +3,7 @@
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -3,7 +3,7 @@
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -4,7 +4,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/font-awesome.min.css"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+SC&display=swap"

View File

@@ -20,7 +20,7 @@ services:
- 9000:9000
- 3333:3333
cypress:
image: cypress/included:13.7.3
image: cypress/included:12.17.4
stdin_open: true
tty: true
working_dir: /mermaid

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -84,13 +84,3 @@ Example with legacy mode enabled (the latest version of KaTeX's stylesheet can b
</body>
</html>
```
## Handling Rendering Differences
Due to differences between default fonts across operating systems and browser's MathML implementations, inconsistent results can be seen across platforms. If having consistent results are important, or the most optimal rendered results are desired, `forceLegacyMathML` can be enabled in the config.
This option will always use KaTeX's stylesheet instead of only when MathML is not supported (as with `legacyMathML`). Note that only `forceLegacyMathML` needs to be set.
If including KaTeX's stylesheet is not a concern, enabling this option is recommended to avoid scenarios where no MathML implementation within a browser provides the desired output (as seen below).
![Image showing differences between Browsers](img/mathMLDifferences.png)

View File

@@ -240,8 +240,6 @@ Communication tools and platforms
### Other
- [Astro](https://astro.build/)
- [Adding diagrams to your Astro site with MermaidJS and Playwright](https://agramont.net/blog/diagraming-with-mermaidjs-astro/)
- [Bisheng](https://www.npmjs.com/package/bisheng)
- [bisheng-plugin-mermaid](https://github.com/yct21/bisheng-plugin-mermaid)
- [Blazorade Mermaid: Render Mermaid diagrams in Blazor applications](https://github.com/Blazorade/Blazorade-Mermaid/wiki)
@@ -251,7 +249,6 @@ Communication tools and platforms
- [Jekyll](https://jekyllrb.com/)
- [jekyll-mermaid](https://rubygems.org/gems/jekyll-mermaid)
- [jekyll-mermaid-diagrams](https://github.com/fuzhibo/jekyll-mermaid-diagrams)
- [MarkChart: Preview Mermaid diagrams on macOS](https://markchart.app/)
- [mermaid-isomorphic](https://github.com/remcohaszing/mermaid-isomorphic)
- [mermaid-server: Generate diagrams using a HTTP request](https://github.com/TomWright/mermaid-server)
- [NiceGUI: Let any browser be the frontend of your Python code](https://nicegui.io) ✅

View File

@@ -28,23 +28,13 @@ Thank you for being part of our story. Here's to creating, innovating, and colla
Knut Sveidqvist 🧜‍♂️✨
## Mermaid Chart's Visual Editor for Flowcharts and Sequence diagrams
## Mermaid Chart's Visual Editor for Flowcharts
The Mermaid Chart team is excited to introduce a new Visual Editor for Flowcharts and Sequence diagrams, enabling users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options.
The Mermaid Chart team is excited to introduce a new Visual Editor for flowcharts, enabling users of all skill levels to create diagrams easily and efficiently, with both GUI and code-based editing options.
Learn more:
Create flowchart nodes, connect them with edges, update shapes, change colors, and edit labels with just a few clicks that automatically reflect in your diagrams code for easy customizability.
- Visual Editor For Flowcharts
- [Blog post](https://www.mermaidchart.com/blog/posts/mermaid-chart-releases-new-visual-editor-for-flowcharts)
- [Demo video](https://www.youtube.com/watch?v=5aja0gijoO0)
- Visual Editor For Sequence diagrams
- [Blog post](https://www.mermaidchart.com/blog/posts/mermaid-chart-unveils-visual-editor-for-sequence-diagrams)
- [Demo video](https://youtu.be/imc2u5_N6Dc)
Read more about it in our latest [BLOG POST](https://www.mermaidchart.com/blog/posts/mermaid-chart-releases-new-visual-editor-for-flowcharts) and watch a [DEMO VIDEO](https://www.youtube.com/watch?v=5aja0gijoO0) on our YouTube page.
## 📖 Blog posts

View File

@@ -6,18 +6,6 @@
# Blog
## [Mermaid Chart Unveils Visual Editor for Sequence Diagrams](https://www.mermaidchart.com/blog/posts/mermaid-chart-unveils-visual-editor-for-sequence-diagrams/)
8 April 2024 · 5 mins
Sequence diagrams are excellent tools for communication and documentation.
## [Modeling system states: It starts with a Turing machine](https://www.mermaidchart.com/blog/posts/modeling-system-states/)
27 March 2024 · 12 mins
In computer science, there are a few fundamental papers that, without exaggeration, changed everything.
## [Mermaid Chart Raises $7.5M to Reinvent Visual Collaboration for Enterprises](https://www.mermaidchart.com/blog/posts/mermaid-chart-raises-7.5m-to-reinvent-visual-collaoration-for-enterprises/)
20 March 2024 · 4 mins

View File

@@ -6,7 +6,7 @@
# Entity Relationship Diagrams
> An entityrelationship model (or ER model) describes interrelated things of interest in a specific domain of knowledge. A basic ER model is composed of entity types (which classify the things of interest) and specifies relationships that can exist between entities (instances of those entity types) [Wikipedia](https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model).
> An entityrelationship model (or ER model) describes interrelated things of interest in a specific domain of knowledge. A basic ER model is composed of entity types (which classify the things of interest) and specifies relationships that can exist between entities (instances of those entity types). Wikipedia.
Note that practitioners of ER modelling almost always refer to _entity types_ simply as _entities_. For example the `CUSTOMER` entity _type_ would be referred to simply as the `CUSTOMER` entity. This is so common it would be inadvisable to do anything else, but technically an entity is an abstract _instance_ of an entity type, and this is what an ER diagram shows - abstract instances, and the relationships between them. This is why entities are always named using singular nouns.
@@ -111,7 +111,7 @@ Only the `first-entity` part of a statement is mandatory. This makes it possible
The `relationship` part of each statement can be broken down into three sub-components:
- the cardinality of the first entity with respect to the second
- the cardinality of the first entity with respect to the second,
- whether the relationship confers identity on a 'child' entity
- the cardinality of the second entity with respect to the first
@@ -232,7 +232,7 @@ erDiagram
#### Attribute Keys and Comments
Attributes may also have a `key` or comment defined. Keys can be `PK`, `FK` or `UK`, for Primary Key, Foreign Key or Unique Key. To specify multiple key constraints on a single attribute, separate them with a comma (e.g., `PK, FK`). A `comment` is defined by double quotes at the end of an attribute. Comments themselves cannot have double-quote characters in them.
Attributes may also have a `key` or comment defined. Keys can be `PK`, `FK` or `UK`, for Primary Key, Foreign Key or Unique Key. To specify multiple key constraints on a single attribute, separate them with a comma (e.g., `PK, FK`).. A `comment` is defined by double quotes at the end of an attribute. Comments themselves cannot have double-quote characters in them.
```mermaid-example
erDiagram

View File

@@ -1178,36 +1178,6 @@ Adding this snippet in the `<head>` would add support for Font Awesome v6.5.1
/>
```
### Custom icons
It is possible to use custom icons served from Font Awesome as long as the website imports the corresponding kit.
Note that this is currently a paid feature from Font Awesome.
For custom icons, you need to use the `fak` prefix.
**Example**
```
flowchart TD
B[fa:fa-twitter] %% standard icon
B-->E(fak:fa-custom-icon-name) %% custom icon
```
And trying to render it
```mermaid-example
flowchart TD
B["fa:fa-twitter for peace"]
B-->C["fab:fa-truck-bold a custom icon"]
```
```mermaid
flowchart TD
B["fa:fa-twitter for peace"]
B-->C["fab:fa-truck-bold a custom icon"]
```
## Graph declarations with spaces between vertices and link and without semicolon
- In graph declarations, the statements also can now end without a semicolon. After release 0.2.16, ending a graph statement with semicolon is just optional. So the below graph declaration is also valid along with the old declarations of the graph.

View File

@@ -56,8 +56,6 @@ In Mermaid, we support the basic git operations like:
With the help of these key git commands, you will be able to draw a gitgraph in Mermaid very easily and quickly.
Entity names are often capitalized, although there is no accepted standard on this, and it is not required in Mermaid.
**NOTE**: `checkout` and `switch` can be used interchangeably.
## Syntax
Mermaid syntax for a gitgraph is very straight-forward and simple. It follows a declarative-approach, where each commit is drawn on the timeline in the diagram, in order of its occurrences/presence in code. Basically, it follows the insertion order for each command.

View File

@@ -168,86 +168,3 @@ quadrantChart
quadrant-3 Delegate
quadrant-4 Delete
```
### Point styling
Points can either be styled directly or with defined shared classes
1. Direct styling
```md
Point A: [0.9, 0.0] radius: 12
Point B: [0.8, 0.1] color: #ff3300, radius: 10
Point C: [0.7, 0.2] radius: 25, color: #00ff33, stroke-color: #10f0f0
Point D: [0.6, 0.3] radius: 15, stroke-color: #00ff0f, stroke-width: 5px ,color: #ff33f0
```
2. Classes styling
```md
Point A:::class1: [0.9, 0.0]
Point B:::class2: [0.8, 0.1]
Point C:::class3: [0.7, 0.2]
Point D:::class3: [0.7, 0.2]
classDef class1 color: #109060
classDef class2 color: #908342, radius : 10, stroke-color: #310085, stroke-width: 10px
classDef class3 color: #f00fff, radius : 10
```
#### Available styles:
| Parameter | Description |
| ------------ | ---------------------------------------------------------------------- |
| color | Fill color of the point |
| radius | Radius of the point |
| stroke-width | Border width of the point |
| stroke-color | Border color of the point (useless when stroke-width is not specified) |
> **Note**
> Order of preference:
>
> 1. Direct styles
> 2. Class styles
> 3. Theme styles
## Example on styling
```mermaid-example
quadrantChart
title Reach and engagement of campaigns
x-axis Low Reach --> High Reach
y-axis Low Engagement --> High Engagement
quadrant-1 We should expand
quadrant-2 Need to promote
quadrant-3 Re-evaluate
quadrant-4 May be improved
Campaign A: [0.9, 0.0] radius: 12
Campaign B:::class1: [0.8, 0.1] color: #ff3300, radius: 10
Campaign C: [0.7, 0.2] radius: 25, color: #00ff33, stroke-color: #10f0f0
Campaign D: [0.6, 0.3] radius: 15, stroke-color: #00ff0f, stroke-width: 5px ,color: #ff33f0
Campaign E:::class2: [0.5, 0.4]
Campaign F:::class3: [0.4, 0.5] color: #0000ff
classDef class1 color: #109060
classDef class2 color: #908342, radius : 10, stroke-color: #310085, stroke-width: 10px
classDef class3 color: #f00fff, radius : 10
```
```mermaid
quadrantChart
title Reach and engagement of campaigns
x-axis Low Reach --> High Reach
y-axis Low Engagement --> High Engagement
quadrant-1 We should expand
quadrant-2 Need to promote
quadrant-3 Re-evaluate
quadrant-4 May be improved
Campaign A: [0.9, 0.0] radius: 12
Campaign B:::class1: [0.8, 0.1] color: #ff3300, radius: 10
Campaign C: [0.7, 0.2] radius: 25, color: #00ff33, stroke-color: #10f0f0
Campaign D: [0.6, 0.3] radius: 15, stroke-color: #00ff0f, stroke-width: 5px ,color: #ff33f0
Campaign E:::class2: [0.5, 0.4]
Campaign F:::class3: [0.4, 0.5] color: #0000ff
classDef class1 color: #109060
classDef class2 color: #908342, radius : 10, stroke-color: #310085, stroke-width: 10px
classDef class3 color: #f00fff, radius : 10
```

View File

@@ -160,7 +160,7 @@ In a real world use of state diagrams you often end up with diagrams that are mu
have several internal states. These are called composite states in this terminology.
In order to define a composite state you need to use the state keyword followed by an id and the body of the composite
state between {}. You can name a composite state on a separate line just like a simple state. See the example below:
state between {}. See the example below:
```mermaid-example
stateDiagram-v2
@@ -169,14 +169,6 @@ stateDiagram-v2
[*] --> second
second --> [*]
}
[*] --> NamedComposite
NamedComposite: Another Composite
state NamedComposite {
[*] --> namedSimple
namedSimple --> [*]
namedSimple: Another simple
}
```
```mermaid
@@ -186,14 +178,6 @@ stateDiagram-v2
[*] --> second
second --> [*]
}
[*] --> NamedComposite
NamedComposite: Another Composite
state NamedComposite {
[*] --> namedSimple
namedSimple --> [*]
namedSimple: Another simple
}
```
You can do this in several layers:

View File

@@ -4,7 +4,7 @@
"version": "10.2.4",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"type": "module",
"packageManager": "pnpm@8.15.7",
"packageManager": "pnpm@8.15.4",
"keywords": [
"diagram",
"markdown",
@@ -25,8 +25,8 @@
"dev:vite": "tsx .vite/server.ts",
"dev:coverage": "pnpm coverage:cypress:clean && VITE_COVERAGE=true pnpm dev:vite",
"release": "pnpm build",
"lint": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content . && pnpm lint:jison && prettier --cache --check .",
"lint:fix": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content --fix . && prettier --write . && tsx scripts/fixCSpell.ts",
"lint": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content --ignore-path .gitignore . && pnpm lint:jison && prettier --cache --check .",
"lint:fix": "cross-env NODE_OPTIONS=--max_old_space_size=8192 eslint --cache --cache-strategy content --fix --ignore-path .gitignore . && prettier --write . && tsx scripts/fixCSpell.ts",
"lint:jison": "tsx ./scripts/jison/lint.mts",
"contributors": "tsx scripts/updateContributors.ts",
"cypress": "cypress run",
@@ -129,7 +129,8 @@
},
"pnpm": {
"patchedDependencies": {
"cytoscape@3.28.1": "patches/cytoscape@3.28.1.patch"
"cytoscape@3.28.1": "patches/cytoscape@3.28.1.patch",
"lodash-es@4.17.21": "patches/lodash-es@4.17.21.patch"
}
}
}

View File

@@ -38,7 +38,7 @@
]
},
"dependencies": {
"@braintree/sanitize-url": "^7.0.0",
"@braintree/sanitize-url": "^6.0.4",
"d3": "^7.9.0",
"khroma": "^2.1.0"
},

View File

@@ -1,6 +1,6 @@
{
"name": "mermaid",
"version": "11.0.0-alpha.7",
"version": "11.0.0-alpha.6",
"description": "Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.",
"type": "module",
"module": "./dist/mermaid.core.mjs",
@@ -87,7 +87,7 @@
"uuid": "^9.0.1"
},
"devDependencies": {
"@adobe/jsonschema2md": "^8.0.0",
"@adobe/jsonschema2md": "^7.1.5",
"@types/cytoscape": "^3.19.16",
"@types/d3": "^7.4.3",
"@types/d3-sankey": "^0.12.4",

View File

@@ -21,7 +21,7 @@ export const updateCurrentConfig = (siteCfg: MermaidConfig, _directives: Mermaid
let sumOfDirectives: MermaidConfig = {};
for (const d of _directives) {
sanitize(d);
// Apply the data from the directive where the overrides the themeVariables
// Apply the data from the directive where the the overrides the themeVariables
sumOfDirectives = assignWithDepth(sumOfDirectives, d);
}

View File

@@ -120,13 +120,6 @@ export interface MermaidConfig {
*
*/
legacyMathML?: boolean;
/**
* This option forces Mermaid to rely on KaTeX's own stylesheet for rendering MathML. Due to differences between OS
* fonts and browser's MathML implementation, this option is recommended if consistent rendering is important.
* If set to true, ignores legacyMathML.
*
*/
forceLegacyMathML?: boolean;
/**
* This option controls if the generated ids of nodes in the SVG are
* generated randomly or based on a seed.

View File

@@ -45,7 +45,7 @@ flowchart
a --> C2
```
To handle this case a special type of edge is inserted. The edge to/from the cluster is replaced with an edge to/from a node in the cluster which is tagged with toCluster/fromCluster. When rendering this edge the intersection between the edge and the border of the cluster is calculated making the edge start/stop there. In practice this renders like an edge to/from the cluster.
To handle this case a special type of edge is inserted. The edge to/from the cluster is replaced with an edge to/from a node in the cluster which is tagged with toCluster/fromCluster. When rendering this edge the intersection between the edge and the border of the cluster is calculated making the edge start/stop there. In practice this renders like an an edge to/from the cluster.
In the diagram above the root diagram would be rendered with C1 whereas C2 would be rendered recursively.

View File

@@ -3,7 +3,6 @@ import { log } from '../logger.js';
import { getConfig } from '../diagram-api/diagramAPI.js';
import { evaluate } from '../diagrams/common/common.js';
import { decodeEntities } from '../utils.js';
import { replaceIconSubstring } from '../rendering-util/createText.js';
/**
* @param dom
@@ -60,7 +59,10 @@ const createLabel = (_vertexText, style, isTitle, isNode) => {
log.debug('vertexText' + vertexText);
const node = {
isNode,
label: replaceIconSubstring(decodeEntities(vertexText)),
label: decodeEntities(vertexText).replace(
/fa[blrs]?:fa-[\w-]+/g, // cspell: disable-line
(s) => `<i class='${s.replace(':', ' ')}'></i>`
),
labelStyle: style.replace('fill:', 'color:'),
};
let vertexNode = addHtmlLabel(node);

View File

@@ -1,5 +1,5 @@
/*
* Borrowed with love from dagre-d3. Many thanks to cpettitt!
* Borrowed with love from from dagre-d3. Many thanks to cpettitt!
*/
import node from './intersect-node.js';

View File

@@ -262,7 +262,7 @@ const getBlocksFlat = () => {
return [...Object.values(blockDatabase)];
};
/**
* Returns the hierarchy of blocks
* Returns the the hierarchy of blocks
* @returns
*/
const getBlocks = () => {

View File

@@ -4,7 +4,7 @@ import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
import { log } from '../../logger.js';
import { getConfig } from '../../diagram-api/diagramAPI.js';
import { render } from '../../dagre-wrapper/index.js';
import utils, { getEdgeId } from '../../utils.js';
import utils from '../../utils.js';
import { interpolateToCurve, getStylesFromArray } from '../../utils.js';
import { setupGraphViewbox } from '../../setupGraphViewbox.js';
import common from '../common/common.js';
@@ -231,10 +231,7 @@ export const addRelations = function (relations: ClassRelation[], g: graphlib.Gr
//Set relationship style and line type
classes: 'relation',
pattern: edge.relation.lineType == 1 ? 'dashed' : 'solid',
id: getEdgeId(edge.id1, edge.id2, {
prefix: 'id',
counter: cnt,
}),
id: `id_${edge.id1}_${edge.id2}_${cnt}`,
// Set link type for rendering
arrowhead: edge.type === 'arrow_open' ? 'none' : 'normal',
//Set edge extra labels

View File

@@ -138,7 +138,7 @@ export interface ClassNote {
text: string;
}
export interface ClassRelation {
export type ClassRelation = {
id1: string;
id2: string;
relationTitle1: string;
@@ -152,7 +152,7 @@ export interface ClassRelation {
type2: number;
lineType: number;
};
}
};
export interface NamespaceNode {
id: string;

View File

@@ -337,20 +337,18 @@ export const renderKatex = async (text: string, config: MermaidConfig): Promise<
return text;
}
if (!(isMathMLSupported() || config.legacyMathML || config.forceLegacyMathML)) {
if (!isMathMLSupported() && !config.legacyMathML) {
return text.replace(katexRegex, 'MathML is unsupported in this environment.');
}
const { default: katex } = await import('katex');
const outputMode =
config.forceLegacyMathML || (!isMathMLSupported() && config.legacyMathML)
? 'htmlAndMathml'
: 'mathml';
return text
.split(lineBreakRegex)
.map((line) =>
hasKatex(line)
? `<div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">${line}</div>`
? `<div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">
${line}
</div>`
: `<div>${line}</div>`
)
.join('')
@@ -359,7 +357,7 @@ export const renderKatex = async (text: string, config: MermaidConfig): Promise<
.renderToString(c, {
throwOnError: true,
displayMode: true,
output: outputMode,
output: isMathMLSupported() ? 'mathml' : 'htmlAndMathml',
})
.replace(/\n/g, ' ')
.replace(/<annotation.*<\/annotation>/g, '')

View File

@@ -1,7 +1,7 @@
import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
import { select, curveLinear, selectAll } from 'd3';
import { getConfig } from '../../diagram-api/diagramAPI.js';
import utils, { getEdgeId } from '../../utils.js';
import utils from '../../utils.js';
import { render } from '../../dagre-wrapper/index.js';
import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
import { log } from '../../logger.js';
@@ -210,11 +210,7 @@ export const addEdges = async function (edges, g, diagObj) {
cnt++;
// Identify Link
const linkIdBase = getEdgeId(edge.start, edge.end, {
counter: cnt,
prefix: 'L',
});
const linkIdBase = 'L-' + edge.start + '-' + edge.end;
// count the links from+to the same node to give unique id
if (linkIdCnt[linkIdBase] === undefined) {
linkIdCnt[linkIdBase] = 0;
@@ -223,8 +219,7 @@ export const addEdges = async function (edges, g, diagObj) {
linkIdCnt[linkIdBase]++;
log.info('abc78 new entry', linkIdBase, linkIdCnt[linkIdBase]);
}
let linkId = `${linkIdBase}_${linkIdCnt[linkIdBase]}`;
let linkId = linkIdBase + '-' + linkIdCnt[linkIdBase];
log.info('abc78 new link id to be used is', linkIdBase, linkId, linkIdCnt[linkIdBase]);
const linkNameStart = 'LS-' + edge.start;
const linkNameEnd = 'LE-' + edge.end;

View File

@@ -6,10 +6,9 @@ import { applyStyle } from 'dagre-d3-es/src/dagre-js/util.js';
import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
import { log } from '../../logger.js';
import common, { evaluate, renderKatex } from '../common/common.js';
import { interpolateToCurve, getStylesFromArray, getEdgeId } from '../../utils.js';
import { interpolateToCurve, getStylesFromArray } from '../../utils.js';
import { setupGraphViewbox } from '../../setupGraphViewbox.js';
import flowChartShapes from './flowChartShapes.js';
import { replaceIconSubstring } from '../../rendering-util/createText.js';
const conf = {};
export const setConf = function (cnf) {
@@ -57,9 +56,14 @@ export const addVertices = async function (vert, g, svgId, root, _doc, diagObj)
let vertexNode;
if (evaluate(getConfig().flowchart.htmlLabels)) {
// TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
const replacedVertexText = replaceIconSubstring(vertexText);
const node = {
label: await renderKatex(replacedVertexText, getConfig()),
label: await renderKatex(
vertexText.replace(
/fa[blrs]?:fa-[\w-]+/g, // cspell:disable-line
(s) => `<i class='${s.replace(':', ' ')}'></i>`
),
getConfig()
),
};
vertexNode = addHtmlLabel(svg, node).node();
vertexNode.parentNode.removeChild(vertexNode);
@@ -175,10 +179,7 @@ export const addEdges = async function (edges, g, diagObj) {
cnt++;
// Identify Link
const linkId = getEdgeId(edge.start, edge.end, {
counter: cnt,
prefix: 'L',
});
const linkId = 'L-' + edge.start + '-' + edge.end;
const linkNameStart = 'LS-' + edge.start;
const linkNameEnd = 'LE-' + edge.end;
@@ -241,7 +242,13 @@ export const addEdges = async function (edges, g, diagObj) {
edgeData.labelType = 'html';
edgeData.label = `<span id="L-${linkId}" class="edgeLabel L-${linkNameStart}' L-${linkNameEnd}" style="${
edgeData.labelStyle
}">${await renderKatex(replaceIconSubstring(edge.text), getConfig())}</span>`;
}">${await renderKatex(
edge.text.replace(
/fa[blrs]?:fa-[\w-]+/g, // cspell:disable-line
(s) => `<i class='${s.replace(':', ' ')}'></i>`
),
getConfig()
)}</span>`;
} else {
edgeData.labelType = 'text';
edgeData.label = edge.text.replace(common.lineBreakRegex, '\n');

View File

@@ -141,7 +141,7 @@ describe('when parsing flowcharts', function () {
expect(edges[3].type).toBe('arrow_point');
expect(edges[3].text).toBe('');
});
it('should handle chaining and multiple nodes in link statement FVC ', function () {
it('should handle chaining and multiple nodes in in link statement FVC ', function () {
const res = flow.parser.parse(`
graph TD
A --> B & B2 & C --> D2;
@@ -181,7 +181,7 @@ describe('when parsing flowcharts', function () {
expect(edges[5].type).toBe('arrow_point');
expect(edges[5].text).toBe('');
});
it('should handle chaining and multiple nodes in link statement with extra info in statements', function () {
it('should handle chaining and multiple nodes in in link statement with extra info in statements', function () {
const res = flow.parser.parse(`
graph TD
A[ h ] -- hello --> B[" test "]:::exClass & C --> D;

View File

@@ -64,7 +64,7 @@ describe('parsing a flow chart', function () {
expect(edges[0].end).toBe('monograph');
});
describe('special characters should be handled.', function () {
describe('special characters should be be handled.', function () {
const charTest = function (char, result) {
const res = flow.parser.parse('graph TD;A(' + char + ')-->B;');

View File

@@ -88,16 +88,6 @@ describe('when parsing a gitGraph', function () {
expect(parser.yy.getCurrentBranch()).toBe('new');
});
it('should switch a branch', function () {
const str = 'gitGraph:\n' + 'branch new\n' + 'switch new\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(0);
expect(parser.yy.getCurrentBranch()).toBe('new');
});
it('should add commits to checked out branch', function () {
const str = 'gitGraph:\n' + 'branch new\n' + 'checkout new\n' + 'commit\n' + 'commit\n';

View File

@@ -520,78 +520,6 @@ describe('when parsing a gitGraph', function () {
]);
});
it('should handle new branch switch', function () {
const str = `gitGraph:
commit
branch testBranch
switch testBranch
`;
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('testBranch');
expect(parser.yy.getDirection()).toBe('LR');
expect(Object.keys(parser.yy.getBranches()).length).toBe(2);
});
it('should handle new branch switch & commit', function () {
const str = `gitGraph:
commit
branch testBranch
switch testBranch
commit
`;
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(2);
expect(parser.yy.getCurrentBranch()).toBe('testBranch');
expect(parser.yy.getDirection()).toBe('LR');
expect(Object.keys(parser.yy.getBranches()).length).toBe(2);
const commit1 = Object.keys(commits)[0];
const commit2 = Object.keys(commits)[1];
expect(commits[commit1].branch).toBe('main');
expect(commits[commit1].parents).toStrictEqual([]);
expect(commits[commit2].branch).toBe('testBranch');
expect(commits[commit2].parents).toStrictEqual([commit1]);
});
it('should handle new branch switch & commit and merge', function () {
const str = `gitGraph:
commit
branch testBranch
switch testBranch
commit
commit
switch main
merge testBranch
`;
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(4);
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(parser.yy.getDirection()).toBe('LR');
expect(Object.keys(parser.yy.getBranches()).length).toBe(2);
const commit1 = Object.keys(commits)[0];
const commit2 = Object.keys(commits)[1];
const commit3 = Object.keys(commits)[2];
const commit4 = Object.keys(commits)[3];
expect(commits[commit1].branch).toBe('main');
expect(commits[commit1].parents).toStrictEqual([]);
expect(commits[commit2].branch).toBe('testBranch');
expect(commits[commit2].parents).toStrictEqual([commits[commit1].id]);
expect(commits[commit3].branch).toBe('testBranch');
expect(commits[commit3].parents).toStrictEqual([commits[commit2].id]);
expect(commits[commit4].branch).toBe('main');
expect(commits[commit4].parents).toStrictEqual([commits[commit1].id, commits[commit3].id]);
expect(parser.yy.getBranchesAsObjArray()).toStrictEqual([
{ name: 'main' },
{ name: 'testBranch' },
]);
});
it('should handle merge tags', function () {
const str = `gitGraph:
commit

View File

@@ -41,7 +41,7 @@ merge(?=\s|$) return 'MERGE';
cherry\-pick(?=\s|$) return 'CHERRY_PICK';
"parent:" return 'PARENT_COMMIT'
// "reset" return 'RESET';
\b(checkout|switch)(?=\s|$) return 'CHECKOUT';
checkout(?=\s|$) return 'CHECKOUT';
"LR" return 'DIR';
"TB" return 'DIR';
"BT" return 'DIR';

View File

@@ -11,7 +11,6 @@
%x point_start
%x point_x
%x point_y
%x class_name
%%
\%\%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */
@@ -36,7 +35,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
" "*"quadrant-2"" "* return 'QUADRANT_2';
" "*"quadrant-3"" "* return 'QUADRANT_3';
" "*"quadrant-4"" "* return 'QUADRANT_4';
"classDef" return 'CLASSDEF';
["][`] { this.begin("md_string");}
<md_string>[^`"]+ { return "MD_STR";}
@@ -45,9 +43,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
<string>["] this.popState();
<string>[^"]* return "STR";
\:\:\: {this.begin('class_name')}
<class_name>^\w+ {this.popState(); return 'class_name';}
\s*\:\s*\[\s* {this.begin("point_start"); return 'point_start';}
<point_start>(1)|(0(.\d+)?) {this.begin('point_x'); return 'point_x';}
<point_start>\s*\]" "* {this.popState();}
@@ -80,31 +75,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
%% /* language grammar */
idStringToken : ALPHA | NUM | NODE_STRING | DOWN | MINUS | DEFAULT | COMMA | COLON | AMP | BRKT | MULT | UNICODE_TEXT;
styleComponent: ALPHA | NUM | NODE_STRING | COLON | UNIT | SPACE | BRKT | STYLE | PCT | MINUS ;
idString
:idStringToken
{$$=$idStringToken}
| idString idStringToken
{$$=$idString+''+$idStringToken}
;
style: styleComponent
|style styleComponent
{$$ = $style + $styleComponent;}
;
stylesOpt: style
{$$ = [$style.trim()]}
| stylesOpt COMMA style
{$stylesOpt.push($style.trim());$$ = $stylesOpt;}
;
classDefStatement
: CLASSDEF SPACE idString SPACE stylesOpt {$$ = $CLASSDEF;yy.addClass($idString,$stylesOpt);}
;
start
: eol start
| SPACE start
@@ -122,7 +92,6 @@ line
statement
:
| classDefStatement {$$=[];}
| SPACE statement
| axisDetails
| quadrantDetails
@@ -134,10 +103,7 @@ statement
;
points
: text point_start point_x point_y {yy.addPoint($1, "", $3, $4, []);}
| text class_name point_start point_x point_y {yy.addPoint($1, $2, $4, $5, []);}
| text point_start point_x point_y stylesOpt {yy.addPoint($1, "", $3, $4, $stylesOpt);}
| text class_name point_start point_x point_y stylesOpt {yy.addPoint($1, $2, $4, $5, $stylesOpt);}
: text point_start point_x point_y {yy.addPoint($1, $3, $4);}
;
axisDetails

View File

@@ -212,34 +212,20 @@ describe('Testing quadrantChart jison file', () => {
it('should be able to parse points', () => {
let str = 'quadrantChart\npoint1: [0.1, 0.4]';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'point1', type: 'text' },
'',
'0.1',
'0.4',
[]
);
expect(mockDB.addPoint).toHaveBeenCalledWith({ text: 'point1', type: 'text' }, '0.1', '0.4');
clearMocks();
str = 'QuadRantChart \n Point1 : [0.1, 0.4] ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Point1', type: 'text' },
'',
'0.1',
'0.4',
[]
);
expect(mockDB.addPoint).toHaveBeenCalledWith({ text: 'Point1', type: 'text' }, '0.1', '0.4');
clearMocks();
str = 'QuadRantChart \n "Point1 : (* +=[❤": [1, 0] ';
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Point1 : (* +=[❤', type: 'text' },
'',
'1',
'0',
[]
'0'
);
clearMocks();
@@ -278,149 +264,15 @@ describe('Testing quadrantChart jison file', () => {
expect(mockDB.setQuadrant4Text).toHaveBeenCalledWith({ text: 'Visionaries', type: 'text' });
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Microsoft', type: 'text' },
'',
'0.75',
'0.75',
[]
'0.75'
);
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Salesforce', type: 'text' },
'',
'0.55',
'0.60',
[]
);
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'IBM', type: 'text' },
'',
'0.51',
'0.40',
[]
);
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Incorta', type: 'text' },
'',
'0.20',
'0.30',
[]
);
});
it('should be able to parse the whole chart with point styling with all params or some params', () => {
const str = `quadrantChart
title Analytics and Business Intelligence Platforms
x-axis "Completeness of Vision ❤" --> "x-axis-2"
y-axis Ability to Execute --> "y-axis-2"
quadrant-1 Leaders
quadrant-2 Challengers
quadrant-3 Niche
quadrant-4 Visionaries
Microsoft: [0.75, 0.75] radius: 10
Salesforce: [0.55, 0.60] radius: 10, color: #ff0000
IBM: [0.51, 0.40] radius: 10, color: #ff0000, stroke-color: #ff00ff
Incorta: [0.20, 0.30] radius: 10 ,color: #ff0000 ,stroke-color: #ff00ff ,stroke-width: 10px`;
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisLeftText).toHaveBeenCalledWith({
text: 'Completeness of Vision ❤',
type: 'text',
});
expect(mockDB.setXAxisRightText).toHaveBeenCalledWith({ text: 'x-axis-2', type: 'text' });
expect(mockDB.setYAxisTopText).toHaveBeenCalledWith({ text: 'y-axis-2', type: 'text' });
expect(mockDB.setYAxisBottomText).toHaveBeenCalledWith({
text: 'Ability to Execute',
type: 'text',
});
expect(mockDB.setQuadrant1Text).toHaveBeenCalledWith({ text: 'Leaders', type: 'text' });
expect(mockDB.setQuadrant2Text).toHaveBeenCalledWith({ text: 'Challengers', type: 'text' });
expect(mockDB.setQuadrant3Text).toHaveBeenCalledWith({ text: 'Niche', type: 'text' });
expect(mockDB.setQuadrant4Text).toHaveBeenCalledWith({ text: 'Visionaries', type: 'text' });
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Microsoft', type: 'text' },
'',
'0.75',
'0.75',
['radius: 10']
);
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Salesforce', type: 'text' },
'',
'0.55',
'0.60',
['radius: 10', 'color: #ff0000']
);
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'IBM', type: 'text' },
'',
'0.51',
'0.40',
['radius: 10', 'color: #ff0000', 'stroke-color: #ff00ff']
);
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Incorta', type: 'text' },
'',
'0.20',
'0.30',
['radius: 10', 'color: #ff0000', 'stroke-color: #ff00ff', 'stroke-width: 10px']
);
});
it('should be able to parse the whole chart with point styling with params in a random order + class names', () => {
const str = `quadrantChart
title Analytics and Business Intelligence Platforms
x-axis "Completeness of Vision ❤" --> "x-axis-2"
y-axis Ability to Execute --> "y-axis-2"
quadrant-1 Leaders
quadrant-2 Challengers
quadrant-3 Niche
quadrant-4 Visionaries
Microsoft: [0.75, 0.75] stroke-color: #ff00ff ,stroke-width: 10px, color: #ff0000, radius: 10
Salesforce:::class1: [0.55, 0.60] radius: 10, color: #ff0000
IBM: [0.51, 0.40] stroke-color: #ff00ff ,stroke-width: 10px
Incorta: [0.20, 0.30] stroke-width: 10px`;
expect(parserFnConstructor(str)).not.toThrow();
expect(mockDB.setXAxisLeftText).toHaveBeenCalledWith({
text: 'Completeness of Vision ❤',
type: 'text',
});
expect(mockDB.setXAxisRightText).toHaveBeenCalledWith({ text: 'x-axis-2', type: 'text' });
expect(mockDB.setYAxisTopText).toHaveBeenCalledWith({ text: 'y-axis-2', type: 'text' });
expect(mockDB.setYAxisBottomText).toHaveBeenCalledWith({
text: 'Ability to Execute',
type: 'text',
});
expect(mockDB.setQuadrant1Text).toHaveBeenCalledWith({ text: 'Leaders', type: 'text' });
expect(mockDB.setQuadrant2Text).toHaveBeenCalledWith({ text: 'Challengers', type: 'text' });
expect(mockDB.setQuadrant3Text).toHaveBeenCalledWith({ text: 'Niche', type: 'text' });
expect(mockDB.setQuadrant4Text).toHaveBeenCalledWith({ text: 'Visionaries', type: 'text' });
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Microsoft', type: 'text' },
'',
'0.75',
'0.75',
['stroke-color: #ff00ff', 'stroke-width: 10px', 'color: #ff0000', 'radius: 10']
);
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Salesforce', type: 'text' },
'class1',
'0.55',
'0.60',
['radius: 10', 'color: #ff0000']
);
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'IBM', type: 'text' },
'',
'0.51',
'0.40',
['stroke-color: #ff00ff', 'stroke-width: 10px']
);
expect(mockDB.addPoint).toHaveBeenCalledWith(
{ text: 'Incorta', type: 'text' },
'',
'0.20',
'0.30',
['stroke-width: 10px']
'0.60'
);
expect(mockDB.addPoint).toHaveBeenCalledWith({ text: 'IBM', type: 'text' }, '0.51', '0.40');
expect(mockDB.addPoint).toHaveBeenCalledWith({ text: 'Incorta', type: 'text' }, '0.20', '0.30');
});
});

View File

@@ -1,7 +1,7 @@
import { scaleLinear } from 'd3';
import { log } from '../../logger.js';
import type { BaseDiagramConfig, QuadrantChartConfig } from '../../config.type.js';
import defaultConfig from '../../defaultConfig.js';
import { log } from '../../logger.js';
import { getThemeVariables } from '../../themes/theme-default.js';
import type { Point } from '../../types.js';
@@ -10,15 +10,7 @@ const defaultThemeVariables = getThemeVariables();
export type TextVerticalPos = 'left' | 'center' | 'right';
export type TextHorizontalPos = 'top' | 'middle' | 'bottom';
export interface StylesObject {
className?: string;
radius?: number;
color?: string;
strokeColor?: string;
strokeWidth?: string;
}
export interface QuadrantPointInputType extends Point, StylesObject {
export interface QuadrantPointInputType extends Point {
text: string;
}
@@ -31,9 +23,7 @@ export interface QuadrantTextType extends Point {
rotation: number;
}
export interface QuadrantPointType
extends Point,
Pick<StylesObject, 'strokeColor' | 'strokeWidth'> {
export interface QuadrantPointType extends Point {
fill: string;
radius: number;
text: QuadrantTextType;
@@ -127,7 +117,6 @@ export class QuadrantBuilder {
private config: QuadrantBuilderConfig;
private themeConfig: QuadrantBuilderThemeConfig;
private data: QuadrantBuilderData;
private classes: Record<string, StylesObject> = {};
constructor() {
this.config = this.getDefaultConfig();
@@ -202,7 +191,6 @@ export class QuadrantBuilder {
this.config = this.getDefaultConfig();
this.themeConfig = this.getDefaultThemeConfig();
this.data = this.getDefaultData();
this.classes = {};
log.info('clear called');
}
@@ -214,10 +202,6 @@ export class QuadrantBuilder {
this.data.points = [...points, ...this.data.points];
}
addClass(className: string, styles: StylesObject) {
this.classes[className] = styles;
}
setConfig(config: Partial<QuadrantBuilderConfig>) {
log.trace('setConfig called with: ', config);
this.config = { ...this.config, ...config };
@@ -486,15 +470,11 @@ export class QuadrantBuilder {
.range([quadrantHeight + quadrantTop, quadrantTop]);
const points: QuadrantPointType[] = this.data.points.map((point) => {
const classStyles = this.classes[point.className as keyof typeof this.classes];
if (classStyles) {
point = { ...classStyles, ...point };
}
const props: QuadrantPointType = {
x: xAxis(point.x),
y: yAxis(point.y),
fill: point.color || this.themeConfig.quadrantPointFill,
radius: point.radius || this.config.pointRadius,
fill: this.themeConfig.quadrantPointFill,
radius: this.config.pointRadius,
text: {
text: point.text,
fill: this.themeConfig.quadrantPointTextFill,
@@ -505,8 +485,6 @@ export class QuadrantBuilder {
fontSize: this.config.pointLabelFontSize,
rotation: 0,
},
strokeColor: point.strokeColor || this.themeConfig.quadrantPointFill,
strokeWidth: point.strokeWidth || '0px',
};
return props;
});

View File

@@ -1,50 +0,0 @@
import quadrantDb from './quadrantDb.js';
describe('quadrant unit tests', () => {
it('should parse the styles array and return a StylesObject', () => {
const styles = ['radius: 10', 'color: #ff0000', 'stroke-color: #ff00ff', 'stroke-width: 10px'];
const result = quadrantDb.parseStyles(styles);
expect(result).toEqual({
radius: 10,
color: '#ff0000',
strokeColor: '#ff00ff',
strokeWidth: '10px',
});
});
it('should throw an error for non supported style name', () => {
const styles: string[] = ['test_name: value'];
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
'style named test_name is not supported.'
);
});
it('should return an empty StylesObject for an empty input array', () => {
const styles: string[] = [];
const result = quadrantDb.parseStyles(styles);
expect(result).toEqual({});
});
it('should throw an error for non supported style value', () => {
let styles: string[] = ['radius: f'];
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
'value for radius f is invalid, please use a valid number'
);
styles = ['color: ffaa'];
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
'value for color ffaa is invalid, please use a valid hex code'
);
styles = ['stroke-color: #f677779'];
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
'value for stroke-color #f677779 is invalid, please use a valid hex code'
);
styles = ['stroke-width: 30'];
expect(() => quadrantDb.parseStyles(styles)).toThrowError(
'value for stroke-width 30 is invalid, please use a valid number of pixels (eg. 10px)'
);
});
});

View File

@@ -9,14 +9,7 @@ import {
setAccDescription,
clear as commonClear,
} from '../common/commonDb.js';
import type { StylesObject } from './quadrantBuilder.js';
import { QuadrantBuilder } from './quadrantBuilder.js';
import {
validateHexCode,
validateSizeInPixels,
validateNumber,
InvalidStyleError,
} from './utils.js';
const config = getConfig();
@@ -24,10 +17,7 @@ function textSanitizer(text: string) {
return sanitizeText(text.trim(), config);
}
interface LexTextObj {
text: string;
type: 'text' | 'markdown';
}
type LexTextObj = { text: string; type: 'text' | 'markdown' };
const quadrantBuilder = new QuadrantBuilder();
@@ -63,52 +53,8 @@ function setYAxisBottomText(textObj: LexTextObj) {
quadrantBuilder.setData({ yAxisBottomText: textSanitizer(textObj.text) });
}
function parseStyles(styles: string[]): StylesObject {
const stylesObject: StylesObject = {};
for (const style of styles) {
const [key, value] = style.trim().split(/\s*:\s*/);
if (key === 'radius') {
if (validateNumber(value)) {
throw new InvalidStyleError(key, value, 'number');
}
stylesObject.radius = parseInt(value);
} else if (key === 'color') {
if (validateHexCode(value)) {
throw new InvalidStyleError(key, value, 'hex code');
}
stylesObject.color = value;
} else if (key === 'stroke-color') {
if (validateHexCode(value)) {
throw new InvalidStyleError(key, value, 'hex code');
}
stylesObject.strokeColor = value;
} else if (key === 'stroke-width') {
if (validateSizeInPixels(value)) {
throw new InvalidStyleError(key, value, 'number of pixels (eg. 10px)');
}
stylesObject.strokeWidth = value;
} else {
throw new Error(`style named ${key} is not supported.`);
}
}
return stylesObject;
}
function addPoint(textObj: LexTextObj, className: string, x: number, y: number, styles: string[]) {
const stylesObject = parseStyles(styles);
quadrantBuilder.addPoints([
{
x,
y,
text: textSanitizer(textObj.text),
className,
...stylesObject,
},
]);
}
function addClass(className: string, styles: string[]) {
quadrantBuilder.addClass(className, parseStyles(styles));
function addPoint(textObj: LexTextObj, x: number, y: number) {
quadrantBuilder.addPoints([{ x, y, text: textSanitizer(textObj.text) }]);
}
function setWidth(width: number) {
@@ -162,9 +108,7 @@ export default {
setXAxisRightText,
setYAxisTopText,
setYAxisBottomText,
parseStyles,
addPoint,
addClass,
getQuadrantData,
clear,
setAccTitle,

View File

@@ -152,9 +152,7 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram
.attr('cx', (data: QuadrantPointType) => data.x)
.attr('cy', (data: QuadrantPointType) => data.y)
.attr('r', (data: QuadrantPointType) => data.radius)
.attr('fill', (data: QuadrantPointType) => data.fill)
.attr('stroke', (data: QuadrantPointType) => data.strokeColor)
.attr('stroke-width', (data: QuadrantPointType) => data.strokeWidth);
.attr('fill', (data: QuadrantPointType) => data.fill);
dataPoints
.append('text')

View File

@@ -1,20 +0,0 @@
class InvalidStyleError extends Error {
constructor(style: string, value: string, type: string) {
super(`value for ${style} ${value} is invalid, please use a valid ${type}`);
this.name = 'InvalidStyleError';
}
}
function validateHexCode(value: string): boolean {
return !/^#?([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/.test(value);
}
function validateNumber(value: string): boolean {
return !/^\d+$/.test(value);
}
function validateSizeInPixels(value: string): boolean {
return !/^\d+px$/.test(value);
}
export { validateHexCode, validateNumber, validateSizeInPixels, InvalidStyleError };

View File

@@ -3,7 +3,7 @@
* (c) 2014-2015 Knut Sveidqvist
* MIT license.
*
* Based on js sequence diagrams jison grammar
* Based on js sequence diagrams jison grammr
* https://bramp.github.io/js-sequence-diagrams/
* (c) 2012-2013 Andrew Brampton (bramp.net)
* Simplified BSD license.
@@ -138,8 +138,8 @@ statement
| autonumber NUM 'NEWLINE' { $$ = {type:'sequenceIndex',sequenceIndex: Number($2), sequenceIndexStep:1, sequenceVisible:true, signalType:yy.LINETYPE.AUTONUMBER};}
| autonumber off 'NEWLINE' { $$ = {type:'sequenceIndex', sequenceVisible:false, signalType:yy.LINETYPE.AUTONUMBER};}
| autonumber 'NEWLINE' {$$ = {type:'sequenceIndex', sequenceVisible:true, signalType:yy.LINETYPE.AUTONUMBER}; }
| 'activate' actor 'NEWLINE' {$$={type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $2.actor};}
| 'deactivate' actor 'NEWLINE' {$$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $2.actor};}
| 'activate' actor 'NEWLINE' {$$={type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $2};}
| 'deactivate' actor 'NEWLINE' {$$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $2};}
| note_statement 'NEWLINE'
| links_statement 'NEWLINE'
| link_statement 'NEWLINE'
@@ -288,11 +288,11 @@ placement
signal
: actor signaltype '+' actor text2
{ $$ = [$1,$4,{type: 'addMessage', from:$1.actor, to:$4.actor, signalType:$2, msg:$5, activate: true},
{type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $4.actor}
{type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $4}
]}
| actor signaltype '-' actor text2
{ $$ = [$1,$4,{type: 'addMessage', from:$1.actor, to:$4.actor, signalType:$2, msg:$5},
{type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $1.actor}
{type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $1}
]}
| actor signaltype actor text2
{ $$ = [$1,$3,{type: 'addMessage', from:$1.actor, to:$3.actor, signalType:$2, msg:$4}]}

View File

@@ -1,6 +1,5 @@
import { getConfig } from '../../diagram-api/diagramAPI.js';
import { log } from '../../logger.js';
import { ImperativeState } from '../../utils/imperativeState.js';
import { sanitizeText } from '../common/common.js';
import {
clear as commonClear,
@@ -11,24 +10,9 @@ import {
setAccTitle,
setDiagramTitle,
} from '../common/commonDb.js';
import type { Actor, AddMessageParams, Box, Message, Note } from './types.js';
import { ImperativeState } from '../../utils/imperativeState.js';
interface SequenceState {
prevActor?: string;
actors: Record<string, Actor>;
createdActors: Record<string, number>;
destroyedActors: Record<string, number>;
boxes: Box[];
messages: Message[];
notes: Note[];
sequenceNumbersEnabled: boolean;
wrapEnabled?: boolean;
currentBox?: Box;
lastCreated?: Actor;
lastDestroyed?: Actor;
}
const state = new ImperativeState<SequenceState>(() => ({
const state = new ImperativeState(() => ({
prevActor: undefined,
actors: {},
createdActors: {},
@@ -43,7 +27,7 @@ const state = new ImperativeState<SequenceState>(() => ({
lastDestroyed: undefined,
}));
export const addBox = function (data: { text: string; color: string; wrap: boolean }) {
export const addBox = function (data) {
state.records.boxes.push({
name: data.text,
wrap: (data.wrap === undefined && autoWrap()) || !!data.wrap,
@@ -53,19 +37,20 @@ export const addBox = function (data: { text: string; color: string; wrap: boole
state.records.currentBox = state.records.boxes.slice(-1)[0];
};
export const addActor = function (
id: string,
name: string,
description: { text: string; wrap?: boolean | null; type: string },
type: string
) {
export const addActor = function (id, name, description, type) {
let assignedBox = state.records.currentBox;
const old = state.records.actors[id];
if (old) {
// If already set and trying to set to a new one throw error
if (state.records.currentBox && old.box && state.records.currentBox !== old.box) {
throw new Error(
`A same participant should only be defined in one Box: ${old.name} can't be in '${old.box.name}' and in '${state.records.currentBox.name}' at the same time.`
'A same participant should only be defined in one Box: ' +
old.name +
" can't be in '" +
old.box.name +
"' and in '" +
state.records.currentBox.name +
"' at the same time."
);
}
@@ -97,7 +82,7 @@ export const addActor = function (
properties: {},
actorCnt: null,
rectData: null,
type: type ?? 'participant',
type: type || 'participant',
};
if (state.records.prevActor && state.records.actors[state.records.prevActor]) {
state.records.actors[state.records.prevActor].nextActor = id;
@@ -109,22 +94,19 @@ export const addActor = function (
state.records.prevActor = id;
};
const activationCount = (part: string) => {
const activationCount = (part) => {
let i;
let count = 0;
if (!part) {
return 0;
}
for (i = 0; i < state.records.messages.length; i++) {
if (
state.records.messages[i].type === LINETYPE.ACTIVE_START &&
state.records.messages[i].from === part
state.records.messages[i].from.actor === part
) {
count++;
}
if (
state.records.messages[i].type === LINETYPE.ACTIVE_END &&
state.records.messages[i].from === part
state.records.messages[i].from.actor === part
) {
count--;
}
@@ -132,12 +114,7 @@ const activationCount = (part: string) => {
return count;
};
export const addMessage = function (
idFrom: Message['from'],
idTo: Message['to'],
message: { text: string; wrap?: boolean },
answer: Message['answer']
) {
export const addMessage = function (idFrom, idTo, message, answer) {
state.records.messages.push({
from: idFrom,
to: idTo,
@@ -148,19 +125,17 @@ export const addMessage = function (
};
export const addSignal = function (
idFrom?: Message['from'],
idTo?: Message['to'],
message?: { text: string; wrap: boolean },
messageType?: number,
activate: boolean = false
idFrom,
idTo,
message = { text: undefined, wrap: undefined },
messageType,
activate = false
) {
if (messageType === LINETYPE.ACTIVE_END) {
const cnt = activationCount(idFrom || '');
const cnt = activationCount(idFrom.actor);
if (cnt < 1) {
// Bail out as there is an activation signal from an inactive participant
const error = new Error('Trying to inactivate an inactive participant (' + idFrom + ')');
// @ts-ignore: we are passing hash param to the error object, however we should define our own custom error class to make it type safe
let error = new Error('Trying to inactivate an inactive participant (' + idFrom.actor + ')');
error.hash = {
text: '->>-',
token: '->>-',
@@ -174,8 +149,8 @@ export const addSignal = function (
state.records.messages.push({
from: idFrom,
to: idTo,
message: message?.text ?? '',
wrap: (message?.wrap === undefined && autoWrap()) || !!message?.wrap,
message: message.text,
wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap,
type: messageType,
activate,
});
@@ -206,7 +181,7 @@ export const getCreatedActors = function () {
export const getDestroyedActors = function () {
return state.records.destroyedActors;
};
export const getActor = function (id: string) {
export const getActor = function (id) {
return state.records.actors[id];
};
export const getActorKeys = function () {
@@ -220,7 +195,7 @@ export const disableSequenceNumbers = function () {
};
export const showSequenceNumbers = () => state.records.sequenceNumbersEnabled;
export const setWrap = function (wrapSetting?: boolean) {
export const setWrap = function (wrapSetting) {
state.records.wrapEnabled = wrapSetting;
};
@@ -230,7 +205,7 @@ export const autoWrap = () => {
if (state.records.wrapEnabled !== undefined) {
return state.records.wrapEnabled;
}
return getConfig()?.sequence?.wrap;
return getConfig().sequence.wrap;
};
export const clear = function () {
@@ -238,25 +213,25 @@ export const clear = function () {
commonClear();
};
export const parseMessage = function (str: string) {
const trimmedStr = str.trim();
export const parseMessage = function (str) {
const _str = str.trim();
const message = {
text: trimmedStr.replace(/^:?(?:no)?wrap:/, '').trim(),
text: _str.replace(/^:?(?:no)?wrap:/, '').trim(),
wrap:
trimmedStr.match(/^:?wrap:/) !== null
_str.match(/^:?wrap:/) !== null
? true
: trimmedStr.match(/^:?nowrap:/) !== null
: _str.match(/^:?nowrap:/) !== null
? false
: undefined,
};
log.debug(`parseMessage: ${message}`);
log.debug('parseMessage:', message);
return message;
};
// We expect the box statement to be color first then description
// The color can be rgb,rgba,hsl,hsla, or css code names #hex codes are not supported for now because of the way the char # is handled
// We extract first segment as color, the rest of the line is considered as text
export const parseBoxData = function (str: string) {
export const parseBoxData = function (str) {
const match = str.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/);
let color = match != null && match[1] ? match[1].trim() : 'transparent';
let title = match != null && match[2] ? match[2].trim() : undefined;
@@ -337,21 +312,18 @@ export const PLACEMENT = {
OVER: 2,
};
export const addNote = function (
actor: { actor: string },
placement: Message['placement'],
message: { text: string; wrap?: boolean }
) {
const note: Note = {
export const addNote = function (actor, placement, message) {
const note = {
actor: actor,
placement: placement,
message: message.text,
wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap,
};
//@ts-ignore: Coerce actor into a [to, from, ...] array
// Coerce actor into a [to, from, ...] array
// eslint-disable-next-line unicorn/prefer-spread
const actors = [].concat(actor, actor);
state.records.notes.push(note);
state.records.messages.push({
from: actors[0],
@@ -363,7 +335,7 @@ export const addNote = function (
});
};
export const addLinks = function (actorId: string, text: { text: string }) {
export const addLinks = function (actorId, text) {
// find the actor
const actor = getActor(actorId);
// JSON.parse the text
@@ -379,17 +351,17 @@ export const addLinks = function (actorId: string, text: { text: string }) {
}
};
export const addALink = function (actorId: string, text: { text: string }) {
export const addALink = function (actorId, text) {
// find the actor
const actor = getActor(actorId);
try {
const links: Record<string, string> = {};
const links = {};
let sanitizedText = sanitizeText(text.text, getConfig());
const sep = sanitizedText.indexOf('@');
var sep = sanitizedText.indexOf('@');
sanitizedText = sanitizedText.replace(/&amp;/g, '&');
sanitizedText = sanitizedText.replace(/&equals;/g, '=');
const label = sanitizedText.slice(0, sep - 1).trim();
const link = sanitizedText.slice(sep + 1).trim();
var label = sanitizedText.slice(0, sep - 1).trim();
var link = sanitizedText.slice(sep + 1).trim();
links[label] = link;
// add the deserialized text to the actor's links field.
@@ -400,26 +372,26 @@ export const addALink = function (actorId: string, text: { text: string }) {
};
/**
* @param actor - the actor to add the links to
* @param links - the links to add to the actor
* @param {any} actor
* @param {any} links
*/
function insertLinks(actor: Actor, links: Record<string, string>) {
function insertLinks(actor, links) {
if (actor.links == null) {
actor.links = links;
} else {
for (const key in links) {
for (let key in links) {
actor.links[key] = links[key];
}
}
}
export const addProperties = function (actorId: string, text: { text: string }) {
export const addProperties = function (actorId, text) {
// find the actor
const actor = getActor(actorId);
// JSON.parse the text
try {
const sanitizedText = sanitizeText(text.text, getConfig());
const properties: Record<string, unknown> = JSON.parse(sanitizedText);
let sanitizedText = sanitizeText(text.text, getConfig());
const properties = JSON.parse(sanitizedText);
// add the deserialized text to the actor's property field.
insertProperties(actor, properties);
} catch (e) {
@@ -428,27 +400,30 @@ export const addProperties = function (actorId: string, text: { text: string })
};
/**
* @param actor - the actor to add the properties to
* @param properties - the properties to add to the actor's properties
* @param {any} actor
* @param {any} properties
*/
function insertProperties(actor: Actor, properties: Record<string, unknown>) {
function insertProperties(actor, properties) {
if (actor.properties == null) {
actor.properties = properties;
} else {
for (const key in properties) {
for (let key in properties) {
actor.properties[key] = properties[key];
}
}
}
/**
*
*/
function boxEnd() {
state.records.currentBox = undefined;
}
export const addDetails = function (actorId: string, text: { text: string }) {
export const addDetails = function (actorId, text) {
// find the actor
const actor = getActor(actorId);
const elem = document.getElementById(text.text)!;
const elem = document.getElementById(text.text);
// JSON.parse the text
try {
@@ -467,7 +442,7 @@ export const addDetails = function (actorId: string, text: { text: string }) {
}
};
export const getActorProperty = function (actor: Actor, key: string) {
export const getActorProperty = function (actor, key) {
if (actor !== undefined && actor.properties !== undefined) {
return actor.properties[key];
}
@@ -475,7 +450,20 @@ export const getActorProperty = function (actor: Actor, key: string) {
return undefined;
};
export const apply = function (param: any | AddMessageParams | AddMessageParams[]) {
/**
* @typedef {object} AddMessageParams A message from one actor to another.
* @property {string} from - The id of the actor sending the message.
* @property {string} to - The id of the actor receiving the message.
* @property {string} msg - The message text.
* @property {number} signalType - The type of signal.
* @property {"addMessage"} type - Set to `"addMessage"` if this is an `AddMessageParams`.
* @property {boolean} [activate] - If `true`, this signal starts an activation.
*/
/**
* @param {object | object[] | AddMessageParams} param - Object of parameters.
*/
export const apply = function (param) {
if (Array.isArray(param)) {
param.forEach(function (item) {
apply(item);

View File

@@ -534,10 +534,10 @@ deactivate Bob`;
expect(messages.length).toBe(4);
expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START);
expect(messages[1].from).toBe('Bob');
expect(messages[1].from.actor).toBe('Bob');
expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[3].type).toBe(diagram.db.LINETYPE.ACTIVE_END);
expect(messages[3].from).toBe('Bob');
expect(messages[3].from.actor).toBe('Bob');
});
it('should handle actor one line notation activation', async () => {
const str = `
@@ -556,10 +556,10 @@ deactivate Bob`;
expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[0].activate).toBeTruthy();
expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START);
expect(messages[1].from).toBe('Bob');
expect(messages[1].from.actor).toBe('Bob');
expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[3].type).toBe(diagram.db.LINETYPE.ACTIVE_END);
expect(messages[3].from).toBe('Bob');
expect(messages[3].from.actor).toBe('Bob');
});
it('should handle stacked activations', async () => {
const str = `
@@ -579,14 +579,14 @@ deactivate Bob`;
expect(messages.length).toBe(8);
expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START);
expect(messages[1].from).toBe('Bob');
expect(messages[1].from.actor).toBe('Bob');
expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED);
expect(messages[3].type).toBe(diagram.db.LINETYPE.ACTIVE_START);
expect(messages[3].from).toBe('Carol');
expect(messages[3].from.actor).toBe('Carol');
expect(messages[5].type).toBe(diagram.db.LINETYPE.ACTIVE_END);
expect(messages[5].from).toBe('Bob');
expect(messages[5].from.actor).toBe('Bob');
expect(messages[7].type).toBe(diagram.db.LINETYPE.ACTIVE_END);
expect(messages[7].from).toBe('Carol');
expect(messages[7].from.actor).toBe('Carol');
});
it('should handle fail parsing when activating an inactive participant', async () => {
const str = `

View File

@@ -144,15 +144,15 @@ export const bounds = {
this.updateBounds(_startx, _starty, _stopx, _stopy);
},
newActivation: function (message, diagram, actors) {
const actorRect = actors[message.from];
const stackedSize = actorActivations(message.from).length || 0;
const actorRect = actors[message.from.actor];
const stackedSize = actorActivations(message.from.actor).length || 0;
const x = actorRect.x + actorRect.width / 2 + ((stackedSize - 1) * conf.activationWidth) / 2;
this.activations.push({
startx: x,
starty: this.verticalPos + 2,
stopx: x + conf.activationWidth,
stopy: undefined,
actor: message.from,
actor: message.from.actor,
anchored: svgDraw.anchorElement(diagram),
});
},
@@ -162,7 +162,7 @@ export const bounds = {
.map(function (activation) {
return activation.actor;
})
.lastIndexOf(message.from);
.lastIndexOf(message.from.actor);
return this.activations.splice(lastActorActivationIdx, 1)[0];
},
createLoop: function (title = { message: undefined, wrap: false, width: undefined }, fill) {
@@ -836,7 +836,7 @@ export const draw = async function (_text: string, id: string, _version: string,
activationData,
verticalPos,
conf,
actorActivations(msg.from).length
actorActivations(msg.from.actor).length
);
bounds.insert(activationData.startx, verticalPos - 10, activationData.stopx, verticalPos);
@@ -1545,14 +1545,14 @@ const calculateLoopBounds = async function (messages, actors, _maxWidthPerActor,
break;
case diagObj.db.LINETYPE.ACTIVE_START:
{
const actorRect = actors[msg.from ? msg.from : msg.to.actor];
const stackedSize = actorActivations(msg.from ? msg.from : msg.to.actor).length;
const actorRect = actors[msg.from ? msg.from.actor : msg.to.actor];
const stackedSize = actorActivations(msg.from ? msg.from.actor : msg.to.actor).length;
const x =
actorRect.x + actorRect.width / 2 + ((stackedSize - 1) * conf.activationWidth) / 2;
const toAdd = {
startx: x,
stopx: x + conf.activationWidth,
actor: msg.from,
actor: msg.from.actor,
enabled: true,
};
bounds.activations.push(toAdd);
@@ -1562,7 +1562,7 @@ const calculateLoopBounds = async function (messages, actors, _maxWidthPerActor,
{
const lastActorActivationIdx = bounds.activations
.map((a) => a.actor)
.lastIndexOf(msg.from);
.lastIndexOf(msg.from.actor);
delete bounds.activations.splice(lastActorActivationIdx, 1)[0];
}
break;

View File

@@ -1,5 +1,6 @@
import common, { calculateMathMLDimensions, hasKatex, renderKatex } from '../common/common.js';
import * as svgDrawCommon from '../common/svgDrawCommon.js';
import { addFunction } from '../../interactionDb.js';
import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js';
import { sanitizeUrl } from '@braintree/sanitize-url';
import * as configApi from '../../config.js';

View File

@@ -1,92 +0,0 @@
export interface Box {
name: string;
wrap: boolean;
fill: string;
actorKeys: string[];
}
export interface Actor {
box?: Box;
name: string;
description: string;
wrap: boolean;
prevActor?: string;
nextActor?: string;
links: Record<string, unknown>;
properties: Record<string, unknown>;
actorCnt: number | null;
rectData: unknown;
type: string;
}
export interface Message {
from?: string;
to?: string;
message:
| string
| {
start: number;
step: number;
visible: boolean;
};
wrap: boolean;
answer?: unknown;
type?: number;
activate?: boolean;
placement?: string;
}
export interface AddMessageParams {
from: string;
to: string;
msg: string;
signalType: number;
type:
| 'addMessage'
| 'sequenceIndex'
| 'addParticipant'
| 'createParticipant'
| 'destroyParticipant'
| 'activeStart'
| 'activeEnd'
| 'addNote'
| 'addLinks'
| 'addALink'
| 'addProperties'
| 'addDetails'
| 'boxStart'
| 'boxEnd'
| 'loopStart'
| 'loopEnd'
| 'rectStart'
| 'rectEnd'
| 'optStart'
| 'optEnd'
| 'altStart'
| 'else'
| 'altEnd'
| 'setAccTitle'
| 'parStart'
| 'parAnd'
| 'parEnd'
| 'and'
| 'criticalStart'
| 'criticalOption'
| 'option'
| 'criticalEnd'
| 'breakStart'
| 'breakEnd'
| 'parOverStart'
| 'parOverEnd'
| 'parOverAnd'
| 'parOverEnd';
activate: boolean;
}
export interface Note {
actor: { actor: string };
placement: Message['placement'];
message: string;
wrap: boolean;
}

View File

@@ -145,7 +145,7 @@ const getRootDocV2 = () => {
* Ex: the section within a fork has its own statements, and incoming and outgoing statements
* refer to the fork as a whole (document).
* See the parser grammar: the definition of a document is a document then a 'line', where a line can be a statement.
* This will push the statement into the list of statements for the current document.
* This will push the statement into the the list of statements for the current document.
*
* @param _doc
*/

View File

@@ -5,7 +5,7 @@ import { render } from '../../dagre-wrapper/index.js';
import { log } from '../../logger.js';
import { configureSvgSize } from '../../setupGraphViewbox.js';
import common from '../common/common.js';
import utils, { getEdgeId } from '../../utils.js';
import utils from '../../utils.js';
import {
DEFAULT_DIAGRAM_DIRECTION,
@@ -252,6 +252,7 @@ const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) =>
type: 'group',
padding: 0, //getConfig().flowchart.padding
};
graphItemCount++;
const parentNodeId = itemId + PARENT_ID;
g.setNode(parentNodeId, groupData);
@@ -269,23 +270,17 @@ const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) =>
from = noteData.id;
to = itemId;
}
g.setEdge(from, to, {
arrowhead: 'none',
arrowType: '',
style: G_EDGE_STYLE,
labelStyle: '',
id: getEdgeId(from, to, {
counter: graphItemCount,
}),
classes: CSS_EDGE_NOTE_EDGE,
arrowheadStyle: G_EDGE_ARROWHEADSTYLE,
labelpos: G_EDGE_LABELPOS,
labelType: G_EDGE_LABELTYPE,
thickness: G_EDGE_THICKNESS,
});
graphItemCount++;
} else {
g.setNode(itemId, nodeData);
}
@@ -329,9 +324,7 @@ const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) =
setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag);
setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag);
const edgeData = {
id: getEdgeId(item.state1.id, item.state2.id, {
counter: graphItemCount,
}),
id: 'edge' + graphItemCount,
arrowhead: 'normal',
arrowTypeEnd: 'arrow_barb',
style: G_EDGE_STYLE,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Some files were not shown because too many files have changed in this diff Show More