Mercurial > hg > webaudioevaluationtool
comparison analysis/analysis.js @ 654:37f3359709bd
Merge
author | Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk> |
---|---|
date | Thu, 31 Mar 2016 15:48:57 +0100 |
parents | 9f0999472b91 |
children |
comparison
equal
deleted
inserted
replaced
605:716c05000a6e | 654:37f3359709bd |
---|---|
1 /* | 1 /* |
2 * Analysis script for WAET | 2 * Analysis script for WAET |
3 */ | 3 */ |
4 | 4 |
5 var chartContext; | 5 // Firefox does not have an XMLDocument.prototype.getElementsByName |
6 // and there is no searchAll style command, this custom function will | |
7 // search all children recusrively for the name. Used for XSD where all | |
8 // element nodes must have a name and therefore can pull the schema node | |
9 XMLDocument.prototype.getAllElementsByName = function(name) | |
10 { | |
11 name = String(name); | |
12 var selected = this.documentElement.getAllElementsByName(name); | |
13 return selected; | |
14 } | |
15 | |
16 Element.prototype.getAllElementsByName = function(name) | |
17 { | |
18 name = String(name); | |
19 var selected = []; | |
20 var node = this.firstElementChild; | |
21 while(node != null) | |
22 { | |
23 if (node.getAttribute('name') == name) | |
24 { | |
25 selected.push(node); | |
26 } | |
27 if (node.childElementCount > 0) | |
28 { | |
29 selected = selected.concat(node.getAllElementsByName(name)); | |
30 } | |
31 node = node.nextElementSibling; | |
32 } | |
33 return selected; | |
34 } | |
35 | |
36 XMLDocument.prototype.getAllElementsByTagName = function(name) | |
37 { | |
38 name = String(name); | |
39 var selected = this.documentElement.getAllElementsByTagName(name); | |
40 return selected; | |
41 } | |
42 | |
43 Element.prototype.getAllElementsByTagName = function(name) | |
44 { | |
45 name = String(name); | |
46 var selected = []; | |
47 var node = this.firstElementChild; | |
48 while(node != null) | |
49 { | |
50 if (node.nodeName == name) | |
51 { | |
52 selected.push(node); | |
53 } | |
54 if (node.childElementCount > 0) | |
55 { | |
56 selected = selected.concat(node.getAllElementsByTagName(name)); | |
57 } | |
58 node = node.nextElementSibling; | |
59 } | |
60 return selected; | |
61 } | |
62 | |
63 // Firefox does not have an XMLDocument.prototype.getElementsByName | |
64 if (typeof XMLDocument.prototype.getElementsByName != "function") { | |
65 XMLDocument.prototype.getElementsByName = function(name) | |
66 { | |
67 name = String(name); | |
68 var node = this.documentElement.firstElementChild; | |
69 var selected = []; | |
70 while(node != null) | |
71 { | |
72 if (node.getAttribute('name') == name) | |
73 { | |
74 selected.push(node); | |
75 } | |
76 node = node.nextElementSibling; | |
77 } | |
78 return selected; | |
79 } | |
80 } | |
81 | |
82 var chartContext, testData; | |
6 window.onload = function() { | 83 window.onload = function() { |
7 // Load the Visualization API and the corechart package. | 84 // Load the Visualization API and the corechart package. |
8 google.charts.load('current', {'packages':['corechart']}); | 85 google.charts.load('current', {'packages':['corechart']}); |
9 chartContext = new Chart(); | 86 chartContext = new Chart(); |
87 testData = new Data(); | |
88 } | |
89 | |
90 function get(url) { | |
91 // Return a new promise. | |
92 return new Promise(function(resolve, reject) { | |
93 // Do the usual XHR stuff | |
94 var req = new XMLHttpRequest(); | |
95 req.open('GET', url); | |
96 req.onload = function() { | |
97 // This is called even on 404 etc | |
98 // so check the status | |
99 if (req.status == 200) { | |
100 // Resolve the promise with the response text | |
101 resolve(req.response); | |
102 } | |
103 else { | |
104 // Otherwise reject with the status text | |
105 // which will hopefully be a meaningful error | |
106 reject(Error(req.statusText)); | |
107 } | |
108 }; | |
109 | |
110 // Handle network errors | |
111 req.onerror = function() { | |
112 reject(Error("Network Error")); | |
113 }; | |
114 | |
115 // Make the request | |
116 req.send(); | |
117 }); | |
10 } | 118 } |
11 | 119 |
12 function arrayMean(values) { | 120 function arrayMean(values) { |
13 var mean = 0; | 121 var mean = 0; |
14 for (var value of values) { | 122 for (var value of values) { |
16 } | 124 } |
17 mean /= values.length; | 125 mean /= values.length; |
18 return mean; | 126 return mean; |
19 } | 127 } |
20 | 128 |
21 function percentile(values, n) { | 129 function percentile(values, p) { |
130 //http://web.stanford.edu/class/archive/anthsci/anthsci192/anthsci192.1064/handouts/calculating%20percentiles.pdf | |
22 values.sort( function(a,b) {return a - b;} ); | 131 values.sort( function(a,b) {return a - b;} ); |
23 // get ordinal rank | 132 // get ordinal rank |
24 var rank = Math.min(Math.floor(values.length*n/100), values.length-1); | 133 var index = values.length*p/100; |
25 return values[rank]; | 134 var k = Math.floor(index); |
135 if (k == index) { | |
136 return values[k]; | |
137 } else { | |
138 var f = index-k; | |
139 var x_int = (1-f)*values[k]+f*values[k+1]; | |
140 return x_int; | |
141 } | |
26 } | 142 } |
27 | 143 |
28 function arrayMin(array) { | 144 function arrayMin(array) { |
29 // Return the minimum value of an array | 145 // Return the minimum value of an array |
30 var min = array[0]; | 146 var min = array[0]; |
43 if (value > max) { | 159 if (value > max) { |
44 max = value; | 160 max = value; |
45 } | 161 } |
46 } | 162 } |
47 return max; | 163 return max; |
164 } | |
165 | |
166 function boxplotRow(array) { | |
167 // Take an array of element values and return array of computed intervals | |
168 var result = { | |
169 median : percentile(array,50), | |
170 pct25 : percentile(array,25), | |
171 pct75 : percentile(array,75), | |
172 IQR : null, | |
173 min: null, | |
174 max: null, | |
175 outliers: new Array() | |
176 } | |
177 result.IQR = result.pct75-result.pct25; | |
178 var rest = []; | |
179 var pct75_IQR = result.pct75+1.5*result.IQR; | |
180 var pct25_IQR = result.pct25-1.5*result.IQR; | |
181 for (var i=0; i<array.length; i++) { | |
182 //outliers, ranger above pct75+1.5*IQR or below pct25-1.5*IQR | |
183 var point = array[i]; | |
184 if (point > pct75_IQR || point < pct25_IQR) { | |
185 result.outliers.push(point); | |
186 } else { | |
187 rest.push(point); | |
188 } | |
189 } | |
190 result.max = arrayMax(rest); | |
191 result.min = arrayMin(rest); | |
192 return result; | |
193 | |
48 } | 194 } |
49 | 195 |
50 function arrayHistogram(values,steps,min,max) { | 196 function arrayHistogram(values,steps,min,max) { |
51 if (steps == undefined) { | 197 if (steps == undefined) { |
52 steps = 0.25; | 198 steps = 0.25; |
75 } | 221 } |
76 return histogram; | 222 return histogram; |
77 } | 223 } |
78 | 224 |
79 function Chart() { | 225 function Chart() { |
80 this.valueData = null; | 226 this.valueData; |
81 this.commentData = null; | |
82 this.loadStatus = 0; | |
83 this.charts = []; | 227 this.charts = []; |
84 | |
85 var XMLHttp = new XMLHttpRequest(); | |
86 XMLHttp.parent = this; | |
87 XMLHttp.open("GET","../scripts/score_parser.php?format=JSON",true); | |
88 XMLHttp.onload = function() { | |
89 // Now we have the JSON data, extract | |
90 this.parent.valueData = JSON.parse(this.responseText); | |
91 this.parent.loadStatus++; | |
92 } | |
93 XMLHttp.send(); | |
94 var XMLHttp2 = new XMLHttpRequest(); | |
95 XMLHttp2.parent = this; | |
96 XMLHttp2.open("GET","../scripts/comment_parser.php?format=JSON",true); | |
97 XMLHttp2.onload = function() { | |
98 // Now we have the JSON data, extract | |
99 this.parent.commentData = JSON.parse(this.responseText); | |
100 this.parent.loadStatus++; | |
101 } | |
102 XMLHttp2.send(); | |
103 | 228 |
104 this.chartObject = function(name) { | 229 this.chartObject = function(name) { |
105 // Create the charting object | 230 // Create the charting object |
106 this.name = name; | 231 this.name = name; |
107 this.root = document.createElement("div"); | 232 this.root = document.createElement("div"); |
130 this.buildTable(); | 255 this.buildTable(); |
131 this.writeLatex(); | 256 this.writeLatex(); |
132 this.chart.draw(this.data,this.options); | 257 this.chart.draw(this.data,this.options); |
133 } | 258 } |
134 this.sortData = function() { | 259 this.sortData = function() { |
135 | 260 this.data.sort(1); |
136 var map = this.data.Jf.map(function(el,i){ | |
137 return {index: i, value: el.c[1].v}; | |
138 }); | |
139 | |
140 map.sort(function(a,b){ | |
141 if (a.value > b.value) {return -1;} | |
142 if (a.value < b.value) {return 1;} | |
143 return 0; | |
144 }) | |
145 | |
146 var Jf = []; | |
147 var cc = []; | |
148 for (var i=0; i<map.length; i++) { | |
149 Jf.push(this.data.Jf[map[i].index]); | |
150 cc.push(this.data.cc[map[i].index]); | |
151 } | |
152 this.data.Jf = Jf; | |
153 this.data.cc = cc; | |
154 } | 261 } |
155 this.sortName = function() { | 262 this.sortName = function() { |
156 var map = this.data.Jf.map(function(el,i){ | 263 this.data.sort(0); |
157 return {index: i, value: el.c[0].v}; | |
158 }); | |
159 | |
160 map.sort(function(a,b){ | |
161 if (a.value < b.value) {return -1;} | |
162 if (a.value > b.value) {return 1;} | |
163 return 0; | |
164 }) | |
165 | |
166 var Jf = []; | |
167 var cc = []; | |
168 for (var i=0; i<map.length; i++) { | |
169 Jf.push(this.data.Jf[map[i].index]); | |
170 cc.push(this.data.cc[map[i].index]); | |
171 } | |
172 this.data.Jf = Jf; | |
173 this.data.cc = cc; | |
174 } | 264 } |
175 this.handleEvent = function() { | 265 this.handleEvent = function() { |
176 // Only used to handle the chart.event.addListener(this,'ready') callback | 266 // Only used to handle the chart.event.addListener(this,'ready') callback |
177 switch(event.currentTarget.getAttribute("name")) | 267 switch(event.currentTarget.getAttribute("name")) |
178 { | 268 { |
201 this.print.addEventListener("click",this); | 291 this.print.addEventListener("click",this); |
202 this.root.appendChild(this.downloadDOM); | 292 this.root.appendChild(this.downloadDOM); |
203 this.buildTable = function() { | 293 this.buildTable = function() { |
204 var table = document.createElement("table"); | 294 var table = document.createElement("table"); |
205 table.border = "1"; | 295 table.border = "1"; |
206 for (var rowIndex=0; rowIndex<this.data.If.length; rowIndex++) { | 296 var numRows = this.data.getNumberOfRows(); |
207 var row = document.createElement("tr"); | 297 var numColumns = this.data.getNumberOfColumns(); |
208 table.appendChild(row); | 298 for (var columnIndex=0; columnIndex<numColumns; columnIndex++) |
209 var rowTitle = document.createElement("td"); | 299 { |
210 rowTitle.textContent = this.data.If[rowIndex].label; | 300 var tableTitle = this.data.getColumnLabel(columnIndex); |
211 row.appendChild(rowTitle); | 301 if (tableTitle != "") { |
212 for (var cIndex=0; cIndex<this.data.cc.length; cIndex++) { | 302 var table_row = document.createElement('tr'); |
213 var column = document.createElement("td"); | 303 table.appendChild(table_row); |
214 column.textContent = this.data.cc[cIndex][rowIndex].tf; | 304 var row_title = document.createElement('td'); |
215 row.appendChild(column); | 305 table_row.appendChild(row_title); |
306 row_title.textContent = tableTitle; | |
307 for (var rowIndex=0; rowIndex<numRows; rowIndex++) | |
308 { | |
309 var row_entry = document.createElement('td'); | |
310 table_row.appendChild(row_entry); | |
311 var entry = this.data.getValue(rowIndex,columnIndex); | |
312 if (isFinite(Number(entry))) | |
313 { | |
314 entry = String(Number(entry).toFixed(4)); | |
315 } | |
316 row_entry.textContent = entry; | |
317 } | |
216 } | 318 } |
217 } | 319 } |
218 this.tableDOM.appendChild(table); | 320 this.tableDOM.appendChild(table); |
219 }; | 321 }; |
220 this.writeLatex = function() { | 322 this.writeLatex = function() { |
323 var numRows = this.data.getNumberOfRows(); | |
324 var numColumns = this.data.getNumberOfColumns(); | |
221 var root = document.createElement("div"); | 325 var root = document.createElement("div"); |
222 root.className = "code"; | 326 root.className = "code"; |
223 var holder = document.createElement("pre"); | 327 var holder = document.createElement("pre"); |
224 // Table start | 328 // Table start |
225 var start = document.createElement("p"); | 329 var start = document.createElement("p"); |
226 start.textContent = "\\" + "begin{tabular}{|l|"; | 330 start.textContent = "\\" + "begin{tabular}{|l|"; |
227 holder.appendChild(start); | 331 holder.appendChild(start); |
228 for (var i=0; i<this.data.cc.length; i++) { | 332 for (var i=0; i<numRows; i++) { |
229 start.textContent = start.textContent+"c|"; | 333 start.textContent = start.textContent+"c|"; |
230 } | 334 } |
231 start.textContent = start.textContent.concat("}"); | 335 start.textContent = start.textContent.concat("}"); |
232 // Now write the rows: | 336 // Now write the rows: |
233 for (var rIndex=0; rIndex<this.data.If.length; rIndex++) { | 337 for (var rIndex=0; rIndex<numColumns; rIndex++) { |
234 var row = document.createElement("p"); | 338 var tableTitle = this.data.getColumnLabel(rIndex); |
235 row.textContent = this.data.If[rIndex].label.concat(" & "); | 339 if(tableTitle != "") |
236 for (var cIndex=0; cIndex<this.data.cc.length; cIndex++) { | 340 { |
237 row.textContent = row.textContent.concat(this.data.cc[cIndex][rIndex].tf); | 341 var row = document.createElement("p"); |
238 if (cIndex < this.data.cc.length-1) { | 342 row.textContent = tableTitle.concat(" & "); |
239 row.textContent = row.textContent.concat(" & "); | 343 for (var cIndex=0; cIndex<numRows; cIndex++) { |
344 var entry = this.data.getValue(cIndex,rIndex); | |
345 if (isFinite(Number(entry))) | |
346 { | |
347 entry = String(Number(entry).toFixed(4)); | |
348 } | |
349 row.textContent = row.textContent.concat(entry); | |
350 if (cIndex < numRows-1) { | |
351 row.textContent = row.textContent.concat(" & "); | |
352 } else { | |
353 row.textContent = row.textContent.concat(" \\\\ \\hline"); | |
354 } | |
240 } | 355 } |
241 } | 356 holder.appendChild(row); |
242 holder.appendChild(row); | 357 } |
243 } | 358 } |
244 // Table end | 359 // Table end |
245 var end = document.createElement("p"); | 360 var end = document.createElement("p"); |
246 end.textContent = "\\" + "end{tabular}"; | 361 end.textContent = "\\" + "end{tabular}"; |
247 holder.appendChild(end); | 362 holder.appendChild(end); |
271 for (var element of page.elements) { | 386 for (var element of page.elements) { |
272 for (var axis of element.axis) { | 387 for (var axis of element.axis) { |
273 // Find the axis | 388 // Find the axis |
274 var axisChart = chartList.find(function(element,index,array){ | 389 var axisChart = chartList.find(function(element,index,array){ |
275 if (element.name == this) {return true;} else {return false;} | 390 if (element.name == this) {return true;} else {return false;} |
276 },"mean-test-"+axis.id); | 391 },"mean-test-"+axis.name); |
277 if (axisChart == null) { | 392 if (axisChart == null) { |
278 axisChart = new this.chartObject("mean-test-"+axis.id); | 393 axisChart = new this.chartObject("mean-test-"+axis.name); |
279 axisChart.options = { | 394 axisChart.options = { |
280 'title':'Mean of axis: '+axis.name, | 395 'title':'Mean of axis: '+axis.name, |
281 'width':window.innerWidth*0.9, | 396 'width':window.innerWidth*0.9, |
282 'height':(window.innerWidth*0.9)/1.77 | 397 'height':(window.innerWidth*0.9)/1.77 |
283 } | 398 } |
300 chart.writeLatex(); | 415 chart.writeLatex(); |
301 this.charts.push(chart); | 416 this.charts.push(chart); |
302 } | 417 } |
303 } | 418 } |
304 | 419 |
420 this.drawTestBoxplot = function() { | |
421 if (this.valueData == null) { | |
422 console.log("Error - Data not loaded"); | |
423 return; | |
424 } | |
425 var chartList = []; | |
426 | |
427 // Creates one chart per axis | |
428 | |
429 // Create the data table | |
430 for (var page of this.valueData.pages) { | |
431 for (var element of page.elements) { | |
432 for (var axis of element.axis) { | |
433 // Find the axis | |
434 var axisChart = chartList.find(function(element,index,array){ | |
435 if (element.name == this) {return true;} else {return false;} | |
436 },"boxplot-test-"+axis.name); | |
437 if (axisChart == null) { | |
438 // Axis chart doesn't exist | |
439 axisChart = new this.chartObject("boxplot-test-"+axis.name); | |
440 axisChart.options = { | |
441 'title':'Boxplot of axis '+axis.name, | |
442 'width':window.innerWidth*0.9, | |
443 'height':(window.innerWidth*0.9)/1.77, | |
444 legend: {position: 'none'}, | |
445 lineWidth: 0, | |
446 series: [{'color': '#D3362D'}], | |
447 intervals: { | |
448 barWidth: 1, | |
449 boxWidth: 1, | |
450 lineWidth: 2, | |
451 style: 'boxes' | |
452 }, | |
453 interval: { | |
454 max: { | |
455 style: 'bars', | |
456 fillOpacity: 1, | |
457 color: '#777' | |
458 }, | |
459 min: { | |
460 style: 'bars', | |
461 fillOpacity: 1, | |
462 color: '#777' | |
463 } | |
464 } | |
465 }; | |
466 axisChart.data.addColumn('string','id'); | |
467 axisChart.data.addColumn('number','median'); | |
468 axisChart.data.addColumn({id:'max',type:'number',role:'interval'}); | |
469 axisChart.data.addColumn({id:'min',type:'number',role:'interval'}); | |
470 axisChart.data.addColumn({id:'firstQuartile',type:'number',role:'interval'}); | |
471 axisChart.data.addColumn({id:'median',type:'number',role:'interval'}); | |
472 axisChart.data.addColumn({id:'thirdQuartile',type:'number',role:'interval'}); | |
473 chartList.push(axisChart); | |
474 document.getElementById("test-pages").appendChild(axisChart.root); | |
475 } | |
476 var result = boxplotRow(axis.values); | |
477 axisChart.data.addRow([element.id,result.median,result.max,result.min,result.pct25,result.median,result.pct75]); | |
478 } | |
479 } | |
480 } | |
481 // Build and push charts | |
482 for (var chart of chartList) { | |
483 chart.chart = new google.visualization.LineChart(chart.chartDOM); | |
484 chart.chart.draw(chart.data,chart.options); | |
485 chart.buildTable(); | |
486 chart.writeLatex(); | |
487 this.charts.push(chart); | |
488 } | |
489 } | |
490 | |
305 this.drawPageMean = function() { | 491 this.drawPageMean = function() { |
306 // First we must get the value data | 492 // First we must get the value data |
307 if (this.valueData == null) { | 493 if (this.valueData == null) { |
308 console.log("Error - Data not loaded"); | 494 console.log("Error - Data not loaded"); |
309 return; | 495 return; |
391 this.charts.push(chart); | 577 this.charts.push(chart); |
392 } | 578 } |
393 } | 579 } |
394 } | 580 } |
395 } | 581 } |
582 | |
583 function Data() { | |
584 // This holds the link between the server side calculations and the client side visualisation of the data | |
585 | |
586 // Dynamically generate the test filtering / page filterting tools | |
587 var self = this; | |
588 // Collect the test types and counts | |
589 this.testSavedDiv = document.getElementById("test-saved"); | |
590 this.testSaves = null; | |
591 this.selectURL = null; | |
592 | |
593 this.specification = new Specification(); | |
594 get("../test-schema.xsd").then(function(response){ | |
595 var parse = new DOMParser(); | |
596 self.specification.schema = parse.parseFromString(response,'text/xml'); | |
597 },function(error){ | |
598 console.log("ERROR: Could not get Test Schema"); | |
599 }); | |
600 this.update = function(url) { | |
601 var self = this; | |
602 } | |
603 | |
604 this.updateData = function(req_str) { | |
605 // Now go get that data | |
606 get(req_str).then(function(response){ | |
607 // Returns the data | |
608 chartContext.valueData = JSON.parse(response); | |
609 },function(error){console.error(error);}); | |
610 } | |
611 } | |
612 | |
613 var interfaceContext = new function() { | |
614 // This creates the interface for the user to connect with the dynamic back-end to retrieve data | |
615 this.rootDOM = document.createElement("div"); | |
616 this.getDataButton = { | |
617 button: document.createElement("button"), | |
618 parent: this, | |
619 handleEvent: function(event) { | |
620 // Get the list of files: | |
621 var req_str = "../scripts/get_filtered_score.php"+this.parent.getFilterString(); | |
622 testData.updateData(req_str); | |
623 } | |
624 } | |
625 this.getDataButton.button.textContent = "Get Filtered Data"; | |
626 this.getDataButton.button.addEventListener("click",this.getDataButton); | |
627 | |
628 this.testSaves = { | |
629 json: null, | |
630 selectedURL: null, | |
631 inputs: [], | |
632 parent: this | |
633 }; | |
634 this.init = function() { | |
635 var self = this; | |
636 get('../scripts/get_tests.php?format=JSON').then(function(response){ | |
637 document.getElementById("test-saved").innerHTML = null; | |
638 var table = document.createElement("table"); | |
639 table.innerHTML = "<tr><td>Test Filename</td><td>Count</td><td>Include</td></tr>"; | |
640 self.testSaves.json = JSON.parse(response); | |
641 for (var test of self.testSaves.json.tests) { | |
642 var tableRow = document.createElement("tr"); | |
643 var tableRowFilename = document.createElement("td"); | |
644 tableRowFilename.textContent = test.testName; | |
645 var tableRowCount = document.createElement("td"); | |
646 tableRowCount.textContent = test.files.length; | |
647 tableRow.appendChild(tableRowFilename); | |
648 tableRow.appendChild(tableRowCount); | |
649 var tableRowInclude = document.createElement("td"); | |
650 var obj = { | |
651 root: document.createElement("input"), | |
652 parent: self.testSaves, | |
653 handleEvent: function(event) { | |
654 this.parent.selectedURL = event.currentTarget.getAttribute("source"); | |
655 var self = this; | |
656 get(this.parent.selectedURL).then(function(response){ | |
657 var parse = new DOMParser(); | |
658 testData.specification.decode(parse.parseFromString(response,'text/xml')); | |
659 self.parent.parent.generateFilters(testData.specification); | |
660 self.parent.parent.getFileCount(); | |
661 return true; | |
662 },function(error){ | |
663 console.log("ERROR: Could not get"+url); | |
664 return false; | |
665 }); | |
666 } | |
667 } | |
668 obj.root.type = "radio"; | |
669 obj.root.name = "test-include"; | |
670 obj.root.setAttribute("source",test.testName); | |
671 obj.root.addEventListener("change",obj); | |
672 tableRowInclude.appendChild(obj.root); | |
673 tableRow.appendChild(tableRowInclude); | |
674 table.appendChild(tableRow); | |
675 self.testSaves.inputs.push(obj); | |
676 } | |
677 document.getElementById("test-saved").appendChild(table); | |
678 },function(error){console.error(error);}); | |
679 } | |
680 | |
681 this.filterDOM = document.createElement("div"); | |
682 this.filterDOM.innerHTML = "<p>PreTest Filters</p><div id='filter-count'></div>"; | |
683 this.filterObjects = []; | |
684 this.generateFilters = function(specification) { | |
685 // Filters are based on the pre and post global surverys | |
686 var FilterObject = function(parent,specification) { | |
687 this.parent = parent; | |
688 this.specification = specification; | |
689 this.rootDOM = document.createElement("div"); | |
690 this.rootDOM.innerHTML = "<span>ID: "+specification.id+", Type: "+specification.type+"</span>"; | |
691 this.rootDOM.className = "filter-entry"; | |
692 this.handleEvent = function(event) { | |
693 switch(this.specification.type) { | |
694 case "number": | |
695 var name = event.currentTarget.name; | |
696 eval("this."+name+" = event.currentTarget.value"); | |
697 break; | |
698 case "checkbox": | |
699 break; | |
700 case "radio": | |
701 break; | |
702 } | |
703 this.parent.getFileCount(); | |
704 } | |
705 this.getFilterPairs = function() { | |
706 var pairs = []; | |
707 switch(this.specification.type) { | |
708 case "number": | |
709 if (this.min != "") { | |
710 pairs.push([specification.id+"-min",this.min]); | |
711 } | |
712 if (this.max != "") { | |
713 pairs.push([specification.id+"-max",this.max]); | |
714 } | |
715 break; | |
716 case "radio": | |
717 case "checkbox": | |
718 for (var i=0; i<this.options.length; i++) { | |
719 if (!this.options[i].checked) { | |
720 pairs.push([specification.id+"-exclude-"+i,specification.options[i].name]); | |
721 } | |
722 } | |
723 break; | |
724 } | |
725 return pairs; | |
726 } | |
727 switch(specification.type) { | |
728 case "number": | |
729 // Number can be ranged by min/max levels | |
730 this.min = ""; | |
731 this.max = ""; | |
732 this.minDOM = document.createElement("input"); | |
733 this.minDOM.type = "number"; | |
734 this.minDOM.name = "min"; | |
735 this.minDOM.addEventListener("change",this); | |
736 this.minDOMText = document.createElement("span"); | |
737 this.minDOMText.textContent = "Minimum: "; | |
738 var pairHolder = document.createElement("div"); | |
739 pairHolder.appendChild(this.minDOMText); | |
740 pairHolder.appendChild(this.minDOM); | |
741 this.rootDOM.appendChild(pairHolder); | |
742 | |
743 this.maxDOM = document.createElement("input"); | |
744 this.maxDOM.type = "number"; | |
745 this.maxDOM.name = "max"; | |
746 this.maxDOM.addEventListener("change",this); | |
747 this.maxDOMText = document.createElement("span"); | |
748 this.maxDOMText.textContent = "Maximum: "; | |
749 var pairHolder = document.createElement("div"); | |
750 pairHolder.appendChild(this.maxDOMText); | |
751 pairHolder.appendChild(this.maxDOM); | |
752 this.rootDOM.appendChild(pairHolder); | |
753 break; | |
754 case "radio": | |
755 case "checkbox": | |
756 this.options = []; | |
757 for (var i=0; i<specification.options.length; i++) { | |
758 var option = specification.options[i]; | |
759 var pairHolder = document.createElement("div"); | |
760 var text = document.createElement("span"); | |
761 text.textContent = option.text; | |
762 var check = document.createElement("input"); | |
763 check.type = "checkbox"; | |
764 check.setAttribute("option-index",i); | |
765 check.checked = true; | |
766 check.addEventListener("click",this); | |
767 this.options.push(check); | |
768 pairHolder.appendChild(text); | |
769 pairHolder.appendChild(check); | |
770 this.rootDOM.appendChild(pairHolder); | |
771 } | |
772 break; | |
773 default: | |
774 break; | |
775 } | |
776 } | |
777 for (var survey_entry of specification.preTest.options.concat(specification.postTest.options)) { | |
778 switch(survey_entry.type) { | |
779 case "number": | |
780 case "radio": | |
781 case "checkbox": | |
782 var node = new FilterObject(this,survey_entry); | |
783 this.filterObjects.push(node); | |
784 this.filterDOM.appendChild(node.rootDOM); | |
785 break; | |
786 default: | |
787 break; | |
788 } | |
789 } | |
790 document.getElementById("test-saved").appendChild(this.filterDOM); | |
791 document.getElementById("test-saved").appendChild(this.getDataButton.button); | |
792 } | |
793 this.getFilterString = function() { | |
794 var pairs = []; | |
795 for (var obj of this.filterObjects) { | |
796 pairs = pairs.concat(obj.getFilterPairs()); | |
797 } | |
798 var req_str = "?url="+this.testSaves.selectedURL; | |
799 var index = 0; | |
800 while(pairs[index] != undefined) { | |
801 req_str += '&'; | |
802 req_str += pairs[index][0]+"="+pairs[index][1]; | |
803 index++; | |
804 } | |
805 return req_str; | |
806 } | |
807 this.getFilteredUrlArray = function() { | |
808 var req_str = "../scripts/get_filtered_count.php"+this.getFilterString(); | |
809 return get(req_str).then(function(response){ | |
810 var urls = JSON.parse(response); | |
811 return urls.urls; | |
812 },function(error){ | |
813 console.error(error); | |
814 }); | |
815 } | |
816 this.getFileCount = function() { | |
817 // First we must get the filter pairs | |
818 this.getFilteredUrlArray().then(function(response){ | |
819 var str = "Filtered to "+response.length+" file"; | |
820 if (response.length != 1) { | |
821 str += "s."; | |
822 } else { | |
823 str += "."; | |
824 } | |
825 document.getElementById("filter-count").textContent = str; | |
826 },function(error){}); | |
827 } | |
828 | |
829 this.init(); | |
830 } |