Added base structure for xychart

This commit is contained in:
Subhash Halder 2023-05-20 19:32:20 +05:30
parent e66135b67e
commit 14e290bf1a
10 changed files with 296 additions and 0 deletions

View File

@ -149,6 +149,7 @@
"vueuse",
"xlink",
"yash",
"xychart",
"yokozuna",
"zenuml"
],

View File

@ -60,6 +60,9 @@
<li>
<h2><a href="./quadrantchart.html">Quadrant charts</a></h2>
</li>
<li>
<h2><a href="./xychart.html">XY charts</a></h2>
</li>
<li>
<h2><a href="./requirements.html">Requirements</a></h2>
</li>

33
demos/xychart.html Normal file
View 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>

View File

@ -7,6 +7,7 @@ import gantt from '../diagrams/gantt/ganttDetector.js';
import { info } from '../diagrams/info/infoDetector.js';
import pie from '../diagrams/pie/pieDetector.js';
import quadrantChart from '../diagrams/quadrant-chart/quadrantDetector.js';
import xychart from '../diagrams/xychart/xychartDetector.js';
import requirement from '../diagrams/requirement/requirementDetector.js';
import sequence from '../diagrams/sequence/sequenceDetector.js';
import classDiagram from '../diagrams/class/classDetector.js';
@ -82,5 +83,6 @@ export const addDiagrams = () => {
journey,
quadrantChart,
sankey
xychart
);
};

View 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;
%%

View File

@ -0,0 +1,5 @@
// @ts-ignore: TODO Fix ts errors
import { scaleLinear } from 'd3';
import { log } from '../../logger.js';
export class XYChartBuilder {}

View 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,
};

View 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;

View 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: () => '',
};

View 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,
};