commit d7cfe5378419eb77763f147e2c3b9d276cc3f322
Author: Pavel Fidranský <fidransky@outlook.com>
Date:   Tue Aug 21 10:26:41 2018 +0200

    new JSON format compatibility fixes

diff --git a/sources/src/main/webapp/js/app.js b/sources/src/main/webapp/js/app.js
index 7c06bf6..ea277e1 100644
--- a/sources/src/main/webapp/js/app.js
+++ b/sources/src/main/webapp/js/app.js
@@ -242,7 +242,7 @@ function App() {
 			});
 
 			if (verticesWithMostEdges.length > 0) {
-				var group = new Group;
+				var group = new Group({});
 
 				verticesWithMostEdges.forEach(function(vertex) {
 					group.addVertex(vertex);
diff --git a/sources/src/main/webapp/js/components/edge.js b/sources/src/main/webapp/js/components/edge.js
index ca14efb..bec89a7 100644
--- a/sources/src/main/webapp/js/components/edge.js
+++ b/sources/src/main/webapp/js/components/edge.js
@@ -6,8 +6,8 @@
 function Edge(props) {
 	/** @prop {integer} id Unique identifier of the edge. */
 	this.id = props.id;
-	/** @prop {integer} archetype Archetype of the edge. */
-	this.archetype = app.archetype.edge[props.subedgeInfo.archetype];
+	/** @prop {integer} archetype Archetype of the edge. TODO: why is there multiple subedgeInfo for one edge? */
+	this.archetype = -1;
 
 	var rootElement;
 
diff --git a/sources/src/main/webapp/js/components/group.js b/sources/src/main/webapp/js/components/group.js
index 0332e90..5164b10 100644
--- a/sources/src/main/webapp/js/components/group.js
+++ b/sources/src/main/webapp/js/components/group.js
@@ -5,7 +5,7 @@
  */
 function Group(props) {
 	/** @prop {integer} id Unique identifier of the group. */
-	this.id = app.groupList.length + 1;
+	this.id = props.hasOwnProperty('id') ? props.id : app.groupList.length + 1;
 	/** @prop {string} name Name of the group. */
 	this.name = props.hasOwnProperty('name') ? props.name : 'Group ' + this.id;
 	/** @prop {array} symbol Symbol of the group. */
diff --git a/sources/src/main/webapp/js/components/vertex.js b/sources/src/main/webapp/js/components/vertex.js
index 54cb2e1..bd000ab 100644
--- a/sources/src/main/webapp/js/components/vertex.js
+++ b/sources/src/main/webapp/js/components/vertex.js
@@ -6,10 +6,10 @@
 function Vertex(props) {
 	/** @prop {integer} id Unique identifier of the vertex. */
 	this.id = props.id;
-	/** @prop {integer} archetype Archetype of the vertex. */
-	this.archetype = app.archetype.vertex[props.archetype];
+	/** @prop {integer} archetype Identifier of the vertex archetype. */
+	this.archetype = props.archetype;
 	/** @prop {string} name Name of the vertex. */
-	this.name = props.name.split(':')[1];
+	this.name = props.title.split(':')[1];
 	/** @prop {array} symbol Symbol of the group. */
 	this.symbol = app.markSymbol.getMarkSymbol();
 
diff --git a/sources/src/main/webapp/js/components/vertexContextMenuList.js b/sources/src/main/webapp/js/components/vertexContextMenuList.js
index 44f8686..b21b9a4 100644
--- a/sources/src/main/webapp/js/components/vertexContextMenuList.js
+++ b/sources/src/main/webapp/js/components/vertexContextMenuList.js
@@ -104,7 +104,7 @@ function VertexContextMenuList() {
 	function nodeListItemClick(e) {
 		if (this instanceof Vertex) {
 			// create a new group
-			var group = new Group;
+			var group = new Group({});
 			group.setExcluded(true);
 			group.addVertex(this);
 
diff --git a/sources/src/main/webapp/js/components/vertexPopover.js b/sources/src/main/webapp/js/components/vertexPopover.js
index d590137..eac5918 100644
--- a/sources/src/main/webapp/js/components/vertexPopover.js
+++ b/sources/src/main/webapp/js/components/vertexPopover.js
@@ -11,19 +11,19 @@ function VertexPopover() {
 	/**
 	 * Sets the contents of the popover.
 	 * @param {string} name Title of the popover.
-	 * @param {array} attributes List of attributes.
+	 * @param {array} attributeList List of attributes.
 	 */
-	this.setContent = function(name, attributes) {
+	this.setContent = function(name, attributeList) {
 		popoverTitle.innerText = name;
 
-		if (attributes.length > 0) {
-			attributes.forEach(function(attributes) {
-				var listItem = app.utils.createHtmlElement('li', {});
-				listItem.appendChild(document.createTextNode(attributes));
+		if (attributeList.length === 0) return;
 
-				detailsListElement.appendChild(listItem);
-			});
-		}
+		attributeList.forEach(function(attribute) {
+			var listItem = app.utils.createHtmlElement('li', {});
+			listItem.appendChild(document.createTextNode(`${attribute[0]}: ${attribute[1]}`));
+
+			detailsListElement.appendChild(listItem);
+		});
 	};
 
 	/**
diff --git a/sources/src/main/webapp/js/graphLoader.js b/sources/src/main/webapp/js/graphLoader.js
index 84a6eb3..95f7606 100644
--- a/sources/src/main/webapp/js/graphLoader.js
+++ b/sources/src/main/webapp/js/graphLoader.js
@@ -20,12 +20,12 @@ function GraphLoader() {
 
 		var canvasSize = ((data.vertices.length * 75) / Math.round(Math.sqrt(data.vertices.length))) + 1000;
 
-		// archetypes
+		// store archetypes
 		app.archetype.vertex = data.vertexArchetypes;
 		app.archetype.edge = data.edgeArchetypes;
 		app.archetype.icon = data.archetypeIcons;
 
-		// vertices
+		// construct vertices
 		var vertexMap = {};
 		data.vertices.forEach(function(component) {
 			var vertex = new Vertex(component);
@@ -55,12 +55,10 @@ function GraphLoader() {
 			app.nodeList.push(vertex);
 			app.vertexList.push(vertex);
 
-			vertexMap[component.symbolicName] = vertex;
-
-			app.viewportComponent.addVertex(vertex);
+			vertexMap[component.originalId] = vertex;
 		});
 
-		// edges
+		// construct edges
 		data.edges.forEach(function(component) {
 			var edge = new Edge(component);
 
@@ -74,13 +72,25 @@ function GraphLoader() {
 				toNode.addInEdge(edge);
 			}
 
-			app.edgeList.push(edge);
+			if (fromNode && toNode) {
+				fromNode.incrementRelatedArchetype(toNode.archetype);
+				toNode.incrementRelatedArchetype(fromNode.archetype);
+			}
 
-			app.viewportComponent.addEdge(edge);
+			app.edgeList.push(edge);
 		});
 
 		delete vertexMap;
 
+		// render components
+		app.vertexList.forEach(function(vertex) {
+			app.viewportComponent.addVertex(vertex);
+		});
+
+		app.edgeList.forEach(function(edge) {
+			app.viewportComponent.addEdge(edge);
+		});
+
 		// center viewport
 		app.viewportComponent.center();
 
@@ -92,34 +102,21 @@ function GraphLoader() {
 			app.sidebarComponent.unconnectedNodeListComponent.add(vertex);
 		});
 
-		// group vertex archetypes
-		var archetypeGroupMap = {};
+		// construct groups
+		data.groups.forEach(function(component) {
+			var group = new Group(component);
+			group.setExcluded(true);
 
-		data.defaultGroupArchetypes.forEach(function(archetypeIndex) {
 			app.vertexList.filter(function(vertex) {
-				return vertex.archetype === app.archetype.vertex[archetypeIndex];
+				return component.verticesId.indexOf(vertex.id) > -1;
 			}).forEach(function(vertex) {
-				if (archetypeGroupMap[archetypeIndex] instanceof Group) {
-					// group of the archetype vertices already exists
-					var group = archetypeGroupMap[archetypeIndex];
-
-				} else {
-					// create a new group
-					var group = new Group({
-						name: `${app.archetype.vertex[archetypeIndex].name} vertices`,
-					});
-					group.setExcluded(true);
-
-					app.nodeList.push(group);
-					app.groupList.push(group);
-
-					app.sidebarComponent.excludedNodeListComponent.add(group);
-
-					archetypeGroupMap[archetypeIndex] = group;
-				}
-
 				group.addVertex(vertex);
 			});
+
+			app.nodeList.push(group);
+			app.groupList.push(group);
+
+			app.sidebarComponent.excludedNodeListComponent.add(group);
 		});
 
 		// update status bar
