n@1223
|
1 /*
|
n@1223
|
2 * Analysis script for WAET
|
n@1223
|
3 */
|
n@1223
|
4
|
n@1223
|
5 var chartContext;
|
n@1223
|
6 window.onload = function() {
|
n@1223
|
7 // Load the Visualization API and the corechart package.
|
n@1223
|
8 google.charts.load('current', {'packages':['corechart']});
|
n@1223
|
9 chartContext = new Chart();
|
n@1223
|
10 }
|
n@1223
|
11
|
n@1227
|
12 function arrayMean(values) {
|
n@1227
|
13 var mean = 0;
|
n@1227
|
14 for (var value of values) {
|
n@1227
|
15 mean += value;
|
n@1227
|
16 }
|
n@1227
|
17 mean /= values.length;
|
n@1227
|
18 return mean;
|
n@1227
|
19 }
|
n@1227
|
20
|
n@1227
|
21 function percentile(values, n) {
|
n@1227
|
22 values.sort( function(a,b) {return a - b;} );
|
n@1227
|
23 // get ordinal rank
|
n@1227
|
24 var rank = Math.min(Math.floor(values.length*n/100), values.length-1);
|
n@1227
|
25 return values[rank];
|
n@1227
|
26 }
|
n@1227
|
27
|
n@1227
|
28 function arrayMin(array) {
|
n@1227
|
29 // Return the minimum value of an array
|
n@1227
|
30 var min = array[0];
|
n@1227
|
31 for (var value of array) {
|
n@1227
|
32 if (value < min) {
|
n@1227
|
33 min = value;
|
n@1227
|
34 }
|
n@1227
|
35 }
|
n@1227
|
36 return min;
|
n@1227
|
37 }
|
n@1227
|
38
|
n@1227
|
39 function arrayMax(array) {
|
n@1227
|
40 // Return the minimum value of an array
|
n@1227
|
41 var max = array[0];
|
n@1227
|
42 for (var value of array) {
|
n@1227
|
43 if (value > max) {
|
n@1227
|
44 max = value;
|
n@1227
|
45 }
|
n@1227
|
46 }
|
n@1227
|
47 return max;
|
n@1227
|
48 }
|
n@1227
|
49
|
n@1227
|
50 function arrayHistogram(values,steps,min,max) {
|
n@1227
|
51 if (steps == undefined) {
|
n@1227
|
52 steps = 0.25;
|
n@1227
|
53 console.log("Warning: arrayHistogram called without steps size set, default to 0.25");
|
n@1227
|
54 }
|
n@1227
|
55 if (min == undefined) {min = arrayMin(values);}
|
n@1227
|
56 if (max == undefined) {max = arrayMax(values);}
|
n@1227
|
57 var histogram = [];
|
n@1227
|
58 var index = min;
|
n@1227
|
59 while(index < max) {
|
n@1227
|
60 histogram.push({
|
n@1227
|
61 marker: index,
|
n@1227
|
62 lt: index,
|
n@1227
|
63 rt: index+steps,
|
n@1227
|
64 count: 0
|
n@1227
|
65 });
|
n@1227
|
66 index += steps;
|
n@1227
|
67 }
|
n@1227
|
68 for (var value of values) {
|
n@1227
|
69 for (var entry of histogram) {
|
n@1227
|
70 if (value >= entry.lt && value <= entry.rt) {
|
n@1227
|
71 entry.count++;
|
n@1227
|
72 break;
|
n@1227
|
73 }
|
n@1227
|
74 }
|
n@1227
|
75 }
|
n@1227
|
76 return histogram;
|
n@1227
|
77 }
|
n@1227
|
78
|
n@1223
|
79 function Chart() {
|
n@1226
|
80 this.valueData = null;
|
n@1226
|
81 this.commentData = null;
|
n@1226
|
82 this.loadStatus = 0;
|
n@1227
|
83 this.charts = [];
|
n@1223
|
84
|
n@1226
|
85 var XMLHttp = new XMLHttpRequest();
|
n@1226
|
86 XMLHttp.parent = this;
|
n@1226
|
87 XMLHttp.open("GET","../scripts/score_parser.php?format=JSON",true);
|
n@1226
|
88 XMLHttp.onload = function() {
|
n@1226
|
89 // Now we have the JSON data, extract
|
n@1226
|
90 this.parent.valueData = JSON.parse(this.responseText);
|
n@1226
|
91 this.parent.loadStatus++;
|
n@1223
|
92 }
|
n@1226
|
93 XMLHttp.send();
|
n@1226
|
94 var XMLHttp2 = new XMLHttpRequest();
|
n@1226
|
95 XMLHttp2.parent = this;
|
n@1226
|
96 XMLHttp2.open("GET","../scripts/comment_parser.php?format=JSON",true);
|
n@1226
|
97 XMLHttp2.onload = function() {
|
n@1226
|
98 // Now we have the JSON data, extract
|
n@1226
|
99 this.parent.commentData = JSON.parse(this.responseText);
|
n@1226
|
100 this.parent.loadStatus++;
|
n@1226
|
101 }
|
n@1226
|
102 XMLHttp2.send();
|
n@1223
|
103
|
n@1227
|
104 this.chartObject = function(name) {
|
n@1227
|
105 // Create the charting object
|
n@1227
|
106 this.name = name;
|
n@1227
|
107 this.root = document.createElement("div");
|
n@1227
|
108 this.root.className = "chart-holder";
|
n@1227
|
109 this.root.setAttribute("name",name);
|
n@1227
|
110 this.chartDOM = document.createElement("div");
|
n@1227
|
111 this.tableDOM = document.createElement("div");
|
n@1227
|
112 this.latexDOM = document.createElement("div");
|
n@1227
|
113 this.downloadDOM = document.createElement("div");
|
n@1227
|
114 this.chart = undefined;
|
n@1227
|
115 this.data = new google.visualization.DataTable();
|
n@1227
|
116 this.options = {};
|
n@1227
|
117 this.print = document.createElement("button");
|
n@1228
|
118 this.sortDataButton = document.createElement("button");
|
n@1228
|
119 this.sortDataButton.textContent = "Sort by Data";
|
n@1228
|
120 this.sortDataButton.addEventListener("click",this);
|
n@1228
|
121 this.sortDataButton.setAttribute("name","sort-data");
|
n@1228
|
122 this.sortNameButton = document.createElement("button");
|
n@1228
|
123 this.sortNameButton.textContent = "Sort by Name";
|
n@1228
|
124 this.sortNameButton.addEventListener("click",this);
|
n@1228
|
125 this.sortNameButton.setAttribute("name","sort-name");
|
n@1228
|
126 this.draw = function() {
|
n@1228
|
127 if (this.chart == undefined) {return;}
|
n@1228
|
128 this.tableDOM.innerHTML = null;
|
n@1228
|
129 this.latexDOM.innerHTML = null;
|
n@1228
|
130 this.buildTable();
|
n@1228
|
131 this.writeLatex();
|
n@1228
|
132 this.chart.draw(this.data,this.options);
|
n@1228
|
133 }
|
n@1228
|
134 this.sortData = function() {
|
n@1228
|
135
|
n@1228
|
136 var map = this.data.Jf.map(function(el,i){
|
n@1228
|
137 return {index: i, value: el.c[1].v};
|
n@1228
|
138 });
|
n@1228
|
139
|
n@1228
|
140 map.sort(function(a,b){
|
n@1228
|
141 if (a.value > b.value) {return -1;}
|
n@1228
|
142 if (a.value < b.value) {return 1;}
|
n@1228
|
143 return 0;
|
n@1228
|
144 })
|
n@1228
|
145
|
n@1228
|
146 var Jf = [];
|
n@1228
|
147 var cc = [];
|
n@1228
|
148 for (var i=0; i<map.length; i++) {
|
n@1228
|
149 Jf.push(this.data.Jf[map[i].index]);
|
n@1228
|
150 cc.push(this.data.cc[map[i].index]);
|
n@1228
|
151 }
|
n@1228
|
152 this.data.Jf = Jf;
|
n@1228
|
153 this.data.cc = cc;
|
n@1228
|
154 }
|
n@1228
|
155 this.sortName = function() {
|
n@1228
|
156 var map = this.data.Jf.map(function(el,i){
|
n@1228
|
157 return {index: i, value: el.c[0].v};
|
n@1228
|
158 });
|
n@1228
|
159
|
n@1228
|
160 map.sort(function(a,b){
|
n@1228
|
161 if (a.value < b.value) {return -1;}
|
n@1228
|
162 if (a.value > b.value) {return 1;}
|
n@1228
|
163 return 0;
|
n@1228
|
164 })
|
n@1228
|
165
|
n@1228
|
166 var Jf = [];
|
n@1228
|
167 var cc = [];
|
n@1228
|
168 for (var i=0; i<map.length; i++) {
|
n@1228
|
169 Jf.push(this.data.Jf[map[i].index]);
|
n@1228
|
170 cc.push(this.data.cc[map[i].index]);
|
n@1228
|
171 }
|
n@1228
|
172 this.data.Jf = Jf;
|
n@1228
|
173 this.data.cc = cc;
|
n@1228
|
174 }
|
n@1227
|
175 this.handleEvent = function() {
|
n@1227
|
176 // Only used to handle the chart.event.addListener(this,'ready') callback
|
n@1228
|
177 switch(event.currentTarget.getAttribute("name"))
|
n@1228
|
178 {
|
n@1228
|
179 case "download":
|
n@1228
|
180 window.open(this.chart.getImageURI());
|
n@1228
|
181 break;
|
n@1228
|
182 case "sort-data":
|
n@1228
|
183 this.sortData();
|
n@1228
|
184 this.draw();
|
n@1228
|
185 break;
|
n@1228
|
186 case "sort-name":
|
n@1228
|
187 this.sortName();
|
n@1228
|
188 this.draw();
|
n@1228
|
189 break;
|
n@1228
|
190 }
|
n@1227
|
191 }
|
n@1227
|
192
|
n@1227
|
193 this.root.appendChild(this.chartDOM);
|
n@1227
|
194 this.root.appendChild(this.tableDOM);
|
n@1227
|
195 this.root.appendChild(this.latexDOM);
|
n@1228
|
196 this.root.appendChild(this.sortDataButton);
|
n@1228
|
197 this.root.appendChild(this.sortNameButton);
|
n@1227
|
198 this.root.appendChild(this.print);
|
n@1227
|
199 this.print.textContent = "Download";
|
n@1228
|
200 this.print.setAttribute("name","download");
|
n@1227
|
201 this.print.addEventListener("click",this);
|
n@1227
|
202 this.root.appendChild(this.downloadDOM);
|
n@1227
|
203 this.buildTable = function() {
|
n@1227
|
204 var table = document.createElement("table");
|
n@1227
|
205 table.border = "1";
|
n@1264
|
206 var numRows = this.data.getNumberOfRows();
|
n@1264
|
207 var numColumns = this.data.getNumberOfColumns();
|
n@1264
|
208 for (var columnIndex=0; columnIndex<numColumns; columnIndex++)
|
n@1264
|
209 {
|
n@1264
|
210 var table_row = document.createElement('tr');
|
n@1264
|
211 table.appendChild(table_row);
|
n@1264
|
212 var row_title = document.createElement('td');
|
n@1264
|
213 table_row.appendChild(row_title);
|
n@1264
|
214 row_title.textContent = this.data.getColumnLabel(columnIndex);
|
n@1264
|
215 for (var rowIndex=0; rowIndex<numRows; rowIndex++)
|
n@1264
|
216 {
|
n@1264
|
217 var row_entry = document.createElement('td');
|
n@1264
|
218 table_row.appendChild(row_entry);
|
n@1264
|
219 var entry = this.data.getValue(rowIndex,columnIndex);
|
n@1264
|
220 if (isFinite(Number(entry)))
|
n@1264
|
221 {
|
n@1264
|
222 entry = String(Number(entry).toFixed(4));
|
n@1264
|
223 }
|
n@1264
|
224 row_entry.textContent = entry;
|
n@1227
|
225 }
|
n@1227
|
226 }
|
n@1227
|
227 this.tableDOM.appendChild(table);
|
n@1227
|
228 };
|
n@1227
|
229 this.writeLatex = function() {
|
n@1264
|
230 var numRows = this.data.getNumberOfRows();
|
n@1264
|
231 var numColumns = this.data.getNumberOfColumns();
|
n@1227
|
232 var root = document.createElement("div");
|
n@1227
|
233 root.className = "code";
|
n@1227
|
234 var holder = document.createElement("pre");
|
n@1227
|
235 // Table start
|
n@1227
|
236 var start = document.createElement("p");
|
n@1227
|
237 start.textContent = "\\" + "begin{tabular}{|l|";
|
n@1227
|
238 holder.appendChild(start);
|
n@1264
|
239 for (var i=0; i<numRows; i++) {
|
n@1227
|
240 start.textContent = start.textContent+"c|";
|
n@1227
|
241 }
|
n@1228
|
242 start.textContent = start.textContent.concat("}");
|
n@1227
|
243 // Now write the rows:
|
n@1264
|
244 for (var rIndex=0; rIndex<numColumns; rIndex++) {
|
n@1227
|
245 var row = document.createElement("p");
|
n@1264
|
246 row.textContent = this.data.getColumnLabel(rIndex).concat(" & ");
|
n@1264
|
247 for (var cIndex=0; cIndex<numRows; cIndex++) {
|
n@1264
|
248 var entry = this.data.getValue(cIndex,rIndex);
|
n@1264
|
249 if (isFinite(Number(entry)))
|
n@1264
|
250 {
|
n@1264
|
251 entry = String(Number(entry).toFixed(4));
|
n@1264
|
252 }
|
n@1264
|
253 row.textContent = row.textContent.concat(entry);
|
n@1264
|
254 if (cIndex < numRows-1) {
|
n@1227
|
255 row.textContent = row.textContent.concat(" & ");
|
n@1227
|
256 }
|
n@1227
|
257 }
|
n@1227
|
258 holder.appendChild(row);
|
n@1227
|
259 }
|
n@1227
|
260 // Table end
|
n@1227
|
261 var end = document.createElement("p");
|
n@1227
|
262 end.textContent = "\\" + "end{tabular}";
|
n@1227
|
263 holder.appendChild(end);
|
n@1227
|
264 root.appendChild(holder);
|
n@1227
|
265 this.latexDOM.appendChild(root);
|
n@1227
|
266 }
|
n@1227
|
267 }
|
n@1227
|
268
|
n@1227
|
269 this.clear = function() {
|
n@1227
|
270 var inject = document.getElementById("test-pages");
|
n@1227
|
271 for (var chart of this.charts) {
|
n@1227
|
272 inject.removeChild(chart.root);
|
n@1227
|
273 }
|
n@1227
|
274 this.charts = [];
|
n@1227
|
275 }
|
n@1227
|
276
|
n@1227
|
277 this.drawTestMean = function() {
|
n@1227
|
278 // This draws one bargraph per axis with every test element on
|
n@1227
|
279 if (this.valueData == null) {
|
n@1227
|
280 console.log("Error - Data not loaded");
|
n@1227
|
281 return;
|
n@1227
|
282 }
|
n@1227
|
283 var chartList = [];
|
n@1227
|
284
|
n@1227
|
285 // Create the data table
|
n@1227
|
286 for (var page of this.valueData.pages) {
|
n@1227
|
287 for (var element of page.elements) {
|
n@1227
|
288 for (var axis of element.axis) {
|
n@1227
|
289 // Find the axis
|
n@1227
|
290 var axisChart = chartList.find(function(element,index,array){
|
n@1227
|
291 if (element.name == this) {return true;} else {return false;}
|
n@1227
|
292 },"mean-test-"+axis.id);
|
n@1227
|
293 if (axisChart == null) {
|
n@1227
|
294 axisChart = new this.chartObject("mean-test-"+axis.id);
|
n@1227
|
295 axisChart.options = {
|
n@1227
|
296 'title':'Mean of axis: '+axis.name,
|
n@1227
|
297 'width':window.innerWidth*0.9,
|
n@1227
|
298 'height':(window.innerWidth*0.9)/1.77
|
n@1227
|
299 }
|
n@1227
|
300 axisChart.data.addColumn('string','id');
|
n@1227
|
301 axisChart.data.addColumn('number',axis.name);
|
n@1227
|
302 chartList.push(axisChart);
|
n@1227
|
303 document.getElementById("test-pages").appendChild(axisChart.root);
|
n@1227
|
304 }
|
n@1227
|
305 var mean = arrayMean(axis.values);
|
n@1227
|
306 axisChart.data.addRow([element.id,mean]);
|
n@1227
|
307 }
|
n@1227
|
308 }
|
n@1227
|
309 }
|
n@1227
|
310
|
n@1227
|
311 // Build and push charts
|
n@1227
|
312 for (var chart of chartList) {
|
n@1227
|
313 chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
|
n@1227
|
314 chart.chart.draw(chart.data,chart.options);
|
n@1227
|
315 chart.buildTable();
|
n@1227
|
316 chart.writeLatex();
|
n@1227
|
317 this.charts.push(chart);
|
n@1227
|
318 }
|
n@1227
|
319 }
|
n@1227
|
320
|
n@1227
|
321 this.drawPageMean = function() {
|
n@1223
|
322 // First we must get the value data
|
n@1226
|
323 if (this.valueData == null) {
|
n@1226
|
324 console.log("Error - Data not loaded");
|
n@1226
|
325 return;
|
n@1226
|
326 }
|
n@1226
|
327 // We create one plot per page
|
n@1226
|
328 for (var page of this.valueData.pages) {
|
n@1227
|
329
|
n@1227
|
330 // Create the chart resulting point
|
n@1227
|
331 var chart = new this.chartObject("mean-page-"+page.id);
|
n@1227
|
332 document.getElementById("test-pages").appendChild(chart.root);
|
n@1226
|
333
|
n@1226
|
334 // Create the data table
|
n@1227
|
335 chart.data.addColumn('string','id');
|
n@1226
|
336 // Get axis labels
|
n@1226
|
337 for (var axis of page.elements[0].axis) {
|
n@1227
|
338 chart.data.addColumn('number',axis.name);
|
n@1226
|
339 }
|
n@1226
|
340 var rows = []; // Rows is an array of tuples [col1, col2, col3 ... colN];
|
n@1226
|
341 for (var element of page.elements) {
|
n@1226
|
342 var entry = [element.id];
|
n@1226
|
343 for (var i=0; i<page.elements[0].axis.length; i++) {
|
n@1226
|
344 var mean =0;
|
n@1226
|
345 if (i < element.axis.length) {
|
n@1226
|
346 var axis = element.axis[i];
|
n@1227
|
347 mean = arrayMean(axis.values);
|
n@1226
|
348 }
|
n@1226
|
349 entry.push(mean);
|
n@1226
|
350 }
|
n@1226
|
351 rows.push(entry);
|
n@1226
|
352 }
|
n@1227
|
353 chart.data.addRows(rows);
|
n@1227
|
354 chart.options = {
|
n@1227
|
355 'title':'Mean of page: '+page.id,
|
n@1227
|
356 'width':800,
|
n@1227
|
357 'height':700
|
n@1227
|
358 }
|
n@1226
|
359 // Draw the chart
|
n@1227
|
360 chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
|
n@1227
|
361 chart.chart.draw(chart.data,chart.options);
|
n@1227
|
362 chart.buildTable();
|
n@1227
|
363 chart.writeLatex();
|
n@1227
|
364 this.charts.push(chart);
|
n@1227
|
365 }
|
n@1227
|
366 }
|
n@1227
|
367
|
n@1227
|
368 this.drawElementHistogram = function() {
|
n@1227
|
369 // First we must get the value data
|
n@1227
|
370 if (this.valueData == null) {
|
n@1227
|
371 console.log("Error - Data not loaded");
|
n@1227
|
372 return;
|
n@1227
|
373 }
|
n@1227
|
374 // We create one plot per element, enjoy...
|
n@1227
|
375 for (var page of this.valueData.pages) {
|
n@1227
|
376 for (var element of page.elements) {
|
n@1227
|
377 // Build the chart object
|
n@1227
|
378 var chart = new this.chartObject("histogram-element-"+element.id);
|
n@1227
|
379 document.getElementById("test-pages").appendChild(chart.root);
|
n@1227
|
380 chart.data.addColumn('string','index');
|
n@1227
|
381 var histograms = [];
|
n@1227
|
382 for (var axis of element.axis) {
|
n@1227
|
383 chart.data.addColumn('number',axis.name);
|
n@1227
|
384 histograms.push(arrayHistogram(axis.values,0.125,0.0,1.0));
|
n@1227
|
385 }
|
n@1227
|
386 for (var axis of element.axis) {
|
n@1227
|
387 for (var i=0; i<histograms[0].length; i++)
|
n@1227
|
388 {
|
n@1227
|
389 var entry = [""+histograms[0][i].lt.toPrecision(2)+"-"+histograms[0][i].rt.toPrecision(3)]
|
n@1227
|
390 for (var histogram of histograms) {
|
n@1227
|
391 entry.push(histogram[i].count);
|
n@1227
|
392 }
|
n@1227
|
393 chart.data.addRow(entry);
|
n@1227
|
394 }
|
n@1227
|
395 }
|
n@1227
|
396 chart.options = {
|
n@1227
|
397 'title':'Histogram of element: '+element.id,
|
n@1227
|
398 'width':800,
|
n@1227
|
399 'height':700,
|
n@1227
|
400 'bar':{'groupWidth': '100%'}
|
n@1227
|
401 }
|
n@1227
|
402 // Draw the chart
|
n@1227
|
403 chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
|
n@1227
|
404 chart.chart.draw(chart.data,chart.options);
|
n@1227
|
405 chart.buildTable();
|
n@1227
|
406 chart.writeLatex();
|
n@1227
|
407 this.charts.push(chart);
|
n@1227
|
408 }
|
n@1226
|
409 }
|
n@1223
|
410 }
|
n@1223
|
411 } |