Join identical anchors in relations

Change-Id: Ib8f853290f0228a6e23b4a20e3fffda302fd9443
diff --git a/dev/demo/relationsdemo.js b/dev/demo/relationsdemo.js
index 0fc1978..ef13cff 100644
--- a/dev/demo/relationsdemo.js
+++ b/dev/demo/relationsdemo.js
@@ -123,6 +123,39 @@
     "</span>" +
     "<span class=\"context-right\"></span>";
 
+/*
+ *     ___OBJA____
+ *     |_________|____DET________
+ *     |_________|____          |
+ *     |_SUBJ_   |   |          |
+ *  ___|_____|__ADV_ | ___PP____|
+ *  |  Y     |   | Y Y |       Y|
+ * -|------  |  -|-----|-- ----------
+ * dann zog ich mich gegen das Altern
+ *   1   2   3   4     5    6    7
+ */
+
+relSnippet =
+  "<span class=\"context-left\"></span>" +
+  "<span class=\"match\">" +
+  "  <span xml:id=\"token-1\">" +
+  "    <span xlink:title=\"malt/d:ADV\" xlink:type=\"simple\" xlink:href=\"#token-4\">dann</span>" +
+  "    zog " +
+  "  </span>" +
+  "  <span xlink:title=\"malt/d:SUBJ\" xlink:type=\"simple\" xlink:href=\"#token-1\">ich</span>" +
+  "  <span xml:id=\"token-4\">" +
+  "    <span xlink:title=\"malt/d:OBJA\" xlink:type=\"simple\" xlink:href=\"#token-1\">mich</span>" +
+  "    <span xlink:title=\"malt/d:PP\" xlink:type=\"simple\" xlink:href=\"#token-3\">gegen</span>" +
+  "  </span>" +
+  "  <span xml:id=\"token-3\">" +
+  "    <span xlink:title=\"malt/d:DET\" xlink:type=\"simple\" xlink:href=\"#token-1\">" +
+  "      das" +
+  "      <span xml:id=\"token-2\">Altern</span>" +
+  "    </span>" +
+  "  </span>" +
+  "</span>" +
+  "<span class=\"context-right\"></span>";
+
 
 requirejs.config({
   baseUrl: '../js/src',
diff --git a/dev/js/src/match/relations.js b/dev/js/src/match/relations.js
index 02d6c8b..1451c1e 100644
--- a/dev/js/src/match/relations.js
+++ b/dev/js/src/match/relations.js
@@ -19,8 +19,8 @@
     _init : function (snippet) {
 
       // Predefine some values
-      this._tokens = [];
-      this._arcs = [];
+      this._tokens  = [];
+      this._arcs    = [];
       this._tokenElements = [];
       this._y = 0;
 
@@ -405,7 +405,7 @@
       //   Keep in mind that the arcs may have long anchors!
       //   1. Iterate over all arcs
       //   2. Sort all multi
-      var anchors = [];
+      var anchors = {};
       
       // 1. Sort by length
       // 2. Tag all spans with the number of overlaps before
@@ -423,27 +423,55 @@
         if (v.start instanceof Array) {
           var middle = Math.ceil(Math.abs(v.start[1] - v.start[0]) / 2) + v.start[0];
 
-          v.startAnchor = {
-            "first":   v.start[0],
-            "last" :   v.start[1],
-            "length" : v.start[1] - v.start[0]
+          // Calculate signature to avoid multiple anchors
+          var anchorSig = "#" + v.start[0] + "_" + v.start[1];
+          if (v.start[0] > v.start[1]) {
+            anchorSig = "#" + v.start[1] + "_" + v.start[0];
           };
 
+          // Check if the anchor already exist
+          var anchor = anchors[anchorSig];
+          if (anchor === undefined) {
+            anchor = {
+              "first":   v.start[0],
+              "last" :   v.start[1],
+              "length" : v.start[1] - v.start[0]
+            };
+            anchors[anchorSig] = anchor;
+            // anchors.push(v.startAnchor);
+          };
+
+          v.startAnchor = anchor;
+
           // Add to anchors list
-          anchors.push(v.startAnchor);
           v.start = middle;
         };
 
         if (v.end instanceof Array) {
           var middle = Math.abs(v.end[0] - v.end[1]) + v.end[0];
-          v.endAnchor = {
-            "first":   v.end[0],
-            "last" :   v.end[1],
-            "length" : v.end[1] - v.end[0]
+
+          // Calculate signature to avoid multiple anchors
+          var anchorSig = "#" + v.end[0] + "_" + v.end[1];
+          if (v.end[0] > v.end[1]) {
+            anchorSig = "#" + v.end[1] + "_" + v.end[0];
           };
 
+          // Check if the anchor already exist
+          var anchor = anchors[anchorSig];
+          if (anchor === undefined) {
+            anchor = {
+              "first":   v.end[0],
+              "last" :   v.end[1],
+              "length" : v.end[1] - v.end[0]
+            };
+            anchors[anchorSig] = anchor;
+            // anchors.push(v.startAnchor);
+          };
+
+          v.endAnchor = anchor;
+
           // Add to anchors list
-          anchors.push(v.endAnchor);
+          // anchors.push(v.endAnchor);
           v.end = middle;
         };
 
@@ -460,11 +488,6 @@
           v.length = v.start - v.end;
         };
 
-        if (v.label === "OBJA") {
-          console.log(v);
-        };
-
-        // console.log(v);
         return v;
       });
 
@@ -478,7 +501,13 @@
 
       // Add sorted arcs and anchors
       this._sortedArcs    = lengthSort(sortedArcs, false);
-      this._sortedAnchors = lengthSort(anchors, true);
+
+      // Translate map to array (there is probably a better JS method)
+      var sortedAnchors = [];
+      for (var i in anchors) {
+        sortedAnchors.push(anchors[i]);
+      };
+      this._sortedAnchors = lengthSort(sortedAnchors, true);
     },