mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-04 16:16:41 +02:00
Added base structure for xychart
This commit is contained in:
@@ -149,6 +149,7 @@
|
|||||||
"vueuse",
|
"vueuse",
|
||||||
"xlink",
|
"xlink",
|
||||||
"yash",
|
"yash",
|
||||||
|
"xychart",
|
||||||
"yokozuna",
|
"yokozuna",
|
||||||
"zenuml"
|
"zenuml"
|
||||||
],
|
],
|
||||||
|
@@ -60,6 +60,9 @@
|
|||||||
<li>
|
<li>
|
||||||
<h2><a href="./quadrantchart.html">Quadrant charts</a></h2>
|
<h2><a href="./quadrantchart.html">Quadrant charts</a></h2>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<h2><a href="./xychart.html">XY charts</a></h2>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h2><a href="./requirements.html">Requirements</a></h2>
|
<h2><a href="./requirements.html">Requirements</a></h2>
|
||||||
</li>
|
</li>
|
||||||
|
33
demos/xychart.html
Normal file
33
demos/xychart.html
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<title>Mermaid Quick Test Page</title>
|
||||||
|
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
|
||||||
|
<style>
|
||||||
|
div.mermaid {
|
||||||
|
/* font-family: 'trebuchet ms', verdana, arial; */
|
||||||
|
font-family: 'Courier New', Courier, monospace !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>XY Charts demos</h1>
|
||||||
|
<pre class="mermaid">
|
||||||
|
xychart
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import mermaid from './mermaid.esm.mjs';
|
||||||
|
mermaid.initialize({
|
||||||
|
theme: 'default',
|
||||||
|
logLevel: 3,
|
||||||
|
securityLevel: 'loose',
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -7,6 +7,7 @@ import gantt from '../diagrams/gantt/ganttDetector.js';
|
|||||||
import { info } from '../diagrams/info/infoDetector.js';
|
import { info } from '../diagrams/info/infoDetector.js';
|
||||||
import pie from '../diagrams/pie/pieDetector.js';
|
import pie from '../diagrams/pie/pieDetector.js';
|
||||||
import quadrantChart from '../diagrams/quadrant-chart/quadrantDetector.js';
|
import quadrantChart from '../diagrams/quadrant-chart/quadrantDetector.js';
|
||||||
|
import xychart from '../diagrams/xychart/xychartDetector.js';
|
||||||
import requirement from '../diagrams/requirement/requirementDetector.js';
|
import requirement from '../diagrams/requirement/requirementDetector.js';
|
||||||
import sequence from '../diagrams/sequence/sequenceDetector.js';
|
import sequence from '../diagrams/sequence/sequenceDetector.js';
|
||||||
import classDiagram from '../diagrams/class/classDetector.js';
|
import classDiagram from '../diagrams/class/classDetector.js';
|
||||||
@@ -82,5 +83,6 @@ export const addDiagrams = () => {
|
|||||||
journey,
|
journey,
|
||||||
quadrantChart,
|
quadrantChart,
|
||||||
sankey
|
sankey
|
||||||
|
xychart
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
143
packages/mermaid/src/diagrams/xychart/parser/xychart.jison
Normal file
143
packages/mermaid/src/diagrams/xychart/parser/xychart.jison
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
%lex
|
||||||
|
%options case-insensitive
|
||||||
|
|
||||||
|
%x string
|
||||||
|
%x string
|
||||||
|
%x md_string
|
||||||
|
%x title
|
||||||
|
%x open_directive
|
||||||
|
%x type_directive
|
||||||
|
%x arg_directive
|
||||||
|
%x close_directive
|
||||||
|
%x acc_title
|
||||||
|
%x acc_descr
|
||||||
|
%x acc_descr_multiline
|
||||||
|
%%
|
||||||
|
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
|
||||||
|
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
|
||||||
|
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
|
||||||
|
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
|
||||||
|
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
|
||||||
|
\%\%(?!\{)[^\n]* /* skip comments */
|
||||||
|
[^\}]\%\%[^\n]* /* skip comments */
|
||||||
|
[\n\r]+ return 'NEWLINE';
|
||||||
|
\%\%[^\n]* /* do nothing */
|
||||||
|
|
||||||
|
title { this.begin("title");return 'title'; }
|
||||||
|
<title>(?!\n|;|#)*[^\n]* { this.popState(); return "title_value"; }
|
||||||
|
|
||||||
|
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
|
||||||
|
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
|
||||||
|
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
|
||||||
|
<acc_descr>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_descr_value"; }
|
||||||
|
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
|
||||||
|
<acc_descr_multiline>[\}] { this.popState(); }
|
||||||
|
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
|
||||||
|
|
||||||
|
|
||||||
|
["][`] { this.begin("md_string");}
|
||||||
|
<md_string>[^`"]+ { return "MD_STR";}
|
||||||
|
<md_string>[`]["] { this.popState();}
|
||||||
|
["] this.begin("string");
|
||||||
|
<string>["] this.popState();
|
||||||
|
<string>[^"]* return "STR";
|
||||||
|
|
||||||
|
" "*"xychart"" "* return 'XYCHART';
|
||||||
|
|
||||||
|
[A-Za-z]+ return 'ALPHA';
|
||||||
|
":" return 'COLON';
|
||||||
|
\+ return 'PLUS';
|
||||||
|
"," return 'COMMA';
|
||||||
|
"=" return 'EQUALS';
|
||||||
|
\= return 'EQUALS';
|
||||||
|
"*" return 'MULT';
|
||||||
|
\# return 'BRKT';
|
||||||
|
[\_] return 'UNDERSCORE';
|
||||||
|
"." return 'DOT';
|
||||||
|
"&" return 'AMP';
|
||||||
|
\- return 'MINUS';
|
||||||
|
[0-9]+ return 'NUM';
|
||||||
|
\s return 'SPACE';
|
||||||
|
";" return 'SEMI';
|
||||||
|
[!"#$%&'*+,-.`?\\_/] return 'PUNCTUATION';
|
||||||
|
<<EOF>> return 'EOF';
|
||||||
|
|
||||||
|
/lex
|
||||||
|
|
||||||
|
%start start
|
||||||
|
|
||||||
|
%% /* language grammar */
|
||||||
|
|
||||||
|
start
|
||||||
|
: eol start
|
||||||
|
| SPACE start
|
||||||
|
| directive start
|
||||||
|
| XYCHART document
|
||||||
|
;
|
||||||
|
|
||||||
|
document
|
||||||
|
: /* empty */
|
||||||
|
| document line
|
||||||
|
;
|
||||||
|
|
||||||
|
line
|
||||||
|
: statement eol
|
||||||
|
;
|
||||||
|
|
||||||
|
statement
|
||||||
|
:
|
||||||
|
| SPACE statement
|
||||||
|
| directive
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
directive
|
||||||
|
: openDirective typeDirective closeDirective
|
||||||
|
| openDirective typeDirective ':' argDirective closeDirective
|
||||||
|
;
|
||||||
|
|
||||||
|
eol
|
||||||
|
: NEWLINE
|
||||||
|
| SEMI
|
||||||
|
| EOF
|
||||||
|
;
|
||||||
|
|
||||||
|
openDirective
|
||||||
|
: open_directive { yy.parseDirective('%%{', 'open_directive'); }
|
||||||
|
;
|
||||||
|
|
||||||
|
typeDirective
|
||||||
|
: type_directive { yy.parseDirective($1, 'type_directive'); }
|
||||||
|
;
|
||||||
|
|
||||||
|
argDirective
|
||||||
|
: arg_directive { $1 = $1.trim().replace(/'/g, '"'); yy.parseDirective($1, 'arg_directive'); }
|
||||||
|
;
|
||||||
|
|
||||||
|
closeDirective
|
||||||
|
: close_directive { yy.parseDirective('}%%', 'close_directive', 'quadrantChart'); }
|
||||||
|
;
|
||||||
|
|
||||||
|
text: alphaNumToken
|
||||||
|
{ $$={text:$1, type: 'text'};}
|
||||||
|
| text textNoTagsToken
|
||||||
|
{ $$={text:$1.text+''+$2, type: $1.type};}
|
||||||
|
| STR
|
||||||
|
{ $$={text: $1, type: 'text'};}
|
||||||
|
| MD_STR
|
||||||
|
{ $$={text: $1, type: 'markdown'};}
|
||||||
|
;
|
||||||
|
|
||||||
|
alphaNum
|
||||||
|
: alphaNumToken
|
||||||
|
{$$=$1;}
|
||||||
|
| alphaNum alphaNumToken
|
||||||
|
{$$=$1+''+$2;}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
alphaNumToken : PUNCTUATION | AMP | NUM| ALPHA | COMMA | PLUS | EQUALS | MULT | DOT | BRKT| UNDERSCORE ;
|
||||||
|
|
||||||
|
textNoTagsToken: alphaNumToken | SPACE | MINUS;
|
||||||
|
|
||||||
|
%%
|
5
packages/mermaid/src/diagrams/xychart/xychartBuilder.ts
Normal file
5
packages/mermaid/src/diagrams/xychart/xychartBuilder.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
// @ts-ignore: TODO Fix ts errors
|
||||||
|
import { scaleLinear } from 'd3';
|
||||||
|
import { log } from '../../logger.js';
|
||||||
|
|
||||||
|
export class XYChartBuilder {}
|
39
packages/mermaid/src/diagrams/xychart/xychartDb.ts
Normal file
39
packages/mermaid/src/diagrams/xychart/xychartDb.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { log } from '../../logger.js';
|
||||||
|
import mermaidAPI from '../../mermaidAPI.js';
|
||||||
|
import * as configApi from '../../config.js';
|
||||||
|
import { sanitizeText } from '../common/common.js';
|
||||||
|
import {
|
||||||
|
setAccTitle,
|
||||||
|
getAccTitle,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
|
getAccDescription,
|
||||||
|
setAccDescription,
|
||||||
|
clear as commonClear,
|
||||||
|
} from '../../commonDb.js';
|
||||||
|
|
||||||
|
const config = configApi.getConfig();
|
||||||
|
|
||||||
|
function textSanitizer(text: string) {
|
||||||
|
return sanitizeText(text.trim(), config);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const parseDirective = function (statement: string, context: string, type: string) {
|
||||||
|
// @ts-ignore: TODO Fix ts errors
|
||||||
|
mermaidAPI.parseDirective(this, statement, context, type);
|
||||||
|
};
|
||||||
|
|
||||||
|
const clear = function () {
|
||||||
|
commonClear();
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
parseDirective,
|
||||||
|
clear,
|
||||||
|
setAccTitle,
|
||||||
|
getAccTitle,
|
||||||
|
setDiagramTitle,
|
||||||
|
getDiagramTitle,
|
||||||
|
getAccDescription,
|
||||||
|
setAccDescription,
|
||||||
|
};
|
20
packages/mermaid/src/diagrams/xychart/xychartDetector.ts
Normal file
20
packages/mermaid/src/diagrams/xychart/xychartDetector.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import type { DiagramDetector, ExternalDiagramDefinition } from '../../diagram-api/types.js';
|
||||||
|
|
||||||
|
const id = 'xychart';
|
||||||
|
|
||||||
|
const detector: DiagramDetector = (txt) => {
|
||||||
|
return txt.match(/^\s*xychart/i) !== null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const loader = async () => {
|
||||||
|
const { diagram } = await import('./xychartDiagram.js');
|
||||||
|
return { id, diagram };
|
||||||
|
};
|
||||||
|
|
||||||
|
const plugin: ExternalDiagramDefinition = {
|
||||||
|
id,
|
||||||
|
detector,
|
||||||
|
loader,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default plugin;
|
12
packages/mermaid/src/diagrams/xychart/xychartDiagram.ts
Normal file
12
packages/mermaid/src/diagrams/xychart/xychartDiagram.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||||
|
// @ts-ignore: TODO Fix ts errors
|
||||||
|
import parser from './parser/xychart.jison';
|
||||||
|
import db from './xychartDb.js';
|
||||||
|
import renderer from './xychartRenderer.js';
|
||||||
|
|
||||||
|
export const diagram: DiagramDefinition = {
|
||||||
|
parser,
|
||||||
|
db,
|
||||||
|
renderer,
|
||||||
|
styles: () => '',
|
||||||
|
};
|
38
packages/mermaid/src/diagrams/xychart/xychartRenderer.ts
Normal file
38
packages/mermaid/src/diagrams/xychart/xychartRenderer.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// @ts-ignore: TODO Fix ts errors
|
||||||
|
import { select } from 'd3';
|
||||||
|
import * as configApi from '../../config.js';
|
||||||
|
import { log } from '../../logger.js';
|
||||||
|
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||||
|
import { Diagram } from '../../Diagram.js';
|
||||||
|
|
||||||
|
export const draw = (txt: string, id: string, _version: string, diagObj: Diagram) => {
|
||||||
|
const conf = configApi.getConfig();
|
||||||
|
|
||||||
|
log.debug('Rendering xychart chart\n' + txt);
|
||||||
|
|
||||||
|
const securityLevel = conf.securityLevel;
|
||||||
|
// Handle root and Document for when rendering in sandbox mode
|
||||||
|
let sandboxElement;
|
||||||
|
if (securityLevel === 'sandbox') {
|
||||||
|
sandboxElement = select('#i' + id);
|
||||||
|
}
|
||||||
|
const root =
|
||||||
|
securityLevel === 'sandbox'
|
||||||
|
? select(sandboxElement.nodes()[0].contentDocument.body)
|
||||||
|
: select('body');
|
||||||
|
|
||||||
|
const svg = root.select(`[id="${id}"]`);
|
||||||
|
|
||||||
|
const group = svg.append('g').attr('class', 'main');
|
||||||
|
|
||||||
|
const width = 500;
|
||||||
|
const height = 500;
|
||||||
|
|
||||||
|
configureSvgSize(svg, height, width, true);
|
||||||
|
|
||||||
|
svg.attr('viewBox', '0 0 ' + width + ' ' + height);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
draw,
|
||||||
|
};
|
Reference in New Issue
Block a user