Skip to content

Commit 3729184

Browse files
committed
Styling from the styles nodes are now parsed correctly and applied til the nodes and edges.
1 parent c11637b commit 3729184

File tree

4 files changed

+147
-22
lines changed

4 files changed

+147
-22
lines changed

src/dgmlParser.ts

Lines changed: 82 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
} from '@model';
1616

1717
export class DgmlParser {
18-
18+
1919
public parseDgmlFile(filename: string): IDirectedGraph | undefined {
2020
const xml = fs.readFileSync(filename, 'utf8');
2121
const obj = parse(xml);
@@ -51,6 +51,7 @@ export class DgmlParser {
5151
});
5252
this.addCategoryStylingToNodes(directedGraph);
5353
this.addCategoryStylingToLinks(directedGraph);
54+
this.addStylingToCategories(directedGraph);
5455
}
5556
return directedGraph;
5657
}
@@ -103,10 +104,10 @@ export class DgmlParser {
103104
}
104105
if (attributesCopy['bounds'] !== undefined && attributesCopy['bounds'].indexOf(',') !== -1) {
105106
const bounds = attributesCopy['bounds'].split(',');
106-
newNode.boundsX = +bounds[0];
107-
newNode.boundsY = +bounds[1];
108-
newNode.boundsWidth = +bounds[2];
109-
newNode.boundsHeight = +bounds[3];
107+
newNode.boundsX = +bounds[0];
108+
newNode.boundsY = +bounds[1];
109+
newNode.boundsWidth = +bounds[2];
110+
newNode.boundsHeight = +bounds[3];
110111
}
111112
if (nodes.filter(n => n.id === newNode.id).length === 0) {
112113
nodes.push(newNode);
@@ -126,6 +127,7 @@ export class DgmlParser {
126127
const newLink = new Link();
127128
newLink.source = attributesCopy['source'];
128129
newLink.target = attributesCopy['target'];
130+
newLink.label = attributesCopy['label'];
129131
newLink.category = attributesCopy['category'];
130132
newLink.visibility = attributesCopy['visibility'] !== undefined ? attributesCopy['visibility'] === 'hidden' : false;
131133
newLink.background = attributesCopy['background'];
@@ -245,7 +247,7 @@ export class DgmlParser {
245247
valueLabel: attributesCopy['valuelabel'],
246248
toolTip: attributesCopy['tooltip'],
247249
condition: this.createCondition(xmlNode),
248-
setter: this.createSetter(xmlNode)
250+
setters: this.createSetter(xmlNode)
249251
} as IStyle;
250252
styles.push(newProperty);
251253
}
@@ -270,22 +272,25 @@ export class DgmlParser {
270272
return condition;
271273
}
272274

273-
private createSetter(xmlNode: IXmlNode): ISetter | undefined {
274-
let setter: ISetter | undefined = undefined;
275+
private createSetter(xmlNode: IXmlNode): ISetter[] | undefined {
276+
let setters: ISetter[] | undefined = undefined;
275277
if (xmlNode.children !== undefined) {
276278
xmlNode.children.forEach(childNode => {
277-
if (childNode.name.toLowerCase() === 'setter' && childNode.attributes !== undefined && setter === undefined) {
279+
if (childNode.name.toLowerCase() === 'setter' && childNode.attributes !== undefined) {
278280
const attributesCopy: { [key: string]: string } = this.toLowercaseDictionary(childNode.attributes);
279281
const newSetter = {
280282
expression: attributesCopy['expression'],
281283
property: attributesCopy['property'],
282284
value: attributesCopy['value']
283285
} as ISetter;
284-
setter = newSetter;
286+
if (!setters) {
287+
setters = [];
288+
}
289+
setters?.push(newSetter);
285290
}
286291
});
287292
}
288-
return setter;
293+
return setters;
289294
}
290295

291296
private addCategoryStylingToNodes(directedGraph: IDirectedGraph): void {
@@ -315,4 +320,70 @@ export class DgmlParser {
315320
});
316321
}
317322
}
323+
324+
private addStylingToCategories(directedGraph: IDirectedGraph): void {
325+
if (directedGraph.categories !== undefined &&
326+
directedGraph.categories.length > 0 &&
327+
directedGraph.styles !== undefined &&
328+
directedGraph.styles.length > 0) {
329+
directedGraph.styles.forEach(style => {
330+
if (style.condition !== undefined &&
331+
style.condition.expression !== undefined &&
332+
style.setters !== undefined &&
333+
style.setters.length > 0) {
334+
const regex = /HasCategory\(['"](\w+)['"]\)+/ig;
335+
const match = regex.exec(style.condition.expression);
336+
if (match) {
337+
const categoryName = match[1];
338+
const category = directedGraph.categories.find(category => category.id.toLowerCase() === categoryName.toLowerCase());
339+
if (category) {
340+
style.setters.forEach(setter => {
341+
if (setter.property !== undefined) {
342+
if (setter.property.toLowerCase() === 'stroke') {
343+
category.stroke = setter.value;
344+
}
345+
if (setter.property.toLowerCase() === 'strokethickness') {
346+
category.strokeThickness = setter.value;
347+
}
348+
if (setter.property.toLowerCase() === 'strokedasharray') {
349+
category.strokeDashArray = setter.value;
350+
}
351+
if (setter.property.toLowerCase() === 'strokedasharray') {
352+
category.strokeDashArray = setter.value;
353+
}
354+
if (setter.property.toLowerCase() === 'fontfamily') {
355+
category.fontFamily = setter.value;
356+
}
357+
if (setter.property.toLowerCase() === 'fontsize') {
358+
category.fontSize = +setter.value;
359+
}
360+
if (setter.property.toLowerCase() === 'fontstyle') {
361+
category.fontStyle = setter.value;
362+
}
363+
if (setter.property.toLowerCase() === 'fontweight') {
364+
category.fontWeight = setter.value;
365+
}
366+
if (setter.property.toLowerCase() === 'background') {
367+
category.background = setter.value;
368+
}
369+
if (setter.property.toLowerCase() === 'horizontalalignment') {
370+
category.horizontalAlignment = setter.value;
371+
}
372+
if (setter.property.toLowerCase() === 'verticalalignment') {
373+
category.verticalAlignment = setter.value;
374+
}
375+
if (setter.property.toLowerCase() === 'minwidth') {
376+
category.minWidth = +setter.value;
377+
}
378+
if (setter.property.toLowerCase() === 'maxwidth') {
379+
category.maxWidth = +setter.value;
380+
}
381+
}
382+
});
383+
}
384+
}
385+
}
386+
});
387+
}
388+
}
318389
}

src/model/IStyle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ export interface IStyle {
1010
valueLabel: string;
1111
toolTip: string;
1212
condition: ICondition;
13-
setter: ISetter;
13+
setters: ISetter[];
1414
}

src/model/Link.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,20 @@ export class Link extends BaseElement {
3434
if (this.visibility !== undefined) { jsStringProperties.push(`hidden: ${this.visibility}`); }
3535
const jsStringColorProperties: string[] = [];
3636
if (this.stroke !== undefined) { jsStringColorProperties.push(`color: "${this.convertColorValue(this.stroke)}"`); }
37-
if (this.categoryRef !== undefined && this.stroke === undefined && this.categoryRef.background !== undefined) { jsStringProperties.push(`color: "${this.convertColorValue(this.categoryRef.background)}"`); }
37+
if (this.categoryRef !== undefined){
38+
if (this.categoryRef.background !== undefined) {
39+
jsStringProperties.push(`color: "${this.convertColorValue(this.categoryRef.background)}"`);
40+
}
41+
if (this.categoryRef.stroke !== undefined) {
42+
jsStringProperties.push(`color: "${this.convertColorValue(this.categoryRef.stroke)}"`);
43+
}
44+
if (this.categoryRef.strokeDashArray !== undefined) {
45+
jsStringProperties.push(`dashes: true`);
46+
}
47+
if (this.categoryRef.strokeThickness !== undefined) {
48+
jsStringProperties.push(`width: ${this.categoryRef.strokeThickness}`);
49+
}
50+
}
3851
if (jsStringColorProperties.length > 0) { jsStringProperties.push(`color: { ${jsStringColorProperties.join(', ')} }`); }
3952
return `{${jsStringProperties.join(', ')}}`;
4053
}

src/model/Node.ts

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,33 +40,74 @@ export class Node extends BaseElement {
4040
public setCategoryRef(categoryRef: ICategory | undefined) {
4141
this.categoryRef = categoryRef;
4242
}
43-
43+
4444
public toJsString(): string {
4545
const jsStringProperties: string[] = [];
4646
if (this.id !== undefined) { jsStringProperties.push(`id: "${this.id}"`); }
47-
const label = this.convertNewlines(this.label);
48-
if (this.label !== undefined) {
49-
jsStringProperties.push(`label: "${label}"`);
50-
} else {
51-
jsStringProperties.push(`label: "${this.id}"`);
47+
let label = this.convertNewlines(this.label);
48+
if (this.fontWeight !== undefined &&
49+
this.fontWeight.toLowerCase().startsWith('bold')) {
50+
label = `<b>${label}</b>`;
5251
}
5352
const description = this.convertNewlines(this.description);
5453
if (this.description !== undefined) { jsStringProperties.push(`title: "${description}"`); }
5554
if (this.strokeThickness !== undefined) { jsStringProperties.push(`borderWidth: "${this.strokeThickness}"`); }
55+
if (this.strokeDashArray !== undefined) { jsStringProperties.push(`shapeProperties: { borderDashes: true }`); }
5656
const jsStringColorProperties: string[] = [];
5757
if (this.stroke !== undefined) { jsStringColorProperties.push(`border: "${this.stroke}"`); }
5858
if (this.background !== undefined) { jsStringColorProperties.push(`background: "${this.convertColorValue(this.background)}"`); }
59-
if (this.categoryRef !== undefined && this.background === undefined && this.categoryRef.background !== undefined) { jsStringColorProperties.push(`background: "${this.convertColorValue(this.categoryRef.background)}"`); }
60-
if (this.categoryRef !== undefined && this.stroke === undefined && this.categoryRef.stroke !== undefined) { jsStringColorProperties.push(`border: "${this.convertColorValue(this.categoryRef.stroke)}"`); }
59+
const jsStringFontProperties: string[] = [];
60+
if (this.fontFamily === undefined) { jsStringFontProperties.push(`face: ${this.fontFamily}`); }
61+
if (this.fontSize === undefined) { jsStringFontProperties.push(`size: ${this.fontSize}`); }
62+
if (this.categoryRef !== undefined) {
63+
if (this.background === undefined &&
64+
this.categoryRef.background !== undefined) {
65+
jsStringColorProperties.push(`background: "${this.convertColorValue(this.categoryRef.background)}"`);
66+
}
67+
if (this.stroke === undefined &&
68+
this.categoryRef.stroke !== undefined) {
69+
jsStringColorProperties.push(`border: "${this.convertColorValue(this.categoryRef.stroke)}"`);
70+
}
71+
if (this.strokeThickness === undefined &&
72+
this.categoryRef.strokeThickness !== undefined) {
73+
jsStringProperties.push(`borderWidth: "${this.convertColorValue(this.categoryRef.strokeThickness)}"`);
74+
}
75+
if (this.strokeDashArray === undefined &&
76+
this.categoryRef.strokeDashArray !== undefined) {
77+
jsStringProperties.push(`shapeProperties: { borderDashes: true }`);
78+
}
79+
if (this.fontFamily === undefined &&
80+
this.categoryRef.fontFamily !== undefined) {
81+
jsStringFontProperties.push(`face: ${this.categoryRef.fontFamily}`);
82+
}
83+
if (this.fontSize === undefined &&
84+
this.categoryRef.fontSize !== undefined) {
85+
jsStringFontProperties.push(`size: ${this.categoryRef.fontSize}`);
86+
}
87+
if (this.fontWeight === undefined &&
88+
this.categoryRef.fontWeight !== undefined &&
89+
this.categoryRef.fontWeight.toLowerCase().startsWith('bold')) {
90+
label = `<b>${label}</b>`;
91+
}
92+
}
93+
if (this.label !== undefined) {
94+
jsStringProperties.push(`label: "${label}"`);
95+
} else {
96+
jsStringProperties.push(`label: "${this.id}"`);
97+
}
6198
if (jsStringColorProperties.length > 0) { jsStringProperties.push(`color: { ${jsStringColorProperties.join(', ')} }`); }
99+
if (jsStringFontProperties.length > 0) {
100+
jsStringFontProperties.push(`multi: 'html'`);
101+
jsStringProperties.push(`font: { ${jsStringFontProperties.join(', ')} }`);
102+
}
62103
if (this.boundsX !== undefined && this.boundsY !== undefined) { jsStringProperties.push(`x: ${this.boundsX}, y: ${this.boundsY}, fixed: { x: true, y: true}`); }
63104
if (this.boundsWidth !== undefined) { jsStringProperties.push(`widthConstraint: { minimum: ${this.boundsWidth} }`); }
64105
if (this.boundsHeight !== undefined) { jsStringProperties.push(`heightConstraint: { minimum: ${this.boundsHeight}, valign: top }`); }
65106
return `{${jsStringProperties.join(', ')}}`;
66107
}
67108

68109
private convertNewlines(text: string | undefined): string {
69-
if(text === undefined || text.length === 0) {
110+
if (text === undefined || text.length === 0) {
70111
return '';
71112
}
72113
text = text.replace('&#xD;&#xA;', '\\n');

0 commit comments

Comments
 (0)