giuliomoro@15: /* giuliomoro@15: * Analysis script for WAET giuliomoro@15: */ giuliomoro@15: giuliomoro@15: // Firefox does not have an XMLDocument.prototype.getElementsByName giuliomoro@15: // and there is no searchAll style command, this custom function will giuliomoro@15: // search all children recusrively for the name. Used for XSD where all giuliomoro@15: // element nodes must have a name and therefore can pull the schema node giuliomoro@15: XMLDocument.prototype.getAllElementsByName = function(name) giuliomoro@15: { giuliomoro@15: name = String(name); giuliomoro@15: var selected = this.documentElement.getAllElementsByName(name); giuliomoro@15: return selected; giuliomoro@15: } giuliomoro@15: giuliomoro@15: Element.prototype.getAllElementsByName = function(name) giuliomoro@15: { giuliomoro@15: name = String(name); giuliomoro@15: var selected = []; giuliomoro@15: var node = this.firstElementChild; giuliomoro@15: while(node != null) giuliomoro@15: { giuliomoro@15: if (node.getAttribute('name') == name) giuliomoro@15: { giuliomoro@15: selected.push(node); giuliomoro@15: } giuliomoro@15: if (node.childElementCount > 0) giuliomoro@15: { giuliomoro@15: selected = selected.concat(node.getAllElementsByName(name)); giuliomoro@15: } giuliomoro@15: node = node.nextElementSibling; giuliomoro@15: } giuliomoro@15: return selected; giuliomoro@15: } giuliomoro@15: giuliomoro@15: XMLDocument.prototype.getAllElementsByTagName = function(name) giuliomoro@15: { giuliomoro@15: name = String(name); giuliomoro@15: var selected = this.documentElement.getAllElementsByTagName(name); giuliomoro@15: return selected; giuliomoro@15: } giuliomoro@15: giuliomoro@15: Element.prototype.getAllElementsByTagName = function(name) giuliomoro@15: { giuliomoro@15: name = String(name); giuliomoro@15: var selected = []; giuliomoro@15: var node = this.firstElementChild; giuliomoro@15: while(node != null) giuliomoro@15: { giuliomoro@15: if (node.nodeName == name) giuliomoro@15: { giuliomoro@15: selected.push(node); giuliomoro@15: } giuliomoro@15: if (node.childElementCount > 0) giuliomoro@15: { giuliomoro@15: selected = selected.concat(node.getAllElementsByTagName(name)); giuliomoro@15: } giuliomoro@15: node = node.nextElementSibling; giuliomoro@15: } giuliomoro@15: return selected; giuliomoro@15: } giuliomoro@15: giuliomoro@15: // Firefox does not have an XMLDocument.prototype.getElementsByName giuliomoro@15: if (typeof XMLDocument.prototype.getElementsByName != "function") { giuliomoro@15: XMLDocument.prototype.getElementsByName = function(name) giuliomoro@15: { giuliomoro@15: name = String(name); giuliomoro@15: var node = this.documentElement.firstElementChild; giuliomoro@15: var selected = []; giuliomoro@15: while(node != null) giuliomoro@15: { giuliomoro@15: if (node.getAttribute('name') == name) giuliomoro@15: { giuliomoro@15: selected.push(node); giuliomoro@15: } giuliomoro@15: node = node.nextElementSibling; giuliomoro@15: } giuliomoro@15: return selected; giuliomoro@15: } giuliomoro@15: } giuliomoro@15: giuliomoro@15: var chartContext, testData; giuliomoro@15: window.onload = function() { giuliomoro@15: // Load the Visualization API and the corechart package. giuliomoro@15: google.charts.load('current', {'packages':['corechart']}); giuliomoro@15: chartContext = new Chart(); giuliomoro@15: testData = new Data(); giuliomoro@15: } giuliomoro@15: giuliomoro@15: function get(url) { giuliomoro@15: // Return a new promise. giuliomoro@15: return new Promise(function(resolve, reject) { giuliomoro@15: // Do the usual XHR stuff giuliomoro@15: var req = new XMLHttpRequest(); giuliomoro@15: req.open('GET', url); giuliomoro@15: req.onload = function() { giuliomoro@15: // This is called even on 404 etc giuliomoro@15: // so check the status giuliomoro@15: if (req.status == 200) { giuliomoro@15: // Resolve the promise with the response text giuliomoro@15: resolve(req.response); giuliomoro@15: } giuliomoro@15: else { giuliomoro@15: // Otherwise reject with the status text giuliomoro@15: // which will hopefully be a meaningful error giuliomoro@15: reject(Error(req.statusText)); giuliomoro@15: } giuliomoro@15: }; giuliomoro@15: giuliomoro@15: // Handle network errors giuliomoro@15: req.onerror = function() { giuliomoro@15: reject(Error("Network Error")); giuliomoro@15: }; giuliomoro@15: giuliomoro@15: // Make the request giuliomoro@15: req.send(); giuliomoro@15: }); giuliomoro@15: } giuliomoro@15: giuliomoro@15: function arrayMean(values) { giuliomoro@15: var mean = 0; giuliomoro@15: for (var value of values) { giuliomoro@15: mean += value; giuliomoro@15: } giuliomoro@15: mean /= values.length; giuliomoro@15: return mean; giuliomoro@15: } giuliomoro@15: giuliomoro@15: function percentile(values, p) { giuliomoro@15: //http://web.stanford.edu/class/archive/anthsci/anthsci192/anthsci192.1064/handouts/calculating%20percentiles.pdf giuliomoro@15: values.sort( function(a,b) {return a - b;} ); giuliomoro@15: // get ordinal rank giuliomoro@15: var index = values.length*p/100; giuliomoro@15: var k = Math.floor(index); giuliomoro@15: if (k == index) { giuliomoro@15: return values[k]; giuliomoro@15: } else { giuliomoro@15: var f = index-k; giuliomoro@15: var x_int = (1-f)*values[k]+f*values[k+1]; giuliomoro@15: return x_int; giuliomoro@15: } giuliomoro@15: } giuliomoro@15: giuliomoro@15: function arrayMin(array) { giuliomoro@15: // Return the minimum value of an array giuliomoro@15: var min = array[0]; giuliomoro@15: for (var value of array) { giuliomoro@15: if (value < min) { giuliomoro@15: min = value; giuliomoro@15: } giuliomoro@15: } giuliomoro@15: return min; giuliomoro@15: } giuliomoro@15: giuliomoro@15: function arrayMax(array) { giuliomoro@15: // Return the minimum value of an array giuliomoro@15: var max = array[0]; giuliomoro@15: for (var value of array) { giuliomoro@15: if (value > max) { giuliomoro@15: max = value; giuliomoro@15: } giuliomoro@15: } giuliomoro@15: return max; giuliomoro@15: } giuliomoro@15: giuliomoro@15: function boxplotRow(array) { giuliomoro@15: // Take an array of element values and return array of computed intervals giuliomoro@15: var result = { giuliomoro@15: median : percentile(array,50), giuliomoro@15: pct25 : percentile(array,25), giuliomoro@15: pct75 : percentile(array,75), giuliomoro@15: IQR : null, giuliomoro@15: min: null, giuliomoro@15: max: null, giuliomoro@15: outliers: new Array() giuliomoro@15: } giuliomoro@15: result.IQR = result.pct75-result.pct25; giuliomoro@15: var rest = []; giuliomoro@15: var pct75_IQR = result.pct75+1.5*result.IQR; giuliomoro@15: var pct25_IQR = result.pct25-1.5*result.IQR; giuliomoro@15: for (var i=0; i pct75_IQR || point < pct25_IQR) { giuliomoro@15: result.outliers.push(point); giuliomoro@15: } else { giuliomoro@15: rest.push(point); giuliomoro@15: } giuliomoro@15: } giuliomoro@15: result.max = arrayMax(rest); giuliomoro@15: result.min = arrayMin(rest); giuliomoro@15: return result; giuliomoro@15: giuliomoro@15: } giuliomoro@15: giuliomoro@15: function arrayHistogram(values,steps,min,max) { giuliomoro@15: if (steps == undefined) { giuliomoro@15: steps = 0.25; giuliomoro@15: console.log("Warning: arrayHistogram called without steps size set, default to 0.25"); giuliomoro@15: } giuliomoro@15: if (min == undefined) {min = arrayMin(values);} giuliomoro@15: if (max == undefined) {max = arrayMax(values);} giuliomoro@15: var histogram = []; giuliomoro@15: var index = min; giuliomoro@15: while(index < max) { giuliomoro@15: histogram.push({ giuliomoro@15: marker: index, giuliomoro@15: lt: index, giuliomoro@15: rt: index+steps, giuliomoro@15: count: 0 giuliomoro@15: }); giuliomoro@15: index += steps; giuliomoro@15: } giuliomoro@15: for (var value of values) { giuliomoro@15: for (var entry of histogram) { giuliomoro@15: if (value >= entry.lt && value <= entry.rt) { giuliomoro@15: entry.count++; giuliomoro@15: break; giuliomoro@15: } giuliomoro@15: } giuliomoro@15: } giuliomoro@15: return histogram; giuliomoro@15: } giuliomoro@15: giuliomoro@15: function Chart() { giuliomoro@15: this.valueData; giuliomoro@15: this.charts = []; giuliomoro@15: giuliomoro@15: this.chartObject = function(name) { giuliomoro@15: // Create the charting object giuliomoro@15: this.name = name; giuliomoro@15: this.root = document.createElement("div"); giuliomoro@15: this.root.className = "chart-holder"; giuliomoro@15: this.root.setAttribute("name",name); giuliomoro@15: this.chartDOM = document.createElement("div"); giuliomoro@15: this.tableDOM = document.createElement("div"); giuliomoro@15: this.latexDOM = document.createElement("div"); giuliomoro@15: this.downloadDOM = document.createElement("div"); giuliomoro@15: this.chart = undefined; giuliomoro@15: this.data = new google.visualization.DataTable(); giuliomoro@15: this.options = {}; giuliomoro@15: this.print = document.createElement("button"); giuliomoro@15: this.sortDataButton = document.createElement("button"); giuliomoro@15: this.sortDataButton.textContent = "Sort by Data"; giuliomoro@15: this.sortDataButton.addEventListener("click",this); giuliomoro@15: this.sortDataButton.setAttribute("name","sort-data"); giuliomoro@15: this.sortNameButton = document.createElement("button"); giuliomoro@15: this.sortNameButton.textContent = "Sort by Name"; giuliomoro@15: this.sortNameButton.addEventListener("click",this); giuliomoro@15: this.sortNameButton.setAttribute("name","sort-name"); giuliomoro@15: this.draw = function() { giuliomoro@15: if (this.chart == undefined) {return;} giuliomoro@15: this.tableDOM.innerHTML = null; giuliomoro@15: this.latexDOM.innerHTML = null; giuliomoro@15: this.buildTable(); giuliomoro@15: this.writeLatex(); giuliomoro@15: this.chart.draw(this.data,this.options); giuliomoro@15: } giuliomoro@15: this.sortData = function() { giuliomoro@15: this.data.sort(1); giuliomoro@15: } giuliomoro@15: this.sortName = function() { giuliomoro@15: this.data.sort(0); giuliomoro@15: } giuliomoro@15: this.handleEvent = function() { giuliomoro@15: // Only used to handle the chart.event.addListener(this,'ready') callback giuliomoro@15: switch(event.currentTarget.getAttribute("name")) giuliomoro@15: { giuliomoro@15: case "download": giuliomoro@15: window.open(this.chart.getImageURI()); giuliomoro@15: break; giuliomoro@15: case "sort-data": giuliomoro@15: this.sortData(); giuliomoro@15: this.draw(); giuliomoro@15: break; giuliomoro@15: case "sort-name": giuliomoro@15: this.sortName(); giuliomoro@15: this.draw(); giuliomoro@15: break; giuliomoro@15: } giuliomoro@15: } giuliomoro@15: giuliomoro@15: this.root.appendChild(this.chartDOM); giuliomoro@15: this.root.appendChild(this.tableDOM); giuliomoro@15: this.root.appendChild(this.latexDOM); giuliomoro@15: this.root.appendChild(this.sortDataButton); giuliomoro@15: this.root.appendChild(this.sortNameButton); giuliomoro@15: this.root.appendChild(this.print); giuliomoro@15: this.print.textContent = "Download"; giuliomoro@15: this.print.setAttribute("name","download"); giuliomoro@15: this.print.addEventListener("click",this); giuliomoro@15: this.root.appendChild(this.downloadDOM); giuliomoro@15: this.buildTable = function() { giuliomoro@15: var table = document.createElement("table"); giuliomoro@15: table.border = "1"; giuliomoro@15: var numRows = this.data.getNumberOfRows(); giuliomoro@15: var numColumns = this.data.getNumberOfColumns(); giuliomoro@15: for (var columnIndex=0; columnIndex"; giuliomoro@15: this.rootDOM.className = "filter-entry"; giuliomoro@15: this.handleEvent = function(event) { giuliomoro@15: switch(this.specification.type) { giuliomoro@15: case "number": giuliomoro@15: var name = event.currentTarget.name; giuliomoro@15: eval("this."+name+" = event.currentTarget.value"); giuliomoro@15: break; giuliomoro@15: case "checkbox": giuliomoro@15: break; giuliomoro@15: case "radio": giuliomoro@15: break; giuliomoro@15: } giuliomoro@15: this.parent.getFileCount(); giuliomoro@15: } giuliomoro@15: this.getFilterPairs = function() { giuliomoro@15: var pairs = []; giuliomoro@15: switch(this.specification.type) { giuliomoro@15: case "number": giuliomoro@15: if (this.min != "") { giuliomoro@15: pairs.push([specification.id+"-min",this.min]); giuliomoro@15: } giuliomoro@15: if (this.max != "") { giuliomoro@15: pairs.push([specification.id+"-max",this.max]); giuliomoro@15: } giuliomoro@15: break; giuliomoro@15: case "radio": giuliomoro@15: case "checkbox": giuliomoro@15: for (var i=0; i