Added feature to morphtable: Legend now fixed
diff --git a/public/css/matchinfo.css b/public/css/matchinfo.css
new file mode 100644
index 0000000..cbdc02a
--- /dev/null
+++ b/public/css/matchinfo.css
@@ -0,0 +1,86 @@
+div.matchinfo {
+ position: relative;
+ width: 100%;
+ height: auto;
+ font-size: 10pt;
+}
+
+div.matchinfo div.matchtable {
+ z-index: 20;
+ margin-left: 122pt;
+ overflow-x: scroll;
+ overflow-y: visible;
+ width: auto;
+}
+
+div.matchtable table {
+ border-spacing: 2pt;
+ border-collapse: separate;
+}
+
+div.matchtable th {
+ color: white;
+}
+
+div.matchtable thead th {
+ background-color: #ff8000;
+}
+
+div.matchtable tbody th {
+ text-overflow: ellipsis;
+}
+
+div.matchtable tr > th:nth-of-type(1),
+div.matchtable tr > th:nth-of-type(2) {
+ position: absolute;
+ z-index: 80;
+ vertical-align: middle;
+ border-top: 2pt solid #ffa500;
+ margin-top: -2pt; /* minus the border*/
+ left: 0;
+ width: 60pt;
+ padding: 0 !important;
+}
+
+div.matchtable tr > th:nth-of-type(2) {
+ left: 62pt;
+}
+
+div.matchtable thead tr:nth-of-type(1) > th:nth-of-type(1),
+div.matchtable thead tr:nth-of-type(1) > th:nth-of-type(2) {
+ background-color: #ff8000;
+ height: 100%;
+}
+
+tbody tr:focus {
+ outline: none;
+}
+
+div.matchtable tbody tr:focus {
+ outline: 4px solid #7ba400;
+ -moz-outline-radius: 4px;
+ outline-radius: 4px;
+}
+
+div.matchtable tbody tr:focus td {
+ background-color: #7ba400;
+ color: white;
+ border-color: white;
+}
+
+div.matchtable tr > * {
+ padding: 0pt 6pt;
+ margin: 0;
+ line-height: 150%;
+}
+
+div.matchtable tr > td {
+ background-color: #ffd080;
+ white-space: nowrap;
+ vertical-align: top;
+ text-align: center;
+}
+
+div.matchtable tr:nth-child(odd) > td {
+ background-color: #f4eebb;
+}
diff --git a/public/js/demo/matchInfo.html b/public/js/demo/matchInfo.html
new file mode 100644
index 0000000..accb304
--- /dev/null
+++ b/public/js/demo/matchInfo.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>MatchInfo demo</title>
+ <meta charset="utf-8" />
+ <script src="../src/matchInfo.js"></script>
+ <link type="text/css" rel="stylesheet"
+ href="../../css/matchinfo.css"></link>
+ <style type="text/css" rel="stylesheet">
+
+body {
+ background-color: #ffa500;
+ font-family: tahoma, verdana, arial;
+}
+
+ </style>
+ </head>
+ <body>
+
+ <div class="matchinfo">
+ <div class="matchtable"></div>
+ </div>
+
+ <script>
+var snippet = "<span title=\"cnx/l:meist\">" +
+ " <span title=\"cnx/p:ADV\">" +
+ " <span title=\"cnx/syn:@PREMOD\">" +
+ " <span title=\"mate/l:meist\">" +
+ " <span title=\"mate/p:ADV\">" +
+ " <span title=\"opennlp/p:ADV\">meist</span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ "</span>" +
+ "<span title=\"cnx/l:deutlich\">" +
+ " <span title=\"cnx/p:A\">" +
+ " <span title=\"cnx/syn:@PREMOD\">" +
+ " <span title=\"mate/l:deutlich\">" +
+ " <span title=\"mate/m:degree:pos\">" +
+ " <span title=\"mate/p:ADJD\">" +
+ " <span title=\"opennlp/p:ADJD\">deutlich</span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ "</span>" +
+ "<span title=\"cnx/l:fähig\">" +
+ " <span title=\"cnx/l:leistung\">" +
+ " <span title=\"cnx/p:A\">" +
+ " <span title=\"cnx/syn:@NH\">" +
+ " <span title=\"mate/l:leistungsfähig\">" +
+ " <span title=\"mate/m:degree:comp\">" +
+ " <span title=\"mate/p:ADJD\">" +
+ " <span title=\"opennlp/p:ADJD\">leistungsfähiger</span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ "</span>";
+
+ // Override getMatchInfo API call
+ KorAP.API.getMatchInfo = function() {
+ return { "snippet": snippet };
+ };
+
+var info = KorAP.MatchInfo.create({
+ 'corpusID' : 'WPD',
+ 'docID' : 'UUU',
+ 'textID' : '01912',
+ 'pos' : 'p121-122'
+},
+[
+ 'base/s=spans',
+ 'corenlp/c=spans',
+ 'corenlp/ne=tokens',
+ 'corenlp/p=tokens',
+ 'corenlp/s=spans',
+ 'glemm/l=tokens',
+ 'mate/l=tokens',
+ 'mate/m=tokens',
+ 'mate/p=tokens',
+ 'opennlp/p=tokens',
+ 'opennlp/s=spans',
+ 'tt/l=tokens',
+ 'tt/p=tokens',
+ 'tt/s=spans'
+]);
+ var t = info.getTable();
+ document.getElementsByClassName('matchtable')[0]
+ .appendChild(t.element());
+ </script>
+
+
+
+ <div class="matchinfo">
+ <div class="matchtable">
+ <table>
+ <thead>
+ <tr>
+ <th>Foundry</th>
+ <th>Layer</th>
+ <th>Ich</th>
+ <th>Du</th>
+ <th>Er</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr tabindex="0">
+ <th>Hallo</th>
+ <th>X</th>
+ <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
+ <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ<br />ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
+ <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
+ </tr>
+ <tr tabindex="0">
+ <th>geht</th>
+ <th>y</th>
+ <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
+ <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
+ <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ<br />ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ<br />ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
+ </tr>
+ <tr tabindex="0">
+ <th>es</th>
+ <th>z</th>
+ <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
+ <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
+ <td>ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ<br />ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ<br />ABC DEF GHI JKL MNO PQR STU VWX YZ ABC DEF GHI JKL MNO PQR STU VWX YZ</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+
+ </body>
+</html>
diff --git a/public/js/spec/matchInfoSpec.js b/public/js/spec/matchInfoSpec.js
index dc0d4a1..4af3764 100644
--- a/public/js/spec/matchInfoSpec.js
+++ b/public/js/spec/matchInfoSpec.js
@@ -1,3 +1,67 @@
+var available = [
+ 'base/s=spans',
+ 'corenlp/c=spans',
+ 'corenlp/ne=tokens',
+ 'corenlp/p=tokens',
+ 'corenlp/s=spans',
+ 'glemm/l=tokens',
+ 'mate/l=tokens',
+ 'mate/m=tokens',
+ 'mate/p=tokens',
+ 'opennlp/p=tokens',
+ 'opennlp/s=spans',
+ 'tt/l=tokens',
+ 'tt/p=tokens',
+ 'tt/s=spans'
+];
+
+var match = {
+ 'corpusID' : 'WPD',
+ 'docID' : 'UUU',
+ 'textID' : '01912',
+ 'pos' : 'p121-122'
+};
+
+var snippet = "<span title=\"cnx/l:meist\">" +
+ " <span title=\"cnx/p:ADV\">" +
+ " <span title=\"cnx/syn:@PREMOD\">" +
+ " <span title=\"mate/l:meist\">" +
+ " <span title=\"mate/p:ADV\">" +
+ " <span title=\"opennlp/p:ADV\">meist</span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ "</span>" +
+ "<span title=\"cnx/l:deutlich\">" +
+ " <span title=\"cnx/p:A\">" +
+ " <span title=\"cnx/syn:@PREMOD\">" +
+ " <span title=\"mate/l:deutlich\">" +
+ " <span title=\"mate/m:degree:pos\">" +
+ " <span title=\"mate/p:ADJD\">" +
+ " <span title=\"opennlp/p:ADJD\">deutlich</span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ "</span>" +
+ "<span title=\"cnx/l:fähig\">" +
+ " <span title=\"cnx/l:leistung\">" +
+ " <span title=\"cnx/p:A\">" +
+ " <span title=\"cnx/syn:@NH\">" +
+ " <span title=\"mate/l:leistungsfähig\">" +
+ " <span title=\"mate/m:degree:comp\">" +
+ " <span title=\"mate/p:ADJD\">" +
+ " <span title=\"opennlp/p:ADJD\">leistungsfähiger</span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ " </span>" +
+ "</span>";
+
describe('KorAP.InfoLayer', function () {
it('should be initializable', function () {
expect(
@@ -37,71 +101,6 @@
});
describe('KorAP.MatchInfo', function () {
- var available = [
- 'base/s=spans',
- 'corenlp/c=spans',
- 'corenlp/ne=tokens',
- 'corenlp/p=tokens',
- 'corenlp/s=spans',
- 'glemm/l=tokens',
- 'mate/l=tokens',
- 'mate/m=tokens',
- 'mate/p=tokens',
- 'opennlp/p=tokens',
- 'opennlp/s=spans',
- 'tt/l=tokens',
- 'tt/p=tokens',
- 'tt/s=spans'
- ];
-
- var match = {
- 'corpusID' : 'WPD',
- 'docID' : 'UUU',
- 'textID' : '01912',
- 'pos' : 'p121-122'
- };
-
- var snippet = "<span title=\"cnx/l:meist\">" +
- " <span title=\"cnx/p:ADV\">" +
- " <span title=\"cnx/syn:@PREMOD\">" +
- " <span title=\"mate/l:meist\">" +
- " <span title=\"mate/p:ADV\">" +
- " <span title=\"opennlp/p:ADV\">meist</span>" +
- " </span>" +
- " </span>" +
- " </span>" +
- " </span>" +
- "</span>" +
- "<span title=\"cnx/l:deutlich\">" +
- " <span title=\"cnx/p:A\">" +
- " <span title=\"cnx/syn:@PREMOD\">" +
- " <span title=\"mate/l:deutlich\">" +
- " <span title=\"mate/m:degree:pos\">" +
- " <span title=\"mate/p:ADJD\">" +
- " <span title=\"opennlp/p:ADJD\">deutlich</span>" +
- " </span>" +
- " </span>" +
- " </span>" +
- " </span>" +
- " </span>" +
- "</span>" +
- "<span title=\"cnx/l:fähig\">" +
- " <span title=\"cnx/l:leistung\">" +
- " <span title=\"cnx/p:A\">" +
- " <span title=\"cnx/syn:@NH\">" +
- " <span title=\"mate/l:leistungsfähig\">" +
- " <span title=\"mate/m:degree:comp\">" +
- " <span title=\"mate/p:ADJD\">" +
- " <span title=\"opennlp/p:ADJD\">leistungsfähiger</span>" +
- " </span>" +
- " </span>" +
- " </span>" +
- " </span>" +
- " </span>" +
- " </span>" +
- "</span>";
-
-
it('should be initializable', function () {
expect(function() {
KorAP.MatchInfo.create()
@@ -168,7 +167,33 @@
expect(table.getValue(2, "cnx", "l")[0]).toBe("fähig");
expect(table.getValue(2, "cnx", "l")[1]).toBe("leistung");
});
+});
+describe('KorAP.MatchTable', function () {
+ it('should be rendered', function () {
+ var info = KorAP.MatchInfo.create(match, available);
+
+ // Override getMatchInfo API call
+ KorAP.API.getMatchInfo = function() {
+ return { "snippet": snippet };
+ };
+
+ var table = info.getTable();
+
+ var e = table.element();
+
+ expect(e.nodeName).toBe('TABLE');
+ expect(e.children[0].nodeName).toBe('THEAD');
+ var tr = e.children[0].children[0];
+ expect(tr.nodeName).toBe('TR');
+ expect(tr.children[0].nodeName).toBe('TH');
+
+ expect(tr.children[0].firstChild.nodeValue).toBe('Foundry');
+ expect(tr.children[1].firstChild.nodeValue).toBe('Layer');
+ expect(tr.children[2].firstChild.nodeValue).toBe('meist');
+ expect(tr.children[3].firstChild.nodeValue).toBe('deutlich');
+ expect(tr.children[4].firstChild.nodeValue).toBe('leistungsfähiger');
+ });
});
// table = view.toTable();
diff --git a/public/js/src/matchInfo.js b/public/js/src/matchInfo.js
index 515a78f..45f24f5 100644
--- a/public/js/src/matchInfo.js
+++ b/public/js/src/matchInfo.js
@@ -19,6 +19,7 @@
// API requests
KorAP.API = KorAP.API || {};
+ // TODO: Make this async
KorAP.API.getMatchInfo = KorAP.API.getMatchInfo || function () { return {} };
KorAP.MatchInfo = {
@@ -81,6 +82,9 @@
},
+ /**
+ * Get table object.
+ */
getTable : function (tokens) {
var focus = [];
@@ -119,7 +123,7 @@
// Get snippet from match info
if (matchResponse["snippet"] !== undefined) {
- this._table = KorAP.InfoTable.create(matchResponse["snippet"]);
+ this._table = KorAP.MatchTable.create(matchResponse["snippet"]);
return this._table;
};
@@ -129,7 +133,7 @@
/*
// Parse snippet for table visualization
getTree : function (foundry, layer) {
- },
+ }
*/
};
@@ -189,9 +193,9 @@
};
- KorAP.InfoTable = {
+ KorAP.MatchTable = {
create : function (snippet) {
- return Object.create(KorAP.InfoTable)._init(snippet);
+ return Object.create(KorAP.MatchTable)._init(snippet);
},
_init : function (snippet) {
// Create html for traversal
@@ -201,15 +205,12 @@
this._pos = 0;
this._token = [];
this._info = [];
- this._foundry = [];
- this._layer = [];
+ this._foundry = {};
+ this._layer = {};
// Parse the snippet
this._parse(html.childNodes);
- this._layer = undefined;
- this._foundry = undefined;
-
html.innerHTML = '';
return this;
},
@@ -275,12 +276,12 @@
found[foundry + "/" + layer].push(RegExp.$3);
// Set foundry
- if (!this._foundry[foundry])
+ if (this._foundry[foundry] === undefined)
this._foundry[foundry] = {};
this._foundry[foundry][layer] = 1;
// Set layer
- if (!this._layer[layer])
+ if (this._layer[layer] === undefined)
this._layer[layer] = {};
this._layer[layer][foundry] = 1;
};
@@ -290,7 +291,8 @@
this._parse(c.childNodes);
}
- // Leaf node - store string on position and go to next string
+ // Leaf node
+ // store string on position and go to next string
else if (c.nodeType === 3) {
if (c.nodeValue.match(/[a-z0-9]/i))
this._token[this._pos++] = c.nodeValue;
@@ -300,13 +302,75 @@
delete this._info[this._pos];
},
element : function () {
- var ce = document.createElement;
// First the legend table
- /*
- var table = ce('table');
- var row = ce('tr');
- table.appendChild(tr);
- */
+ var d = document;
+ var table = d.createElement('table');
+ var tr = table.appendChild(d.createElement('thead'))
+ .appendChild(
+ d.createElement('tr')
+ );
+
+ var addCell = function (type, name) {
+ var c = this.appendChild(d.createElement(type))
+ if (name === undefined)
+ return c;
+
+ if (name instanceof Array) {
+ for (var n = 0; n < name.length; n++) {
+ c.appendChild(d.createTextNode(name[n]));
+ if (n !== name.length - 1) {
+ c.appendChild(d.createElement('br'));
+ };
+ };
+ }
+ else {
+ c.appendChild(d.createTextNode(name));
+ };
+ };
+
+ tr.addCell = addCell;
+
+ // Add header information
+ tr.addCell('th', 'Foundry');
+ tr.addCell('th', 'Layer');
+
+ // Add tokens
+ for (var i in this._token) {
+ tr.addCell('th', this.getToken(i));
+ };
+
+ var tbody = table.appendChild(
+ d.createElement('tbody')
+ );
+
+ var foundryList = Object.keys(this._foundry).sort();
+
+ for (var f = 0; f < foundryList.length; f++) {
+ var foundry = foundryList[f];
+ var layerList =
+ Object.keys(this._foundry[foundry]).sort();
+
+ for (var l = 0; l < layerList.length; l++) {
+ var layer = layerList[l];
+ tr = tbody.appendChild(
+ d.createElement('tr')
+ );
+ tr.setAttribute('tabindex', 0);
+ tr.addCell = addCell;
+
+ tr.addCell('th', foundry);
+ tr.addCell('th', layer);
+
+ for (var v = 0; v < this.length(); v++) {
+ tr.addCell(
+ 'td',
+ this.getValue(v, foundry, layer)
+ );
+ };
+ };
+ };
+
+ return table;
}
};
@@ -314,6 +378,6 @@
/*
KorAP.InfoFoundryLayer = {};
KorAP.InfoTree = {};
- KorAP.InfoTable = {};
+ KorAP.MatchTable = {};
*/
}(this.KorAP));