Making timeline diagram lazy-loaded internal, removing separate package

This commit is contained in:
ashishj
2023-01-26 10:29:35 +01:00
25 changed files with 114 additions and 156 deletions

View File

@@ -41,11 +41,11 @@ const packageOptions = {
packageName: 'mermaid-mindmap', packageName: 'mermaid-mindmap',
file: 'detector.ts', file: 'detector.ts',
}, },
'mermaid-timeline': { // 'mermaid-timeline': {
name: 'mermaid-timeline', // name: 'mermaid-timeline',
packageName: 'mermaid-timeline', // packageName: 'mermaid-timeline',
file: 'detector.ts', // file: 'detector.ts',
}, // },
// 'mermaid-timeline-detector': { // 'mermaid-timeline-detector': {
// name: 'mermaid-timeline-detector', // name: 'mermaid-timeline-detector',
// packageName: 'mermaid-timeline', // packageName: 'mermaid-timeline',
@@ -138,7 +138,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
'packages/mermaid-mindmap/src/**', 'packages/mermaid-mindmap/src/**',
'packages/mermaid/src/**', 'packages/mermaid/src/**',
// 'packages/mermaid-example-diagram/src/**', // 'packages/mermaid-example-diagram/src/**',
'packages/mermaid-timeline/src/**', // 'packages/mermaid-timeline/src/**',
], ],
}; };
} }
@@ -166,7 +166,7 @@ if (watch) {
if (!mermaidOnly) { if (!mermaidOnly) {
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' })); build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-mindmap' }));
// build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' })); // build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-example-diagram' }));
build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-timeline' })); //build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-timeline' }));
//build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-timeline-detector' })); //build(getBuildConfig({ minify: false, watch, entryName: 'mermaid-timeline-detector' }));
} }
} else if (visualize) { } else if (visualize) {

View File

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

View File

@@ -74,18 +74,18 @@
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid">
timeline timeline
title MermaidChart 2023 Timeline title MermaidChart 2023 Timeline
section 2023 Q1 &lt;br&gt; Release Personal Tier section 2023 Q1 <br> Release Personal Tier
Buttet 1 : sub-point 1a : sub-point 1b Buttet 1 : sub-point 1a : sub-point 1b
: sub-point 1c : sub-point 1c
Bullet 2 : sub-point 2a : sub-point 2b Bullet 2 : sub-point 2a : sub-point 2b
section 2023 Q2 <br> Release XYZ Tier section 2023 Q2 <br> Release XYZ Tier
Buttet 3 : sub-point <br/> 3a : sub-point 3b Buttet 3 : sub-point <br> 3a : sub-point 3b
: sub-point 3c : sub-point 3c
Bullet 4 : sub-point 4a : sub-point 4b Bullet 4 : sub-point 4a : sub-point 4b
</pre> </pre>
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid">
timeline timeline
title England's History Timeline title England's History Timeline
section Stone Age section Stone Age
@@ -173,13 +173,11 @@ mindmap
gc7((grand<br/>grand<br/>child 8)) gc7((grand<br/>grand<br/>child 8))
</pre> </pre>
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid2">
gantt flowchart-elk TB
title Style today marker (vertical line should be 5px wide and half-transparent blue) a --> b
dateFormat YYYY-MM-DD a --> c
axisFormat %d b --> d
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5 c --> d
section Section1
Today: 1, -1h
</pre> </pre>
<!-- <div id="cy"></div> --> <!-- <div id="cy"></div> -->
@@ -189,9 +187,9 @@ mindmap
<script type="module"> <script type="module">
//import mindmap from '../../packages/mermaid-mindmap/src/detector'; //import mindmap from '../../packages/mermaid-mindmap/src/detector';
// import example from '../../packages/mermaid-example-diagram/src/detector'; // import example from '../../packages/mermaid-example-diagram/src/detector';
import timeline from '../../packages/mermaid-timeline/src/detector'; // import timeline from '../../packages/mermaid-timeline/src/detector';
import mermaid from '../../packages/mermaid/src/mermaid'; import mermaid from '../../packages/mermaid/src/mermaid';
await mermaid.registerExternalDiagrams([timeline]); // await mermaid.registerExternalDiagrams([]);
mermaid.parseError = function (err, hash) { mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err); // console.error('Mermaid error: ', err);
}; };
@@ -201,13 +199,14 @@ mindmap
logLevel: 0, logLevel: 0,
flowchart: { flowchart: {
useMaxWidth: false, useMaxWidth: false,
htmlLabels: false, htmlLabels: true,
}, },
gantt: { gantt: {
useMaxWidth: false, useMaxWidth: false,
}, },
timeline: { timeline: {
disableMulticolor: false, disableMulticolor: false,
htmlLabels: false,
}, },
useMaxWidth: true, useMaxWidth: true,
lazyLoadedDiagrams: [ lazyLoadedDiagrams: [

View File

@@ -54,7 +54,7 @@
</style> </style>
</head> </head>
<body> <body>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid2">
%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
graph TB graph TB
a --> b a --> b
@@ -62,14 +62,14 @@ graph TB
b --> d b --> d
c --> d c --> d
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid2">
flowchart-elk TB flowchart-elk TB
a --> b a --> b
a --> c a --> c
b --> d b --> d
c --> d c --> d
</pre> </pre>
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid2">
%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%% %%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
flowchart TB flowchart TB
%% I could not figure out how to use double quotes in labels in Mermaid %% I could not figure out how to use double quotes in labels in Mermaid
@@ -125,7 +125,7 @@ flowchart TB
</pre </pre
> >
<br /> <br />
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid2">
flowchart TB flowchart TB
%% I could not figure out how to use double quotes in labels in Mermaid %% I could not figure out how to use double quotes in labels in Mermaid
subgraph ibm[IBM Espresso CPU] subgraph ibm[IBM Espresso CPU]
@@ -227,14 +227,24 @@ sequenceDiagram
Customer->>+Merchant: Receives goods or services Customer->>+Merchant: Receives goods or services
</pre </pre
> >
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid">
gantt mindmap
title Style today marker (vertical line should be 5px wide and half-transparent blue) root((mindmap))
dateFormat YYYY-MM-DD Origins
axisFormat %d Long history
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5 ::icon(fa fa-book)
section Section1 Popularisation
Today: 1, -1h British popular psychology author Tony Buzan
Research
On effectiveness<br/>and features
On Automatic creation
Uses
Creative techniques
Strategic planning
Argument mapping
Tools
Pen and paper
Mermaid
</pre> </pre>
<!-- <div id="cy"></div> --> <!-- <div id="cy"></div> -->
@@ -252,7 +262,7 @@ sequenceDiagram
// console.error('Mermaid error: ', err); // console.error('Mermaid error: ', err);
}; };
mermaid.initialize({ mermaid.initialize({
// theme: 'forest', theme: 'dark',
startOnLoad: true, startOnLoad: true,
logLevel: 0, logLevel: 0,
flowchart: { flowchart: {

View File

@@ -457,16 +457,4 @@ Let's put them to use, and see how our sample diagram looks in different themes:
2010 : Pinterest 2010 : Pinterest
``` ```
## Integrating with your library/website.
Timeline uses the experimental lazy loading & async rendering features which could change in the future.
```html
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
import timeline from 'https://cdn.jsdelivr.net/npm/@mermaid-js/mermaid-timeline@9/dist/mermaid-timeline.esm.min.mjs';
await mermaid.registerExternalDiagrams([timeline]);
</script>
```
You can also refer the implementation in the live editor [here](https://github.com/mermaid-js/mermaid-live-editor/blob/fcf53c98c25604c90a218104268c339be53035a6/src/lib/util/mermaid.ts) to see how the async loading is done. You can also refer the implementation in the live editor [here](https://github.com/mermaid-js/mermaid-live-editor/blob/fcf53c98c25604c90a218104268c339be53035a6/src/lib/util/mermaid.ts) to see how the async loading is done.

View File

@@ -347,4 +347,40 @@ root
expect(child.children.length).toEqual(2); expect(child.children.length).toEqual(2);
expect(child.children[1].nodeId).toEqual('b'); expect(child.children[1].nodeId).toEqual('b');
}); });
it('MMP-23 Rows with only spaces should not interfere', function () {
let str = 'mindmap\nroot\n A\n \n\n B';
mindmap.parse(str);
const mm = mindmap.yy.getMindmap();
expect(mm.nodeId).toEqual('root');
expect(mm.children.length).toEqual(2);
const child = mm.children[0];
expect(child.nodeId).toEqual('A');
const child2 = mm.children[1];
expect(child2.nodeId).toEqual('B');
});
it('MMP-24 Handle rows above the mindmap declarations', function () {
let str = '\n \nmindmap\nroot\n A\n \n\n B';
mindmap.parse(str);
const mm = mindmap.yy.getMindmap();
expect(mm.nodeId).toEqual('root');
expect(mm.children.length).toEqual(2);
const child = mm.children[0];
expect(child.nodeId).toEqual('A');
const child2 = mm.children[1];
expect(child2.nodeId).toEqual('B');
});
it('MMP-25 Handle rows above the mindmap declarations, no space', function () {
let str = '\n\n\nmindmap\nroot\n A\n \n\n B';
mindmap.parse(str);
const mm = mindmap.yy.getMindmap();
expect(mm.nodeId).toEqual('root');
expect(mm.children.length).toEqual(2);
const child = mm.children[0];
expect(child.nodeId).toEqual('A');
const child2 = mm.children[1];
expect(child2.nodeId).toEqual('B');
});
}); });

