X-Git-Url: https://git.auder.net/?p=erdiag.git;a=blobdiff_plain;f=parser.js;h=8fc65edc3330eedf29ac02c7d9a9e957ab217a3f;hp=51a05e0815f2b9d60c29b2f104f610d2bab86f9d;hb=c728aeca9ef83bb786ed0c886a2b3dc4faf3dc45;hpb=eabe4071112a744a7be577263013a9bb0e4eb524
diff --git a/parser.js b/parser.js
index 51a05e0..8fc65ed 100644
--- a/parser.js
+++ b/parser.js
@@ -26,7 +26,9 @@ class ErDiags
"*": "0,n",
"+": "1,n",
"?": "0,1",
- "1": "1,1"
+ "1": "1,1",
+ "?R": "(0,1)",
+ "1R": "(1,1)",
};
}
@@ -67,7 +69,7 @@ class ErDiags
{
case '[':
// Entity = { name: { attributes, [weak] } }
- let name = lines[start].match(/[^\[\]\s]+/)[0];
+ let name = lines[start].match(/[^\[\]"\s]+/)[0];
let entity = { attributes: this.parseAttributes(lines, start+1, end) };
if (lines[start].charAt(1) == '[')
entity.weak = true;
@@ -79,7 +81,7 @@ class ErDiags
case '{': //association
// Association = { [name], [attributes], [weak], entities: ArrayOf entity indices }
let relationship = { };
- let nameRes = lines[start].match(/[^{}\s]+/);
+ let nameRes = lines[start].match(/[^{}"\s]+/);
if (nameRes !== null)
relationship.name = nameRes[0];
if (lines[start].charAt(1) == '{')
@@ -102,7 +104,7 @@ class ErDiags
field.isKey = true;
line = line.slice(1);
}
- field.name = line.match(/[^()\s]+/)[0];
+ field.name = line.match(/[^()"\s]+/)[0];
let parenthesis = line.match(/\((.+)\)/);
if (parenthesis !== null)
{
@@ -136,7 +138,10 @@ class ErDiags
return inheritance;
}
- // Association (parsed here): { entities: ArrayOf entity names + cardinality, [attributes: ArrayOf {name, [isKey], [type], [qualifiers]}] }
+ // Association (parsed here): {
+ // entities: ArrayOf entity names + cardinality,
+ // [attributes: ArrayOf {name, [isKey], [type], [qualifiers]}]
+ // }
parseAssociation(lines, start, end)
{
let assoce = { };
@@ -192,30 +197,30 @@ class ErDiags
mcdDot += 'rankdir="LR";\n';
// Nodes:
if (mcdStyle == "compact")
- mcdDot += "node [shape=plaintext];\n";
+ mcdDot += 'node [shape=plaintext];\n';
_.shuffle(Object.keys(this.entities)).forEach( name => {
if (mcdStyle == "bubble")
{
- mcdDot += name + '[shape=rectangle, label="' + name + '"';
+ mcdDot += '"' + name + '" [shape=rectangle, label="' + name + '"';
if (this.entities[name].weak)
mcdDot += ', peripheries=2';
mcdDot += '];\n';
if (!!this.entities[name].attributes)
{
- _.shuffle(this.entities[name].attributes).forEach( a => {
+ this.entities[name].attributes.forEach( a => {
let label = (a.isKey ? '#' : '') + a.name;
let attrName = name + '_' + a.name;
- mcdDot += attrName + '[shape=ellipse, label="' + label + '"];\n';
+ mcdDot += '"' + attrName + '" [shape=ellipse, label="' + label + '"];\n';
if (Math.random() < 0.5)
- mcdDot += attrName + ' -- ' + name + ';\n';
+ mcdDot += '"' + attrName + '" -- "' + name + '";\n';
else
- mcdDot += name + ' -- ' + attrName + ';\n';
+ mcdDot += '"' + name + '" -- "' + attrName + '";\n';
});
}
}
else
{
- mcdDot += name + '[label=<';
+ mcdDot += '"' + name + '" [label=<';
if (this.entities[name].weak)
{
mcdDot += '
' +
@@ -238,44 +243,68 @@ class ErDiags
}
});
// Inheritances:
- this.inheritances.forEach( i => {
+ _.shuffle(this.inheritances).forEach( i => {
+ // TODO: node shape = triangle fill yellow. See
+ // https://merise.developpez.com/faq/?page=MCD#CIF-ou-dependance-fonctionnelle-de-A-a-Z
+ // https://merise.developpez.com/faq/?page=MLD#Comment-transformer-un-MCD-en-MLD
+ // https://www.developpez.net/forums/d1088964/general-developpement/alm/modelisation/structure-agregation-l-association-d-association/
_.shuffle(i.children).forEach( c => {
if (Math.random() < 0.5)
- mcdDot += c + ':name -- ' + i.parent;
+ mcdDot += '"' + c + '":name -- "' + i.parent;
else
- mcdDot += i.parent + ':name -- ' + c;
- mcdDot += ':name [dir="forward", arrowhead="vee", style="dashed"];\n';
+ mcdDot += '"' + i.parent + '":name -- "' + c;
+ mcdDot += '":name [dir="forward", arrowhead="vee", style="dashed"];\n';
});
});
// Relationships:
+ if (mcdStyle == "compact")
+ mcdDot += 'node [shape=rectangle, style=rounded];\n';
let assoceCounter = 0;
_.shuffle(this.associations).forEach( a => {
let name = !!a.name && a.name.length > 0
? a.name
: '_assoce' + assoceCounter++;
- mcdDot += name + '[shape="diamond", style="filled", color="lightgrey", label="' + (!!a.name ? a.name : '') + '"';
- if (a.weak)
- mcdDot += ', peripheries=2';
- mcdDot += '];\n';
+ if (mcdStyle == "bubble")
+ {
+ mcdDot += '"' + name + '" [shape="diamond", style="filled", color="lightgrey", label="' + name + '"';
+ if (a.weak)
+ mcdDot += ', peripheries=2';
+ mcdDot += '];\n';
+ if (!!a.attributes)
+ {
+ a.attributes.forEach( attr => {
+ let label = (attr.isKey ? '#' : '') + attr.name;
+ mcdDot += '"' + name + '_' + attr.name + '" [shape=ellipse, label="' + label + '"];\n';
+ let attrName = name + '_' + attr.name;
+ if (Math.random() < 0.5)
+ mcdDot += '"' + attrName + '" -- "' + name + '";\n';
+ else
+ mcdDot += '"' + name + '" -- "' + attrName + '";\n';
+ });
+ }
+ }
+ else
+ {
+ let label = name;
+ if (!!a.attributes)
+ {
+ a.attributes.forEach( attr => {
+ let attrLabel = (attr.isKey ? '#' : '') + attr.name;
+ label += '\\n<' + attrLabel + '>';
+ });
+ }
+ mcdDot += '"' + name + '" [color="lightgrey", label="' + label + '"';
+ if (a.weak)
+ mcdDot += ', peripheries=2';
+ mcdDot += '];\n';
+ }
_.shuffle(a.entities).forEach( e => {
if (Math.random() < 0.5)
- mcdDot += e.name + ':name -- ' + name;
+ mcdDot += '"' + e.name + '":name -- "' + name + '"';
else
- mcdDot += name + ' -- ' + e.name + ':name';
+ mcdDot += '"' + name + '" -- "' + e.name + '":name';
mcdDot += '[label="' + ErDiags.CARDINAL[e.card] + '"];\n';
});
- if (!!a.attributes)
- {
- _.shuffle(a.attributes).forEach( attr => {
- let label = (attr.isKey ? '#' : '') + attr.name;
- mcdDot += name + '_' + attr.name + '[shape=ellipse, label="' + label + '"];\n';
- let attrName = name + '_' + attr.name;
- if (Math.random() < 0.5)
- mcdDot += attrName + ' -- ' + name + ';\n';
- else
- mcdDot += name + ' -- ' + attrName + ';\n';
- });
- }
});
mcdDot += '}';
console.log(mcdDot);