annotate analysis/analysis.js @ 630:9dcfd654abad Dev_main

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