nickjillings@2131
|
1 /*
|
nicholas@2538
|
2 * Analysis script for WAET
|
nicholas@2538
|
3 */
|
nickjillings@2131
|
4
|
nickjillings@2192
|
5 // Firefox does not have an XMLDocument.prototype.getElementsByName
|
nickjillings@2192
|
6 // and there is no searchAll style command, this custom function will
|
nickjillings@2192
|
7 // search all children recusrively for the name. Used for XSD where all
|
nickjillings@2192
|
8 // element nodes must have a name and therefore can pull the schema node
|
nicholas@2538
|
9 XMLDocument.prototype.getAllElementsByName = function (name) {
|
nickjillings@2192
|
10 name = String(name);
|
nickjillings@2192
|
11 var selected = this.documentElement.getAllElementsByName(name);
|
nickjillings@2192
|
12 return selected;
|
nickjillings@2192
|
13 }
|
nickjillings@2192
|
14
|
nicholas@2538
|
15 Element.prototype.getAllElementsByName = function (name) {
|
nickjillings@2192
|
16 name = String(name);
|
nickjillings@2192
|
17 var selected = [];
|
nickjillings@2192
|
18 var node = this.firstElementChild;
|
nicholas@2538
|
19 while (node != null) {
|
nicholas@2538
|
20 if (node.getAttribute('name') == name) {
|
nickjillings@2192
|
21 selected.push(node);
|
nickjillings@2192
|
22 }
|
nicholas@2538
|
23 if (node.childElementCount > 0) {
|
nickjillings@2192
|
24 selected = selected.concat(node.getAllElementsByName(name));
|
nickjillings@2192
|
25 }
|
nickjillings@2192
|
26 node = node.nextElementSibling;
|
nickjillings@2192
|
27 }
|
nickjillings@2192
|
28 return selected;
|
nickjillings@2192
|
29 }
|
nickjillings@2192
|
30
|
nicholas@2538
|
31 XMLDocument.prototype.getAllElementsByTagName = function (name) {
|
nickjillings@2192
|
32 name = String(name);
|
nickjillings@2192
|
33 var selected = this.documentElement.getAllElementsByTagName(name);
|
nickjillings@2192
|
34 return selected;
|
nickjillings@2192
|
35 }
|
nickjillings@2192
|
36
|
nicholas@2538
|
37 Element.prototype.getAllElementsByTagName = function (name) {
|
nickjillings@2192
|
38 name = String(name);
|
nickjillings@2192
|
39 var selected = [];
|
nickjillings@2192
|
40 var node = this.firstElementChild;
|
nicholas@2538
|
41 while (node != null) {
|
nicholas@2538
|
42 if (node.nodeName == name) {
|
nickjillings@2192
|
43 selected.push(node);
|
nickjillings@2192
|
44 }
|
nicholas@2538
|
45 if (node.childElementCount > 0) {
|
nickjillings@2192
|
46 selected = selected.concat(node.getAllElementsByTagName(name));
|
nickjillings@2192
|
47 }
|
nickjillings@2192
|
48 node = node.nextElementSibling;
|
nickjillings@2192
|
49 }
|
nickjillings@2192
|
50 return selected;
|
nickjillings@2192
|
51 }
|
nickjillings@2192
|
52
|
nickjillings@2192
|
53 // Firefox does not have an XMLDocument.prototype.getElementsByName
|
nickjillings@2192
|
54 if (typeof XMLDocument.prototype.getElementsByName != "function") {
|
nicholas@2538
|
55 XMLDocument.prototype.getElementsByName = function (name) {
|
nickjillings@2192
|
56 name = String(name);
|
nickjillings@2192
|
57 var node = this.documentElement.firstElementChild;
|
nickjillings@2192
|
58 var selected = [];
|
nicholas@2538
|
59 while (node != null) {
|
nicholas@2538
|
60 if (node.getAttribute('name') == name) {
|
nickjillings@2192
|
61 selected.push(node);
|
nickjillings@2192
|
62 }
|
nickjillings@2192
|
63 node = node.nextElementSibling;
|
nickjillings@2192
|
64 }
|
nickjillings@2192
|
65 return selected;
|
nickjillings@2192
|
66 }
|
nickjillings@2192
|
67 }
|
nickjillings@2192
|
68
|
nickjillings@2192
|
69 var chartContext, testData;
|
nicholas@2538
|
70 window.onload = function () {
|
nickjillings@2131
|
71 // Load the Visualization API and the corechart package.
|
nicholas@2538
|
72 google.charts.load('current', {
|
nicholas@2538
|
73 'packages': ['corechart']
|
nicholas@2538
|
74 });
|
nickjillings@2131
|
75 chartContext = new Chart();
|
nickjillings@2192
|
76 testData = new Data();
|
nickjillings@2192
|
77 }
|
nickjillings@2192
|
78
|
nickjillings@2192
|
79 function get(url) {
|
nicholas@2538
|
80 // Return a new promise.
|
nicholas@2538
|
81 return new Promise(function (resolve, reject) {
|
nicholas@2538
|
82 // Do the usual XHR stuff
|
nicholas@2538
|
83 var req = new XMLHttpRequest();
|
nicholas@2538
|
84 req.open('GET', url);
|
nicholas@2538
|
85 req.onload = function () {
|
nicholas@2538
|
86 // This is called even on 404 etc
|
nicholas@2538
|
87 // so check the status
|
nicholas@2538
|
88 if (req.status == 200) {
|
nicholas@2538
|
89 // Resolve the promise with the response text
|
nicholas@2538
|
90 resolve(req.response);
|
nicholas@2538
|
91 } else {
|
nicholas@2538
|
92 // Otherwise reject with the status text
|
nicholas@2538
|
93 // which will hopefully be a meaningful error
|
nicholas@2538
|
94 reject(Error(req.statusText));
|
nicholas@2538
|
95 }
|
nicholas@2538
|
96 };
|
nickjillings@2192
|
97
|
nicholas@2538
|
98 // Handle network errors
|
nicholas@2538
|
99 req.onerror = function () {
|
nicholas@2538
|
100 reject(Error("Network Error"));
|
nicholas@2538
|
101 };
|
nickjillings@2192
|
102
|
nicholas@2538
|
103 // Make the request
|
nicholas@2538
|
104 req.send();
|
nicholas@2538
|
105 });
|
nickjillings@2131
|
106 }
|
nickjillings@2131
|
107
|
nickjillings@2135
|
108 function arrayMean(values) {
|
nickjillings@2135
|
109 var mean = 0;
|
nickjillings@2135
|
110 for (var value of values) {
|
nickjillings@2135
|
111 mean += value;
|
nickjillings@2135
|
112 }
|
nickjillings@2135
|
113 mean /= values.length;
|
nickjillings@2135
|
114 return mean;
|
nickjillings@2135
|
115 }
|
nickjillings@2135
|
116
|
nickjillings@2183
|
117 function percentile(values, p) {
|
nickjillings@2183
|
118 //http://web.stanford.edu/class/archive/anthsci/anthsci192/anthsci192.1064/handouts/calculating%20percentiles.pdf
|
nicholas@2538
|
119 values.sort(function (a, b) {
|
nicholas@2538
|
120 return a - b;
|
nicholas@2538
|
121 });
|
nickjillings@2135
|
122 // get ordinal rank
|
nicholas@2538
|
123 var index = values.length * p / 100;
|
nickjillings@2183
|
124 var k = Math.floor(index);
|
nickjillings@2183
|
125 if (k == index) {
|
nickjillings@2183
|
126 return values[k];
|
nickjillings@2183
|
127 } else {
|
nicholas@2538
|
128 var f = index - k;
|
nicholas@2538
|
129 var x_int = (1 - f) * values[k] + f * values[k + 1];
|
nickjillings@2183
|
130 return x_int;
|
nickjillings@2183
|
131 }
|
nickjillings@2135
|
132 }
|
nickjillings@2135
|
133
|
nickjillings@2135
|
134 function arrayMin(array) {
|
nickjillings@2135
|
135 // Return the minimum value of an array
|
nickjillings@2135
|
136 var min = array[0];
|
nickjillings@2135
|
137 for (var value of array) {
|
nickjillings@2135
|
138 if (value < min) {
|
nickjillings@2135
|
139 min = value;
|
nickjillings@2135
|
140 }
|
nickjillings@2135
|
141 }
|
nickjillings@2135
|
142 return min;
|
nickjillings@2135
|
143 }
|
nickjillings@2135
|
144
|
nickjillings@2135
|
145 function arrayMax(array) {
|
nickjillings@2135
|
146 // Return the minimum value of an array
|
nickjillings@2135
|
147 var max = array[0];
|
nickjillings@2135
|
148 for (var value of array) {
|
nickjillings@2135
|
149 if (value > max) {
|
nickjillings@2135
|
150 max = value;
|
nickjillings@2135
|
151 }
|
nickjillings@2135
|
152 }
|
nickjillings@2135
|
153 return max;
|
nickjillings@2135
|
154 }
|
nickjillings@2135
|
155
|
nickjillings@2181
|
156 function boxplotRow(array) {
|
nickjillings@2181
|
157 // Take an array of element values and return array of computed intervals
|
nickjillings@2181
|
158 var result = {
|
nicholas@2538
|
159 median: percentile(array, 50),
|
nicholas@2538
|
160 pct25: percentile(array, 25),
|
nicholas@2538
|
161 pct75: percentile(array, 75),
|
nicholas@2538
|
162 IQR: null,
|
nickjillings@2181
|
163 min: null,
|
nickjillings@2181
|
164 max: null,
|
nickjillings@2181
|
165 outliers: new Array()
|
nickjillings@2181
|
166 }
|
nicholas@2538
|
167 result.IQR = result.pct75 - result.pct25;
|
nickjillings@2181
|
168 var rest = [];
|
nicholas@2538
|
169 var pct75_IQR = result.pct75 + 1.5 * result.IQR;
|
nicholas@2538
|
170 var pct25_IQR = result.pct25 - 1.5 * result.IQR;
|
nicholas@2538
|
171 for (var i = 0; i < array.length; i++) {
|
nickjillings@2181
|
172 //outliers, ranger above pct75+1.5*IQR or below pct25-1.5*IQR
|
nickjillings@2181
|
173 var point = array[i];
|
nickjillings@2181
|
174 if (point > pct75_IQR || point < pct25_IQR) {
|
nickjillings@2181
|
175 result.outliers.push(point);
|
nickjillings@2181
|
176 } else {
|
nickjillings@2181
|
177 rest.push(point);
|
nickjillings@2181
|
178 }
|
nickjillings@2181
|
179 }
|
nickjillings@2181
|
180 result.max = arrayMax(rest);
|
nickjillings@2181
|
181 result.min = arrayMin(rest);
|
nickjillings@2181
|
182 return result;
|
nicholas@2538
|
183
|
nickjillings@2181
|
184 }
|
nickjillings@2181
|
185
|
nicholas@2538
|
186 function arrayHistogram(values, steps, min, max) {
|
nickjillings@2135
|
187 if (steps == undefined) {
|
nickjillings@2135
|
188 steps = 0.25;
|
nickjillings@2135
|
189 console.log("Warning: arrayHistogram called without steps size set, default to 0.25");
|
nickjillings@2135
|
190 }
|
nicholas@2538
|
191 if (min == undefined) {
|
nicholas@2538
|
192 min = arrayMin(values);
|
nicholas@2538
|
193 }
|
nicholas@2538
|
194 if (max == undefined) {
|
nicholas@2538
|
195 max = arrayMax(values);
|
nicholas@2538
|
196 }
|
nickjillings@2135
|
197 var histogram = [];
|
nickjillings@2135
|
198 var index = min;
|
nicholas@2538
|
199 while (index < max) {
|
nickjillings@2135
|
200 histogram.push({
|
nickjillings@2135
|
201 marker: index,
|
nickjillings@2135
|
202 lt: index,
|
nicholas@2538
|
203 rt: index + steps,
|
nickjillings@2135
|
204 count: 0
|
nickjillings@2135
|
205 });
|
nickjillings@2135
|
206 index += steps;
|
nickjillings@2135
|
207 }
|
nickjillings@2135
|
208 for (var value of values) {
|
nickjillings@2135
|
209 for (var entry of histogram) {
|
nickjillings@2135
|
210 if (value >= entry.lt && value <= entry.rt) {
|
nickjillings@2135
|
211 entry.count++;
|
nickjillings@2135
|
212 break;
|
nickjillings@2135
|
213 }
|
nickjillings@2135
|
214 }
|
nickjillings@2135
|
215 }
|
nickjillings@2135
|
216 return histogram;
|
nickjillings@2135
|
217 }
|
nickjillings@2135
|
218
|
nickjillings@2131
|
219 function Chart() {
|
nickjillings@2192
|
220 this.valueData;
|
nickjillings@2135
|
221 this.charts = [];
|
nicholas@2538
|
222
|
nicholas@2538
|
223 this.chartObject = function (name) {
|
nickjillings@2135
|
224 // Create the charting object
|
nickjillings@2135
|
225 this.name = name;
|
nickjillings@2135
|
226 this.root = document.createElement("div");
|
nickjillings@2135
|
227 this.root.className = "chart-holder";
|
nicholas@2538
|
228 this.root.setAttribute("name", name);
|
nickjillings@2135
|
229 this.chartDOM = document.createElement("div");
|
nickjillings@2135
|
230 this.tableDOM = document.createElement("div");
|
nickjillings@2135
|
231 this.latexDOM = document.createElement("div");
|
nickjillings@2135
|
232 this.downloadDOM = document.createElement("div");
|
nickjillings@2135
|
233 this.chart = undefined;
|
nickjillings@2135
|
234 this.data = new google.visualization.DataTable();
|
nickjillings@2135
|
235 this.options = {};
|
nickjillings@2135
|
236 this.print = document.createElement("button");
|
nickjillings@2136
|
237 this.sortDataButton = document.createElement("button");
|
nickjillings@2136
|
238 this.sortDataButton.textContent = "Sort by Data";
|
nicholas@2538
|
239 this.sortDataButton.addEventListener("click", this);
|
nicholas@2538
|
240 this.sortDataButton.setAttribute("name", "sort-data");
|
nickjillings@2136
|
241 this.sortNameButton = document.createElement("button");
|
nickjillings@2136
|
242 this.sortNameButton.textContent = "Sort by Name";
|
nicholas@2538
|
243 this.sortNameButton.addEventListener("click", this);
|
nicholas@2538
|
244 this.sortNameButton.setAttribute("name", "sort-name");
|
nicholas@2538
|
245 this.draw = function () {
|
nicholas@2538
|
246 if (this.chart == undefined) {
|
nicholas@2538
|
247 return;
|
nicholas@2538
|
248 }
|
nickjillings@2136
|
249 this.tableDOM.innerHTML = null;
|
nickjillings@2136
|
250 this.latexDOM.innerHTML = null;
|
nickjillings@2136
|
251 this.buildTable();
|
nickjillings@2136
|
252 this.writeLatex();
|
nicholas@2538
|
253 this.chart.draw(this.data, this.options);
|
nickjillings@2136
|
254 }
|
nicholas@2538
|
255 this.sortData = function () {
|
nickjillings@2173
|
256 this.data.sort(1);
|
nickjillings@2136
|
257 }
|
nicholas@2538
|
258 this.sortName = function () {
|
nickjillings@2173
|
259 this.data.sort(0);
|
nickjillings@2136
|
260 }
|
nicholas@2538
|
261 this.handleEvent = function () {
|
nickjillings@2135
|
262 // Only used to handle the chart.event.addListener(this,'ready') callback
|
nicholas@2538
|
263 switch (event.currentTarget.getAttribute("name")) {
|
nickjillings@2136
|
264 case "download":
|
nickjillings@2136
|
265 window.open(this.chart.getImageURI());
|
nickjillings@2136
|
266 break;
|
nickjillings@2136
|
267 case "sort-data":
|
nickjillings@2136
|
268 this.sortData();
|
nickjillings@2136
|
269 this.draw();
|
nickjillings@2136
|
270 break;
|
nickjillings@2136
|
271 case "sort-name":
|
nickjillings@2136
|
272 this.sortName();
|
nickjillings@2136
|
273 this.draw();
|
nickjillings@2136
|
274 break;
|
nickjillings@2136
|
275 }
|
nickjillings@2135
|
276 }
|
nicholas@2538
|
277
|
nickjillings@2135
|
278 this.root.appendChild(this.chartDOM);
|
nickjillings@2135
|
279 this.root.appendChild(this.tableDOM);
|
nickjillings@2135
|
280 this.root.appendChild(this.latexDOM);
|
nickjillings@2136
|
281 this.root.appendChild(this.sortDataButton);
|
nickjillings@2136
|
282 this.root.appendChild(this.sortNameButton);
|
nickjillings@2135
|
283 this.root.appendChild(this.print);
|
nickjillings@2135
|
284 this.print.textContent = "Download";
|
nicholas@2538
|
285 this.print.setAttribute("name", "download");
|
nicholas@2538
|
286 this.print.addEventListener("click", this);
|
nickjillings@2135
|
287 this.root.appendChild(this.downloadDOM);
|
nicholas@2538
|
288 this.buildTable = function () {
|
nickjillings@2135
|
289 var table = document.createElement("table");
|
nickjillings@2135
|
290 table.border = "1";
|
nickjillings@2172
|
291 var numRows = this.data.getNumberOfRows();
|
nickjillings@2172
|
292 var numColumns = this.data.getNumberOfColumns();
|
nicholas@2538
|
293 for (var columnIndex = 0; columnIndex < numColumns; columnIndex++) {
|
nickjillings@2181
|
294 var tableTitle = this.data.getColumnLabel(columnIndex);
|
nickjillings@2181
|
295 if (tableTitle != "") {
|
nickjillings@2181
|
296 var table_row = document.createElement('tr');
|
nickjillings@2181
|
297 table.appendChild(table_row);
|
nickjillings@2181
|
298 var row_title = document.createElement('td');
|
nickjillings@2181
|
299 table_row.appendChild(row_title);
|
nickjillings@2181
|
300 row_title.textContent = tableTitle;
|
nicholas@2538
|
301 for (var rowIndex = 0; rowIndex < numRows; rowIndex++) {
|
nickjillings@2181
|
302 var row_entry = document.createElement('td');
|
nickjillings@2181
|
303 table_row.appendChild(row_entry);
|
nicholas@2538
|
304 var entry = this.data.getValue(rowIndex, columnIndex);
|
nicholas@2538
|
305 if (isFinite(Number(entry))) {
|
nickjillings@2181
|
306 entry = String(Number(entry).toFixed(4));
|
nickjillings@2181
|
307 }
|
nickjillings@2181
|
308 row_entry.textContent = entry;
|
nickjillings@2172
|
309 }
|
nickjillings@2135
|
310 }
|
nickjillings@2135
|
311 }
|
nickjillings@2135
|
312 this.tableDOM.appendChild(table);
|
nickjillings@2135
|
313 };
|
nicholas@2538
|
314 this.writeLatex = function () {
|
nickjillings@2172
|
315 var numRows = this.data.getNumberOfRows();
|
nickjillings@2172
|
316 var numColumns = this.data.getNumberOfColumns();
|
nickjillings@2135
|
317 var root = document.createElement("div");
|
nickjillings@2135
|
318 root.className = "code";
|
nickjillings@2135
|
319 var holder = document.createElement("pre");
|
nickjillings@2135
|
320 // Table start
|
nickjillings@2135
|
321 var start = document.createElement("p");
|
nickjillings@2135
|
322 start.textContent = "\\" + "begin{tabular}{|l|";
|
nickjillings@2135
|
323 holder.appendChild(start);
|
nicholas@2538
|
324 for (var i = 0; i < numRows; i++) {
|
nicholas@2538
|
325 start.textContent = start.textContent + "c|";
|
nickjillings@2135
|
326 }
|
nickjillings@2136
|
327 start.textContent = start.textContent.concat("}");
|
nickjillings@2135
|
328 // Now write the rows:
|
nicholas@2538
|
329 for (var rIndex = 0; rIndex < numColumns; rIndex++) {
|
nickjillings@2181
|
330 var tableTitle = this.data.getColumnLabel(rIndex);
|
nicholas@2538
|
331 if (tableTitle != "") {
|
nickjillings@2181
|
332 var row = document.createElement("p");
|
nickjillings@2181
|
333 row.textContent = tableTitle.concat(" & ");
|
nicholas@2538
|
334 for (var cIndex = 0; cIndex < numRows; cIndex++) {
|
nicholas@2538
|
335 var entry = this.data.getValue(cIndex, rIndex);
|
nicholas@2538
|
336 if (isFinite(Number(entry))) {
|
nickjillings@2181
|
337 entry = String(Number(entry).toFixed(4));
|
nickjillings@2181
|
338 }
|
nickjillings@2181
|
339 row.textContent = row.textContent.concat(entry);
|
nicholas@2538
|
340 if (cIndex < numRows - 1) {
|
nickjillings@2181
|
341 row.textContent = row.textContent.concat(" & ");
|
nickjillings@2181
|
342 } else {
|
nickjillings@2181
|
343 row.textContent = row.textContent.concat(" \\\\ \\hline");
|
nickjillings@2181
|
344 }
|
nickjillings@2172
|
345 }
|
nickjillings@2181
|
346 holder.appendChild(row);
|
nickjillings@2135
|
347 }
|
nickjillings@2135
|
348 }
|
nickjillings@2135
|
349 // Table end
|
nickjillings@2135
|
350 var end = document.createElement("p");
|
nickjillings@2135
|
351 end.textContent = "\\" + "end{tabular}";
|
nickjillings@2135
|
352 holder.appendChild(end);
|
nickjillings@2135
|
353 root.appendChild(holder);
|
nickjillings@2135
|
354 this.latexDOM.appendChild(root);
|
nickjillings@2135
|
355 }
|
nickjillings@2135
|
356 }
|
nicholas@2538
|
357
|
nicholas@2538
|
358 this.clear = function () {
|
nickjillings@2135
|
359 var inject = document.getElementById("test-pages");
|
nickjillings@2135
|
360 for (var chart of this.charts) {
|
nickjillings@2135
|
361 inject.removeChild(chart.root);
|
nickjillings@2135
|
362 }
|
nickjillings@2135
|
363 this.charts = [];
|
nickjillings@2135
|
364 }
|
nicholas@2538
|
365
|
nicholas@2538
|
366 this.drawTestMean = function () {
|
nickjillings@2135
|
367 // This draws one bargraph per axis with every test element on
|
nickjillings@2135
|
368 if (this.valueData == null) {
|
nickjillings@2135
|
369 console.log("Error - Data not loaded");
|
nickjillings@2135
|
370 return;
|
nickjillings@2135
|
371 }
|
nickjillings@2135
|
372 var chartList = [];
|
nicholas@2538
|
373
|
nickjillings@2135
|
374 // Create the data table
|
nickjillings@2135
|
375 for (var page of this.valueData.pages) {
|
nickjillings@2135
|
376 for (var element of page.elements) {
|
nickjillings@2135
|
377 for (var axis of element.axis) {
|
nickjillings@2135
|
378 // Find the axis
|
nicholas@2538
|
379 var axisChart = chartList.find(function (element, index, array) {
|
nicholas@2538
|
380 if (element.name == this) {
|
nicholas@2538
|
381 return true;
|
nicholas@2538
|
382 } else {
|
nicholas@2538
|
383 return false;
|
nicholas@2538
|
384 }
|
nicholas@2538
|
385 }, "mean-test-" + axis.name);
|
nickjillings@2135
|
386 if (axisChart == null) {
|
nicholas@2538
|
387 axisChart = new this.chartObject("mean-test-" + axis.name);
|
nickjillings@2135
|
388 axisChart.options = {
|
nicholas@2538
|
389 'title': 'Mean of axis: ' + axis.name,
|
nicholas@2538
|
390 'width': window.innerWidth * 0.9,
|
nicholas@2538
|
391 'height': (window.innerWidth * 0.9) / 1.77
|
nickjillings@2135
|
392 }
|
nicholas@2538
|
393 axisChart.data.addColumn('string', 'id');
|
nicholas@2538
|
394 axisChart.data.addColumn('number', axis.name);
|
nickjillings@2135
|
395 chartList.push(axisChart);
|
nickjillings@2135
|
396 document.getElementById("test-pages").appendChild(axisChart.root);
|
nickjillings@2135
|
397 }
|
nickjillings@2135
|
398 var mean = arrayMean(axis.values);
|
nicholas@2538
|
399 axisChart.data.addRow([element.id, mean]);
|
nickjillings@2135
|
400 }
|
nickjillings@2135
|
401 }
|
nickjillings@2135
|
402 }
|
nicholas@2538
|
403
|
nickjillings@2135
|
404 // Build and push charts
|
nickjillings@2135
|
405 for (var chart of chartList) {
|
nickjillings@2135
|
406 chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
|
nicholas@2538
|
407 chart.chart.draw(chart.data, chart.options);
|
nickjillings@2135
|
408 chart.buildTable();
|
nickjillings@2135
|
409 chart.writeLatex();
|
nickjillings@2135
|
410 this.charts.push(chart);
|
nickjillings@2135
|
411 }
|
nickjillings@2135
|
412 }
|
nicholas@2538
|
413
|
nicholas@2538
|
414 this.drawTestBoxplot = function () {
|
nickjillings@2181
|
415 if (this.valueData == null) {
|
nickjillings@2181
|
416 console.log("Error - Data not loaded");
|
nickjillings@2181
|
417 return;
|
nickjillings@2181
|
418 }
|
nickjillings@2181
|
419 var chartList = [];
|
nicholas@2538
|
420
|
nickjillings@2181
|
421 // Creates one chart per axis
|
nicholas@2538
|
422
|
nickjillings@2181
|
423 // Create the data table
|
nickjillings@2181
|
424 for (var page of this.valueData.pages) {
|
nickjillings@2181
|
425 for (var element of page.elements) {
|
nickjillings@2181
|
426 for (var axis of element.axis) {
|
nickjillings@2181
|
427 // Find the axis
|
nicholas@2538
|
428 var axisChart = chartList.find(function (element, index, array) {
|
nicholas@2538
|
429 if (element.name == this) {
|
nicholas@2538
|
430 return true;
|
nicholas@2538
|
431 } else {
|
nicholas@2538
|
432 return false;
|
nicholas@2538
|
433 }
|
nicholas@2538
|
434 }, "boxplot-test-" + axis.name);
|
nickjillings@2181
|
435 if (axisChart == null) {
|
nickjillings@2181
|
436 // Axis chart doesn't exist
|
nicholas@2538
|
437 axisChart = new this.chartObject("boxplot-test-" + axis.name);
|
nickjillings@2181
|
438 axisChart.options = {
|
nicholas@2538
|
439 'title': 'Boxplot of axis ' + axis.name,
|
nicholas@2538
|
440 'width': window.innerWidth * 0.9,
|
nicholas@2538
|
441 'height': (window.innerWidth * 0.9) / 1.77,
|
nicholas@2538
|
442 legend: {
|
nicholas@2538
|
443 position: 'none'
|
nicholas@2538
|
444 },
|
nickjillings@2181
|
445 lineWidth: 0,
|
nicholas@2538
|
446 series: [{
|
nicholas@2538
|
447 'color': '#D3362D'
|
nicholas@2538
|
448 }],
|
nickjillings@2181
|
449 intervals: {
|
nickjillings@2181
|
450 barWidth: 1,
|
nickjillings@2181
|
451 boxWidth: 1,
|
nickjillings@2181
|
452 lineWidth: 2,
|
nickjillings@2181
|
453 style: 'boxes'
|
nickjillings@2181
|
454 },
|
nickjillings@2181
|
455 interval: {
|
nickjillings@2181
|
456 max: {
|
nickjillings@2181
|
457 style: 'bars',
|
nickjillings@2181
|
458 fillOpacity: 1,
|
nickjillings@2181
|
459 color: '#777'
|
nickjillings@2181
|
460 },
|
nickjillings@2181
|
461 min: {
|
nickjillings@2181
|
462 style: 'bars',
|
nickjillings@2181
|
463 fillOpacity: 1,
|
nickjillings@2181
|
464 color: '#777'
|
nickjillings@2181
|
465 }
|
nickjillings@2181
|
466 }
|
nickjillings@2181
|
467 };
|
nicholas@2538
|
468 axisChart.data.addColumn('string', 'id');
|
nicholas@2538
|
469 axisChart.data.addColumn('number', 'median');
|
nicholas@2538
|
470 axisChart.data.addColumn({
|
nicholas@2538
|
471 id: 'max',
|
nicholas@2538
|
472 type: 'number',
|
nicholas@2538
|
473 role: 'interval'
|
nicholas@2538
|
474 });
|
nicholas@2538
|
475 axisChart.data.addColumn({
|
nicholas@2538
|
476 id: 'min',
|
nicholas@2538
|
477 type: 'number',
|
nicholas@2538
|
478 role: 'interval'
|
nicholas@2538
|
479 });
|
nicholas@2538
|
480 axisChart.data.addColumn({
|
nicholas@2538
|
481 id: 'firstQuartile',
|
nicholas@2538
|
482 type: 'number',
|
nicholas@2538
|
483 role: 'interval'
|
nicholas@2538
|
484 });
|
nicholas@2538
|
485 axisChart.data.addColumn({
|
nicholas@2538
|
486 id: 'median',
|
nicholas@2538
|
487 type: 'number',
|
nicholas@2538
|
488 role: 'interval'
|
nicholas@2538
|
489 });
|
nicholas@2538
|
490 axisChart.data.addColumn({
|
nicholas@2538
|
491 id: 'thirdQuartile',
|
nicholas@2538
|
492 type: 'number',
|
nicholas@2538
|
493 role: 'interval'
|
nicholas@2538
|
494 });
|
nickjillings@2181
|
495 chartList.push(axisChart);
|
nickjillings@2181
|
496 document.getElementById("test-pages").appendChild(axisChart.root);
|
nickjillings@2181
|
497 }
|
nickjillings@2181
|
498 var result = boxplotRow(axis.values);
|
nicholas@2538
|
499 axisChart.data.addRow([element.id, result.median, result.max, result.min, result.pct25, result.median, result.pct75]);
|
nickjillings@2181
|
500 }
|
nickjillings@2181
|
501 }
|
nickjillings@2181
|
502 }
|
nickjillings@2181
|
503 // Build and push charts
|
nickjillings@2181
|
504 for (var chart of chartList) {
|
nickjillings@2181
|
505 chart.chart = new google.visualization.LineChart(chart.chartDOM);
|
nicholas@2538
|
506 chart.chart.draw(chart.data, chart.options);
|
nickjillings@2181
|
507 chart.buildTable();
|
nickjillings@2181
|
508 chart.writeLatex();
|
nickjillings@2181
|
509 this.charts.push(chart);
|
nickjillings@2181
|
510 }
|
nickjillings@2181
|
511 }
|
nicholas@2538
|
512
|
nicholas@2538
|
513 this.drawPageMean = function () {
|
nickjillings@2131
|
514 // First we must get the value data
|
nickjillings@2134
|
515 if (this.valueData == null) {
|
nickjillings@2134
|
516 console.log("Error - Data not loaded");
|
nickjillings@2134
|
517 return;
|
nickjillings@2134
|
518 }
|
nickjillings@2134
|
519 // We create one plot per page
|
nickjillings@2134
|
520 for (var page of this.valueData.pages) {
|
nicholas@2538
|
521
|
nickjillings@2135
|
522 // Create the chart resulting point
|
nicholas@2538
|
523 var chart = new this.chartObject("mean-page-" + page.id);
|
nickjillings@2135
|
524 document.getElementById("test-pages").appendChild(chart.root);
|
nicholas@2538
|
525
|
nickjillings@2134
|
526 // Create the data table
|
nicholas@2538
|
527 chart.data.addColumn('string', 'id');
|
nickjillings@2134
|
528 // Get axis labels
|
nickjillings@2134
|
529 for (var axis of page.elements[0].axis) {
|
nicholas@2538
|
530 chart.data.addColumn('number', axis.name);
|
nickjillings@2134
|
531 }
|
nickjillings@2134
|
532 var rows = []; // Rows is an array of tuples [col1, col2, col3 ... colN];
|
nickjillings@2134
|
533 for (var element of page.elements) {
|
nickjillings@2134
|
534 var entry = [element.id];
|
nicholas@2538
|
535 for (var i = 0; i < page.elements[0].axis.length; i++) {
|
nicholas@2538
|
536 var mean = 0;
|
nickjillings@2134
|
537 if (i < element.axis.length) {
|
nickjillings@2134
|
538 var axis = element.axis[i];
|
nickjillings@2135
|
539 mean = arrayMean(axis.values);
|
nickjillings@2134
|
540 }
|
nickjillings@2134
|
541 entry.push(mean);
|
nickjillings@2134
|
542 }
|
nickjillings@2134
|
543 rows.push(entry);
|
nickjillings@2134
|
544 }
|
nickjillings@2135
|
545 chart.data.addRows(rows);
|
nickjillings@2135
|
546 chart.options = {
|
nicholas@2538
|
547 'title': 'Mean of page: ' + page.id,
|
nicholas@2538
|
548 'width': 800,
|
nicholas@2538
|
549 'height': 700
|
nicholas@2538
|
550 }
|
nicholas@2538
|
551 // Draw the chart
|
nickjillings@2135
|
552 chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
|
nicholas@2538
|
553 chart.chart.draw(chart.data, chart.options);
|
nickjillings@2135
|
554 chart.buildTable();
|
nickjillings@2135
|
555 chart.writeLatex();
|
nickjillings@2135
|
556 this.charts.push(chart);
|
nickjillings@2135
|
557 }
|
nickjillings@2135
|
558 }
|
nicholas@2538
|
559
|
nicholas@2538
|
560 this.drawElementHistogram = function () {
|
nickjillings@2135
|
561 // First we must get the value data
|
nickjillings@2135
|
562 if (this.valueData == null) {
|
nickjillings@2135
|
563 console.log("Error - Data not loaded");
|
nickjillings@2135
|
564 return;
|
nickjillings@2135
|
565 }
|
nickjillings@2135
|
566 // We create one plot per element, enjoy...
|
nickjillings@2135
|
567 for (var page of this.valueData.pages) {
|
nickjillings@2135
|
568 for (var element of page.elements) {
|
nickjillings@2135
|
569 // Build the chart object
|
nicholas@2538
|
570 var chart = new this.chartObject("histogram-element-" + element.id);
|
nickjillings@2135
|
571 document.getElementById("test-pages").appendChild(chart.root);
|
nicholas@2538
|
572 chart.data.addColumn('string', 'index');
|
nickjillings@2135
|
573 var histograms = [];
|
nickjillings@2135
|
574 for (var axis of element.axis) {
|
nicholas@2538
|
575 chart.data.addColumn('number', axis.name);
|
nicholas@2538
|
576 histograms.push(arrayHistogram(axis.values, 0.125, 0.0, 1.0));
|
nickjillings@2135
|
577 }
|
nickjillings@2135
|
578 for (var axis of element.axis) {
|
nicholas@2538
|
579 for (var i = 0; i < histograms[0].length; i++) {
|
nicholas@2538
|
580 var entry = ["" + histograms[0][i].lt.toPrecision(2) + "-" + histograms[0][i].rt.toPrecision(3)]
|
nickjillings@2135
|
581 for (var histogram of histograms) {
|
nickjillings@2135
|
582 entry.push(histogram[i].count);
|
nickjillings@2135
|
583 }
|
nickjillings@2135
|
584 chart.data.addRow(entry);
|
nickjillings@2135
|
585 }
|
nickjillings@2135
|
586 }
|
nickjillings@2135
|
587 chart.options = {
|
nicholas@2538
|
588 'title': 'Histogram of element: ' + element.id,
|
nicholas@2538
|
589 'width': 800,
|
nicholas@2538
|
590 'height': 700,
|
nicholas@2538
|
591 'bar': {
|
nicholas@2538
|
592 'groupWidth': '100%'
|
nicholas@2538
|
593 }
|
nicholas@2538
|
594 }
|
nicholas@2538
|
595 // Draw the chart
|
nickjillings@2135
|
596 chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
|
nicholas@2538
|
597 chart.chart.draw(chart.data, chart.options);
|
nickjillings@2135
|
598 chart.buildTable();
|
nickjillings@2135
|
599 chart.writeLatex();
|
nickjillings@2135
|
600 this.charts.push(chart);
|
nickjillings@2135
|
601 }
|
nickjillings@2134
|
602 }
|
nickjillings@2131
|
603 }
|
nickjillings@2192
|
604 }
|
nickjillings@2192
|
605
|
nickjillings@2192
|
606 function Data() {
|
nickjillings@2192
|
607 // This holds the link between the server side calculations and the client side visualisation of the data
|
nicholas@2538
|
608
|
nickjillings@2192
|
609 // Dynamically generate the test filtering / page filterting tools
|
nickjillings@2192
|
610 var self = this;
|
nickjillings@2192
|
611 // Collect the test types and counts
|
nickjillings@2192
|
612 this.testSavedDiv = document.getElementById("test-saved");
|
nickjillings@2192
|
613 this.testSaves = null;
|
nickjillings@2192
|
614 this.selectURL = null;
|
nicholas@2538
|
615
|
nickjillings@2192
|
616 this.specification = new Specification();
|
nicholas@2538
|
617 get("../xml/test-schema.xsd").then(function (response) {
|
nickjillings@2192
|
618 var parse = new DOMParser();
|
nicholas@2538
|
619 self.specification.schema = parse.parseFromString(response, 'text/xml');
|
nicholas@2538
|
620 }, function (error) {
|
nickjillings@2192
|
621 console.log("ERROR: Could not get Test Schema");
|
nickjillings@2192
|
622 });
|
nicholas@2538
|
623 this.update = function (url) {
|
nickjillings@2192
|
624 var self = this;
|
nickjillings@2192
|
625 }
|
nicholas@2538
|
626
|
nicholas@2538
|
627 this.updateData = function (req_str) {
|
nickjillings@2193
|
628 // Now go get that data
|
nicholas@2538
|
629 get(req_str).then(function (response) {
|
nickjillings@2193
|
630 // Returns the data
|
nickjillings@2193
|
631 chartContext.valueData = JSON.parse(response);
|
nicholas@2538
|
632 }, function (error) {
|
nicholas@2538
|
633 console.error(error);
|
nicholas@2538
|
634 });
|
nickjillings@2193
|
635 }
|
nickjillings@2192
|
636 }
|
nickjillings@2192
|
637
|
nicholas@2538
|
638 var interfaceContext = new function () {
|
nickjillings@2192
|
639 // This creates the interface for the user to connect with the dynamic back-end to retrieve data
|
nickjillings@2192
|
640 this.rootDOM = document.createElement("div");
|
nickjillings@2193
|
641 this.getDataButton = {
|
nickjillings@2193
|
642 button: document.createElement("button"),
|
nickjillings@2193
|
643 parent: this,
|
nicholas@2538
|
644 handleEvent: function (event) {
|
nickjillings@2193
|
645 // Get the list of files:
|
nicholas@2538
|
646 var req_str = "../php/get_filtered_score.php" + this.parent.getFilterString();
|
nickjillings@2193
|
647 testData.updateData(req_str);
|
nickjillings@2193
|
648 }
|
nickjillings@2193
|
649 }
|
nickjillings@2193
|
650 this.getDataButton.button.textContent = "Get Filtered Data";
|
nicholas@2538
|
651 this.getDataButton.button.addEventListener("click", this.getDataButton);
|
nicholas@2538
|
652
|
nicholas@2287
|
653 this.getRawScoreData = {
|
nicholas@2287
|
654 root: document.createElement("div"),
|
nicholas@2287
|
655 csvDOM: document.createElement("button"),
|
nicholas@2287
|
656 jsonDOM: document.createElement("button"),
|
nicholas@2287
|
657 xmlDOM: document.createElement("button"),
|
nicholas@2287
|
658 presentDOM: document.createElement("div"),
|
nicholas@2287
|
659 parent: this,
|
nicholas@2287
|
660 XHR: new XMLHttpRequest(),
|
nicholas@2538
|
661 handleEvent: function (event) {
|
nicholas@2287
|
662 this.presentDOM.innerHTML = null;
|
nicholas@2538
|
663 var url = "../php/get_filtered_score.php" + this.parent.getFilterString();
|
nicholas@2538
|
664 this.XHR.open("GET", url + "&format=" + event.currentTarget.textContent, true);
|
nicholas@2538
|
665 switch (event.currentTarget.textContent) {
|
nicholas@2287
|
666 case "CSV":
|
nicholas@2538
|
667 this.XHR.onload = function () {
|
nicholas@2287
|
668 var file = [this.response];
|
nicholas@2538
|
669 var bb = new Blob(file, {
|
nicholas@2538
|
670 type: 'text/csv'
|
nicholas@2538
|
671 });
|
nicholas@2538
|
672 this.parent.presentDOM.appendChild(this.parent.generateLink(bb, "scores.csv"));
|
nicholas@2287
|
673 }
|
nicholas@2287
|
674 break;
|
nicholas@2287
|
675 case "JSON":
|
nicholas@2538
|
676 this.XHR.onload = function () {
|
nicholas@2287
|
677 var file = [this.response];
|
nicholas@2538
|
678 var bb = new Blob(file, {
|
nicholas@2538
|
679 type: 'application/json'
|
nicholas@2538
|
680 });
|
nicholas@2538
|
681 this.parent.presentDOM.appendChild(this.parent.generateLink(bb, "scores.json"));
|
nicholas@2287
|
682 }
|
nicholas@2287
|
683 break;
|
nicholas@2287
|
684 case "XML":
|
nicholas@2538
|
685 this.XHR.onload = function () {
|
nicholas@2287
|
686 var file = [this.response];
|
nicholas@2538
|
687 var bb = new Blob(file, {
|
nicholas@2538
|
688 type: 'text/xml'
|
nicholas@2538
|
689 });
|
nicholas@2538
|
690 this.parent.presentDOM.appendChild(this.parent.generateLink(bb, "scores.xml"));
|
nicholas@2287
|
691 }
|
nicholas@2287
|
692 break;
|
nicholas@2287
|
693 }
|
nicholas@2287
|
694 this.XHR.send();
|
nicholas@2287
|
695 },
|
nicholas@2538
|
696 generateLink: function (blob, filename) {
|
nicholas@2287
|
697 var dnlk = window.URL.createObjectURL(blob);
|
nicholas@2287
|
698 var a = document.createElement("a");
|
nicholas@2287
|
699 a.hidden = '';
|
nicholas@2287
|
700 a.href = dnlk;
|
nicholas@2287
|
701 a.download = filename;
|
nicholas@2287
|
702 a.textContent = "Save File";
|
nicholas@2287
|
703 return a;
|
nicholas@2287
|
704 }
|
nicholas@2287
|
705 }
|
nicholas@2538
|
706
|
nicholas@2287
|
707 this.getRawScoreData.root.appendChild(this.getRawScoreData.csvDOM);
|
nicholas@2287
|
708 this.getRawScoreData.root.appendChild(this.getRawScoreData.jsonDOM);
|
nicholas@2287
|
709 this.getRawScoreData.root.appendChild(this.getRawScoreData.xmlDOM);
|
nicholas@2287
|
710 this.getRawScoreData.root.appendChild(this.getRawScoreData.presentDOM);
|
nicholas@2287
|
711 this.getRawScoreData.XHR.parent = this.getRawScoreData;
|
nicholas@2287
|
712 this.getRawScoreData.csvDOM.textContent = 'CSV';
|
nicholas@2538
|
713 this.getRawScoreData.csvDOM.addEventListener('click', this.getRawScoreData);
|
nicholas@2287
|
714 this.getRawScoreData.jsonDOM.textContent = 'JSON';
|
nicholas@2538
|
715 this.getRawScoreData.jsonDOM.addEventListener('click', this.getRawScoreData);
|
nicholas@2287
|
716 this.getRawScoreData.xmlDOM.textContent = 'XML';
|
nicholas@2538
|
717 this.getRawScoreData.xmlDOM.addEventListener('click', this.getRawScoreData);
|
nicholas@2538
|
718
|
nickjillings@2195
|
719 this.testSaves = {
|
nickjillings@2195
|
720 json: null,
|
nickjillings@2195
|
721 selectedURL: null,
|
nickjillings@2195
|
722 inputs: [],
|
nickjillings@2195
|
723 parent: this
|
nickjillings@2195
|
724 };
|
nicholas@2538
|
725 this.init = function () {
|
nickjillings@2195
|
726 var self = this;
|
nicholas@2538
|
727 get('../php/get_tests.php?format=JSON').then(function (response) {
|
nickjillings@2195
|
728 document.getElementById("test-saved").innerHTML = null;
|
nickjillings@2195
|
729 var table = document.createElement("table");
|
nickjillings@2195
|
730 table.innerHTML = "<tr><td>Test Filename</td><td>Count</td><td>Include</td></tr>";
|
nickjillings@2195
|
731 self.testSaves.json = JSON.parse(response);
|
nickjillings@2195
|
732 for (var test of self.testSaves.json.tests) {
|
nickjillings@2195
|
733 var tableRow = document.createElement("tr");
|
nickjillings@2195
|
734 var tableRowFilename = document.createElement("td");
|
nickjillings@2195
|
735 tableRowFilename.textContent = test.testName;
|
nickjillings@2195
|
736 var tableRowCount = document.createElement("td");
|
nickjillings@2195
|
737 tableRowCount.textContent = test.files.length;
|
nickjillings@2195
|
738 tableRow.appendChild(tableRowFilename);
|
nickjillings@2195
|
739 tableRow.appendChild(tableRowCount);
|
nickjillings@2195
|
740 var tableRowInclude = document.createElement("td");
|
nickjillings@2195
|
741 var obj = {
|
nickjillings@2195
|
742 root: document.createElement("input"),
|
nickjillings@2195
|
743 parent: self.testSaves,
|
nicholas@2538
|
744 handleEvent: function (event) {
|
nickjillings@2195
|
745 this.parent.selectedURL = event.currentTarget.getAttribute("source");
|
nickjillings@2195
|
746 var self = this;
|
nicholas@2538
|
747 get(this.parent.selectedURL).then(function (response) {
|
nickjillings@2195
|
748 var parse = new DOMParser();
|
nicholas@2538
|
749 testData.specification.decode(parse.parseFromString(response, 'text/xml'));
|
nickjillings@2195
|
750 self.parent.parent.generateFilters(testData.specification);
|
nickjillings@2195
|
751 self.parent.parent.getFileCount();
|
nickjillings@2195
|
752 return true;
|
nicholas@2538
|
753 }, function (error) {
|
nicholas@2538
|
754 console.log("ERROR: Could not get" + url);
|
nickjillings@2195
|
755 return false;
|
nickjillings@2195
|
756 });
|
nickjillings@2195
|
757 }
|
nickjillings@2195
|
758 }
|
nickjillings@2195
|
759 obj.root.type = "radio";
|
nickjillings@2195
|
760 obj.root.name = "test-include";
|
nicholas@2538
|
761 obj.root.setAttribute("source", test.testName);
|
nicholas@2538
|
762 obj.root.addEventListener("change", obj);
|
nickjillings@2195
|
763 tableRowInclude.appendChild(obj.root);
|
nickjillings@2195
|
764 tableRow.appendChild(tableRowInclude);
|
nickjillings@2195
|
765 table.appendChild(tableRow);
|
nickjillings@2195
|
766 self.testSaves.inputs.push(obj);
|
nickjillings@2195
|
767 }
|
nickjillings@2195
|
768 document.getElementById("test-saved").appendChild(table);
|
nicholas@2538
|
769 }, function (error) {
|
nicholas@2538
|
770 console.error(error);
|
nicholas@2538
|
771 });
|
nickjillings@2195
|
772 }
|
nicholas@2538
|
773
|
nickjillings@2192
|
774 this.filterDOM = document.createElement("div");
|
nickjillings@2192
|
775 this.filterDOM.innerHTML = "<p>PreTest Filters</p><div id='filter-count'></div>";
|
nickjillings@2192
|
776 this.filterObjects = [];
|
nicholas@2538
|
777 this.generateFilters = function (specification) {
|
nickjillings@2192
|
778 // Filters are based on the pre and post global surverys
|
nicholas@2538
|
779 var FilterObject = function (parent, specification) {
|
nickjillings@2192
|
780 this.parent = parent;
|
nickjillings@2192
|
781 this.specification = specification;
|
nickjillings@2192
|
782 this.rootDOM = document.createElement("div");
|
nicholas@2538
|
783 this.rootDOM.innerHTML = "<span>ID: " + specification.id + ", Type: " + specification.type + "</span>";
|
nickjillings@2192
|
784 this.rootDOM.className = "filter-entry";
|
nicholas@2538
|
785 this.handleEvent = function (event) {
|
nicholas@2538
|
786 switch (this.specification.type) {
|
nickjillings@2192
|
787 case "number":
|
nickjillings@2192
|
788 var name = event.currentTarget.name;
|
nicholas@2538
|
789 eval("this." + name + " = event.currentTarget.value");
|
nickjillings@2192
|
790 break;
|
nickjillings@2192
|
791 case "checkbox":
|
nickjillings@2192
|
792 break;
|
nickjillings@2192
|
793 case "radio":
|
nickjillings@2192
|
794 break;
|
nickjillings@2192
|
795 }
|
nickjillings@2192
|
796 this.parent.getFileCount();
|
nickjillings@2192
|
797 }
|
nicholas@2538
|
798 this.getFilterPairs = function () {
|
nickjillings@2192
|
799 var pairs = [];
|
nicholas@2538
|
800 switch (this.specification.type) {
|
nickjillings@2192
|
801 case "number":
|
nickjillings@2192
|
802 if (this.min != "") {
|
nicholas@2538
|
803 pairs.push([specification.id + "-min", this.min]);
|
nickjillings@2192
|
804 }
|
nickjillings@2192
|
805 if (this.max != "") {
|
nicholas@2538
|
806 pairs.push([specification.id + "-max", this.max]);
|
nickjillings@2192
|
807 }
|
nickjillings@2192
|
808 break;
|
nickjillings@2192
|
809 case "radio":
|
nickjillings@2192
|
810 case "checkbox":
|
nicholas@2538
|
811 for (var i = 0; i < this.options.length; i++) {
|
nickjillings@2192
|
812 if (!this.options[i].checked) {
|
nicholas@2538
|
813 pairs.push([specification.id + "-exclude-" + i, specification.options[i].name]);
|
nickjillings@2192
|
814 }
|
nickjillings@2192
|
815 }
|
nickjillings@2192
|
816 break;
|
nickjillings@2192
|
817 }
|
nickjillings@2192
|
818 return pairs;
|
nickjillings@2192
|
819 }
|
nicholas@2538
|
820 switch (specification.type) {
|
nickjillings@2192
|
821 case "number":
|
nickjillings@2192
|
822 // Number can be ranged by min/max levels
|
nickjillings@2192
|
823 this.min = "";
|
nickjillings@2192
|
824 this.max = "";
|
nickjillings@2192
|
825 this.minDOM = document.createElement("input");
|
nickjillings@2192
|
826 this.minDOM.type = "number";
|
nickjillings@2192
|
827 this.minDOM.name = "min";
|
nicholas@2538
|
828 this.minDOM.addEventListener("change", this);
|
nickjillings@2192
|
829 this.minDOMText = document.createElement("span");
|
nickjillings@2192
|
830 this.minDOMText.textContent = "Minimum: ";
|
nickjillings@2192
|
831 var pairHolder = document.createElement("div");
|
nickjillings@2192
|
832 pairHolder.appendChild(this.minDOMText);
|
nickjillings@2192
|
833 pairHolder.appendChild(this.minDOM);
|
nickjillings@2192
|
834 this.rootDOM.appendChild(pairHolder);
|
nicholas@2538
|
835
|
nickjillings@2192
|
836 this.maxDOM = document.createElement("input");
|
nickjillings@2192
|
837 this.maxDOM.type = "number";
|
nickjillings@2192
|
838 this.maxDOM.name = "max";
|
nicholas@2538
|
839 this.maxDOM.addEventListener("change", this);
|
nickjillings@2192
|
840 this.maxDOMText = document.createElement("span");
|
nickjillings@2192
|
841 this.maxDOMText.textContent = "Maximum: ";
|
nickjillings@2192
|
842 var pairHolder = document.createElement("div");
|
nickjillings@2192
|
843 pairHolder.appendChild(this.maxDOMText);
|
nickjillings@2192
|
844 pairHolder.appendChild(this.maxDOM);
|
nickjillings@2192
|
845 this.rootDOM.appendChild(pairHolder);
|
nickjillings@2192
|
846 break;
|
nickjillings@2192
|
847 case "radio":
|
nickjillings@2192
|
848 case "checkbox":
|
nickjillings@2192
|
849 this.options = [];
|
nicholas@2538
|
850 for (var i = 0; i < specification.options.length; i++) {
|
nickjillings@2192
|
851 var option = specification.options[i];
|
nickjillings@2192
|
852 var pairHolder = document.createElement("div");
|
nickjillings@2192
|
853 var text = document.createElement("span");
|
nickjillings@2192
|
854 text.textContent = option.text;
|
nickjillings@2192
|
855 var check = document.createElement("input");
|
nickjillings@2192
|
856 check.type = "checkbox";
|
nicholas@2538
|
857 check.setAttribute("option-index", i);
|
nickjillings@2192
|
858 check.checked = true;
|
nicholas@2538
|
859 check.addEventListener("click", this);
|
nickjillings@2192
|
860 this.options.push(check);
|
nickjillings@2192
|
861 pairHolder.appendChild(text);
|
nickjillings@2192
|
862 pairHolder.appendChild(check);
|
nickjillings@2192
|
863 this.rootDOM.appendChild(pairHolder);
|
nickjillings@2192
|
864 }
|
nickjillings@2192
|
865 break;
|
nickjillings@2192
|
866 default:
|
nickjillings@2192
|
867 break;
|
nickjillings@2192
|
868 }
|
nickjillings@2192
|
869 }
|
nicholas@2251
|
870 var options = [];
|
nicholas@2538
|
871 if (specification.preTest) {
|
nicholas@2251
|
872 options = options.concat(specification.preTest.options);
|
nicholas@2251
|
873 }
|
nicholas@2251
|
874 if (specification.postTest) {
|
nicholas@2251
|
875 options = options.concat(specification.postTest.options);
|
nicholas@2251
|
876 }
|
nicholas@2251
|
877 for (var survey_entry of options) {
|
nicholas@2538
|
878 switch (survey_entry.type) {
|
nickjillings@2192
|
879 case "number":
|
nickjillings@2192
|
880 case "radio":
|
nickjillings@2192
|
881 case "checkbox":
|
nicholas@2538
|
882 var node = new FilterObject(this, survey_entry);
|
nickjillings@2192
|
883 this.filterObjects.push(node);
|
nickjillings@2192
|
884 this.filterDOM.appendChild(node.rootDOM);
|
nickjillings@2192
|
885 break;
|
nickjillings@2192
|
886 default:
|
nickjillings@2192
|
887 break;
|
nickjillings@2192
|
888 }
|
nickjillings@2192
|
889 }
|
nickjillings@2192
|
890 document.getElementById("test-saved").appendChild(this.filterDOM);
|
nickjillings@2193
|
891 document.getElementById("test-saved").appendChild(this.getDataButton.button);
|
nicholas@2287
|
892 document.getElementById("test-saved").appendChild(this.getRawScoreData.root);
|
nickjillings@2192
|
893 }
|
nicholas@2538
|
894 this.getFilterString = function () {
|
nickjillings@2192
|
895 var pairs = [];
|
nickjillings@2192
|
896 for (var obj of this.filterObjects) {
|
nickjillings@2192
|
897 pairs = pairs.concat(obj.getFilterPairs());
|
nickjillings@2192
|
898 }
|
nicholas@2538
|
899 var req_str = "?url=" + this.testSaves.selectedURL;
|
nickjillings@2192
|
900 var index = 0;
|
nicholas@2538
|
901 while (pairs[index] != undefined) {
|
nickjillings@2192
|
902 req_str += '&';
|
nicholas@2538
|
903 req_str += pairs[index][0] + "=" + pairs[index][1];
|
nickjillings@2192
|
904 index++;
|
nickjillings@2192
|
905 }
|
nickjillings@2193
|
906 return req_str;
|
nickjillings@2193
|
907 }
|
nicholas@2538
|
908 this.getFilteredUrlArray = function () {
|
nicholas@2538
|
909 var req_str = "../php/get_filtered_count.php" + this.getFilterString();
|
nicholas@2538
|
910 return get(req_str).then(function (response) {
|
nickjillings@2192
|
911 var urls = JSON.parse(response);
|
nickjillings@2193
|
912 return urls.urls;
|
nicholas@2538
|
913 }, function (error) {
|
nickjillings@2193
|
914 console.error(error);
|
nickjillings@2193
|
915 });
|
nickjillings@2193
|
916 }
|
nicholas@2538
|
917 this.getFileCount = function () {
|
nickjillings@2193
|
918 // First we must get the filter pairs
|
nicholas@2538
|
919 this.getFilteredUrlArray().then(function (response) {
|
nicholas@2538
|
920 var str = "Filtered to " + response.length + " file";
|
nickjillings@2193
|
921 if (response.length != 1) {
|
nickjillings@2192
|
922 str += "s.";
|
nickjillings@2192
|
923 } else {
|
nickjillings@2192
|
924 str += ".";
|
nickjillings@2192
|
925 }
|
nickjillings@2192
|
926 document.getElementById("filter-count").textContent = str;
|
nicholas@2538
|
927 }, function (error) {});
|
nickjillings@2192
|
928 }
|
nicholas@2538
|
929
|
nickjillings@2195
|
930 this.init();
|
nicholas@2538
|
931 }
|