Introduce display of relational structures (experimental)

Change-Id: I3f8f16ff477e0ff21d846a4a0799a8e48f3f43e4
diff --git a/dev/js/spec/matchSpec.js b/dev/js/spec/matchSpec.js
index 68bd981..806aee8 100644
--- a/dev/js/spec/matchSpec.js
+++ b/dev/js/spec/matchSpec.js
@@ -430,7 +430,7 @@
     it('should parse into a tree (async) 1', function (done) {
       var info = matchClass.create(match).info();
       expect(info).toBeTruthy();
-      info.getTree(undefined, undefined, function (treem) {
+      info.getTree(undefined, undefined, "spans", function (treem) {
         tree = treem;
         done();
       });
@@ -475,7 +475,7 @@
 
     it('should add a tree view async 1', function (done) {
       expect(info).toBeTruthy();
-      info.addTree('mate', 'beebop', function () {
+      info.addTree('mate', 'beebop', "spans", function () {
         done();
       });
     });
@@ -565,7 +565,7 @@
     it('should be rendered async 1', function (done) {
       var info = matchClass.create(match).info();
       expect(info).toBeTruthy();
-      info.getTree(undefined, undefined, function (y) {
+      info.getTree(undefined, undefined, "spans", function (y) {
         tree = y;
         done();
       });
diff --git a/dev/js/src/match/info.js b/dev/js/src/match/info.js
index cb01593..7880a63 100644
--- a/dev/js/src/match/info.js
+++ b/dev/js/src/match/info.js
@@ -5,16 +5,16 @@
   'match/infolayer',
   'match/table',
   'match/tree',
+  'match/relations',
   'match/treemenu',
   'match/querycreator',
-  'match/relations',
   'util'
 ], function (infoLayerClass,
 	           matchTableClass,
 	           matchTreeClass,
+             matchRelClass,
 	           matchTreeMenuClass,
-             matchQueryCreator,
-             matchRelClass) {
+             matchQueryCreator) {
   
   // Override 
   KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () {
@@ -139,7 +139,7 @@
     /**
      * Retrieve and parse snippet for tree representation
      */
-    getTree : function (foundry, layer, cb) {
+    getTree : function (foundry, layer, type, cb) {
       var focus = [];
       
       // TODO: Support and cache multiple trees
@@ -154,7 +154,17 @@
           if (matchResponse["snippet"] !== undefined) {
             // Todo: This should be cached somehow
 
-            cb(matchTreeClass.create(matchResponse["snippet"]));
+            if (type === "spans") {
+              cb(matchTreeClass.create(matchResponse["snippet"]));
+            }
+            else if (type === "rels") {
+              cb(matchRelClass.create(matchResponse["snippet"]));              
+            }
+
+            // Unknown tree type
+            else {
+              cb(null);
+            };
           }
           else {
             cb(null);
@@ -182,7 +192,7 @@
     /**
      * Add a new tree view to the list
      */
-    addTree : function (foundry, layer, cb) {
+    addTree : function (foundry, layer, type, cb) {
       var matchtree = document.createElement('div');
       matchtree.classList.add('matchtree');
       
@@ -213,7 +223,7 @@
       tree.classList.add('loading');
 
       // Get tree data async
-      this.getTree(foundry, layer, function (treeObj) {
+      this.getTree(foundry, layer, type, function (treeObj) {
 
         tree.classList.remove('loading');
 
@@ -224,30 +234,35 @@
         }
         else {
           tree.appendChild(treeObj.element());
+          treeObj.show();
           // Reposition the view to the center
           // (This may in a future release be a reposition
           // to move the root into the center or the actual
           // match)
 
-          var dl = document.createElement('li');
-          dl.className = 'download';
-          dl.addEventListener(
-            'click', function (e) {
+          // This is currently not supported by relations
+          if (type === "spans") {
+            var dl = document.createElement('li');
+            dl.className = 'download';
+            dl.addEventListener(
+              'click', function (e) {
 
-              var a = document.createElement('a');
-              a.setAttribute('href-lang', 'image/svg+xml');
-              a.setAttribute('href', 'data:image/svg+xml;base64,'+treeObj.toBase64());
-              a.setAttribute('download', 'tree.svg');
-              a.target = '_blank';
-
-              document.body.appendChild(a);
-              a.click();
-              document.body.removeChild(a)
-
-              e.halt();
-            }
-          );
-          actions.appendChild(dl);
+                var a = document.createElement('a');
+                a.setAttribute('href-lang', 'image/svg+xml');
+                a.setAttribute('href', 'data:image/svg+xml;base64,'+treeObj.toBase64());
+                a.setAttribute('download', 'tree.svg');
+                a.target = '_blank';
+                
+                document.body.appendChild(a);
+                a.click();
+                document.body.removeChild(a)
+                e.halt();
+              }
+            );
+            
+            actions.appendChild(dl);
+          };
+          
           treeObj.center();
         };
   
@@ -293,11 +308,9 @@
       for (i in spans) {
         treeLayers.push(spans[i]);
       };
-      /*
       for (i in rels) {
         treeLayers.push(rels[i]);
       };
-      */
 
       // Get spans
       treeLayers = treeLayers.sort(
@@ -327,7 +340,8 @@
         menuList.push([
           span.foundry + '/' + span.layer,
           span.foundry,
-          span.layer
+          span.layer,
+          span.type
         ]);
       };
 
diff --git a/dev/js/src/match/relations.js b/dev/js/src/match/relations.js
index 942acee..e3bed9d 100644
--- a/dev/js/src/match/relations.js
+++ b/dev/js/src/match/relations.js
@@ -527,6 +527,26 @@
       this._sortedAnchors = lengthSort(sortedAnchors, true);
     },
 
+    /**
+     * Center the viewport of the canvas
+     * TODO:
+     *   This is identical to tree
+     */
+    center : function () {
+      if (this._element === undefined)
+       return;
+
+      var treeDiv = this._element.parentNode;
+
+      var cWidth = parseFloat(window.getComputedStyle(this._element).width);
+      var treeWidth = parseFloat(window.getComputedStyle(treeDiv).width);
+      // Reposition:
+      if (cWidth > treeWidth) {
+       var scrollValue = (cWidth - treeWidth) / 2;
+       treeDiv.scrollLeft = scrollValue;
+      };
+    },
+
 
     // Show the element
     show : function () {
diff --git a/dev/js/src/match/tree.js b/dev/js/src/match/tree.js
index dc4f229..88f0542 100644
--- a/dev/js/src/match/tree.js
+++ b/dev/js/src/match/tree.js
@@ -162,8 +162,15 @@
       return this;
     },
 
+    // Dummy method to be compatible with relTree
+    show : function () {
+      return;
+    },
+
     /**
      * Center the viewport of the canvas
+     * TODO:
+     *   This is identical to relations
      */
     center : function () {
       if (this._element === undefined)
diff --git a/dev/js/src/match/treeitem.js b/dev/js/src/match/treeitem.js
index c284de3..ad457b1 100644
--- a/dev/js/src/match/treeitem.js
+++ b/dev/js/src/match/treeitem.js
@@ -42,14 +42,23 @@
     },
 
     /**
+     * The type attribute of the menu item.
+     * Is either "spans" or "rels".
+     */
+    type : function () {
+      return this._type;
+    },
+    
+    /**
      * Override click action of the menu item.
      */
     onclick : function (e) {
       var menu = this.menu();
       menu.hide();
       e.halt();
-      if (menu.info() !== undefined)
-	      menu.info().addTree(this._foundry, this._layer);
+      if (menu.info() !== undefined) {
+	      menu.info().addTree(this._foundry, this._layer, this._type);
+      };
     },
 
     // Initialize tree menu item.
@@ -60,6 +69,7 @@
       this._name    = params[0];
       this._foundry = params[1];
       this._layer   = params[2];
+      this._type    = params[3];
       this._content = document.createTextNode(this._name);
       this._lcField = ' ' + this.content().textContent.toLowerCase();
       return this;
diff --git a/dev/js/src/match/treemenu.js b/dev/js/src/match/treemenu.js
index 2ca0731..4c9539d 100644
--- a/dev/js/src/match/treemenu.js
+++ b/dev/js/src/match/treemenu.js
@@ -15,10 +15,10 @@
      * @param params The match menu items
      *   as an array of arrays.
      */
-    create : function (info, params) {
+    create : function (info, list) {
       var obj = Object.create(menuClass)
 	        .upgradeTo(this)
-	        ._init(params, {itemClass : itemClass});
+	        ._init(list, {itemClass : itemClass});
       obj.limit(6);
       obj._info = info;