Skip to content

Commit 6f5d16d

Browse files
committed
Added dgmlManager
1 parent 828c6c4 commit 6f5d16d

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

src/dgmlManager.ts

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import { Component } from "@src";
2+
3+
export class DGMLManager {
4+
5+
public createNewDirectedGraph(domImpl: DOMImplementation, direction: string, layout: string, zoomLevel: string) {
6+
let xmlDoc: Document = domImpl.createDocument('', null, null);
7+
const root = xmlDoc.createElement("DirectedGraph");
8+
root.setAttribute("GraphDirection", direction);
9+
root.setAttribute("Layout", layout);
10+
root.setAttribute("ZoomLevel", zoomLevel);
11+
root.setAttribute("xmlns", "http://schemas.microsoft.com/vs/2009/dgml");
12+
xmlDoc.appendChild(root);
13+
return xmlDoc;
14+
}
15+
16+
private addNodeToRoot(xmlDoc: Document, tagName: string): Element | null {
17+
const root = xmlDoc.documentElement;
18+
const elements = root.getElementsByTagName(tagName);
19+
let nodeElement: Element;
20+
if (elements.length === 0) {
21+
nodeElement = xmlDoc.createElement(tagName);
22+
root.appendChild(nodeElement);
23+
return nodeElement;
24+
}
25+
else {
26+
const exitingNode = elements.item(0);
27+
return exitingNode;
28+
}
29+
}
30+
31+
private addNode(element: Element | null, nodeElement: Element, attribute: string = 'Id') {
32+
if (element !== null) {
33+
let nodeAlreadyAdded = false;
34+
if (element.childNodes.length > 0) {
35+
for (let i = 0; i < element.childNodes.length; i++) {
36+
let node = element.childNodes[i];
37+
if (node.nodeType === 1 && (node as Element).hasAttribute(attribute) &&
38+
(node as Element).getAttribute(attribute)?.toLowerCase() === nodeElement.getAttribute(attribute)?.toLowerCase()) {
39+
nodeAlreadyAdded = true;
40+
}
41+
};
42+
}
43+
if (!nodeAlreadyAdded) {
44+
element.appendChild(nodeElement);
45+
}
46+
}
47+
}
48+
49+
private addLinkNode(xmlDoc: Document, element: Element | null, source: string, target: string) {
50+
if (element !== null) {
51+
let nodeAlreadyAdded = false;
52+
if (element.childNodes.length > 0) {
53+
for (let i = 0; i < element.childNodes.length; i++) {
54+
let node = element.childNodes[i];
55+
if (node.nodeType === 1 &&
56+
(node as Element).hasAttribute("Source") &&
57+
(node as Element).hasAttribute("Target") &&
58+
(node as Element).getAttribute("Source")?.toLowerCase() === source.toLowerCase() &&
59+
(node as Element).getAttribute("Target")?.toLowerCase() === target.toLowerCase()) {
60+
nodeAlreadyAdded = true;
61+
}
62+
}
63+
}
64+
if (!nodeAlreadyAdded) {
65+
const linkElement = xmlDoc.createElement("Link");
66+
linkElement.setAttribute("Source", source);
67+
linkElement.setAttribute("Target", target);
68+
element.appendChild(linkElement);
69+
}
70+
}
71+
}
72+
73+
public addNodesAndLinks(xmlDoc: Document, componentHash: { [selector: string]: Component; }) {
74+
const nodesElement = this.addNodeToRoot(xmlDoc, "Nodes");
75+
const linksElement = this.addNodeToRoot(xmlDoc, "Links");
76+
for (let selector in componentHash) {
77+
const component = componentHash[selector];
78+
if (component.isRoot) {
79+
this.generateDirectedGraphNodesXml(xmlDoc, component.subComponents, component, true, nodesElement);
80+
this.generateDirectedGraphLinksXml(xmlDoc, component.subComponents, selector, "", linksElement);
81+
}
82+
}
83+
}
84+
85+
private generateDirectedGraphNodesXml(xmlDoc: Document, components: Component[], component: Component, isRoot: boolean, nodesElement: Element | null) {
86+
const nodeElement = xmlDoc.createElement("Node");
87+
nodeElement.setAttribute("ComponentFilename", component.tsFilename);
88+
nodeElement.setAttribute("Label", component.selector);
89+
nodeElement.setAttribute("Id", component.selector);
90+
if (isRoot) {
91+
nodeElement.setAttribute("Category", "RootComponent");
92+
}
93+
this.addNode(nodesElement, nodeElement);
94+
if (components.length > 0) {
95+
components.forEach((subComponent) => {
96+
this.generateDirectedGraphNodesXml(xmlDoc, subComponent.subComponents, subComponent, subComponent.isRoot, nodesElement);
97+
});
98+
}
99+
}
100+
101+
private generateDirectedGraphLinksXml(xmlDoc: Document, subComponents: Component[], displayName: string, parentDisplayName: string, linksElement: Element | null) {
102+
if (parentDisplayName.length > 0) {
103+
this.addLinkNode(xmlDoc, linksElement, parentDisplayName, displayName);
104+
}
105+
if (subComponents.length > 0) {
106+
subComponents.forEach((subComponent) => {
107+
this.generateDirectedGraphLinksXml(xmlDoc, subComponent.subComponents, subComponent.selector, displayName, linksElement);
108+
});
109+
}
110+
}
111+
112+
public addCategory(xmlDoc: Document, id: string, label: string, backgroundColor: string) {
113+
const categoriesElement = this.addNodeToRoot(xmlDoc, "Categories");
114+
const categoryElement = xmlDoc.createElement("Category");
115+
categoryElement.setAttribute("Id", id);
116+
categoryElement.setAttribute("Label", label);
117+
categoryElement.setAttribute("Background", backgroundColor);
118+
categoryElement.setAttribute("IsTag", "True");
119+
this.addNode(categoriesElement, categoryElement);
120+
}
121+
122+
public addProperties(xmlDoc: Document) {
123+
const propertiesElement = this.addNodeToRoot(xmlDoc, "Properties");
124+
this.addProperty(xmlDoc, propertiesElement, "ComponentFilename", "System.String");
125+
this.addProperty(xmlDoc, propertiesElement, "Background", "System.Windows.Media.Brush");
126+
this.addProperty(xmlDoc, propertiesElement, "GraphDirection", "Microsoft.VisualStudio.Diagrams.Layout.LayoutOrientation");
127+
this.addProperty(xmlDoc, propertiesElement, "GroupLabel", "System.String");
128+
this.addProperty(xmlDoc, propertiesElement, "IsTag", "System.Boolean");
129+
this.addProperty(xmlDoc, propertiesElement, "Label", "System.String");
130+
this.addProperty(xmlDoc, propertiesElement, "Layout", "System.String");
131+
this.addProperty(xmlDoc, propertiesElement, "TargetType", "System.String");
132+
this.addProperty(xmlDoc, propertiesElement, "ValueLabel", "System.String");
133+
this.addProperty(xmlDoc, propertiesElement, "ZoomLevel", "System.String");
134+
this.addProperty(xmlDoc, propertiesElement, "Expression", "System.String");
135+
}
136+
137+
private addProperty(xmlDoc: Document, propertiesElement: Element | null, idValue: string, datatypeValue: string) {
138+
const propertyElement = xmlDoc.createElement("Property");
139+
propertyElement.setAttribute("Id", idValue);
140+
propertyElement.setAttribute("DataType", datatypeValue);
141+
this.addNode(propertiesElement, propertyElement);
142+
}
143+
144+
public addStyles(xmlDoc: Document) {
145+
const stylesElement = this.addNodeToRoot(xmlDoc, "Styles");
146+
const styleElement = xmlDoc.createElement("Style");
147+
styleElement.setAttribute("TargetType", "Node");
148+
styleElement.setAttribute("GroupLabel", "Root component");
149+
styleElement.setAttribute("ValueLabel", "Has category");
150+
const conditionElement = xmlDoc.createElement("Condition");
151+
conditionElement.setAttribute("Expression", "HasCategory('RootComponent')");
152+
styleElement.appendChild(conditionElement);
153+
const setterElement = xmlDoc.createElement("Setter");
154+
setterElement.setAttribute("Property", "Background");
155+
setterElement.setAttribute("Property", "#FF00AA00");
156+
styleElement.appendChild(setterElement);
157+
this.addNode(stylesElement, styleElement, "GroupLabel");
158+
}
159+
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './arrayUtils';
22
export * from './componentManager';
33
export * from './config';
4+
export * from './dgmlManager';
45
export * from './filesystemUtils';
56
export * from './moduleManager';

0 commit comments

Comments
 (0)