View File

@@ -25,6 +25,7 @@
<CLASS>\n { this.popState();} <CLASS>\n { this.popState();}
// [\s]*"::icon(" { this.begin('ICON'); } // [\s]*"::icon(" { this.begin('ICON'); }
"::icon(" { yy.getLogger().trace('Begin icon');this.begin('ICON'); } "::icon(" { yy.getLogger().trace('Begin icon');this.begin('ICON'); }
[\s]+[\n] {yy.getLogger().trace('SPACELINE');return 'SPACELINE' /* skip all whitespace */ ;}
[\n]+ return 'NL'; [\n]+ return 'NL';
<ICON>[^\)]+ { return 'ICON'; } <ICON>[^\)]+ { return 'ICON'; }
<ICON>\) {yy.getLogger().trace('end icon');this.popState();} <ICON>\) {yy.getLogger().trace('end icon');this.popState();}
@@ -64,14 +65,25 @@
start start
// %{ : info document 'EOF' { return yy; } } // %{ : info document 'EOF' { return yy; } }
: MINDMAP document { return yy; } : mindMap
| MINDMAP NL document { return yy; } | spaceLines mindMap
| SPACELIST MINDMAP document { return yy; } ;
;
spaceLines
: SPACELINE
| spaceLines SPACELINE
| spaceLines NL
;
mindMap
: MINDMAP document { return yy; }
| MINDMAP NL document { return yy; }
;
stop stop
: NL {yy.getLogger().trace('Stop NL ');} : NL {yy.getLogger().trace('Stop NL ');}
| EOF {yy.getLogger().trace('Stop EOF ');} | EOF {yy.getLogger().trace('Stop EOF ');}
| SPACELINE
| stop NL {yy.getLogger().trace('Stop NL2 ');} | stop NL {yy.getLogger().trace('Stop NL2 ');}
| stop EOF {yy.getLogger().trace('Stop EOF2 ');} | stop EOF {yy.getLogger().trace('Stop EOF2 ');}
; ;
@@ -81,9 +93,10 @@ document
; ;
statement statement
: SPACELIST node { yy.getLogger().trace('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type); } : SPACELIST node { yy.getLogger().info('Node: ',$2.id);yy.addNode($1.length, $2.id, $2.descr, $2.type); }
| SPACELIST ICON { yy.getLogger().trace('Icon: ',$2);yy.decorateNode({icon: $2}); } | SPACELIST ICON { yy.getLogger().trace('Icon: ',$2);yy.decorateNode({icon: $2}); }
| SPACELIST CLASS { yy.decorateNode({class: $2}); } | SPACELIST CLASS { yy.decorateNode({class: $2}); }
| SPACELINE { yy.getLogger().trace('SPACELIST');}
| node { yy.getLogger().trace('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type); } | node { yy.getLogger().trace('Node: ',$1.id);yy.addNode(0, $1.id, $1.descr, $1.type); }
| ICON { yy.decorateNode({icon: $1}); } | ICON { yy.decorateNode({icon: $1}); }
| CLASS { yy.decorateNode({class: $1}); } | CLASS { yy.decorateNode({class: $1}); }

View File

@@ -203,14 +203,12 @@ const roundedRectBkg = function (elem, node) {
* @returns {number} The height nodes dom element * @returns {number} The height nodes dom element
*/ */
export const drawNode = function (elem, node, fullSection, conf) { export const drawNode = function (elem, node, fullSection, conf) {
const section = (fullSection % MAX_SECTIONS) - 1; const section = fullSection % (MAX_SECTIONS - 1);
const nodeElem = elem.append('g'); const nodeElem = elem.append('g');
node.section = section; node.section = section;
nodeElem.attr( nodeElem.attr(
'class', 'class',
(node.class ? node.class + ' ' : '') + (node.class ? node.class + ' ' : '') + 'mindmap-node ' + ('section-' + section)
'mindmap-node ' +
(section < 0 ? 'section-root' : 'section-' + section)
); );
const bkgElem = nodeElem.append('g'); const bkgElem = nodeElem.append('g');
@@ -305,7 +303,7 @@ export const drawNode = function (elem, node, fullSection, conf) {
}; };
export const drawEdge = function drawEdge(edgesElem, mindmap, parent, depth, fullSection) { export const drawEdge = function drawEdge(edgesElem, mindmap, parent, depth, fullSection) {
const section = (fullSection % MAX_SECTIONS) - 1; const section = fullSection % (MAX_SECTIONS - 1);
const sx = parent.x + parent.width / 2; const sx = parent.x + parent.width / 2;
const sy = parent.y + parent.height / 2; const sy = parent.y + parent.height / 2;
const ex = mindmap.x + mindmap.width / 2; const ex = mindmap.x + mindmap.width / 2;

View File

@@ -1,58 +0,0 @@
{
"name": "@mermaid-js/mermaid-timeline",
"version": "9.4.0",
"description": "Timeline diagram module for Mermaid.js.",
"module": "dist/mermaid-timeline.core.mjs",
"types": "dist/detector.d.ts",
"type": "module",
"exports": {
".": {
"import": "./dist/mermaid-timeline.core.mjs",
"types": "./dist/detector.d.ts"
},
"./*": "./*"
},
"keywords": [
"diagram",
"markdown",
"timeline",
"mermaid"
],
"scripts": {
"prepublishOnly": "pnpm -w run build"
},
"repository": {
"type": "git",
"url": "https://github.com/mermaid-js/mermaid"
},
"author": "Ashish Jain",
"license": "MIT",
"standard": {
"ignore": [
"**/parser/*.js",
"dist/**/*.js",
"cypress/**/*.js"
],
"globals": [
"page"
]
},
"dependencies": {
"d3": "^7.0.0",
"khroma": "^2.0.0"
},
"devDependencies": {
"concurrently": "^7.4.0",
"rimraf": "^3.0.2"
},
"resolutions": {
"d3": "^7.0.0"
},
"files": [
"dist"
],
"sideEffects": [
"**/*.css",
"**/*.scss"
]
}

View File

@@ -1,7 +0,0 @@
export {};
declare global {
interface Window {
mermaid: any; // 👈️ turn off type checking
}
}

View File

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

View File

@@ -1,5 +1,4 @@
import { registerDiagram } from './diagramAPI'; import { registerDiagram } from './diagramAPI';
// @ts-ignore: TODO Fix ts errors // @ts-ignore: TODO Fix ts errors
import gitGraphParser from '../diagrams/git/parser/gitGraph'; import gitGraphParser from '../diagrams/git/parser/gitGraph';
import { gitGraphDetector } from '../diagrams/git/gitGraphDetector'; import { gitGraphDetector } from '../diagrams/git/gitGraphDetector';
@@ -97,6 +96,7 @@ import errorStyles from '../diagrams/error/styles';
import flowchartElk from '../diagrams/flowchart/elk/detector'; import flowchartElk from '../diagrams/flowchart/elk/detector';
import { registerLazyLoadedDiagrams } from './detectType'; import { registerLazyLoadedDiagrams } from './detectType';
import timelineDetector from '../diagrams/timeline/detector';
let hasLoadedDiagrams = false; let hasLoadedDiagrams = false;
export const addDiagrams = () => { export const addDiagrams = () => {
if (hasLoadedDiagrams) { if (hasLoadedDiagrams) {
@@ -105,7 +105,7 @@ export const addDiagrams = () => {
// This is added here to avoid race-conditions. // This is added here to avoid race-conditions.
// We could optimize the loading logic somehow. // We could optimize the loading logic somehow.
hasLoadedDiagrams = true; hasLoadedDiagrams = true;
registerLazyLoadedDiagrams(flowchartElk); registerLazyLoadedDiagrams(flowchartElk, timelineDetector);
registerDiagram( registerDiagram(
'error', 'error',

View File

@@ -1,4 +1,4 @@
import type { ExternalDiagramDefinition } from 'mermaid'; import type { ExternalDiagramDefinition } from '../../diagram-api/types';
const id = 'timeline'; const id = 'timeline';

View File

@@ -1,8 +1,8 @@
import { parser as timeline } from './parser/timeline'; import { parser as timeline } from './parser/timeline';
import * as timelineDB from './timelineDb'; import * as timelineDB from './timelineDb';
import { injectUtils } from './mermaidUtils'; import { injectUtils } from './mermaidUtils';
import * as _commonDb from '../../mermaid/src/commonDb'; import * as _commonDb from '../../commonDb';
import { parseDirective as _parseDirective } from '../../mermaid/src/directiveUtils'; import { parseDirective as _parseDirective } from '../../directiveUtils';
import { import {
log, log,
@@ -10,7 +10,7 @@ import {
getConfig, getConfig,
sanitizeText, sanitizeText,
setupGraphViewBox, setupGraphViewBox,
} from '../../mermaid/src/diagram-api/diagramAPI'; } from '../../diagram-api/diagramAPI';
injectUtils( injectUtils(
log, log,

View File

@@ -1,6 +1,6 @@
import mermaid, { type MermaidConfig } from 'mermaid'; import mermaid, { type MermaidConfig } from 'mermaid';
import mindmap from '@mermaid-js/mermaid-mindmap'; import mindmap from '@mermaid-js/mermaid-mindmap';
import timeline from '@mermaid-js/mermaid-timeline'; // import timeline from '@mermaid-js/mermaid-timeline';
const init = (async () => { const init = (async () => {
try { try {

View File

@@ -10,7 +10,8 @@
timeline timeline
title History of Social Media Platform title History of Social Media Platform
2002 : LinkedIn 2002 : LinkedIn
2004 : Facebook : Google 2004 : Facebook
: Google
2005 : Youtube 2005 : Youtube
2006 : Twitter 2006 : Twitter
``` ```
@@ -290,16 +291,4 @@ Let's put them to use, and see how our sample diagram looks in different themes:
2010 : Pinterest 2010 : Pinterest
``` ```
## Integrating with your library/website.
Timeline uses the experimental lazy loading & async rendering features which could change in the future.
```html
<script type="module">
import mermaid from '<CDN_URL>/mermaid@<MERMAID_VERSION>/dist/mermaid.esm.min.mjs';
import timeline from '<CDN_URL>/@mermaid-js/mermaid-timeline@<MERMAID_VERSION>/dist/mermaid-timeline.esm.min.mjs';
await mermaid.registerExternalDiagrams([timeline]);
</script>
```
You can also refer the implementation in the live editor [here](https://github.com/mermaid-js/mermaid-live-editor/blob/fcf53c98c25604c90a218104268c339be53035a6/src/lib/util/mermaid.ts) to see how the async loading is done. You can also refer the implementation in the live editor [here](https://github.com/mermaid-js/mermaid-live-editor/blob/fcf53c98c25604c90a218104268c339be53035a6/src/lib/util/mermaid.ts) to see how the async loading is done.

View File

@@ -36,10 +36,10 @@ export default defineConfig({
__dirname, __dirname,
'../../../mermaid-mindmap/dist/mermaid-mindmap.esm.min.mjs' '../../../mermaid-mindmap/dist/mermaid-mindmap.esm.min.mjs'
), // Use this one to build ), // Use this one to build
'@mermaid-js/mermaid-timeline': path.join( // '@mermaid-js/mermaid-timeline': path.join(
__dirname, // __dirname,
'../../../mermaid-timeline/dist/mermaid-timeline.esm.min.mjs' // '../../../mermaid-timeline/dist/mermaid-timeline.esm.min.mjs'
), // ),
}, },
}, },
server: { server: {

View File

@@ -336,9 +336,9 @@ const registerExternalDiagrams = async (
} else { } else {
await loadExternalDiagrams(...diagrams); await loadExternalDiagrams(...diagrams);
} }
externalDiagramsRegistered = true;
}; };
externalDiagramsRegistered = true;
/** /**
* ##contentLoaded Callback function that is called when page is loaded. This functions fetches * ##contentLoaded Callback function that is called when page is loaded. This functions fetches
* configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the * configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the