mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
Multiple improvements on syntax
Syntax has been simplified Removed extra initial states Removed unused groups Nodes can be wrapped in double qotes Updated demo page
This commit is contained in:
parent
726efdad53
commit
6722ac7540
@ -16,16 +16,93 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1>Sankey diagram demos</h1>
|
<h1>Sankey diagram demos</h1>
|
||||||
<h2>Simple flow</h2>
|
<h2>Simple example</h2>
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
sankey
|
sankey
|
||||||
a->28->b->10->c
|
|
||||||
a->11->b
|
node[title="hello, how are you?"]
|
||||||
k->18->b->35->d->13->e->43->dd11
|
node[title="hello, mister Sankey"]
|
||||||
d->5->e
|
|
||||||
d->10->c
|
First -> 30 -> Second
|
||||||
k->25->e
|
First -> 10 -> Third
|
||||||
|
Second -> 20 -> Third
|
||||||
</pre>
|
</pre>
|
||||||
|
<!-- node[title="hello, mister "sankey", backslash for you "] -->
|
||||||
|
|
||||||
|
<h2>Energy flow</h2>
|
||||||
|
<pre class="mermaid">
|
||||||
|
sankey
|
||||||
|
|
||||||
|
"Agricultural 'waste'" -> 124.729 -> "Bio-conversion"
|
||||||
|
"Bio-conversion" -> 0.597 -> "Liquid"
|
||||||
|
"Bio-conversion" -> 26.862 -> "Losses"
|
||||||
|
"Bio-conversion" -> 280.322 -> "Solid"
|
||||||
|
"Bio-conversion" -> 81.144 -> "Gas"
|
||||||
|
"Biofuel imports" -> 35 -> "Liquid"
|
||||||
|
"Biomass imports" -> 35 -> "Solid"
|
||||||
|
"Coal imports" -> 11.606 -> "Coal"
|
||||||
|
"Coal reserves" -> 63.965 -> "Coal"
|
||||||
|
"Coal" -> 75.571 -> "Solid"
|
||||||
|
"District heating" -> 10.639 -> "Industry"
|
||||||
|
"District heating" -> 22.505 -> "Heating and cooling - commercial"
|
||||||
|
"District heating" -> 46.184 -> "Heating and cooling - homes"
|
||||||
|
"Electricity grid" -> 104.453 -> "Over generation / exports"
|
||||||
|
"Electricity grid" -> 113.726 -> "Heating and cooling - homes"
|
||||||
|
"Electricity grid" -> 27.14 -> "H2 conversion"
|
||||||
|
"Electricity grid" -> 342.165 -> "Industry"
|
||||||
|
"Electricity grid" -> 37.797 -> "Road transport"
|
||||||
|
"Electricity grid" -> 4.412 -> "Agriculture"
|
||||||
|
"Electricity grid" -> 40.858 -> "Heating and cooling - commercial"
|
||||||
|
"Electricity grid" -> 56.691 -> "Losses"
|
||||||
|
"Electricity grid" -> 7.863 -> "Rail transport"
|
||||||
|
"Electricity grid" -> 90.008 -> "Lighting & appliances - commercial"
|
||||||
|
"Electricity grid" -> 93.494 -> "Lighting & appliances - homes"
|
||||||
|
"Gas imports" -> 40.719 -> "Ngas"
|
||||||
|
"Gas reserves" -> 82.233 -> "Ngas"
|
||||||
|
"Gas" -> 0.129 -> "Heating and cooling - commercial"
|
||||||
|
"Gas" -> 1.401 -> "Losses"
|
||||||
|
"Gas" -> 151.891 -> "Thermal generation"
|
||||||
|
"Gas" -> 2.096 -> "Agriculture"
|
||||||
|
"Gas" -> 48.58 -> "Industry"
|
||||||
|
"Geothermal" -> 7.013 -> "Electricity grid"
|
||||||
|
"H2 conversion" -> 20.897 -> "H2"
|
||||||
|
"H2 conversion" -> 6.242 -> "Losses"
|
||||||
|
"H2" -> 20.897 -> "Road transport"
|
||||||
|
"Hydro" -> 6.995 -> "Electricity grid"
|
||||||
|
"Liquid" -> 121.066 -> "Industry"
|
||||||
|
"Liquid" -> 128.69 -> "International shipping"
|
||||||
|
"Liquid" -> 135.835 -> "Road transport"
|
||||||
|
"Liquid" -> 14.458 -> "Domestic aviation"
|
||||||
|
"Liquid" -> 206.267 -> "International aviation"
|
||||||
|
"Liquid" -> 3.64 -> "Agriculture"
|
||||||
|
"Liquid" -> 33.218 -> "National navigation"
|
||||||
|
"Liquid" -> 4.413 -> "Rail transport"
|
||||||
|
"Marine algae" -> 4.375 -> "Bio-conversion"
|
||||||
|
"Ngas" -> 122.952 -> "Gas"
|
||||||
|
"Nuclear" -> 839.978 -> "Thermal generation"
|
||||||
|
"Oil imports" -> 504.287 -> "Oil"
|
||||||
|
"Oil reserves" -> 107.703 -> "Oil"
|
||||||
|
"Oil" -> 611.99 -> "Liquid"
|
||||||
|
"Other waste" -> 56.587 -> "Solid"
|
||||||
|
"Other waste" -> 77.81 -> "Bio-conversion"
|
||||||
|
"Pumped heat" -> 193.026 -> "Heating and cooling - homes"
|
||||||
|
"Pumped heat" -> 70.672 -> "Heating and cooling - commercial"
|
||||||
|
"Solar PV" -> 59.901 -> "Electricity grid"
|
||||||
|
"Solar Thermal" -> 19.263 -> "Heating and cooling - homes"
|
||||||
|
"Solar" -> 19.263 -> "Solar Thermal"
|
||||||
|
"Solar" -> 59.901 -> "Solar PV"
|
||||||
|
"Solid" -> 0.882 -> "Agriculture"
|
||||||
|
"Solid" -> 400.12 -> "Thermal generation"
|
||||||
|
"Solid" -> 46.477 -> "Industry"
|
||||||
|
"Thermal generation" -> 525.531 -> "Electricity grid"
|
||||||
|
"Thermal generation" -> 787.129 -> "Losses"
|
||||||
|
"Thermal generation" -> 79.329 -> "District heating"
|
||||||
|
"Tidal" -> 9.452 -> "Electricity grid"
|
||||||
|
"UK land based bioenergy" -> 182.01 -> "Bio-conversion"
|
||||||
|
"Wave" -> 19.013 -> "Electricity grid"
|
||||||
|
"Wind" -> 289.366 -> "Electricity grid"
|
||||||
|
</pre>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import mermaid from './mermaid.esm.mjs';
|
import mermaid from './mermaid.esm.mjs';
|
||||||
mermaid.initialize({
|
mermaid.initialize({
|
||||||
|
@ -4,38 +4,36 @@
|
|||||||
%options case-insensitive
|
%options case-insensitive
|
||||||
%options easy_keyword_rules
|
%options easy_keyword_rules
|
||||||
|
|
||||||
%s group
|
|
||||||
// when we are inside [] section we are defining attrubutes
|
// when we are inside [] section we are defining attrubutes
|
||||||
%x attributes
|
%x attributes
|
||||||
// after attr= we are expecting a value without quotes
|
|
||||||
%x value
|
|
||||||
// or if we use "" we are expecting a string containing value
|
// or if we use "" we are expecting a string containing value
|
||||||
%x string
|
%x string
|
||||||
|
%x value
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
// skip all whitespace EXCEPT newlines, but not within a string
|
||||||
|
<INITIAL,attributes,value>[^\S\r\n]+ {}
|
||||||
|
|
||||||
|
// main
|
||||||
"sankey" { return 'SANKEY'; }
|
"sankey" { return 'SANKEY'; }
|
||||||
\d+ { return 'AMOUNT'; }
|
\d+(.\d+)? { return 'AMOUNT'; }
|
||||||
"->" { return 'ARROW'; }
|
"->" { return 'ARROW'; }
|
||||||
\w+ { return 'NODE'; }
|
\w+ { return 'NODE'; }
|
||||||
(?:<<EOF>>|[\n;])+ { return 'EOS'; } // end of statement is ; \n or end of file
|
(?:<<EOF>>|[\n;])+ { return 'EOS'; } // end of statement is semicolon ; new line \n or end of file
|
||||||
\s+ // skip all whitespace
|
// attributes
|
||||||
"{" { this.pushState('group'); return 'OPEN_GROUP'; }
|
|
||||||
<group>"}" { this.popState(); return 'CLOSE_GROUP'; }
|
|
||||||
"[" { this.pushState('attributes'); return 'OPEN_ATTRIBUTES'; }
|
"[" { this.pushState('attributes'); return 'OPEN_ATTRIBUTES'; }
|
||||||
<attributes>"]" { this.popState(); return 'CLOSE_ATTRIBUTES'; }
|
<attributes>"]" { this.popState(); return 'CLOSE_ATTRIBUTES'; }
|
||||||
<attributes>\w+ { return 'ATTRIBUTE'; }
|
<attributes>\w+ { return 'ATTRIBUTE'; }
|
||||||
<attributes>(?=\=s*)[\s\w] { return 'VALUE';}
|
|
||||||
<attributes>\= { this.pushState('value'); return 'EQUAL'; }
|
<attributes>\= { this.pushState('value'); return 'EQUAL'; }
|
||||||
<attributes>\s+ // skip all whitespace
|
<value>\w+ { this.popState(); return 'VALUE'; }
|
||||||
<value>[\w]+ { this.popState(); return 'VALUE';}
|
// strings
|
||||||
<value>\s+ //skip
|
<INITIAL,attributes,value>\" { this.pushState('string'); return 'OPEN_STRING'; }
|
||||||
<value>\" { this.pushState('string'); return 'OPEN_STRING'; }
|
|
||||||
<string>(?!\\)\" {
|
<string>(?!\\)\" {
|
||||||
if(this.topState()==='string') this.popState();
|
if(this.topState()==='string') this.popState();
|
||||||
if(this.topState()==='value') this.popState();
|
if(this.topState()==='value') this.popState();
|
||||||
return 'CLOSE_STRING';
|
return 'CLOSE_STRING';
|
||||||
}
|
}
|
||||||
<string>([^"\\]|\\\")+ { return 'STRING'; }
|
<string>([^"\\]|\\\"|\\\\)+ { return 'STRING'; }
|
||||||
|
|
||||||
/lex
|
/lex
|
||||||
|
|
||||||
@ -79,14 +77,8 @@ tail
|
|||||||
| node { $$ = $node; }
|
| node { $$ = $node; }
|
||||||
;
|
;
|
||||||
|
|
||||||
node: NODE { $$ = yy.addNode($NODE); };
|
node
|
||||||
|
: NODE { $$ = yy.addNode($NODE); }
|
||||||
|
| OPEN_STRING STRING[title] CLOSE_STRING { $$ = yy.addNode($title); /* TODO: add title and id separately?*/ }
|
||||||
|
;
|
||||||
|
|
||||||
// : NODE exhaust intake exhaust_chain optional_attributes EOS
|
|
||||||
// exhaust_chain: ARROW AMOUNT intake_chain | ;
|
|
||||||
// intake_chain: ARROW NODE exhaust_chain | ;
|
|
||||||
|
|
||||||
// exhaust: ARROW AMOUNT;
|
|
||||||
// intake: ARROW NODE;
|
|
||||||
|
|
||||||
// node_chain_amount: NODE ARROW amount_node_chain | NODE;
|
|
||||||
// amount_node_chain: AMOUNT ARROW node_chain_amount | AMOUNT;
|
|
||||||
|
@ -38,11 +38,23 @@ describe('Sankey diagram', function () {
|
|||||||
parser.parse(str);
|
parser.parse(str);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('parses node as a string', () => {
|
||||||
|
const str = `
|
||||||
|
sankey
|
||||||
|
"node a" -> 30 -> "node b" -> 12 -> "node e"
|
||||||
|
"node c" -> 30 -> "node d" -> 12 -> "node e"
|
||||||
|
"node c" -> 40 -> "node e" -> 12 -> "node q"
|
||||||
|
`;
|
||||||
|
|
||||||
|
parser.parse(str);
|
||||||
|
});
|
||||||
|
|
||||||
describe('while attributes parsing', () => {
|
describe('while attributes parsing', () => {
|
||||||
it('parses different quotless variations', () => {
|
it('parses different quotless variations', () => {
|
||||||
const str = `
|
const str = `
|
||||||
sankey
|
sankey
|
||||||
node[]
|
node[]
|
||||||
|
|
||||||
node[attr=1]
|
node[attr=1]
|
||||||
node_a -> 30 -> node_b
|
node_a -> 30 -> node_b
|
||||||
node[attrWithoutValue]
|
node[attrWithoutValue]
|
||||||
@ -57,12 +69,89 @@ describe('Sankey diagram', function () {
|
|||||||
it('parses strings as values', () => {
|
it('parses strings as values', () => {
|
||||||
const str = `
|
const str = `
|
||||||
sankey
|
sankey
|
||||||
node[attr="hello, how are you?"]
|
node[title="hello, how are you?"]
|
||||||
node[attr="hello\\"afaasd"]
|
node[title="hello, mister \\"sankey\\", backslash for you \\\\"]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
parser.parse(str);
|
parser.parse(str);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('parses truly complex example', () => {
|
||||||
|
const str = `
|
||||||
|
sankey
|
||||||
|
|
||||||
|
"Agricultural 'waste'" -> 124.729 -> "Bio-conversion"
|
||||||
|
"Bio-conversion" -> 0.597 -> "Liquid"
|
||||||
|
"Bio-conversion" -> 26.862 -> "Losses"
|
||||||
|
"Bio-conversion" -> 280.322 -> "Solid"
|
||||||
|
"Bio-conversion" -> 81.144 -> "Gas"
|
||||||
|
"Biofuel imports" -> 35 -> "Liquid"
|
||||||
|
"Biomass imports" -> 35 -> "Solid"
|
||||||
|
"Coal imports" -> 11.606 -> "Coal"
|
||||||
|
"Coal reserves" -> 63.965 -> "Coal"
|
||||||
|
"Coal" -> 75.571 -> "Solid"
|
||||||
|
"District heating" -> 10.639 -> "Industry"
|
||||||
|
"District heating" -> 22.505 -> "Heating and cooling - commercial"
|
||||||
|
"District heating" -> 46.184 -> "Heating and cooling - homes"
|
||||||
|
"Electricity grid" -> 104.453 -> "Over generation / exports"
|
||||||
|
"Electricity grid" -> 113.726 -> "Heating and cooling - homes"
|
||||||
|
"Electricity grid" -> 27.14 -> "H2 conversion"
|
||||||
|
"Electricity grid" -> 342.165 -> "Industry"
|
||||||
|
"Electricity grid" -> 37.797 -> "Road transport"
|
||||||
|
"Electricity grid" -> 4.412 -> "Agriculture"
|
||||||
|
"Electricity grid" -> 40.858 -> "Heating and cooling - commercial"
|
||||||
|
"Electricity grid" -> 56.691 -> "Losses"
|
||||||
|
"Electricity grid" -> 7.863 -> "Rail transport"
|
||||||
|
"Electricity grid" -> 90.008 -> "Lighting & appliances - commercial"
|
||||||
|
"Electricity grid" -> 93.494 -> "Lighting & appliances - homes"
|
||||||
|
"Gas imports" -> 40.719 -> "Ngas"
|
||||||
|
"Gas reserves" -> 82.233 -> "Ngas"
|
||||||
|
"Gas" -> 0.129 -> "Heating and cooling - commercial"
|
||||||
|
"Gas" -> 1.401 -> "Losses"
|
||||||
|
"Gas" -> 151.891 -> "Thermal generation"
|
||||||
|
"Gas" -> 2.096 -> "Agriculture"
|
||||||
|
"Gas" -> 48.58 -> "Industry"
|
||||||
|
"Geothermal" -> 7.013 -> "Electricity grid"
|
||||||
|
"H2 conversion" -> 20.897 -> "H2"
|
||||||
|
"H2 conversion" -> 6.242 -> "Losses"
|
||||||
|
"H2" -> 20.897 -> "Road transport"
|
||||||
|
"Hydro" -> 6.995 -> "Electricity grid"
|
||||||
|
"Liquid" -> 121.066 -> "Industry"
|
||||||
|
"Liquid" -> 128.69 -> "International shipping"
|
||||||
|
"Liquid" -> 135.835 -> "Road transport"
|
||||||
|
"Liquid" -> 14.458 -> "Domestic aviation"
|
||||||
|
"Liquid" -> 206.267 -> "International aviation"
|
||||||
|
"Liquid" -> 3.64 -> "Agriculture"
|
||||||
|
"Liquid" -> 33.218 -> "National navigation"
|
||||||
|
"Liquid" -> 4.413 -> "Rail transport"
|
||||||
|
"Marine algae" -> 4.375 -> "Bio-conversion"
|
||||||
|
"Ngas" -> 122.952 -> "Gas"
|
||||||
|
"Nuclear" -> 839.978 -> "Thermal generation"
|
||||||
|
"Oil imports" -> 504.287 -> "Oil"
|
||||||
|
"Oil reserves" -> 107.703 -> "Oil"
|
||||||
|
"Oil" -> 611.99 -> "Liquid"
|
||||||
|
"Other waste" -> 56.587 -> "Solid"
|
||||||
|
"Other waste" -> 77.81 -> "Bio-conversion"
|
||||||
|
"Pumped heat" -> 193.026 -> "Heating and cooling - homes"
|
||||||
|
"Pumped heat" -> 70.672 -> "Heating and cooling - commercial"
|
||||||
|
"Solar PV" -> 59.901 -> "Electricity grid"
|
||||||
|
"Solar Thermal" -> 19.263 -> "Heating and cooling - homes"
|
||||||
|
"Solar" -> 19.263 -> "Solar Thermal"
|
||||||
|
"Solar" -> 59.901 -> "Solar PV"
|
||||||
|
"Solid" -> 0.882 -> "Agriculture"
|
||||||
|
"Solid" -> 400.12 -> "Thermal generation"
|
||||||
|
"Solid" -> 46.477 -> "Industry"
|
||||||
|
"Thermal generation" -> 525.531 -> "Electricity grid"
|
||||||
|
"Thermal generation" -> 787.129 -> "Losses"
|
||||||
|
"Thermal generation" -> 79.329 -> "District heating"
|
||||||
|
"Tidal" -> 9.452 -> "Electricity grid"
|
||||||
|
"UK land based bioenergy" -> 182.01 -> "Bio-conversion"
|
||||||
|
"Wave" -> 19.013 -> "Electricity grid"
|
||||||
|
"Wind" -> 289.366 -> "Electricity grid"
|
||||||
|
`
|
||||||
|
parser.parse(str);
|
||||||
|
|
||||||
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -79,9 +79,9 @@ const addLink = function(source?: Node, target?: Node, value?: number): Link {
|
|||||||
class Node {
|
class Node {
|
||||||
ID: string;
|
ID: string;
|
||||||
title: string;
|
title: string;
|
||||||
constructor(ID: string) {
|
constructor(ID: string, title: string = ID) {
|
||||||
this.ID = ID;
|
this.ID = ID;
|
||||||
this.title = ID;
|
this.title = title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// @ts-nocheck TODO: fix file
|
// @ts-nocheck TODO: fix file
|
||||||
import { Diagram } from '../../Diagram.js';
|
import { Diagram } from '../../Diagram.js';
|
||||||
import { log } from '../../logger.js';
|
// import { log } from '../../logger.js';
|
||||||
import * as configApi from '../../config.js';
|
import * as configApi from '../../config.js';
|
||||||
import {
|
import {
|
||||||
select as d3select,
|
select as d3select,
|
||||||
@ -43,7 +43,7 @@ export const draw = function (text: string, id: string, _version: string, diagOb
|
|||||||
// Launch parsing
|
// Launch parsing
|
||||||
diagObj.parser.parse(text);
|
diagObj.parser.parse(text);
|
||||||
// debugger;
|
// debugger;
|
||||||
log.debug('Parsed sankey diagram');
|
// log.debug('Parsed sankey diagram');
|
||||||
|
|
||||||
// Figure out what is happening there
|
// Figure out what is happening there
|
||||||
// The main thing is svg object that is a d3 wrapper for svg operations
|
// The main thing is svg object that is a d3 wrapper for svg operations
|
||||||
@ -64,7 +64,7 @@ export const draw = function (text: string, id: string, _version: string, diagOb
|
|||||||
//
|
//
|
||||||
const elem = doc.getElementById(id);
|
const elem = doc.getElementById(id);
|
||||||
const width = elem.parentElement.offsetWidth;
|
const width = elem.parentElement.offsetWidth;
|
||||||
const height = 300; // TODO calculate height?
|
const height = 600; // TODO calculate height?
|
||||||
|
|
||||||
// FIX: using max width prevents height from being set
|
// FIX: using max width prevents height from being set
|
||||||
configureSvgSize(svg, height, width, true);
|
configureSvgSize(svg, height, width, true);
|
||||||
@ -92,7 +92,7 @@ export const draw = function (text: string, id: string, _version: string, diagOb
|
|||||||
}
|
}
|
||||||
|
|
||||||
diagObj.db.getNodes().forEach(node => {
|
diagObj.db.getNodes().forEach(node => {
|
||||||
graph.nodes.push({ id: node.ID });
|
graph.nodes.push({ id: node.ID, title: node.title });
|
||||||
});
|
});
|
||||||
|
|
||||||
diagObj.db.getLinks().forEach(link => {
|
diagObj.db.getLinks().forEach(link => {
|
||||||
@ -158,7 +158,7 @@ export const draw = function (text: string, id: string, _version: string, diagOb
|
|||||||
.attr('x', (d) => d.x0)
|
.attr('x', (d) => d.x0)
|
||||||
.attr('y', (d) => d.y0)
|
.attr('y', (d) => d.y0)
|
||||||
.append('rect')
|
.append('rect')
|
||||||
.attr('height', (d) => { console.log(d); return (d.y1 - d.y0); })
|
.attr('height', (d) => { return (d.y1 - d.y0); })
|
||||||
.attr('width', (d) => d.x1 - d.x0)
|
.attr('width', (d) => d.x1 - d.x0)
|
||||||
.attr('fill', (d) => color(d.id));
|
.attr('fill', (d) => color(d.id));
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ export const draw = function (text: string, id: string, _version: string, diagOb
|
|||||||
.attr("y", d => (d.y1 + d.y0) / 2)
|
.attr("y", d => (d.y1 + d.y0) / 2)
|
||||||
.attr("dy", "0.35em")
|
.attr("dy", "0.35em")
|
||||||
.attr("text-anchor", d => d.x0 < width / 2 ? "start" : "end")
|
.attr("text-anchor", d => d.x0 < width / 2 ? "start" : "end")
|
||||||
.text(d => d.id)
|
.text(d => d.title)
|
||||||
|
|
||||||
// Creates the paths that represent the links.
|
// Creates the paths that represent the links.
|
||||||
const link_g = svg.append("g")
|
const link_g = svg.append("g")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user