blob: 77d05ec18582e2ff41a2ce93433b132ca2be0a51 [file] [log] [blame]
Akronf5dc5102017-05-16 20:32:57 +02001define(function () {
2 "use strict";
3
4 var svgNS = "http://www.w3.org/2000/svg";
5
6 return {
7 create : function (snippet) {
8 var obj = Object.create(this)._init(snippet);
9 obj._tokens = ["Das", "ist", "ja", "toll"];
10 obj._tokenElements = [];
11 obj._arcs = [
12 { start: 1, end: 3, label: "small" },
13 { start: 3, end: 0, label: "large" }
14 ]
15 obj.maxArc = 200; // maximum height of the bezier control point
16 return obj;
17 },
18
19 _init : function (snippet) {
20 /*
21 var html = document.createElement("div");
22 html.innerHTML = snippet;
23 */
24 return this;
25 },
26
27 // This is a shorthand for SVG element creation
28 _c : function (tag) {
29 return document.createElementNS(svgNS, tag);
30 },
31
32 // Returns the center point of the requesting token
33 _tokenPoint : function (node) {
34 var box = node.getBoundingClientRect();
35 return box.x + (box.width / 2);
36 },
37
38 // Create an arc with a label
39 // Potentially needs a height parameter for stacks
40 _createArc : function (start, end, label) {
41
42 var startPos = this._tokenPoint(this._tokenElements[start]);
43 var endPos = this._tokenPoint(this._tokenElements[end]);
44
45 var y = 0;
46 var g = this._c("g");
47 var p = g.appendChild(this._c("path"));
48
49 // Create arc
50 var middle = Math.abs(endPos - startPos) / 2;
51
52 var cHeight = middle < this.maxArc ? middle : this.maxArc;
53
54 var x = Math.min(startPos, endPos);
55
56 var arc = "M "+ startPos + " " + y +
57 " C " + startPos + " " + (y-cHeight) +
58 " " + endPos + " " + (y-cHeight) +
59 " " + endPos + " " + y;
60 p.setAttribute("d", arc);
61
62 if (label !== undefined) {
63 var labelE = g.appendChild(this._c("text"));
64 labelE.setAttribute("x", x + middle);
65 labelE.setAttribute("y", -1 * cHeight + 10);
66 labelE.setAttribute("text-anchor", "middle");
67 labelE.appendChild(document.createTextNode(label));
68 };
69
70 return g;
71 },
72
73 element : function () {
74 if (this._element !== undefined)
75 return this._element;
76
77 // Create svg
78 var svg = this._c("svg");
79 svg.setAttribute("width", 700);
80 svg.setAttribute("height", 300);
81 this._element = svg;
82 return this._element;
83 },
84
85 // Add a relation with a start, an end,
86 // a direction value and a label text
87 addArc : function (start, end, direction, label) {
88 },
89
90 /*
91 * All arcs need to be sorted before shown,
92 * to avoid nesting.
93 */
94 _sortArcs : function () {
95
96 // 1. Sort by length
97 // 2. Tag all spans with the number of overlaps before
98 // a) Iterate over all spans
99 // b) check the latest preceeding overlapping span (lpos)
100 // -> not found: tag with 0
101 // -> found: Add +1 to the level of the (lpos)
102 // c) If the new tag is smaller than the previous element,
103 // reorder
104 },
105
106 show : function () {
107 var svg = this._element;
108
109 /*
110 * Generate token list
111 */
112 var text = svg.appendChild(this._c("text"));
113 text.setAttribute("y", 135);
114 text.setAttribute("x", 160);
115
116 var lastRight = 0;
117 for (var node_i in this._tokens) {
118 // Append svg
119 var tspan = text.appendChild(this._c("tspan"));
120 tspan.appendChild(document.createTextNode(this._tokens[node_i]));
121
122 this._tokenElements.push(tspan);
123
124 // Add whitespace!
125 text.appendChild(document.createTextNode(" "));
126 };
127
128 this.arcs = svg.appendChild(this._c("g"));
129 this.arcs.classList.add("arcs");
130
131 var textBox = text.getBoundingClientRect();
132
133 this.arcs.setAttribute(
134 "transform",
135 "translate(0," + textBox.y +")"
136 );
137
138 /*
139 * TODO:
140 * Before creating the arcs, the height of the arc
141 * needs to be calculated to make it possible to "stack" arcs.
142 * That means, the arcs need to be presorted, so massively
143 * overlapping arcs are taken first.
144 */
145 for (var i in this._arcs) {
146 var arc = this._arcs[i];
147 this.arcs.appendChild(this._createArc(arc.start, arc.end, arc.label));
148 };
149 }
150 }
151});