Improve relation tree visualizations

Change-Id: I99c414a61f48ad237746f54885ca7ef6afadb6dd
diff --git a/dev/demo/relations.html b/dev/demo/relations.html
index d651988..89abf06 100644
--- a/dev/demo/relations.html
+++ b/dev/demo/relations.html
@@ -5,43 +5,22 @@
     <script data-main="relationsdemo.js" src="../js/lib/require.js" async="async"></script>
     <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
     <style>
-        tspan, text {  
-          font-size: 11pt; 
-          stroke-width: 0; 
-          line-height: 100%; 
-          stroke-opacity:0; 
-          padding-right: 3pt 
-          fill: black; 
-        }
-        /*
-        svg.relTree g > text > tspan {
-          text-anchor: middle;
-        }
-        */
-        g.arcs text { 
-          font-size: 9pt; 
-          fill: blue;
-        }
-        path { 
-          stroke-width: 2; 
-          stroke: black;  
-          fill: none;
-        }
-        path.anchor {
-          stroke: green;
-          z-index: 20;
-        }
-        marker > path {
-          fill-opacity:1;
-          fill: black;
-        }
-        marker {
-          overflow:visible
-        }
     </style>
     
   </head>
   <body>
-    <div id="tree"></div>
+    <div id="search">
+      <ol>
+        <li class="active action">
+          <div class="matchinfo">
+            <div class="matchtree">
+              <div id="treeRel"></div>
+              <div id="treeHier"></div>
+            </div>
+          </div>
+        </li>
+      </ol>
+    </div>
+
   </body>
 </html>
diff --git a/dev/demo/relationsdemo.js b/dev/demo/relationsdemo.js
index 17fcfb3..12d536c 100644
--- a/dev/demo/relationsdemo.js
+++ b/dev/demo/relationsdemo.js
@@ -1,10 +1,69 @@
+var treeSnippet =
+  "<span class=\"context-left\"></span>" +
+  "<span class=\"match\">" +
+  "  <span title=\"xip/c:MC\">" +
+  "    <span title=\"xip/c:TOP\">" +
+  "      <span title=\"xip/c:PP\">" +
+  "        <span title=\"xip/c:PREP\">Mit</span>" +
+  "        <span title=\"xip/c:NP\">" +
+  "          <span title=\"xip/c:DET\">dieser</span>" +
+  "          <span title=\"xip/c:NPA\">" +
+  "            <span title=\"xip/c:NOUN\">Methode</span>" +
+  "          </span>" +
+  "        </span>" +
+  "      </span>" +
+  "      <span title=\"xip/c:VERB\">ist</span>" +
+  "      <span title=\"xip/c:NP\">" +
+  "        <span title=\"xip/c:PRON\">es</span>" +
+  "      </span>" +
+  "      <span title=\"xip/c:AP\">" +
+  "        <span title=\"xip/c:ADV\">nun</span>" +
+  "        <span title=\"xip/c:ADJ\">möglich</span>" +
+  "      </span>" +
+  "      <span title=\"xip/c:ADV\">z. B.</span>" +
+  "      <span title=\"xip/c:NPA\">" +
+  "        <span title=\"xip/c:NP\">" +
+  "          <span title=\"xip/c:NOUN\">Voice</span>" +
+  "        </span>" +
+  "      </span>" + "(" +
+  "      <span title=\"xip/c:INS\">" +
+  "        <span title=\"xip/c:NPA\">" +
+  "          <span title=\"xip/c:NP\">" +
+  "            <span title=\"xip/c:NOUN\">Sprache</span>" +
+  "          </span>" +
+  "        </span>" +
+  "      </span>" + ")" +
+  "      <span title=\"xip/c:VERB\">bevorzugt</span>" +
+  "      <span title=\"xip/c:PP\">" +
+  "        <span title=\"xip/c:PREP\">in</span>" +
+  "        <span title=\"xip/c:NP\">" +
+  "          <span title=\"xip/c:PRON\">der</span>" +
+  "        </span>" +
+  "        <span title=\"xip/c:NPA\">" +
+  "          <span title=\"xip/c:NP\">" +
+  "            <span title=\"xip/c:NOUN\">Bridge</span>" +
+  "          </span>" +
+  "        </span>" +
+  "      </span>" +
+  "      <span title=\"xip/c:INFC\">" +
+  "        <span title=\"xip/c:INS\">" +
+  "          <span title=\"xip/c:VERB\">weiterzugeben</span>" +
+  "        </span>" +
+  "      </span>" +
+  "    </span>" +
+  "  </span>" +
+  "</span>" +
+  "<span class=\"context-right\"></span>";
+
 requirejs.config({
-  baseUrl: '../js/src'
+  baseUrl: '../js/src',
+  paths : {
+    'lib': '../lib'
+  }
 });
 
