annotate analysis/analysis.js @ 1103:2051868b21f0

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