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