Made images downloadable
Change-Id: I5e0d3b7899a8193f1a3ee6048b4f50038ab1a5fb
diff --git a/dev/demo/matchdemo.js b/dev/demo/matchdemo.js
index f5a1b96..7bffc50 100644
--- a/dev/demo/matchdemo.js
+++ b/dev/demo/matchdemo.js
@@ -119,6 +119,4 @@
return cb({ "snippet": snippet });
}
};
-
-
});
diff --git a/dev/js/src/match/info.js b/dev/js/src/match/info.js
index 9d1922a..ef05607 100644
--- a/dev/js/src/match/info.js
+++ b/dev/js/src/match/info.js
@@ -133,21 +133,22 @@
// TODO: Support and cache multiple trees
KorAP.API.getMatchInfo(
- this._match, {
- 'spans' : true,
- 'foundry' : foundry,
- 'layer' : layer
- },
- function (matchResponse) {
- // Get snippet from match info
- if (matchResponse["snippet"] !== undefined) {
- // Todo: This should be cached somehow
- cb(matchTreeClass.create(matchResponse["snippet"]));
- }
- else {
- cb(null);
- };
- }.bind(this)
+ this._match, {
+ 'spans' : true,
+ 'foundry' : foundry,
+ 'layer' : layer
+ },
+ function (matchResponse) {
+ // Get snippet from match info
+ if (matchResponse["snippet"] !== undefined) {
+ // Todo: This should be cached somehow
+
+ cb(matchTreeClass.create(matchResponse["snippet"]));
+ }
+ else {
+ cb(null);
+ };
+ }.bind(this)
);
},
@@ -181,17 +182,21 @@
.appendChild(document.createTextNode(layer));
var tree = matchtree.appendChild(
- document.createElement('div')
+ document.createElement('div')
);
this._element.insertBefore(matchtree, this._element.lastChild);
- var close = tree.appendChild(document.createElement('em'));
+ var actions = tree.appendChild(document.createElement('ul'));
+ actions.classList.add('action', 'image');
+ var close = actions.appendChild(document.createElement('li'));
+ close.className = 'close';
+ close.appendChild(document.createElement('span'));
close.addEventListener(
- 'click', function (e) {
- matchtree.parentNode.removeChild(matchtree);
- e.halt();
- }
+ 'click', function (e) {
+ matchtree.parentNode.removeChild(matchtree);
+ e.halt();
+ }
);
tree.classList.add('loading');
@@ -199,25 +204,44 @@
// Get tree data async
this.getTree(foundry, layer, function (treeObj) {
- tree.classList.remove('loading');
+ tree.classList.remove('loading');
- // Something went wrong - probably log!!!
+ // Something went wrong - probably log!!!
- if (treeObj === null) {
- tree.appendChild(document.createTextNode('No data available.'));
- }
- else {
- tree.appendChild(treeObj.element());
- // 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)
- treeObj.center();
- };
+ if (treeObj === null) {
+ tree.appendChild(document.createTextNode('No data available.'));
+ }
+ else {
+ tree.appendChild(treeObj.element());
+ // 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) {
+
+ 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();
+ };
- if (cb !== undefined)
- cb(treeObj);
-
+ if (cb !== undefined)
+ cb(treeObj);
});
},
@@ -227,7 +251,7 @@
element : function () {
if (this._element !== undefined)
- return this._element;
+ return this._element;
// Create info table
var info = document.createElement('div');
diff --git a/dev/js/src/match/tree.js b/dev/js/src/match/tree.js
index 5e39a1a..c5ae923 100644
--- a/dev/js/src/match/tree.js
+++ b/dev/js/src/match/tree.js
@@ -35,25 +35,25 @@
*/
create : function (snippet) {
return Object.create(this).
- _init(snippet);
+ _init(snippet);
},
// Initialize the tree based on a snippet.
_init : function (snippet) {
this._next = new Number(0);
-
+
// Create html for traversal
var html = document.createElement("div");
html.innerHTML = snippet;
var g = new dagre.graphlib.Graph({
- "directed" : true
+ "directed" : true
});
g.setGraph({
- "nodesep" : 35,
- "ranksep" : 15,
- "marginx" : 40,
- "marginy" : 10
+ "nodesep" : 35,
+ "ranksep" : 15,
+ "marginx" : 40,
+ "marginy" : 10
});
g.setDefaultEdgeLabel({});
@@ -61,8 +61,8 @@
// This is a new root
this._addNode(
- this._next++,
- { "class" : "root" }
+ this._next++,
+ { "class" : "root" }
);
// Parse nodes from root
@@ -70,7 +70,7 @@
// Root node has only one child - remove
if (g.outEdges(0).length === 1)
- g.removeNode(0);
+ g.removeNode(0);
html = undefined;
return this;
@@ -104,60 +104,60 @@
// Parse the snippet
_parse : function (parent, children, mark) {
for (var i in children) {
- var c = children[i];
+ var c = children[i];
- // Element node
- if (c.nodeType == 1) {
+ // Element node
+ if (c.nodeType == 1) {
- // Get title from html
- if (c.getAttribute("title")) {
- var title = this._clean(c.getAttribute("title"));
+ // Get title from html
+ if (c.getAttribute("title")) {
+ var title = this._clean(c.getAttribute("title"));
- // Add child node
- var id = this._next++;
+ // Add child node
+ var id = this._next++;
- var obj = this._addNode(id, {
- "class" : "middle",
- "label" : title
- });
+ var obj = this._addNode(id, {
+ "class" : "middle",
+ "label" : title
+ });
if (mark !== undefined) {
obj.class += ' mark';
};
- this._addEdge(parent, id);
+ this._addEdge(parent, id);
- // Check for next level
- if (c.hasChildNodes())
- this._parse(id, c.childNodes, mark);
- }
+ // Check for next level
+ if (c.hasChildNodes())
+ this._parse(id, c.childNodes, mark);
+ }
- // Step further
- else if (c.hasChildNodes()) {
+ // Step further
+ else if (c.hasChildNodes()) {
if (c.tagName === 'MARK') {
- this._parse(parent, c.childNodes, true);
+ this._parse(parent, c.childNodes, true);
}
else {
- this._parse(parent, c.childNodes, mark);
+ this._parse(parent, c.childNodes, mark);
};
};
- }
+ }
- // Text node
- else if (c.nodeType == 3)
+ // Text node
+ else if (c.nodeType == 3)
- if (c.nodeValue.match(/[-a-z0-9]/i)) {
+ if (c.nodeValue.match(/[-a-z0-9]/i)) {
- // Add child node
- var id = this._next++;
- this._addNode(id, {
- "class" : "leaf",
- "label" : c.nodeValue
- });
+ // Add child node
+ var id = this._next++;
+ this._addNode(id, {
+ "class" : "leaf",
+ "label" : c.nodeValue
+ });
- this._addEdge(parent, id);
- };
+ this._addEdge(parent, id);
+ };
};
return this;
},
@@ -167,7 +167,7 @@
*/
center : function () {
if (this._element === undefined)
- return;
+ return;
var treeDiv = this._element.parentNode;
@@ -175,22 +175,27 @@
var treeWidth = parseFloat(window.getComputedStyle(treeDiv).width);
// Reposition:
if (cWidth > treeWidth) {
- var scrollValue = (cWidth - treeWidth) / 2;
- treeDiv.scrollLeft = scrollValue;
+ var scrollValue = (cWidth - treeWidth) / 2;
+ treeDiv.scrollLeft = scrollValue;
};
},
+
+ toBase64 : function () {
+ return btoa(unescape(encodeURIComponent(this.element().outerHTML)));
+ },
+
/**
* Get the dom element of the tree view.
*/
element : function () {
if (this._element !== undefined)
- return this._element;
+ return this._element;
var g = this._graph;
dagre.layout(g);
-
+
var canvas = document.createElementNS(svgXmlns, 'svg');
this._element = canvas;
@@ -198,82 +203,82 @@
// Create edges
g.edges().forEach(
- function (e) {
- var src = g.node(e.v);
- var target = g.node(e.w);
- var p = document.createElementNS(svgXmlns, 'path');
- p.setAttributeNS(null, "d", _line(src, target));
- p.classList.add('edge');
- canvas.appendChild(p);
- });
+ function (e) {
+ var src = g.node(e.v);
+ var target = g.node(e.w);
+ var p = document.createElementNS(svgXmlns, 'path');
+ p.setAttributeNS(null, "d", _line(src, target));
+ p.classList.add('edge');
+ canvas.appendChild(p);
+ });
// Create nodes
g.nodes().forEach(
- function (v) {
- v = g.node(v);
- var group = document.createElementNS(svgXmlns, 'g');
- group.setAttribute('class', v.class);
+ function (v) {
+ v = g.node(v);
+ var group = document.createElementNS(svgXmlns, 'g');
+ group.setAttribute('class', v.class);
+
+ // Add node box
+ var rect = group.appendChild(document.createElementNS(svgXmlns, 'rect'));
+ rect.setAttribute('x', v.x - v.width / 2);
+ rect.setAttribute('y', v.y - v.height / 2);
+ rect.setAttribute('rx', 5);
+ rect.setAttribute('ry', 5);
+ rect.setAttribute('width', v.width);
+ rect.setAttribute('height', v.height);
- // Add node box
- var rect = group.appendChild(document.createElementNS(svgXmlns, 'rect'));
- rect.setAttribute('x', v.x - v.width / 2);
- rect.setAttribute('y', v.y - v.height / 2);
- rect.setAttribute('rx', 5);
- rect.setAttribute('ry', 5);
- rect.setAttribute('width', v.width);
- rect.setAttribute('height', v.height);
+ if (v.class === 'root' && v.label === undefined) {
+ rect.setAttribute('width', v.height);
+ rect.setAttribute('x', v.x - v.height / 2);
+ rect.setAttribute('class', 'empty');
+ };
- if (v.class === 'root' && v.label === undefined) {
- rect.setAttribute('width', v.height);
- rect.setAttribute('x', v.x - v.height / 2);
- rect.setAttribute('class', 'empty');
- };
+ // Add label
+ if (v.label !== undefined) {
+ var text = group.appendChild(document.createElementNS(svgXmlns, 'text'));
+ var y = v.y - v.height / 2;
+ text.setAttribute('y', y);
+ text.setAttribute(
+ 'transform',
+ 'translate(' + v.width/2 + ',' + ((v.height / 2) + 5) + ')'
+ );
+
+ if (v.class === "leaf") {
+ text.setAttribute('title', v.label);
- // Add label
- if (v.label !== undefined) {
- var text = group.appendChild(document.createElementNS(svgXmlns, 'text'));
- var y = v.y - v.height / 2;
- text.setAttribute('y', y);
- text.setAttribute(
- 'transform',
- 'translate(' + v.width/2 + ',' + ((v.height / 2) + 5) + ')'
- );
+ var labelPart = v.label.split(" ");
+ var n = 0;
+ for (var i = 0; i < labelPart.length; i++) {
+ if (labelPart[i].length === 0)
+ continue;
- if (v.class === "leaf") {
- text.setAttribute('title', v.label);
+ var tspan = document.createElementNS(svgXmlns, 'tspan');
+ tspan.appendChild(document.createTextNode(labelPart[i]));
+ if (n !== 0)
+ tspan.setAttribute('dy', LINEHEIGHT + 'pt');
+ else
+ n = 1;
+ tspan.setAttribute('x', v.x - v.width / 2);
+ y += LINEHEIGHT;
+ text.appendChild(tspan);
+ };
- var labelPart = v.label.split(" ");
- var n = 0;
- for (var i = 0; i < labelPart.length; i++) {
- if (labelPart[i].length === 0)
- continue;
+ y += LINEHEIGHT;
- var tspan = document.createElementNS(svgXmlns, 'tspan');
- tspan.appendChild(document.createTextNode(labelPart[i]));
- if (n !== 0)
- tspan.setAttribute('dy', LINEHEIGHT + 'pt');
- else
- n = 1;
- tspan.setAttribute('x', v.x - v.width / 2);
- y += LINEHEIGHT;
- text.appendChild(tspan);
- };
-
- y += LINEHEIGHT;
-
- // The text is below the canvas - readjust the height!
- if (y > height)
- height = y;
- }
- else {
- var tspan = document.createElementNS(svgXmlns, 'tspan');
- tspan.appendChild(document.createTextNode(v.label));
- tspan.setAttribute('x', v.x - v.width / 2);
- text.appendChild(tspan);
- };
- };
- canvas.appendChild(group);
- }
+ // The text is below the canvas - readjust the height!
+ if (y > height)
+ height = y;
+ }
+ else {
+ var tspan = document.createElementNS(svgXmlns, 'tspan');
+ tspan.appendChild(document.createTextNode(v.label));
+ tspan.setAttribute('x', v.x - v.width / 2);
+ text.appendChild(tspan);
+ };
+ };
+ canvas.appendChild(group);
+ }
);
canvas.setAttribute('width', g.graph().width);
diff --git a/dev/scss/main/matchinfo.scss b/dev/scss/main/matchinfo.scss
index ef867b2..2f74d66 100644
--- a/dev/scss/main/matchinfo.scss
+++ b/dev/scss/main/matchinfo.scss
@@ -187,24 +187,40 @@
margin-right: $right-match-distance;
background-color: $light-orange; // $nearly-white; // $light-orange;
- > em {
- color: $nearly-white;
- cursor: pointer;
+ > ul.action.image {
display: block;
position: absolute;
right: 0px;
top: 0px;
+ z-index: 20;
+ /*
+ margin: 0;
+ padding: 0;
+ */
width: $right-match-distance;
- border-width: 0;
- z-index: 8;
- text-decoration:none;
- text-align: center;
- font-weight: bold;
- font-style: normal;
+ li {
+ cursor: pointer;
+ color: $nearly-white;
+ text-decoration: none;
+ > span {
+ @include blind;
+ }
+ border-width: 0;
+ // z-index: 8;
+ text-decoration:none;
+ text-align: center;
+ font-weight: bold;
+ font-style: normal;
- &::after {
- font-family: 'FontAwesome';
- content: $fa-close;
+ &.download::after {
+ font-family: 'FontAwesome';
+ content: $fa-download;
+ }
+
+ &.close::after {
+ font-family: 'FontAwesome';
+ content: $fa-close;
+ }
}
}
}
diff --git a/dev/scss/util.scss b/dev/scss/util.scss
index a33644a..ed737f1 100644
--- a/dev/scss/util.scss
+++ b/dev/scss/util.scss
@@ -216,6 +216,7 @@
$fa-up: "\f0d8";
$fa-down: "\f0d7";
$fa-close: "\f00d";
+$fa-download: "\f019";
$fa-info: "\f05a";
$fa-elipsis: "\f141";
$fa-previous: "\f0d9";