-require(['match/relations'], function (relClass) {
+require(['match/relations', 'match/tree'], function (relClass, treeClass) {
   var rel = relClass.create();
-  document.getElementById("tree").appendChild(rel.element());
 
   /*
    * Start and end may be spans, i.e. arrays
@@ -31,6 +90,13 @@
     .addRel({ start: [5,6], end: 7, label: "g" })
     .addRel({ start: 4, end: [6,8], label: "f", direction: "bi" })
   ;
-  
+
+  document.getElementById("treeRel").appendChild(rel.element());
+
+  // Todo: Probably rename to rel.draw()
   rel.show();
+
+  var tree = treeClass.create(treeSnippet);
+  document.getElementById("treeHier").appendChild(tree.element());
 });
+
diff --git a/dev/js/src/match/relations.js b/dev/js/src/match/relations.js
index f79d189..5193635 100644
--- a/dev/js/src/match/relations.js
+++ b/dev/js/src/match/relations.js
@@ -29,24 +29,30 @@
       return this;
     },
 
+
     // This is a shorthand for SVG element creation
     _c : function (tag) {
       return document.createElementNS(svgNS, tag);
     },
 
+
     // Returns the center point of the requesting token
     _tokenPoint : function (node) {
       var box = node.getBoundingClientRect();
       return box.x + (box.width / 2);
     },
 
+
+    // Draws an anchor
     _drawAnchor : function (anchor) {
+
+      // Calculate the span of the first and last token, the anchor spans
       var firstBox = this._tokenElements[anchor.first].getBoundingClientRect();
       var lastBox = this._tokenElements[anchor.last].getBoundingClientRect();
 
-      var startPos = firstBox.left;
-      var endPos = lastBox.right;
-
+      var startPos = firstBox.left - this.offsetLeft;
+      var endPos = lastBox.right - this.offsetLeft;
+      
       var y = this._y + (anchor.overlaps * this.anchorDiff) - this.anchorStart;
 
       var l = this._c('path');
@@ -80,8 +86,12 @@
         endPos = this._tokenPoint(this._tokenElements[arc.last]);
       };
 
+      startPos -= this.offsetLeft;
+      endPos -= this.offsetLeft;
+
       var g = this._c("g");
       var p = g.appendChild(this._c("path"));
+      p.setAttribute('class', 'edge');
 
       // Create arc
       var middle = Math.abs(endPos - startPos) / 2;
@@ -279,7 +289,7 @@
       var g = svg.appendChild(this._c("g"));
 
       /*
-       * Generate token list
+       * Create token list
        */
       var text = g.appendChild(this._c("text"));
       text.setAttribute("text-anchor", "start");
@@ -307,18 +317,26 @@
         tspan.setAttribute("dx", this.tokenSep);
       };
 
+      var globalBoundingBox = g.getBoundingClientRect();
+      this.offsetLeft = globalBoundingBox.left;
+
       var arcs = g.appendChild(this._c("g"));
       arcs.classList.add("arcs");
-      
+
+      // Sort arcs if not sorted yet
       if (this._sortedArcs === undefined) {
         this._sortArcs();
       };
 
       var i;
+
+      // Draw all anchors
       for (i in this._sortedAnchors) {
         arcs.appendChild(this._drawAnchor(this._sortedAnchors[i]));
       };
-      
+
+
+      // draw all arcs
       for (i in this._sortedArcs) {
         arcs.appendChild(this._drawArc(this._sortedArcs[i]));
       };
diff --git a/dev/scss/main/main.scss b/dev/scss/main/main.scss
index e73bce3..f6d1b7a 100644
--- a/dev/scss/main/main.scss
+++ b/dev/scss/main/main.scss
@@ -1,7 +1,8 @@
 @import "highlight";  // JSON highlighting
 @import "kwic";       // Kwic view information
 @import "logos";      // Logo images
-@import "matchinfo";  // Match table and tree
+@import "matchinfo";  // Match table
+@import "tree";       // Tree view
 @import "pagination"; // Pagination
 @import "query";      // View query
 @import "resultinfo"; // Information on results
diff --git a/dev/scss/main/matchinfo.scss b/dev/scss/main/matchinfo.scss
index 4446fc8..dd6bd9c 100644
--- a/dev/scss/main/matchinfo.scss
+++ b/dev/scss/main/matchinfo.scss
@@ -336,54 +336,3 @@
 }
 
 
-/**
- * SVG tree
- */
-path.edge {
-  stroke: $darker-orange;
-  stroke-width: 2px;
-  fill: none;
-}
-
-g.root rect.empty {
-  stroke: $darker-orange;
-  fill: $darker-orange;
-  stroke-width: 2px;
-}
-
-g.middle rect {
-  stroke: $darker-orange;
-  stroke-width: 2px;
-  fill: $middle-orange;
-}
-
-g.middle.mark {
-  rect {
-    fill: $darker-orange;
-  }
-  > text {
-    fill: $light-orange;
-    > tspan {
-      stroke: $light-orange;
-    }
-  }
-}
-
-
-g.leaf.mark text > tspan {
-  font-weight: bold;
-}
-
-g.leaf > rect {
-  display: none;
-}
-
-g > text > tspan {
-  text-anchor: middle;
-  font-size: 9pt;
-}
-
-g.leaf > text > tspan {
-  font-size: 10pt;
-  overflow: visible;
-}
diff --git a/dev/scss/main/tree.scss b/dev/scss/main/tree.scss
new file mode 100644
index 0000000..eb58b3a
--- /dev/null
+++ b/dev/scss/main/tree.scss
@@ -0,0 +1,69 @@
+@charset "utf-8";
+@import "../util";
+
+/**
+ * SVG tree
+ */
+path.edge {
+  stroke: $darker-orange;
+  stroke-width: 2px;
+  fill: none;
+}
+
+marker#arr {
+  overflow: visible;
+  path {
+    fill-opacity:1;
+    stroke-width: 2; 
+    stroke: $darkest-orange;
+    fill: $darkest-orange;
+  }
+}
+
+path.anchor {
+  stroke: $darkest-orange;
+  z-index: 20;
+}
+
+g.root rect.empty {
+  stroke: $darker-orange;
+  fill: $darker-orange;
+  stroke-width: 2px;
+}
+
+g.middle rect {
+  stroke: $darker-orange;
+  stroke-width: 2px;
+  fill: $middle-orange;
+}
+
+g.middle.mark {
+  rect {
+    fill: $darker-orange;
+  }
+  > text {
+    fill: $light-orange;
+    > tspan {
+      stroke: $light-orange;
+    }
+  }
+}
+
+
+g.leaf.mark text > tspan {
+  font-weight: bold;
+}
+
+g.leaf > rect {
+  display: none;
+}
+
+g > text > tspan {
+  text-anchor: middle;
+  font-size: 9pt;
+}
+
+g.leaf > text > tspan {
+  font-size: 10pt;
+  overflow: visible;
+}