3265 lines
534 KiB
HTML
3265 lines
534 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||
|
<title>Recovery System Evaluation Tool (ReSET)</title>
|
||
|
<script>
|
||
|
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b
|
||
|
f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget
|
||
|
{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.l
|
||
|
</script>
|
||
|
<script>
|
||
|
/*! @license Copyright 2011 Dan Vanderkam (danvdk@gmail.com) MIT-licensed (http://opensource.org/licenses/MIT) */
|
||
|
var DygraphLayout=function(a){this.dygraph_=a;this.datasets=[];this.setNames=[];this.annotations=[];this.yAxes_=null;this.xTicks_=null;this.yTicks_=null};DygraphLayout.prototype.attr_=function(a){return this.dygraph_.attr_(a)};DygraphLayout.prototype.addDataset=function(a,b){this.datasets.push(b);this.setNames.push(a)};DygraphLayout.prototype.getPlotArea=function(){return this.computePlotArea_()};DygraphLayout.prototype.computePlotArea_=function(){var a={x:0,y:0};if(this.attr_("drawYAxis")){a.x=this.attr_("yAxisLabelWidth")+2*this.attr_("axisTickSize")}a.w=this.dygraph_.width_-a.x-this.attr_("rightGap");a.h=this.dygraph_.height_;if(this.attr_("drawXAxis")){if(this.attr_("xAxisHeight")){a.h-=this.attr_("xAxisHeight")}else{a.h-=this.attr_("axisLabelFontSize")+2*this.attr_("axisTickSize")}}if(this.dygraph_.numAxes()==2){a.w-=(this.attr_("yAxisLabelWidth")+2*this.attr_("axisTickSize"))}else{if(this.dygraph_.numAxes()>2){this.dygraph_.error("Only two y-axes are supported at this time. (Trying to use "+this.dygraph_.numAxes()+")")}}if(this.attr_("title")){a.h-=this.attr_("titleHeight");a.y+=this.attr_("titleHeight")}if(this.attr_("xlabel")){a.h-=this.attr_("xLabelHeight")}if(this.attr_("ylabel")){}if(this.attr_("y2label")){}if(this.attr_("showRangeSelector")){a.h-=this.attr_("rangeSelectorHeight")+4}return a};DygraphLayout.prototype.setAnnotations=function(d){this.annotations=[];var e=this.attr_("xValueParser")||function(a){return a};for(var c=0;c<d.length;c++){var b={};if(!d[c].xval&&!d[c].x){this.dygraph_.error("Annotations must have an 'x' property");return}if(d[c].icon&&!(d[c].hasOwnProperty("width")&&d[c].hasOwnProperty("height"))){this.dygraph_.error("Must set width and height when setting annotation.icon property");return}Dygraph.update(b,d[c]);if(!b.xval){b.xval=e(b.x)}this.annotations.push(b)}};DygraphLayout.prototype.setXTicks=function(a){this.xTicks_=a};DygraphLayout.prototype.setYAxes=function(a){this.yAxes_=a};DygraphLayout.prototype.setDateWindow=function(a){this.dateWindow_=a};DygraphLayout.prototype.evaluate=function(){this._evaluateLimits();this._evaluateLineCharts();this._evaluateLineTicks();this._evaluateAnnotations()};DygraphLayout.prototype._evaluateLimits=function(){this.minxval=this.maxxval=null;if(this.dateWindow_){this.minxval=this.dateWindow_[0];this.maxxval=this.dateWindow_[1]}else{for(var f=0;f<this.datasets.length;++f){var d=this.datasets[f];if(d.length>1){var b=d[0][0];if(!this.minxval||b<this.minxval){this.minxval=b}var a=d[d.length-1][0];if(!this.maxxval||a>this.maxxval){this.maxxval=a}}}}this.xrange=this.maxxval-this.minxval;this.xscale=(this.xrange!==0?1/this.xrange:1);for(var c=0;c<this.yAxes_.length;c++){var e=this.yAxes_[c];e.minyval=e.computedValueRange[0];e.maxyval=e.computedValueRange[1];e.yrange=e.maxyval-e.minyval;e.yscale=(e.yrange!==0?1/e.yrange:1);if(e.g.attr_("logscale")){e.ylogrange=Dygraph.log10(e.maxyval)-Dygraph.log10(e.minyval);e.ylogscale=(e.ylogrange!==0?1/e.ylogrange:1);if(!isFinite(e.ylogrange)||isNaN(e.ylogrange)){e.g.error("axis "+c+" of graph at "+e.g+" can't be displayed in log scale for range ["+e.minyval+" - "+e.maxyval+"]")}}}};DygraphLayout._calcYNormal=function(a,b){if(a.logscale){return 1-((Dygraph.log10(b)-Dygraph.log10(a.minyval))*a.ylogscale)}else{return 1-((b-a.minyval)*a.yscale)}};DygraphLayout.prototype._evaluateLineCharts=function(){this.setPointsLengths=[];this.setPointsOffsets=[];var c=this.attr_("connectSeparatedPoints");var g=0;var k=0;for(var a=0;a<this.datasets.length;++a){k+=this.datasets[a].length}this.points=new Array(k);for(var a=0;a<this.datasets.length;++a){this.setPointsOffsets.push(g);var e=this.datasets[a];var l=this.setNames[a];var b=this.dygraph_.axisPropertiesForSeries(l);for(var f=0;f<e.length;f++){var o=e[f];var d=o[0];var m=o[1];var n=(d-this.minxval)*this.xscale;var h=DygraphLayout._calcYNormal(b,m);if(c&&m===null){m=null}this.points[g]={x:n,y:h,xval:d,yval:m,name:l};g++}this.setPointsLengths.push(g-this.setPointsOffsets[a])}};DygraphLayout.prototype._evaluateLineTicks=function(){var d,c,b,f;this.xticks=[];for(d=0;d<this.xTicks_.l
|
||
|
|
||
|
// ┌────────────────────────────────────────────────────────────────────┐ \\
|
||
|
// │ Raphaël 2.1.0 - JavaScript Vector Library │ \\
|
||
|
// ├────────────────────────────────────────────────────────────────────┤ \\
|
||
|
// │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
|
||
|
// │ Copyright © 2008-2012 Sencha Labs (http://sencha.com) │ \\
|
||
|
// ├────────────────────────────────────────────────────────────────────┤ \\
|
||
|
// │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\
|
||
|
// └────────────────────────────────────────────────────────────────────┘ \\
|
||
|
|
||
|
(function(a){var b="0.3.4",c="hasOwnProperty",d=/[\.\/]/,e="*",f=function(){},g=function(a,b){return a-b},h,i,j={n:{}},k=function(a,b){var c=j,d=i,e=Array.prototype.slice.call(arguments,2),f=k.listeners(a),l=0,m=!1,n,o=[],p={},q=[],r=h,s=[];h=a,i=0;for(var t=0,u=f.length;t<u;t++)"zIndex"in f[t]&&(o.push(f[t].zIndex),f[t].zIndex<0&&(p[f[t].zIndex]=f[t]));o.sort(g);while(o[l]<0){n=p[o[l++]],q.push(n.apply(b,e));if(i){i=d;return q}}for(t=0;t<u;t++){n=f[t];if("zIndex"in n)if(n.zIndex==o[l]){q.push(n.apply(b,e));if(i)break;do{l++,n=p[o[l]],n&&q.push(n.apply(b,e));if(i)break}while(n)}else p[n.zIndex]=n;else{q.push(n.apply(b,e));if(i)break}}i=d,h=r;return q.length?q:null};k.listeners=function(a){var b=a.split(d),c=j,f,g,h,i,k,l,m,n,o=[c],p=[];for(i=0,k=b.length;i<k;i++){n=[];for(l=0,m=o.length;l<m;l++){c=o[l].n,g=[c[b[i]],c[e]],h=2;while(h--)f=g[h],f&&(n.push(f),p=p.concat(f.f||[]))}o=n}return p},k.on=function(a,b){var c=a.split(d),e=j;for(var g=0,h=c.length;g<h;g++)e=e.n,!e[c[g]]&&(e[c[g]]={n:{}}),e=e[c[g]];e.f=e.f||[];for(g=0,h=e.f.length;g<h;g++)if(e.f[g]==b)return f;e.f.push(b);return function(a){+a==+a&&(b.zIndex=+a)}},k.stop=function(){i=1},k.nt=function(a){if(a)return(new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)")).test(h);return h},k.off=k.unbind=function(a,b){var f=a.split(d),g,h,i,k,l,m,n,o=[j];for(k=0,l=f.length;k<l;k++)for(m=0;m<o.length;m+=i.length-2){i=[m,1],g=o[m].n;if(f[k]!=e)g[f[k]]&&i.push(g[f[k]]);else for(h in g)g[c](h)&&i.push(g[h]);o.splice.apply(o,i)}for(k=0,l=o.length;k<l;k++){g=o[k];while(g.n){if(b){if(g.f){for(m=0,n=g.f.length;m<n;m++)if(g.f[m]==b){g.f.splice(m,1);break}!g.f.length&&delete g.f}for(h in g.n)if(g.n[c](h)&&g.n[h].f){var p=g.n[h].f;for(m=0,n=p.length;m<n;m++)if(p[m]==b){p.splice(m,1);break}!p.length&&delete g.n[h].f}}else{delete g.f;for(h in g.n)g.n[c](h)&&g.n[h].f&&delete g.n[h].f}g=g.n}}},k.once=function(a,b){var c=function(){var d=b.apply(this,arguments);k.unbind(a,c);return d};return k.on(a,c)},k.version=b,k.toString=function(){return"You are running Eve "+b},typeof module!="undefined"&&module.exports?module.exports=k:typeof define!="undefined"?define("eve",[],function(){return k}):a.eve=k})(this),function(){function cF(a){for(var b=0;b<cy.length;b++)cy[b].el.paper==a&&cy.splice(b--,1)}function cE(b,d,e,f,h,i){e=Q(e);var j,k,l,m=[],o,p,q,t=b.ms,u={},v={},w={};if(f)for(y=0,z=cy.length;y<z;y++){var x=cy[y];if(x.el.id==d.id&&x.anim==b){x.percent!=e?(cy.splice(y,1),l=1):k=x,d.attr(x.totalOrigin);break}}else f=+v;for(var y=0,z=b.percents.length;y<z;y++){if(b.percents[y]==e||b.percents[y]>f*b.top){e=b.percents[y],p=b.percents[y-1]||0,t=t/b.top*(e-p),o=b.percents[y+1],j=b.anim[e];break}f&&d.attr(b.anim[b.percents[y]])}if(!!j){if(!k){for(var A in j)if(j[g](A))if(U[g](A)||d.paper.customAttributes[g](A)){u[A]=d.attr(A),u[A]==null&&(u[A]=T[A]),v[A]=j[A];switch(U[A]){case C:w[A]=(v[A]-u[A])/t;break;case"colour":u[A]=a.getRGB(u[A]);var B=a.getRGB(v[A]);w[A]={r:(B.r-u[A].r)/t,g:(B.g-u[A].g)/t,b:(B.b-u[A].b)/t};break;case"path":var D=bR(u[A],v[A]),E=D[1];u[A]=D[0],w[A]=[];for(y=0,z=u[A].length;y<z;y++){w[A][y]=[0];for(var F=1,G=u[A][y].length;F<G;F++)w[A][y][F]=(E[y][F]-u[A][y][F])/t}break;case"transform":var H=d._,I=ca(H[A],v[A]);if(I){u[A]=I.from,v[A]=I.to,w[A]=[],w[A].real=!0;for(y=0,z=u[A].length;y<z;y++){w[A][y]=[u[A][y][0]];for(F=1,G=u[A][y].length;F<G;F++)w[A][y][F]=(v[A][y][F]-u[A][y][F])/t}}else{var J=d.matrix||new cb,K={_:{transform:H.transform},getBBox:function(){return d.getBBox(1)}};u[A]=[J.a,J.b,J.c,J.d,J.e,J.f],b$(K,v[A]),v[A]=K._.transform,w[A]=[(K.matrix.a-J.a)/t,(K.matrix.b-J.b)/t,(K.matrix.c-J.c)/t,(K.matrix.d-J.d)/t,(K.matrix.e-J.e)/t,(K.matrix.f-J.f)/t]}break;case"csv":var L=r(j[A])[s](c),M=r(u[A])[s](c);if(A=="clip-rect"){u[A]=M,w[A]=[],y=M.length;while(y--)w[A][y]=(L[y]-u[A][y])/t}v[A]=L;break;default:L=[][n](j[A]),M=[][n](u[A]),w[A]=[],y=d.paper.customAttributes[A].length;while(y--)w[A][y]=((L[y]||0)-(M[y]||0))/t}}var O=j.easing,P=a.easing_formulas[O];if(!P){P=r(O).match(N);if(P&&P.length==5){var R=P;P=function(a){return cC(a,+R[1],+R[2],+R[3],+R[4],t)}}else P=bf}q=j.start|
|
||
|
</script>
|
||
|
<script>
|
||
|
(function($) {
|
||
|
//
|
||
|
// Public interface
|
||
|
//
|
||
|
|
||
|
// The main event - creates a pretty graph. See index.html for documentation.
|
||
|
$.fn.tufteBar = function(options) {
|
||
|
var defaultCopy = $.extend(true, {}, $.fn.tufteBar.defaults);
|
||
|
var options = $.extend(true, defaultCopy, options);
|
||
|
|
||
|
return this.each(function () {
|
||
|
draw(makePlot($(this), options), options);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Defaults are exposed publically so you can reuse bits that you find
|
||
|
// handy (the colors, for instance)
|
||
|
$.fn.tufteBar.defaults = {
|
||
|
barWidth: 0.8,
|
||
|
colors: ['#07093D', '#0C0F66', '#476FB2'],
|
||
|
color: function(index, stackedIndex, options) { return options.colors[stackedIndex % options.colors.length]; },
|
||
|
barLabel: function(index, stackedIndex) {
|
||
|
return $.tufteBar.formatNumber(totalValue(this[0]));
|
||
|
},
|
||
|
axisLabel: function(index, stackedIndex) { return index; },
|
||
|
legend: {
|
||
|
color: function(index, options) { return options.colors[index % options.colors.length]; },
|
||
|
label: function(index) { return this; }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$.tufteBar = {
|
||
|
// Add thousands separators to a number to make it look pretty.
|
||
|
// 1000 -> 1,000
|
||
|
formatNumber: function(nStr) {
|
||
|
// http://www.mredkj.com/javascript/nfbasic.html
|
||
|
nStr += '';
|
||
|
x = nStr.split('.');
|
||
|
x1 = x[0];
|
||
|
x2 = x.length > 1 ? '.' + x[1] : '';
|
||
|
var rgx = /(\d+)(\d{3})/;
|
||
|
while (rgx.test(x1)) {
|
||
|
x1 = x1.replace(rgx, '$1' + ',' + '$2');
|
||
|
}
|
||
|
return x1 + x2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Private functions
|
||
|
//
|
||
|
|
||
|
// This function should be applied to any option used from the options hash.
|
||
|
// It allows options to be provided as either static values or functions which are
|
||
|
// evaluated each time they are used
|
||
|
function resolveOption(option, element) {
|
||
|
// the @arguments@ special variable looks like an array, but really isn't, so we
|
||
|
// need to transform it in order to perform array function on it
|
||
|
function toArray() {
|
||
|
var result = []
|
||
|
for (var i = 0; i < this.length; i++)
|
||
|
result.push(this[i])
|
||
|
return(result)
|
||
|
}
|
||
|
|
||
|
return $.isFunction(option) ? option.apply(element, toArray.apply(arguments).slice(2, arguments.length)) : option;
|
||
|
}
|
||
|
|
||
|
// Returns the total value of a bar, for labeling or plotting. Y values can either be
|
||
|
// a single number (for a normal graph), or an array of numbers (for a stacked graph)
|
||
|
function totalValue(value) {
|
||
|
if (value instanceof Array)
|
||
|
return $.sum(value);
|
||
|
else
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
function draw(plot, options) {
|
||
|
var ctx = plot.ctx;
|
||
|
var axis = plot.axis;
|
||
|
|
||
|
// Iterate over each bar
|
||
|
$(options.data).each(function (i) {
|
||
|
var element = this;
|
||
|
var x = i + 0.5;
|
||
|
var all_y = null;
|
||
|
|
||
|
if (element[0] instanceof Array) {
|
||
|
// This is a stacked bar, so the data is all good to go
|
||
|
all_y = element[0];
|
||
|
} else {
|
||
|
// This is a normal bar, wrap in an array to make it a stacked bar with one data point
|
||
|
all_y = [element[0]];
|
||
|
}
|
||
|
|
||
|
if ($(all_y).any(function() { return isNaN(+this); })) {
|
||
|
throw("Non-numeric value provided for y: " + element[0]);
|
||
|
}
|
||
|
|
||
|
var lastY = 0;
|
||
|
|
||
|
pixel_scaling_function = function(axis) {
|
||
|
var scale = axis.pixelLength / (axis.max - axis.min);
|
||
|
return function (value) {
|
||
|
return (value - axis.min) * scale;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// These functions transform a value from plot coordinates to pixel coordinates
|
||
|
var t = {}
|
||
|
t.W = pixel_scaling_function(axis.x);
|
||
|
t.H = pixel_scaling_function(axis.y);
|
||
|
t.X = t.W;
|
||
|
// Y needs to invert the result since 0 in plot coords is bottom left, but 0 in pixel coords is top left
|
||
|
t.Y = function(y) { return axis.y.pixelLength - t.H(y) };
|
||
|
|
||
|
// Iterate over each data point for this bar and render a rectangle for each
|
||
|
$(all_y).each(function(stackedIndex) {
|
||
|
var optionResolver = function(option) { // Curry resolveOption for convenience
|
||
|
return resolveOption(option, element, i, stackedIndex, options);
|
||
|
}
|
||
|
|
||
|
var y = all_y[stackedIndex];
|
||
|
var halfBar = optionResolver(options.barWidth) / 2;
|
||
|
var left = x - halfBar,
|
||
|
width = halfBar * 2,
|
||
|
top = lastY + y,
|
||
|
height = y;
|
||
|
|
||
|
// Need to both fill and stroke the rect to make sure the whole area is covered
|
||
|
// You get nasty artifacts otherwise
|
||
|
var color = optionResolver(options.color);
|
||
|
var coords = [t.X(left), t.Y(top), t.W(width), t.H(height)];
|
||
|
|
||
|
ctx.rect(coords[0], coords[1], coords[2], coords[3]).attr({stroke: color, fill: color});
|
||
|
|
||
|
lastY = lastY + y;
|
||
|
});
|
||
|
|
||
|
addLabel = function(klass, text, pos) {
|
||
|
html = '<div style="position:absolute;" class="label ' + klass + '">' + text + "</div>";
|
||
|
$(html).css(pos).appendTo( plot.target );
|
||
|
}
|
||
|
|
||
|
var optionResolver = function(option) { // Curry resolveOption for convenience
|
||
|
return resolveOption(option, element, i, options);
|
||
|
}
|
||
|
addLabel('bar-label', optionResolver(options.barLabel), {
|
||
|
left: t.X(x - 0.5),
|
||
|
bottom: t.H(lastY),
|
||
|
width: t.W(1)
|
||
|
});
|
||
|
addLabel('axis-label', optionResolver(options.axisLabel), {
|
||
|
left: t.X(x - 0.5),
|
||
|
top: t.Y(0),
|
||
|
width: t.W(1)
|
||
|
});
|
||
|
});
|
||
|
addLegend(plot, options);
|
||
|
}
|
||
|
|
||
|
// If legend data has been provided, transform it into an
|
||
|
// absolutely positioned table placed at the top right of the graph
|
||
|
function addLegend(plot, options) {
|
||
|
if (options.legend.data) {
|
||
|
elements = $(options.legend.data).collect(function(i) {
|
||
|
var optionResolver = (function (element) {
|
||
|
return function(option) { // Curry resolveOption for convenience
|
||
|
return resolveOption(option, element, i, options);
|
||
|
}
|
||
|
})(this);
|
||
|
|
||
|
var colorBox = '<div class="color-box" style="background-color:' + optionResolver(options.legend.color) + '"></div>';
|
||
|
var label = optionResolver(options.legend.label);
|
||
|
|
||
|
return "<tr><td>" + colorBox + "</td><td>" + label + "</td></tr>";
|
||
|
});
|
||
|
|
||
|
$('<table class="legend">' + elements.reverse().join("") + '</table>').css({
|
||
|
position: 'absolute',
|
||
|
top: '0px',
|
||
|
left: plot.width + 'px'
|
||
|
}).appendTo( plot.target );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Calculates the range of the graph by looking for the
|
||
|
// maximum y-value
|
||
|
function makeAxis(options) {
|
||
|
var axis = {
|
||
|
x: {},
|
||
|
y: {}
|
||
|
}
|
||
|
|
||
|
axis.x.min = 0
|
||
|
axis.x.max = options.data.length;
|
||
|
axis.y.min = 0;
|
||
|
axis.y.max = 0;
|
||
|
|
||
|
$(options.data).each(function() {
|
||
|
var y = totalValue(this[0]);
|
||
|
if( y < axis.y.min ) throw("Negative values not supported");
|
||
|
if( y > axis.y.max ) axis.y.max = y;
|
||
|
});
|
||
|
|
||
|
if( axis.x.max <= 0) throw("You must have at least one data point");
|
||
|
if( axis.y.max <= 0) throw("You must have at least one y-value greater than 0");
|
||
|
|
||
|
return axis;
|
||
|
}
|
||
|
|
||
|
// Creates the canvas object to draw on, and set up the axes
|
||
|
function makePlot(target, options) {
|
||
|
var plot = {};
|
||
|
plot.target = target;
|
||
|
plot.width = target.width();
|
||
|
plot.height = target.height();
|
||
|
target.html( '' ).css( 'position', 'relative' );
|
||
|
|
||
|
if( plot.width <= 0 || plot.height <= 0 ) {
|
||
|
throw "Invalid dimensions for plot, width = " + plot.width + ", height = " + plot.height;
|
||
|
}
|
||
|
|
||
|
// the canvas
|
||
|
plot.ctx = Raphael(target[0].id, plot.width, plot.height);
|
||
|
|
||
|
plot.axis = makeAxis(options);
|
||
|
plot.axis.x.pixelLength = plot.width;
|
||
|
plot.axis.y.pixelLength = plot.height;
|
||
|
|
||
|
return plot;
|
||
|
}
|
||
|
} )( jQuery );
|
||
|
</script>
|
||
|
<script>
|
||
|
(function ( $ ) {
|
||
|
var methods = {
|
||
|
// $([1,2,3]).collect(function() { return this * this }) // => [1, 4, 9]
|
||
|
collect: function(enumerable, callback) {
|
||
|
var result = [];
|
||
|
$.each(enumerable, function(index) {
|
||
|
result.push(callback.call(this, index));
|
||
|
});
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
// $([1,2,3]).inject(0, function(a) { return a + this }) // => 6
|
||
|
inject: function(enumerable, initialValue, callback) {
|
||
|
var accumulator = initialValue;
|
||
|
|
||
|
$.each(enumerable, function (index) {
|
||
|
accumulator = callback.call(this, accumulator, index);
|
||
|
});
|
||
|
return accumulator;
|
||
|
},
|
||
|
|
||
|
// $([1,2,3]).select(function() { return this % 2 == 1 }) // => [1, 3]
|
||
|
select: function(enumerable, callback) {
|
||
|
var result = [];
|
||
|
$.each(enumerable, function(index) {
|
||
|
if (callback.call(this, index))
|
||
|
result.push(this);
|
||
|
});
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
// $([1,2,3]).reject(function() { return this % 2 == 1 }) // => [2]
|
||
|
reject: function(enumerable, callback) {
|
||
|
return $.select(enumerable, negate(callback));
|
||
|
},
|
||
|
|
||
|
// $([1,2]).any(function() { return this == 1 }) // => true
|
||
|
any: function(enumerable, callback) {
|
||
|
return $.inject(enumerable, false, function(accumulator, index) {
|
||
|
return accumulator || callback.call(this, index);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
// $([1,1]).any(function() { return this == 1 }) // => true
|
||
|
all: function(enumerable, callback) {
|
||
|
return $.inject(enumerable, true, function(accumulator, index) {
|
||
|
return accumulator && callback.call(this, index);
|
||
|
});
|
||
|
},
|
||
|
|
||
|
// $([1,2,3]).sum() // => 6
|
||
|
sum: function(enumerable) {
|
||
|
return $.inject(enumerable, 0, function(accumulator) {
|
||
|
return accumulator + this;
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var staticFunctions = {};
|
||
|
var iteratorFunctions = {};
|
||
|
$.each( methods, function(name, f){
|
||
|
staticFunctions[name] = makeStaticFunction(f);
|
||
|
iteratorFunctions[name] = makeIteratorFunction(staticFunctions[name]);
|
||
|
});
|
||
|
$.extend(staticFunctions);
|
||
|
$.fn.extend(iteratorFunctions);
|
||
|
|
||
|
// Private methods
|
||
|
function makeStaticFunction(f) {
|
||
|
return function() {
|
||
|
if (arguments.length > 1) // The first argument is the enumerable
|
||
|
validateCallback(arguments[arguments.length - 1]);
|
||
|
|
||
|
return f.apply(this, arguments);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function makeIteratorFunction(staticFunction) {
|
||
|
return function() {
|
||
|
// arguments isn't a real array, concat doesn't work
|
||
|
// unless you explicitly convert it
|
||
|
function toArray() {
|
||
|
var result = []
|
||
|
for (var i = 0; i < this.length; i++)
|
||
|
result.push(this[i])
|
||
|
return(result)
|
||
|
}
|
||
|
return staticFunction.apply(this, [this].concat(toArray.apply(arguments)))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function validateCallback(callback) {
|
||
|
if (!jQuery.isFunction(callback))
|
||
|
throw("callback needs to be a function, it was: " + callback);
|
||
|
}
|
||
|
|
||
|
function negate(f) {
|
||
|
return function() {
|
||
|
return !f.apply(this, arguments)
|
||
|
}
|
||
|
}
|
||
|
})( jQuery );
|
||
|
</script>
|
||
|
<style>
|
||
|
/*!
|
||
|
* Bootstrap v3.3.1 (http://getbootstrap.com)
|
||
|
* Copyright 2011-2014 Twitter, Inc.
|
||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
|
*/
|
||
|
|
||
|
/*!
|
||
|
* Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=4c5f95730016373513dd)
|
||
|
* Config saved to config.json and https://gist.github.com/4c5f95730016373513dd
|
||
|
*/
|
||
|
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"
|
||
|
|
||
|
/*!
|
||
|
* Bootstrap v3.3.1 (http://getbootstrap.com)
|
||
|
* Copyright 2011-2014 Twitter, Inc.
|
||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
|
*/
|
||
|
|
||
|
/*!
|
||
|
* Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=cb1f000e89151af802e4)
|
||
|
* Config saved to config.json and https://gist.github.com/cb1f000e89151af802e4
|
||
|
*/
|
||
|
.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-default .badge,.btn-primary .badge,.btn-success .badge,.btn-info .badge,.btn-warning .badge,.btn-danger .badge{text-shadow:none}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top, #fff 0, #e0e0e0 100%);background-image:-o-linear-gradient(top, #fff 0, #e0e0e0 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), to(#e0e0e0));background-image:linear-gradient(to bottom, #fff 0, #e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top, #337ab7 0, #265a88 100%);background-image:-o-linear-gradient(top, #337ab7 0, #265a88 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #337ab7), to(#265a88));background-image:linear-gradient(to bottom, #337ab7 0, #265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#245580}.btn-primary:hover,.btn-primary:focus{background-color:#265a88;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#265a88;border-color:#245580}.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #419641 100%);background-image:-o-linear-gradient(top, #5cb85c 0, #419641 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #5cb85c), to(#419641));background-image:linear-gradient(to bottom, #5cb85c 0, #419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #2aabd2 100%);background-image:-o-linear-gradient(top, #5bc0de 0, #2aabd2 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #5bc0de), to(#2aabd2));background-image:linear-gradient(to bottom, #5bc0de 0, #2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}
|
||
|
</style>
|
||
|
<style>
|
||
|
.graph {
|
||
|
font-family: Arial, Sans-serif;
|
||
|
font-size: 14px;
|
||
|
}
|
||
|
|
||
|
.graph .label {
|
||
|
text-align: center;
|
||
|
padding-top: 5px;
|
||
|
padding-bottom: 5px;
|
||
|
}
|
||
|
.graph-header h3 {
|
||
|
margin-bottom: 0px;
|
||
|
}
|
||
|
.graph-header {
|
||
|
text-align: center;
|
||
|
}
|
||
|
.graph-header p {
|
||
|
margin-top: 0px;
|
||
|
}
|
||
|
|
||
|
.graph .legend td, .graph .legend, .graph .legend tr {
|
||
|
padding: 0px;
|
||
|
margin: 0px;
|
||
|
border-collapse:collapse;
|
||
|
}
|
||
|
|
||
|
.graph .legend {
|
||
|
margin-left: 10px;
|
||
|
}
|
||
|
.graph .legend td {
|
||
|
padding-right: 5px;
|
||
|
}
|
||
|
|
||
|
.graph .legend .color-box {
|
||
|
width: 14px;
|
||
|
height: 10px;
|
||
|
overflow: hidden;
|
||
|
}
|
||
|
</style>
|
||
|
<!--<script type="text/javascript" src="https://www.google.com/jsapi"></script>-->
|
||
|
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
|
||
|
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8; IE=EmulateIE9">
|
||
|
|
||
|
<!--[if IE]><script>
|
||
|
// Copyright 2006 Google Inc.
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
// See the License for the specific language governing permissions and
|
||
|
// limitations under the License.
|
||
|
|
||
|
|
||
|
// Known Issues:
|
||
|
//
|
||
|
// * Patterns are not implemented.
|
||
|
// * Radial gradient are not implemented. The VML version of these look very
|
||
|
// different from the canvas one.
|
||
|
// * Clipping paths are not implemented.
|
||
|
// * Coordsize. The width and height attribute have higher priority than the
|
||
|
// width and height style values which isn't correct.
|
||
|
// * Painting mode isn't implemented.
|
||
|
// * Canvas width/height should is using content-box by default. IE in
|
||
|
// Quirks mode will draw the canvas using border-box. Either change your
|
||
|
// doctype to HTML5
|
||
|
// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
|
||
|
// or use Box Sizing Behavior from WebFX
|
||
|
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
|
||
|
// * Non uniform scaling does not correctly scale strokes.
|
||
|
// * Optimize. There is always room for speed improvements.
|
||
|
|
||
|
// Only add this code if we do not already have a canvas implementation
|
||
|
if (!document.createElement('canvas').getContext) {
|
||
|
|
||
|
(function() {
|
||
|
|
||
|
// alias some functions to make (compiled) code shorter
|
||
|
var m = Math;
|
||
|
var mr = m.round;
|
||
|
var ms = m.sin;
|
||
|
var mc = m.cos;
|
||
|
var abs = m.abs;
|
||
|
var sqrt = m.sqrt;
|
||
|
|
||
|
// this is used for sub pixel precision
|
||
|
var Z = 10;
|
||
|
var Z2 = Z / 2;
|
||
|
|
||
|
/**
|
||
|
* This funtion is assigned to the <canvas> elements as element.getContext().
|
||
|
* @this {HTMLElement}
|
||
|
* @return {CanvasRenderingContext2D_}
|
||
|
*/
|
||
|
function getContext() {
|
||
|
return this.context_ ||
|
||
|
(this.context_ = new CanvasRenderingContext2D_(this));
|
||
|
}
|
||
|
|
||
|
var slice = Array.prototype.slice;
|
||
|
|
||
|
/**
|
||
|
* Binds a function to an object. The returned function will always use the
|
||
|
* passed in {@code obj} as {@code this}.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* g = bind(f, obj, a, b)
|
||
|
* g(c, d) // will do f.call(obj, a, b, c, d)
|
||
|
*
|
||
|
* @param {Function} f The function to bind the object to
|
||
|
* @param {Object} obj The object that should act as this when the function
|
||
|
* is called
|
||
|
* @param {*} var_args Rest arguments that will be used as the initial
|
||
|
* arguments when the function is called
|
||
|
* @return {Function} A new function that has bound this
|
||
|
*/
|
||
|
function bind(f, obj, var_args) {
|
||
|
var a = slice.call(arguments, 2);
|
||
|
return function() {
|
||
|
return f.apply(obj, a.concat(slice.call(arguments)));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
var G_vmlCanvasManager_ = {
|
||
|
init: function(opt_doc) {
|
||
|
if (/MSIE/.test(navigator.userAgent) && !window.opera) {
|
||
|
var doc = opt_doc || document;
|
||
|
// Create a dummy element so that IE will allow canvas elements to be
|
||
|
// recognized.
|
||
|
doc.createElement('canvas');
|
||
|
doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
|
||
|
}
|
||
|
},
|
||
|
|
||
|
init_: function(doc) {
|
||
|
// create xmlns
|
||
|
if (!doc.namespaces['g_vml_']) {
|
||
|
doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml',
|
||
|
'#default#VML');
|
||
|
|
||
|
}
|
||
|
if (!doc.namespaces['g_o_']) {
|
||
|
doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office',
|
||
|
'#default#VML');
|
||
|
}
|
||
|
|
||
|
// Setup default CSS. Only add one style sheet per document
|
||
|
if (!doc.styleSheets['ex_canvas_']) {
|
||
|
var ss = doc.createStyleSheet();
|
||
|
ss.owningElement.id = 'ex_canvas_';
|
||
|
ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
|
||
|
// default size is 300x150 in Gecko and Opera
|
||
|
'text-align:left;width:300px;height:150px}' +
|
||
|
'g_vml_\\:*{behavior:url(#default#VML)}' +
|
||
|
'g_o_\\:*{behavior:url(#default#VML)}';
|
||
|
|
||
|
}
|
||
|
|
||
|
// find all canvas elements
|
||
|
var els = doc.getElementsByTagName('canvas');
|
||
|
for (var i = 0; i < els.length; i++) {
|
||
|
this.initElement(els[i]);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Public initializes a canvas element so that it can be used as canvas
|
||
|
* element from now on. This is called automatically before the page is
|
||
|
* loaded but if you are creating elements using createElement you need to
|
||
|
* make sure this is called on the element.
|
||
|
* @param {HTMLElement} el The canvas element to initialize.
|
||
|
* @return {HTMLElement} the element that was created.
|
||
|
*/
|
||
|
initElement: function(el) {
|
||
|
if (!el.getContext) {
|
||
|
|
||
|
el.getContext = getContext;
|
||
|
|
||
|
// Remove fallback content. There is no way to hide text nodes so we
|
||
|
// just remove all childNodes. We could hide all elements and remove
|
||
|
// text nodes but who really cares about the fallback content.
|
||
|
el.innerHTML = '';
|
||
|
|
||
|
// do not use inline function because that will leak memory
|
||
|
el.attachEvent('onpropertychange', onPropertyChange);
|
||
|
el.attachEvent('onresize', onResize);
|
||
|
|
||
|
var attrs = el.attributes;
|
||
|
if (attrs.width && attrs.width.specified) {
|
||
|
// TODO: use runtimeStyle and coordsize
|
||
|
// el.getContext().setWidth_(attrs.width.nodeValue);
|
||
|
el.style.width = attrs.width.nodeValue + 'px';
|
||
|
} else {
|
||
|
el.width = el.clientWidth;
|
||
|
}
|
||
|
if (attrs.height && attrs.height.specified) {
|
||
|
// TODO: use runtimeStyle and coordsize
|
||
|
// el.getContext().setHeight_(attrs.height.nodeValue);
|
||
|
el.style.height = attrs.height.nodeValue + 'px';
|
||
|
} else {
|
||
|
el.height = el.clientHeight;
|
||
|
}
|
||
|
//el.getContext().setCoordsize_()
|
||
|
}
|
||
|
return el;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function onPropertyChange(e) {
|
||
|
var el = e.srcElement;
|
||
|
|
||
|
switch (e.propertyName) {
|
||
|
case 'width':
|
||
|
el.style.width = el.attributes.width.nodeValue + 'px';
|
||
|
el.getContext().clearRect();
|
||
|
break;
|
||
|
case 'height':
|
||
|
el.style.height = el.attributes.height.nodeValue + 'px';
|
||
|
el.getContext().clearRect();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function onResize(e) {
|
||
|
var el = e.srcElement;
|
||
|
if (el.firstChild) {
|
||
|
el.firstChild.style.width = el.clientWidth + 'px';
|
||
|
el.firstChild.style.height = el.clientHeight + 'px';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
G_vmlCanvasManager_.init();
|
||
|
|
||
|
// precompute "00" to "FF"
|
||
|
var dec2hex = [];
|
||
|
for (var i = 0; i < 16; i++) {
|
||
|
for (var j = 0; j < 16; j++) {
|
||
|
dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function createMatrixIdentity() {
|
||
|
return [
|
||
|
[1, 0, 0],
|
||
|
[0, 1, 0],
|
||
|
[0, 0, 1]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
function matrixMultiply(m1, m2) {
|
||
|
var result = createMatrixIdentity();
|
||
|
|
||
|
for (var x = 0; x < 3; x++) {
|
||
|
for (var y = 0; y < 3; y++) {
|
||
|
var sum = 0;
|
||
|
|
||
|
for (var z = 0; z < 3; z++) {
|
||
|
sum += m1[x][z] * m2[z][y];
|
||
|
}
|
||
|
|
||
|
result[x][y] = sum;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
function copyState(o1, o2) {
|
||
|
o2.fillStyle = o1.fillStyle;
|
||
|
o2.lineCap = o1.lineCap;
|
||
|
o2.lineJoin = o1.lineJoin;
|
||
|
o2.lineWidth = o1.lineWidth;
|
||
|
o2.miterLimit = o1.miterLimit;
|
||
|
o2.shadowBlur = o1.shadowBlur;
|
||
|
o2.shadowColor = o1.shadowColor;
|
||
|
o2.shadowOffsetX = o1.shadowOffsetX;
|
||
|
o2.shadowOffsetY = o1.shadowOffsetY;
|
||
|
o2.strokeStyle = o1.strokeStyle;
|
||
|
o2.globalAlpha = o1.globalAlpha;
|
||
|
o2.arcScaleX_ = o1.arcScaleX_;
|
||
|
o2.arcScaleY_ = o1.arcScaleY_;
|
||
|
o2.lineScale_ = o1.lineScale_;
|
||
|
}
|
||
|
|
||
|
function processStyle(styleString) {
|
||
|
var str, alpha = 1;
|
||
|
|
||
|
styleString = String(styleString);
|
||
|
if (styleString.substring(0, 3) == 'rgb') {
|
||
|
var start = styleString.indexOf('(', 3);
|
||
|
var end = styleString.indexOf(')', start + 1);
|
||
|
var guts = styleString.substring(start + 1, end).split(',');
|
||
|
|
||
|
str = '#';
|
||
|
for (var i = 0; i < 3; i++) {
|
||
|
str += dec2hex[Number(guts[i])];
|
||
|
}
|
||
|
|
||
|
if (guts.length == 4 && styleString.substr(3, 1) == 'a') {
|
||
|
alpha = guts[3];
|
||
|
}
|
||
|
} else {
|
||
|
str = styleString;
|
||
|
}
|
||
|
|
||
|
return {color: str, alpha: alpha};
|
||
|
}
|
||
|
|
||
|
function processLineCap(lineCap) {
|
||
|
switch (lineCap) {
|
||
|
case 'butt':
|
||
|
return 'flat';
|
||
|
case 'round':
|
||
|
return 'round';
|
||
|
case 'square':
|
||
|
default:
|
||
|
return 'square';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This class implements CanvasRenderingContext2D interface as described by
|
||
|
* the WHATWG.
|
||
|
* @param {HTMLElement} surfaceElement The element that the 2D context should
|
||
|
* be associated with
|
||
|
*/
|
||
|
function CanvasRenderingContext2D_(surfaceElement) {
|
||
|
this.m_ = createMatrixIdentity();
|
||
|
|
||
|
this.mStack_ = [];
|
||
|
this.aStack_ = [];
|
||
|
this.currentPath_ = [];
|
||
|
|
||
|
// Canvas context properties
|
||
|
this.strokeStyle = '#000';
|
||
|
this.fillStyle = '#000';
|
||
|
|
||
|
this.lineWidth = 1;
|
||
|
this.lineJoin = 'miter';
|
||
|
this.lineCap = 'butt';
|
||
|
this.miterLimit = Z * 1;
|
||
|
this.globalAlpha = 1;
|
||
|
this.canvas = surfaceElement;
|
||
|
|
||
|
var el = surfaceElement.ownerDocument.createElement('div');
|
||
|
el.style.width = surfaceElement.clientWidth + 'px';
|
||
|
el.style.height = surfaceElement.clientHeight + 'px';
|
||
|
//el.style.overflow = 'hidden';//IE8 fix
|
||
|
el.style.position = 'absolute';
|
||
|
surfaceElement.appendChild(el);
|
||
|
|
||
|
this.element_ = el;
|
||
|
this.arcScaleX_ = 1;
|
||
|
this.arcScaleY_ = 1;
|
||
|
this.lineScale_ = 1;
|
||
|
}
|
||
|
|
||
|
var contextPrototype = CanvasRenderingContext2D_.prototype;
|
||
|
contextPrototype.clearRect = function() {
|
||
|
this.element_.innerHTML = '';
|
||
|
};
|
||
|
|
||
|
contextPrototype.beginPath = function() {
|
||
|
// TODO: Branch current matrix so that save/restore has no effect
|
||
|
// as per safari docs.
|
||
|
this.currentPath_ = [];
|
||
|
};
|
||
|
|
||
|
contextPrototype.moveTo = function(aX, aY) {
|
||
|
var p = this.getCoords_(aX, aY);
|
||
|
this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
|
||
|
this.currentX_ = p.x;
|
||
|
this.currentY_ = p.y;
|
||
|
};
|
||
|
|
||
|
contextPrototype.lineTo = function(aX, aY) {
|
||
|
var p = this.getCoords_(aX, aY);
|
||
|
this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});
|
||
|
|
||
|
this.currentX_ = p.x;
|
||
|
this.currentY_ = p.y;
|
||
|
};
|
||
|
|
||
|
contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
|
||
|
aCP2x, aCP2y,
|
||
|
aX, aY) {
|
||
|
var p = this.getCoords_(aX, aY);
|
||
|
var cp1 = this.getCoords_(aCP1x, aCP1y);
|
||
|
var cp2 = this.getCoords_(aCP2x, aCP2y);
|
||
|
bezierCurveTo(this, cp1, cp2, p);
|
||
|
};
|
||
|
|
||
|
// Helper function that takes the already fixed cordinates.
|
||
|
function bezierCurveTo(self, cp1, cp2, p) {
|
||
|
self.currentPath_.push({
|
||
|
type: 'bezierCurveTo',
|
||
|
cp1x: cp1.x,
|
||
|
cp1y: cp1.y,
|
||
|
cp2x: cp2.x,
|
||
|
cp2y: cp2.y,
|
||
|
x: p.x,
|
||
|
y: p.y
|
||
|
});
|
||
|
self.currentX_ = p.x;
|
||
|
self.currentY_ = p.y;
|
||
|
}
|
||
|
|
||
|
contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
|
||
|
// the following is lifted almost directly from
|
||
|
// http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
|
||
|
|
||
|
var cp = this.getCoords_(aCPx, aCPy);
|
||
|
var p = this.getCoords_(aX, aY);
|
||
|
|
||
|
var cp1 = {
|
||
|
x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
|
||
|
y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
|
||
|
};
|
||
|
var cp2 = {
|
||
|
x: cp1.x + (p.x - this.currentX_) / 3.0,
|
||
|
y: cp1.y + (p.y - this.currentY_) / 3.0
|
||
|
};
|
||
|
|
||
|
bezierCurveTo(this, cp1, cp2, p);
|
||
|
};
|
||
|
|
||
|
contextPrototype.arc = function(aX, aY, aRadius,
|
||
|
aStartAngle, aEndAngle, aClockwise) {
|
||
|
aRadius *= Z;
|
||
|
var arcType = aClockwise ? 'at' : 'wa';
|
||
|
|
||
|
var xStart = aX + mc(aStartAngle) * aRadius - Z2;
|
||
|
var yStart = aY + ms(aStartAngle) * aRadius - Z2;
|
||
|
|
||
|
var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
|
||
|
var yEnd = aY + ms(aEndAngle) * aRadius - Z2;
|
||
|
|
||
|
// IE won't render arches drawn counter clockwise if xStart == xEnd.
|
||
|
if (xStart == xEnd && !aClockwise) {
|
||
|
xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
|
||
|
// that can be represented in binary
|
||
|
}
|
||
|
|
||
|
var p = this.getCoords_(aX, aY);
|
||
|
var pStart = this.getCoords_(xStart, yStart);
|
||
|
var pEnd = this.getCoords_(xEnd, yEnd);
|
||
|
|
||
|
this.currentPath_.push({type: arcType,
|
||
|
x: p.x,
|
||
|
y: p.y,
|
||
|
radius: aRadius,
|
||
|
xStart: pStart.x,
|
||
|
yStart: pStart.y,
|
||
|
xEnd: pEnd.x,
|
||
|
yEnd: pEnd.y});
|
||
|
|
||
|
};
|
||
|
|
||
|
contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
|
||
|
this.moveTo(aX, aY);
|
||
|
this.lineTo(aX + aWidth, aY);
|
||
|
this.lineTo(aX + aWidth, aY + aHeight);
|
||
|
this.lineTo(aX, aY + aHeight);
|
||
|
this.closePath();
|
||
|
};
|
||
|
|
||
|
contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
|
||
|
var oldPath = this.currentPath_;
|
||
|
this.beginPath();
|
||
|
|
||
|
this.moveTo(aX, aY);
|
||
|
this.lineTo(aX + aWidth, aY);
|
||
|
this.lineTo(aX + aWidth, aY + aHeight);
|
||
|
this.lineTo(aX, aY + aHeight);
|
||
|
this.closePath();
|
||
|
this.stroke();
|
||
|
|
||
|
this.currentPath_ = oldPath;
|
||
|
};
|
||
|
|
||
|
contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
|
||
|
var oldPath = this.currentPath_;
|
||
|
this.beginPath();
|
||
|
|
||
|
this.moveTo(aX, aY);
|
||
|
this.lineTo(aX + aWidth, aY);
|
||
|
this.lineTo(aX + aWidth, aY + aHeight);
|
||
|
this.lineTo(aX, aY + aHeight);
|
||
|
this.closePath();
|
||
|
this.fill();
|
||
|
|
||
|
this.currentPath_ = oldPath;
|
||
|
};
|
||
|
|
||
|
contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
|
||
|
var gradient = new CanvasGradient_('gradient');
|
||
|
gradient.x0_ = aX0;
|
||
|
gradient.y0_ = aY0;
|
||
|
gradient.x1_ = aX1;
|
||
|
gradient.y1_ = aY1;
|
||
|
return gradient;
|
||
|
};
|
||
|
|
||
|
contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
|
||
|
aX1, aY1, aR1) {
|
||
|
var gradient = new CanvasGradient_('gradientradial');
|
||
|
gradient.x0_ = aX0;
|
||
|
gradient.y0_ = aY0;
|
||
|
gradient.r0_ = aR0;
|
||
|
gradient.x1_ = aX1;
|
||
|
gradient.y1_ = aY1;
|
||
|
gradient.r1_ = aR1;
|
||
|
return gradient;
|
||
|
};
|
||
|
|
||
|
contextPrototype.drawImage = function(image, var_args) {
|
||
|
var dx, dy, dw, dh, sx, sy, sw, sh;
|
||
|
|
||
|
// to find the original width we overide the width and height
|
||
|
var oldRuntimeWidth = image.runtimeStyle.width;
|
||
|
var oldRuntimeHeight = image.runtimeStyle.height;
|
||
|
image.runtimeStyle.width = 'auto';
|
||
|
image.runtimeStyle.height = 'auto';
|
||
|
|
||
|
// get the original size
|
||
|
var w = image.width;
|
||
|
var h = image.height;
|
||
|
|
||
|
// and remove overides
|
||
|
image.runtimeStyle.width = oldRuntimeWidth;
|
||
|
image.runtimeStyle.height = oldRuntimeHeight;
|
||
|
|
||
|
if (arguments.length == 3) {
|
||
|
dx = arguments[1];
|
||
|
dy = arguments[2];
|
||
|
sx = sy = 0;
|
||
|
sw = dw = w;
|
||
|
sh = dh = h;
|
||
|
} else if (arguments.length == 5) {
|
||
|
dx = arguments[1];
|
||
|
dy = arguments[2];
|
||
|
dw = arguments[3];
|
||
|
dh = arguments[4];
|
||
|
sx = sy = 0;
|
||
|
sw = w;
|
||
|
sh = h;
|
||
|
} else if (arguments.length == 9) {
|
||
|
sx = arguments[1];
|
||
|
sy = arguments[2];
|
||
|
sw = arguments[3];
|
||
|
sh = arguments[4];
|
||
|
dx = arguments[5];
|
||
|
dy = arguments[6];
|
||
|
dw = arguments[7];
|
||
|
dh = arguments[8];
|
||
|
} else {
|
||
|
throw Error('Invalid number of arguments');
|
||
|
}
|
||
|
|
||
|
var d = this.getCoords_(dx, dy);
|
||
|
|
||
|
var w2 = sw / 2;
|
||
|
var h2 = sh / 2;
|
||
|
|
||
|
var vmlStr = [];
|
||
|
|
||
|
var W = 10;
|
||
|
var H = 10;
|
||
|
|
||
|
// For some reason that I've now forgotten, using divs didn't work
|
||
|
vmlStr.push(' <g_vml_:group',
|
||
|
' coordsize="', Z * W, ',', Z * H, '"',
|
||
|
' coordorigin="0,0"' ,
|
||
|
' style="width:', W, 'px;height:', H, 'px;position:absolute;');
|
||
|
|
||
|
// If filters are necessary (rotation exists), create them
|
||
|
// filters are bog-slow, so only create them if abbsolutely necessary
|
||
|
// The following check doesn't account for skews (which don't exist
|
||
|
// in the canvas spec (yet) anyway.
|
||
|
|
||
|
if (this.m_[0][0] != 1 || this.m_[0][1]) {
|
||
|
var filter = [];
|
||
|
|
||
|
// Note the 12/21 reversal
|
||
|
filter.push('M11=', this.m_[0][0], ',',
|
||
|
'M12=', this.m_[1][0], ',',
|
||
|
'M21=', this.m_[0][1], ',',
|
||
|
'M22=', this.m_[1][1], ',',
|
||
|
'Dx=', mr(d.x / Z), ',',
|
||
|
'Dy=', mr(d.y / Z), '');
|
||
|
|
||
|
// Bounding box calculation (need to minimize displayed area so that
|
||
|
// filters don't waste time on unused pixels.
|
||
|
var max = d;
|
||
|
var c2 = this.getCoords_(dx + dw, dy);
|
||
|
var c3 = this.getCoords_(dx, dy + dh);
|
||
|
var c4 = this.getCoords_(dx + dw, dy + dh);
|
||
|
|
||
|
max.x = m.max(max.x, c2.x, c3.x, c4.x);
|
||
|
max.y = m.max(max.y, c2.y, c3.y, c4.y);
|
||
|
|
||
|
vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
|
||
|
'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
|
||
|
filter.join(''), ", sizingmethod='clip');")
|
||
|
} else {
|
||
|
vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
|
||
|
}
|
||
|
|
||
|
vmlStr.push(' ">' ,
|
||
|
'<g_vml_:image src="', image.src, '"',
|
||
|
' style="width:', Z * dw, 'px;',
|
||
|
' height:', Z * dh, 'px;"',
|
||
|
' cropleft="', sx / w, '"',
|
||
|
' croptop="', sy / h, '"',
|
||
|
' cropright="', (w - sx - sw) / w, '"',
|
||
|
' cropbottom="', (h - sy - sh) / h, '"',
|
||
|
' />',
|
||
|
'</g_vml_:group>');
|
||
|
|
||
|
this.element_.insertAdjacentHTML('BeforeEnd',
|
||
|
vmlStr.join(''));
|
||
|
};
|
||
|
|
||
|
contextPrototype.stroke = function(aFill) {
|
||
|
var lineStr = [];
|
||
|
var lineOpen = false;
|
||
|
var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
|
||
|
var color = a.color;
|
||
|
var opacity = a.alpha * this.globalAlpha;
|
||
|
|
||
|
var W = 10;
|
||
|
var H = 10;
|
||
|
|
||
|
lineStr.push('<g_vml_:shape',
|
||
|
' filled="', !!aFill, '"',
|
||
|
' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
|
||
|
' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
|
||
|
' stroked="', !aFill, '"',
|
||
|
' path="');
|
||
|
|
||
|
var newSeq = false;
|
||
|
var min = {x: null, y: null};
|
||
|
var max = {x: null, y: null};
|
||
|
|
||
|
for (var i = 0; i < this.currentPath_.length; i++) {
|
||
|
var p = this.currentPath_[i];
|
||
|
var c;
|
||
|
|
||
|
switch (p.type) {
|
||
|
case 'moveTo':
|
||
|
c = p;
|
||
|
lineStr.push(' m ', mr(p.x), ',', mr(p.y));
|
||
|
break;
|
||
|
case 'lineTo':
|
||
|
lineStr.push(' l ', mr(p.x), ',', mr(p.y));
|
||
|
break;
|
||
|
case 'close':
|
||
|
lineStr.push(' x ');
|
||
|
p = null;
|
||
|
break;
|
||
|
case 'bezierCurveTo':
|
||
|
lineStr.push(' c ',
|
||
|
mr(p.cp1x), ',', mr(p.cp1y), ',',
|
||
|
mr(p.cp2x), ',', mr(p.cp2y), ',',
|
||
|
mr(p.x), ',', mr(p.y));
|
||
|
break;
|
||
|
case 'at':
|
||
|
case 'wa':
|
||
|
lineStr.push(' ', p.type, ' ',
|
||
|
mr(p.x - this.arcScaleX_ * p.radius), ',',
|
||
|
mr(p.y - this.arcScaleY_ * p.radius), ' ',
|
||
|
mr(p.x + this.arcScaleX_ * p.radius), ',',
|
||
|
mr(p.y + this.arcScaleY_ * p.radius), ' ',
|
||
|
mr(p.xStart), ',', mr(p.yStart), ' ',
|
||
|
mr(p.xEnd), ',', mr(p.yEnd));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
// TODO: Following is broken for curves due to
|
||
|
// move to proper paths.
|
||
|
|
||
|
// Figure out dimensions so we can do gradient fills
|
||
|
// properly
|
||
|
if (p) {
|
||
|
if (min.x == null || p.x < min.x) {
|
||
|
min.x = p.x;
|
||
|
}
|
||
|
if (max.x == null || p.x > max.x) {
|
||
|
max.x = p.x;
|
||
|
}
|
||
|
if (min.y == null || p.y < min.y) {
|
||
|
min.y = p.y;
|
||
|
}
|
||
|
if (max.y == null || p.y > max.y) {
|
||
|
max.y = p.y;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
lineStr.push(' ">');
|
||
|
|
||
|
if (!aFill) {
|
||
|
var lineWidth = this.lineScale_ * this.lineWidth;
|
||
|
|
||
|
// VML cannot correctly render a line if the width is less than 1px.
|
||
|
// In that case, we dilute the color to make the line look thinner.
|
||
|
if (lineWidth < 1) {
|
||
|
opacity *= lineWidth;
|
||
|
}
|
||
|
|
||
|
lineStr.push(
|
||
|
'<g_vml_:stroke',
|
||
|
' opacity="', opacity, '"',
|
||
|
' joinstyle="', this.lineJoin, '"',
|
||
|
' miterlimit="', this.miterLimit, '"',
|
||
|
' endcap="', processLineCap(this.lineCap), '"',
|
||
|
' weight="', lineWidth, 'px"',
|
||
|
' color="', color, '" />'
|
||
|
);
|
||
|
} else if (typeof this.fillStyle == 'object') {
|
||
|
var fillStyle = this.fillStyle;
|
||
|
var angle = 0;
|
||
|
var focus = {x: 0, y: 0};
|
||
|
|
||
|
// additional offset
|
||
|
var shift = 0;
|
||
|
// scale factor for offset
|
||
|
var expansion = 1;
|
||
|
|
||
|
if (fillStyle.type_ == 'gradient') {
|
||
|
var x0 = fillStyle.x0_ / this.arcScaleX_;
|
||
|
var y0 = fillStyle.y0_ / this.arcScaleY_;
|
||
|
var x1 = fillStyle.x1_ / this.arcScaleX_;
|
||
|
var y1 = fillStyle.y1_ / this.arcScaleY_;
|
||
|
var p0 = this.getCoords_(x0, y0);
|
||
|
var p1 = this.getCoords_(x1, y1);
|
||
|
var dx = p1.x - p0.x;
|
||
|
var dy = p1.y - p0.y;
|
||
|
angle = Math.atan2(dx, dy) * 180 / Math.PI;
|
||
|
|
||
|
// The angle should be a non-negative number.
|
||
|
if (angle < 0) {
|
||
|
angle += 360;
|
||
|
}
|
||
|
|
||
|
// Very small angles produce an unexpected result because they are
|
||
|
// converted to a scientific notation string.
|
||
|
if (angle < 1e-6) {
|
||
|
angle = 0;
|
||
|
}
|
||
|
} else {
|
||
|
var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_);
|
||
|
var width = max.x - min.x;
|
||
|
var height = max.y - min.y;
|
||
|
focus = {
|
||
|
x: (p0.x - min.x) / width,
|
||
|
y: (p0.y - min.y) / height
|
||
|
};
|
||
|
|
||
|
width /= this.arcScaleX_ * Z;
|
||
|
height /= this.arcScaleY_ * Z;
|
||
|
var dimension = m.max(width, height);
|
||
|
shift = 2 * fillStyle.r0_ / dimension;
|
||
|
expansion = 2 * fillStyle.r1_ / dimension - shift;
|
||
|
}
|
||
|
|
||
|
// We need to sort the color stops in ascending order by offset,
|
||
|
// otherwise IE won't interpret it correctly.
|
||
|
var stops = fillStyle.colors_;
|
||
|
stops.sort(function(cs1, cs2) {
|
||
|
return cs1.offset - cs2.offset;
|
||
|
});
|
||
|
|
||
|
var length = stops.length;
|
||
|
var color1 = stops[0].color;
|
||
|
var color2 = stops[length - 1].color;
|
||
|
var opacity1 = stops[0].alpha * this.globalAlpha;
|
||
|
var opacity2 = stops[length - 1].alpha * this.globalAlpha;
|
||
|
|
||
|
var colors = [];
|
||
|
for (var i = 0; i < length; i++) {
|
||
|
var stop = stops[i];
|
||
|
colors.push(stop.offset * expansion + shift + ' ' + stop.color);
|
||
|
}
|
||
|
|
||
|
// When colors attribute is used, the meanings of opacity and o:opacity2
|
||
|
// are reversed.
|
||
|
lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"',
|
||
|
' method="none" focus="100%"',
|
||
|
' color="', color1, '"',
|
||
|
' color2="', color2, '"',
|
||
|
' colors="', colors.join(','), '"',
|
||
|
' opacity="', opacity2, '"',
|
||
|
' g_o_:opacity2="', opacity1, '"',
|
||
|
' angle="', angle, '"',
|
||
|
' focusposition="', focus.x, ',', focus.y, '" />');
|
||
|
} else {
|
||
|
lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
|
||
|
'" />');
|
||
|
}
|
||
|
|
||
|
lineStr.push('</g_vml_:shape>');
|
||
|
|
||
|
this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
|
||
|
};
|
||
|
|
||
|
contextPrototype.fill = function() {
|
||
|
this.stroke(true);
|
||
|
}
|
||
|
|
||
|
contextPrototype.closePath = function() {
|
||
|
this.currentPath_.push({type: 'close'});
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
contextPrototype.getCoords_ = function(aX, aY) {
|
||
|
var m = this.m_;
|
||
|
return {
|
||
|
x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
|
||
|
y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
|
||
|
}
|
||
|
};
|
||
|
|
||
|
contextPrototype.save = function() {
|
||
|
var o = {};
|
||
|
copyState(this, o);
|
||
|
this.aStack_.push(o);
|
||
|
this.mStack_.push(this.m_);
|
||
|
this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
|
||
|
};
|
||
|
|
||
|
contextPrototype.restore = function() {
|
||
|
copyState(this.aStack_.pop(), this);
|
||
|
this.m_ = this.mStack_.pop();
|
||
|
};
|
||
|
|
||
|
function matrixIsFinite(m) {
|
||
|
for (var j = 0; j < 3; j++) {
|
||
|
for (var k = 0; k < 2; k++) {
|
||
|
if (!isFinite(m[j][k]) || isNaN(m[j][k])) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function setM(ctx, m, updateLineScale) {
|
||
|
if (!matrixIsFinite(m)) {
|
||
|
return;
|
||
|
}
|
||
|
ctx.m_ = m;
|
||
|
|
||
|
if (updateLineScale) {
|
||
|
// Get the line scale.
|
||
|
// Determinant of this.m_ means how much the area is enlarged by the
|
||
|
// transformation. So its square root can be used as a scale factor
|
||
|
// for width.
|
||
|
var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
|
||
|
ctx.lineScale_ = sqrt(abs(det));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
contextPrototype.translate = function(aX, aY) {
|
||
|
var m1 = [
|
||
|
[1, 0, 0],
|
||
|
[0, 1, 0],
|
||
|
[aX, aY, 1]
|
||
|
];
|
||
|
|
||
|
setM(this, matrixMultiply(m1, this.m_), false);
|
||
|
};
|
||
|
|
||
|
contextPrototype.rotate = function(aRot) {
|
||
|
var c = mc(aRot);
|
||
|
var s = ms(aRot);
|
||
|
|
||
|
var m1 = [
|
||
|
[c, s, 0],
|
||
|
[-s, c, 0],
|
||
|
[0, 0, 1]
|
||
|
];
|
||
|
|
||
|
setM(this, matrixMultiply(m1, this.m_), false);
|
||
|
};
|
||
|
|
||
|
contextPrototype.scale = function(aX, aY) {
|
||
|
this.arcScaleX_ *= aX;
|
||
|
this.arcScaleY_ *= aY;
|
||
|
var m1 = [
|
||
|
[aX, 0, 0],
|
||
|
[0, aY, 0],
|
||
|
[0, 0, 1]
|
||
|
];
|
||
|
|
||
|
setM(this, matrixMultiply(m1, this.m_), true);
|
||
|
};
|
||
|
|
||
|
contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
|
||
|
var m1 = [
|
||
|
[m11, m12, 0],
|
||
|
[m21, m22, 0],
|
||
|
[dx, dy, 1]
|
||
|
];
|
||
|
|
||
|
setM(this, matrixMultiply(m1, this.m_), true);
|
||
|
};
|
||
|
|
||
|
contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
|
||
|
var m = [
|
||
|
[m11, m12, 0],
|
||
|
[m21, m22, 0],
|
||
|
[dx, dy, 1]
|
||
|
];
|
||
|
|
||
|
setM(this, m, true);
|
||
|
};
|
||
|
|
||
|
/******** STUBS ********/
|
||
|
contextPrototype.clip = function() {
|
||
|
// TODO: Implement
|
||
|
};
|
||
|
|
||
|
contextPrototype.arcTo = function() {
|
||
|
// TODO: Implement
|
||
|
};
|
||
|
|
||
|
contextPrototype.createPattern = function() {
|
||
|
return new CanvasPattern_;
|
||
|
};
|
||
|
|
||
|
// Gradient / Pattern Stubs
|
||
|
function CanvasGradient_(aType) {
|
||
|
this.type_ = aType;
|
||
|
this.x0_ = 0;
|
||
|
this.y0_ = 0;
|
||
|
this.r0_ = 0;
|
||
|
this.x1_ = 0;
|
||
|
this.y1_ = 0;
|
||
|
this.r1_ = 0;
|
||
|
this.colors_ = [];
|
||
|
}
|
||
|
|
||
|
CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
|
||
|
aColor = processStyle(aColor);
|
||
|
this.colors_.push({offset: aOffset,
|
||
|
color: aColor.color,
|
||
|
alpha: aColor.alpha});
|
||
|
};
|
||
|
|
||
|
function CanvasPattern_() {}
|
||
|
|
||
|
// set up externs
|
||
|
G_vmlCanvasManager = G_vmlCanvasManager_;
|
||
|
CanvasRenderingContext2D = CanvasRenderingContext2D_;
|
||
|
CanvasGradient = CanvasGradient_;
|
||
|
CanvasPattern = CanvasPattern_;
|
||
|
|
||
|
})();
|
||
|
|
||
|
} // if
|
||
|
</script><![endif]-->
|
||
|
<script>
|
||
|
|
||
|
/* == functions.js
|
||
|
---------------------------*/
|
||
|
|
||
|
//google.load("visualization", "1", {packages:["corechart"]});
|
||
|
|
||
|
$(document).ready(function(){
|
||
|
variables = getVariables();
|
||
|
writeOptions(variables);
|
||
|
|
||
|
$('#calculate').click(function(){
|
||
|
calculate();
|
||
|
});
|
||
|
|
||
|
$('input').on('focus', function(){
|
||
|
if($('#results:visible').length > 0){
|
||
|
$('#results').hide();
|
||
|
$('#notes').hide();
|
||
|
$('.breakdown').html('');
|
||
|
$('#graph2').html('');
|
||
|
$('#results-table').html('');
|
||
|
}
|
||
|
});
|
||
|
$("input").bind({
|
||
|
keydown: function(e) {
|
||
|
if(e.which == 8){
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if(e.which >= 48 && e.which <= 57){
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if(e.which==190 && $(e.currentTarget).val().split('.').length === 1){
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
function getVariables(){
|
||
|
var variables = new Array();
|
||
|
|
||
|
$('#vars label, #vars2 label, #vars3 label, #vars4 label').each(function(){
|
||
|
variables.push($(this).html().replace(/\[.*\]\:/, '').replace(/\:/, ''));
|
||
|
});
|
||
|
return variables;
|
||
|
}
|
||
|
|
||
|
function writeOptions(variables){
|
||
|
var times = variables.length;
|
||
|
for(i=0; i<times; i++){
|
||
|
$('#isolate').append('<option value="' + variables[i] + '">' + variables[i] + '</option>');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function calculate(){
|
||
|
// get values for this calculation
|
||
|
var iter = $('#iteration').val();
|
||
|
var inc = $('#increment').val();
|
||
|
var niceTarget = $('#isolate').val();
|
||
|
|
||
|
// convert the target label into a id
|
||
|
var target;
|
||
|
$('label').each(function(){
|
||
|
if($(this).html().indexOf(niceTarget) != -1){
|
||
|
target = $(this).attr('for');
|
||
|
}
|
||
|
});
|
||
|
|
||
|
//get the target unit of messure
|
||
|
var targetMessure = $('#' + target).parents('.form-group').find('label').html().replace(/.*\[/, '').replace(/\]\:/, '');
|
||
|
|
||
|
$('#results-table').html('');
|
||
|
$('#results-table').append('<table cellspacing="0" class="table table-stripped table-hover"></table>');
|
||
|
|
||
|
// row for headings
|
||
|
$('#results table').append('<tr id="headings"><th>' + niceTarget + '</th></tr>');
|
||
|
|
||
|
// fill headings
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
$('#results #headings').append('<th class="var-header">' + roundNumber(targetValIter, 2) + ' ' + targetMessure + '</th>');
|
||
|
}
|
||
|
|
||
|
if(validate(target, iter, inc)){
|
||
|
// make all calculations
|
||
|
|
||
|
// encounter
|
||
|
$('#results-table table').append('<tr class="result-section" id="encounter-section"><td colspan="6">Encounter Rate Results</td></tr>');
|
||
|
maximum_swath(target, iter, inc, true);
|
||
|
used_swath(target, iter, inc, true);
|
||
|
encounter_rate(target, iter, inc, true);
|
||
|
areal_coverage_rate(target, iter, inc, true);
|
||
|
area_covered_acre(target, iter, inc, true);
|
||
|
area_covered_sqmi(target, iter, inc, true);
|
||
|
|
||
|
// recovery
|
||
|
$('#results-table table').append('<tr class="result-section" id="recovery-section"><td colspan="6">Recovery Results</td></tr>');
|
||
|
fluid_recovery(target, iter, inc, true);
|
||
|
emulsion_recovery(target, iter, inc, true);
|
||
|
oil_recovery(target, iter, inc, true);
|
||
|
water_takenon(target, iter, inc, true);
|
||
|
|
||
|
// storage
|
||
|
$('#results-table table').append('<tr class="result-section" id="storage-section"><td colspan="6">Storage Results</td></tr>');
|
||
|
water_retained(target, iter, inc, true);
|
||
|
decant_rate(target, iter, inc, true);
|
||
|
time_to_fill(target, iter, inc, true);
|
||
|
// offload_time(target, iter, inc, true);
|
||
|
time_for_cycle(target, iter, inc, true);
|
||
|
skimming_time(target, iter, inc, true);
|
||
|
skimming_time_percent(target, iter, inc, true);
|
||
|
total_fills(target, iter, inc, true);
|
||
|
|
||
|
// volume
|
||
|
$('#results-table table').append('<tr class="result-section" id="volume-section"><td colspan="6">Volume Results</td></tr>');
|
||
|
total_fluid_volume(target, iter, inc, true);
|
||
|
total_emulsion_volume(target, iter, inc, true);
|
||
|
|
||
|
ersp(target, iter, inc, true);
|
||
|
|
||
|
breakdown(target, iter, inc);
|
||
|
|
||
|
simulation_notes(target, iter, inc);
|
||
|
|
||
|
$('#results').fadeIn();
|
||
|
$('#notes').fadeIn();
|
||
|
|
||
|
drawTimeline(target, iter, inc);
|
||
|
|
||
|
//drawLineGraph(target, iter, inc);
|
||
|
|
||
|
$("#graph1 h3").html('ERSP vs ' + $('#' + target).parents('.form-group').find('label').html().replace(':', ''));
|
||
|
$("#graph1 h5").html($('#' + target).parents('.form-group').find('label').html().replace(':', ''));
|
||
|
|
||
|
drawBarChart(target, iter, inc);
|
||
|
|
||
|
} else {
|
||
|
$('#results').hide();
|
||
|
$('#notes').hide();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function simulation_notes(target, iter, inc){
|
||
|
// reset current notes
|
||
|
$('#notes p.temp').remove();
|
||
|
|
||
|
// offload time greater than 24 - op
|
||
|
// var time = offload_time(target, iter, inc, false);
|
||
|
// var test = false;
|
||
|
// var op = parseFloat($('#optime').val());
|
||
|
// for(i=0; i<iter; i++){
|
||
|
// if(parseFloat((time[i] / 60)) > (24 - op)){
|
||
|
// test = true;
|
||
|
// }
|
||
|
// }
|
||
|
// if(test == true){
|
||
|
// $('#notes .panel-body').append('<p class="temp">Offload not achievable between Operating Periods</p>');
|
||
|
// }
|
||
|
|
||
|
// MES > 1000
|
||
|
var mes = used_swath(target, iter, inc, false);
|
||
|
var test = false;
|
||
|
for(i=0; i<iter; i++){
|
||
|
if(parseFloat(mes[i]) > 1000){
|
||
|
test = true;
|
||
|
}
|
||
|
}
|
||
|
if(test == true){
|
||
|
$('#notes .panel-body').append('<p class="temp">Swath used for calculation may not be achievable</p>');
|
||
|
}
|
||
|
|
||
|
// Emulsion = 0%
|
||
|
var emulsion = parseFloat($('#emulsionper').val());
|
||
|
var test = false;
|
||
|
if(emulsion == 0){
|
||
|
test = true;
|
||
|
}
|
||
|
if(test == true){
|
||
|
$('#notes .panel-body').append('<p class="temp">Emulsion % = 0, all references to Emulsion are for oil only</p>');
|
||
|
}
|
||
|
|
||
|
// optime exceeded 24 hours
|
||
|
var optime = $('#optime').val();
|
||
|
if(optime >= 19 && target == 'optime'){
|
||
|
$('#notes .panel-body').append('<p class="temp">Operating Period can not exceed 24 hours.</p>');
|
||
|
}
|
||
|
|
||
|
// decant rate > decant pump rate
|
||
|
var rate = decant_rate(target, iter, inc, false);
|
||
|
var pump = parseFloat($('#decant-pump').val());
|
||
|
var test = false;
|
||
|
for(i=0; i<iter; i++){
|
||
|
if(rate[i] > pump){
|
||
|
test = true;
|
||
|
}
|
||
|
}
|
||
|
if(test == true){
|
||
|
$('#notes .panel-body').append('<p class="temp">Calculated Decant Rate is greater than Decant Pump Rate</p>');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function breakdown(target, iter, inc){
|
||
|
$('.breakdown').html(' ');
|
||
|
|
||
|
var emulsion = emulsion_water(target, iter, inc, false);
|
||
|
var oil = ersp(target, iter, inc, false);
|
||
|
var water = free_water(target, iter, inc, false);
|
||
|
var i = 0;
|
||
|
var begining = emulsion[0] + oil[0] + water[0];
|
||
|
var ending = emulsion[emulsion.length - 1] + oil[oil.length - 1] + water[water.length - 1];
|
||
|
// figure out the raito based on the trend of getting bigger or smaller in the iteration
|
||
|
if(begining > ending){
|
||
|
window.pixel_ratio = begining / 1050;
|
||
|
} else {
|
||
|
window.pixel_ratio = ending / 1050;
|
||
|
}
|
||
|
if(iter == 1){
|
||
|
breakdown_section('Each Operating Period', 0, emulsion[0], oil[0], water[0], inc, target);
|
||
|
} else {
|
||
|
for(i=0; i<iter; i++){
|
||
|
breakdown_section('Iteration ' + parseInt(i+1), i, emulsion[i], oil[i], water[i], inc, target);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function breakdown_section(title, i, emulsion, oil, water, inc, target){
|
||
|
var total = emulsion + oil + water;
|
||
|
var iter_val = get_targetValIter(target, i, inc);
|
||
|
var niceTarget = $('#isolate').val();
|
||
|
var targetMessure = $('#' + target).parents('.form-group').find('label').html().replace(/.*\[/, '').replace(/\]\:/, '');
|
||
|
|
||
|
var percentage = {
|
||
|
emulsion: Math.round(emulsion / total * 100),
|
||
|
oil: Math.round(oil / total * 100),
|
||
|
water: Math.round(water / total * 100)
|
||
|
};
|
||
|
|
||
|
var html = '' +
|
||
|
'<div class="section-' + i + ' col-md-12 section">' +
|
||
|
'<div class="info clearfix">' +
|
||
|
'<div>' + title + '</div>' +
|
||
|
'<div>' + niceTarget + ' = ' + roundNumber(iter_val, 2) + ' ' + targetMessure + '</div>' +
|
||
|
'<div>Total Recovered and Retained Fluids = ' + addCommas(Math.round(total)) + ' bbl</div>' +
|
||
|
'</div>' +
|
||
|
'<div class="legend clearfix">' +
|
||
|
'<div class="oil"><span class="swatch" style="background:black;"></span> Oil = ' + addCommas(Math.round(oil)) + ' bbl (' + percentage.oil + '%)</div>' +
|
||
|
'<div class="emulsion"><span class="swatch" style="background:#d3d3d3;"></span> Water in Emulsion = ' + addCommas(Math.round(emulsion)) + ' bbl (' + percentage.emulsion + '%)</div>' +
|
||
|
'<div class="water"><span class="swatch" style="background:#0070dc;"></span>Retained Free Water = ' + addCommas(Math.round(water)) + ' bbl (' + percentage.water + '%)</div>' +
|
||
|
'</div>' +
|
||
|
'<div class="graph"></div>' +
|
||
|
'</div>';
|
||
|
$('.breakdown').append(html);
|
||
|
|
||
|
var pixel = {
|
||
|
emulsion: emulsion / window.pixel_ratio,
|
||
|
oil: oil / window.pixel_ratio,
|
||
|
water: water / window.pixel_ratio
|
||
|
}
|
||
|
|
||
|
var paper = Raphael($('.breakdown .section-' + i + ' .graph')[0], 1050);
|
||
|
|
||
|
var dummy_water_rect = paper.rect(0, 0, pixel.oil + pixel.emulsion, 30);
|
||
|
dummy_water_rect.attr('fill', '#0070dc');
|
||
|
dummy_water_rect.attr('stroke-width', 0);
|
||
|
|
||
|
var oil_rect = paper.rect(0, 2, pixel.oil, 26);
|
||
|
oil_rect.attr('fill', 'black');
|
||
|
oil_rect.attr('stroke-width', 0);
|
||
|
|
||
|
var emulsion_rect = paper.rect(pixel.oil, 2, pixel.emulsion, 26);
|
||
|
emulsion_rect.attr('fill', '#d3d3d3');
|
||
|
emulsion_rect.attr('stroke-width', 0);
|
||
|
|
||
|
var water_rect = paper.rect(pixel.oil + pixel.emulsion, 0, pixel.water, 30);
|
||
|
water_rect.attr('fill', '#0070dc');
|
||
|
water_rect.attr('stroke-width', 0);
|
||
|
}
|
||
|
|
||
|
function free_water(target, iter, inc, print){
|
||
|
var tfv = total_fluid_volume(target, iter, inc, false);
|
||
|
var tev = total_emulsion_volume(target, iter, inc, false);
|
||
|
|
||
|
if(print === true){
|
||
|
$('#results-table table').append('<tr id="result-free_water"><td>Total Volume of Free Water Recovered & Retained in Operating Period</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
for(i=0; i<iter; i++){
|
||
|
result = tfv[i] - tev[i];
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-free_water').append('<td>' + addCommas(Math.round(result)) + ' bbl</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function emulsion_water(target, iter, inc, print){
|
||
|
var oil = ersp(target, iter, inc, false);
|
||
|
var tev = total_emulsion_volume(target, iter, inc, false);
|
||
|
|
||
|
if(print === true){
|
||
|
$('#results-table table').append('<tr id="result-emulsion_water"><td>Total Volume of Water in Emulsion Recovered in Operating Period</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
for(i=0; i<iter; i++){
|
||
|
result = tev[i] - oil[i];
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-emulsion_water').append('<td>' + addCommas(Math.round(result)) + ' bbl</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function drawTimeline(target, iter, inc){
|
||
|
// clear the canvas if it exists already
|
||
|
$('#graph2').children().remove();
|
||
|
|
||
|
var paper = Raphael(document.getElementById('graph2'));
|
||
|
var transit = parseFloat($('#transit').val() / 60);
|
||
|
// use time_to_fill instead of skimming_time, skimming_time is total amount of time spent skimming in the op period
|
||
|
var fill_time = time_to_fill(target, iter, inc, false);
|
||
|
var offload = offload_time(target, iter, inc, false);
|
||
|
var op_time;
|
||
|
if(target == 'optime'){
|
||
|
op_time = parseFloat($('#optime').val()) + ((iter - 1) * inc);
|
||
|
if(op_time > 24){
|
||
|
op_time = 24;
|
||
|
}
|
||
|
} else {
|
||
|
op_time = parseFloat($('#optime').val());
|
||
|
}
|
||
|
var max_width = $('#graph2').css('width').replace('px', '');
|
||
|
var max_height = $('#graph2').css('height').replace('px', '');
|
||
|
|
||
|
|
||
|
// title
|
||
|
var title = paper.text(max_width / 2, 10, 'Recovery Cycle Timeline');
|
||
|
title.attr({'font-size': 20});
|
||
|
title.attr({'font-weight': 'bold'});
|
||
|
|
||
|
// draw the guide and legend
|
||
|
var center = max_width / 2;
|
||
|
var legend_width = 267;
|
||
|
var draw_legendbox = paper.rect(center - 133, 25 + 10, legend_width, 25);
|
||
|
|
||
|
// draw the swatches of color and text labels
|
||
|
var draw_legendskim = paper.rect(center - (legend_width / 2) + 5, 30 + 10, 15, 15);
|
||
|
draw_legendskim.attr('fill', 'green');
|
||
|
draw_legendskim.attr('stroke', 'white');
|
||
|
// label skim
|
||
|
draw_legendskimlabel = paper.text(center - (legend_width / 2) + 25, 37 + 10, 'Skim Time');
|
||
|
draw_legendskimlabel.attr({'text-anchor': 'start'});
|
||
|
|
||
|
var draw_legendtransit = paper.rect(center - (legend_width / 2) + 77, 30 + 10, 15, 15);
|
||
|
draw_legendtransit.attr('fill', 'red');
|
||
|
draw_legendtransit.attr('stroke', 'white');
|
||
|
// label transit
|
||
|
draw_legendtransitlabel = paper.text(center - (legend_width / 2) + 97, 37 + 10, 'Transit Time');
|
||
|
draw_legendtransitlabel.attr({'text-anchor': 'start'});
|
||
|
|
||
|
var draw_legendoffload = paper.rect(center - (legend_width / 2) + 158, 30 + 10, 15, 15);
|
||
|
draw_legendoffload.attr('fill', 'orange');
|
||
|
draw_legendoffload.attr('stroke', 'white');
|
||
|
// label offload
|
||
|
draw_legendoffloadlabel = paper.text(center - (legend_width / 2) + 178, 37 + 10, 'Offload/Rig Time');
|
||
|
draw_legendoffloadlabel.attr({'text-anchor': 'start'});
|
||
|
|
||
|
// Guide
|
||
|
//var draw_guideline = paper.path('M0 180L450 180');
|
||
|
//draw_guideline.attr('stroke', 'gray');
|
||
|
// Guide hour label
|
||
|
var draw_guidehourlabel = paper.text(max_width / 2, 75, 'Operating Period [hrs]');
|
||
|
// Guide times
|
||
|
var draw_guidestartlabel = paper.text(3, 95, '0');
|
||
|
draw_guidestartlabel.attr('fill', '#999');
|
||
|
var draw_guideendlabel = paper.text(max_width - 6, 95, op_time);
|
||
|
draw_guideendlabel.attr('fill', '#999');
|
||
|
|
||
|
// new guide
|
||
|
var lines = max_width / op_time;
|
||
|
var grid = Array();
|
||
|
for(i=0; i<lines; i++){
|
||
|
grid[i] = Array();
|
||
|
// grid[i]['line'] = paper.path('M'+lines*i+' 110L'+lines*i+' 450');
|
||
|
// grid[i]['line'].attr('stroke', '#ddd');
|
||
|
if(i != 0 && i != op_time){
|
||
|
grid[i]['label'] = paper.text(lines*i, 95, i);
|
||
|
grid[i]['label'].attr('fill', '#999');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// draw the first cycle for each of the variables
|
||
|
var x = 0;
|
||
|
var y = 120;
|
||
|
var targetMessure = $('#' + target).parents('.form-group').find('label').html().replace(/.*\[/, '').replace(/\]\:/, '');
|
||
|
for(l=0; l<iter; l++){
|
||
|
if(target == 'offload'){
|
||
|
offload = get_targetValIter(target, l, inc);
|
||
|
} else if(target == 'transit'){
|
||
|
transit = get_targetValIter(target, l, inc);
|
||
|
transit = transit / 60;
|
||
|
}
|
||
|
offload[l] = offload[l] / 60;
|
||
|
offload[l] = offload[l] / op_time * max_width;
|
||
|
|
||
|
for(i=0; i<26; i++){
|
||
|
if(x <= max_width){
|
||
|
// draw the skim time for the first cycle
|
||
|
var draw_skim = paper.rect(x, y, fill_time[l] / op_time * max_width, 15);
|
||
|
draw_skim.attr('fill', 'green');
|
||
|
draw_skim.attr('stroke-width', '0');
|
||
|
draw_skim.attr('stroke', 'white');
|
||
|
} else {
|
||
|
var draw_skim = paper.rect(x, y, 450, 15);
|
||
|
draw_skim.attr('fill', 'green');
|
||
|
draw_skim.attr('stroke-width', '0');
|
||
|
draw_skim.attr('stroke', 'white');
|
||
|
}
|
||
|
|
||
|
if(x <= max_width){
|
||
|
// draw the transit time to the unload point for the first cycle
|
||
|
var draw_transit = paper.rect(x + (fill_time[l] / op_time * max_width), y, transit / op_time * max_width, 15);
|
||
|
draw_transit.attr('fill', 'red');
|
||
|
draw_transit.attr('stroke-width', '0');
|
||
|
draw_transit.attr('stroke', 'white');
|
||
|
}
|
||
|
|
||
|
if(x <= max_width){
|
||
|
// draw the unload time for the first cycle
|
||
|
var draw_unload = paper.rect(x + (fill_time[l] / op_time * max_width) + (transit / op_time * max_width), y, offload[l], 15);
|
||
|
draw_unload.attr('fill', 'orange');
|
||
|
draw_unload.attr('stroke-width', '0');
|
||
|
draw_unload.attr('stroke', 'white');
|
||
|
}
|
||
|
|
||
|
if(x <= max_width){
|
||
|
// draw the transit time back to the spill
|
||
|
var draw_transit = paper.rect(x + ((fill_time[l] / op_time * max_width) + (transit / op_time * max_width) + offload[l]), y, transit / op_time * max_width, 15);
|
||
|
draw_transit.attr('fill', 'red');
|
||
|
draw_transit.attr('stroke-width', '0');
|
||
|
draw_transit.attr('stroke', 'white');
|
||
|
}
|
||
|
|
||
|
x = x + ((fill_time[l] / op_time * max_width) + (transit / op_time * max_width) + offload[l] + (transit / op_time * max_width));
|
||
|
}
|
||
|
|
||
|
// draw mask if optime is the target
|
||
|
if(target == 'optime'){
|
||
|
var iter_time = get_targetValIter('optime', l, inc);
|
||
|
var mask_time = op_time - iter_time;
|
||
|
var mask_width = mask_time / op_time * max_width;
|
||
|
var mask = paper.rect(max_width - (mask_time / op_time * max_width), y, mask_width, 15);
|
||
|
mask.attr('fill', 'white');
|
||
|
mask.attr('stroke-width', '0');
|
||
|
mask.attr('stroke', 'white');
|
||
|
}
|
||
|
|
||
|
// label iteration timeline
|
||
|
var targetValIter = get_targetValIter(target, l, inc);
|
||
|
if(target == 'thickness'){
|
||
|
var draw_label = paper.text(3, y - 5, roundNumber(targetValIter, 3) + ' ' + targetMessure);
|
||
|
|
||
|
} else {
|
||
|
var draw_label = paper.text(3, y - 5, roundNumber(targetValIter, 2) + ' ' + targetMessure);
|
||
|
}
|
||
|
|
||
|
draw_label.attr('text-anchor', 'start');
|
||
|
|
||
|
x = 0;
|
||
|
y += 15 + 15;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function drawLineGraph(target, iter, inc){
|
||
|
var data = [[$('#' + target).attr('name'), 'ERSP']];
|
||
|
var recovered = ersp(target, iter, inc, false);
|
||
|
|
||
|
for(i=0; i<iter; i++){
|
||
|
targetValIter = get_targetValIter(target, i, inc);
|
||
|
data.push([targetValIter, Math.round(recovered[i])]);
|
||
|
}
|
||
|
|
||
|
var data = google.visualization.arrayToDataTable(data);
|
||
|
|
||
|
var options = {
|
||
|
title: 'The affect of ' + $('#' + target).siblings('label').html().replace('\:', '') + ' on ERSP',
|
||
|
vAxis: {title: 'ESRP [bbl]', titleTextStyle: {color: 'red'}},
|
||
|
hAxis: {title: $('#' + target).siblings('label').html().replace('\:', ''), titleTextStyle: {color: 'red'}}
|
||
|
};
|
||
|
|
||
|
var chart = new google.visualization.LineChart(document.getElementById('graph1'));
|
||
|
chart.draw(data, options);
|
||
|
}
|
||
|
|
||
|
function drawBarChart(target, iter, inc) {
|
||
|
var recovered = ersp(target, iter, inc, false);
|
||
|
var data = Array(); //'Day, ' + $('#' + target).attr('name') + ', ESRP,\n';
|
||
|
var targetMessure = $('#' + target).parents('.form-group').find('label').html().replace(/.*\[/, '').replace(/\]\:/, '');
|
||
|
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
if(target == "thickness"){
|
||
|
data.push([Math.round(recovered[i]), {label: roundNumber(targetValIter, 3) + ' ' + targetMessure} ]);
|
||
|
} else {
|
||
|
data.push([Math.round(recovered[i]), {label: roundNumber(targetValIter, 2) + ' ' + targetMessure} ]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$('#graph1-area').tufteBar({
|
||
|
data: data,
|
||
|
barWidth: .5,
|
||
|
axisLabel: function(index){
|
||
|
return this[1].label;
|
||
|
},
|
||
|
label: function(index){
|
||
|
return 'ERSP for ';
|
||
|
},
|
||
|
colors: ['green']
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function get_graph_data(target, iter, inc){
|
||
|
var recovered = ersp(target, iter, inc, false);
|
||
|
var data = $('#' + target).attr('name') + ', ESRP,\n';
|
||
|
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
if(target == "thickness"){
|
||
|
data += roundNumber(targetValIter, 3) + ', ' + Math.round(recovered[i]) + ',\n';
|
||
|
} else {
|
||
|
data += roundNumber(targetValIter, 2) + ', ' + Math.round(recovered[i]) + ',\n';
|
||
|
}
|
||
|
}
|
||
|
//alert(data);
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
function validate(target, iter, inc){
|
||
|
var test = true;
|
||
|
// make sure all fields are filled
|
||
|
$('.panel input').each(function(){
|
||
|
if($(this).val() == ''){
|
||
|
test = false;
|
||
|
|
||
|
//alert($(this).attr('id'));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var throughput = $('#throughput').val();
|
||
|
var recovery = $('#recovery').val();
|
||
|
var decant = $('#decant').val();
|
||
|
var emulsion = $('#emulsionper').val();
|
||
|
|
||
|
if(throughput > 100 || recovery > 100 || decant > 100 || emulsion > 100){
|
||
|
alert('Percentages can not be greater than 100%');
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if(test == false){
|
||
|
alert('Please fill in all system information fields');
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
var op = $('#optime').val();
|
||
|
if(op > 24){
|
||
|
alert('Operating Period cannot be greater than 24 hours');
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// if($('#notes .error').length > 0){
|
||
|
// return false;
|
||
|
// }
|
||
|
|
||
|
// swath vars
|
||
|
max_swath = maximum_swath(target, iter, inc, false);
|
||
|
var swath = parseInt($('#swath').val());
|
||
|
|
||
|
// decant rate vars
|
||
|
d_rate = decant_rate(target, iter, inc, false);
|
||
|
d_pump_rate = parseInt($('#decant-pump').val());
|
||
|
|
||
|
if(swath > Math.round(max_swath[0])){
|
||
|
// validate initial swath sizez
|
||
|
alert('This variable set allows for an intial maximum swath size of ' + Math.round(max_swath[0]) + ' ft');
|
||
|
return false;
|
||
|
} else if(d_pump_rate < d_rate[0]){
|
||
|
alert('This variable set must have a Decant Pump Rate of at least ' + roundNumber(d_rate[0], 2) + ' gpm');
|
||
|
return false;
|
||
|
} else {
|
||
|
return true;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function area_covered_sqmi(target, iter, inc, print){
|
||
|
// area_covered_sqmi = area_covered_acre / 640
|
||
|
var area = area_covered_acre(target, iter, inc, false);
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-area-covered-sqmi"><td>Area Covered (sq mi) in Op Period</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water retained
|
||
|
for(i=0; i<iter; i++){
|
||
|
result = area[i] / 640;
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-area-covered-sqmi').append('<td>' + addCommas(roundNumber(result, 2)) + ' sq mi</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function area_covered_acre(target, iter, inc, print){
|
||
|
// area_covered_acre = areal covereage rate * 60 * skimming time
|
||
|
var area = areal_coverage_rate(target, iter, inc, false);
|
||
|
var skimming = skimming_time(target, iter, inc, false);
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-area-covered"><td>Area Covered (acre) in Op Period</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water retained
|
||
|
for(i=0; i<iter; i++){
|
||
|
result = area[i] * 60 * skimming[i];
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-area-covered').append('<td>' + addCommas(Math.round(result)) + ' acres</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function skimming_time_percent(target, iter, inc, print){
|
||
|
// skimming time percent = skimming_time / operating time * 100
|
||
|
var time = skimming_time(target, iter, inc, false);
|
||
|
var operating = parseFloat($('#optime').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-skimmingper"><td>Skimming Time in Operating Period %</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water retained
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'optime'){
|
||
|
result = time[i] / targetValIter * 100;
|
||
|
} else {
|
||
|
result = time[i] / operating * 100;
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-skimmingper').append('<td>' + addCommas(Math.round(result)) + ' %</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function skimming_time(target, iter, inc, print){
|
||
|
// skimming time = time to fill * total fills
|
||
|
var time = time_to_fill(target, iter, inc, false);
|
||
|
var fills = total_fills(target, iter, inc, false);
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-skimming"><td>Skimming Time in Operating Period</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water retained
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
result = time[i] * fills[i];
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-skimming').append('<td>' + addCommas(roundNumber(result, 1)) + ' hr</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function ersp(target, iter, inc, print){
|
||
|
// ersp = total emulsion volume * (1 - emulsionper)
|
||
|
var volume = total_emulsion_volume(target, iter, inc, false);
|
||
|
var emulsion = parseFloat($('#emulsionper').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-ersp"><td><strong>Total Volume Oil Recovered / Operating Period</strong></td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water retained
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'emulsionper'){
|
||
|
result = volume[i] * (1 - (targetValIter / 100));
|
||
|
} else {
|
||
|
result = volume[i] * (1 - (emulsion / 100));
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-ersp').append('<td><strong>' + addCommas(Math.round(result)) + ' bbl</strong></td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function total_emulsion_volume(target, iter, inc, print){
|
||
|
// total emulsion volume = total fluid volume - ( getBblhr(water retained) * time to fill * total fills )
|
||
|
var fluid = total_fluid_volume(target, iter, inc, false);
|
||
|
var water = water_retained(target, iter, inc, false);
|
||
|
var time = time_to_fill(target, iter, inc, false);
|
||
|
var fills = total_fills(target, iter, inc, false);
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-emulsion_volume"><td>Total volume of Oil/Emulsion Recovered / Operating Period</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water retained
|
||
|
for(i=0; i<iter; i++){
|
||
|
|
||
|
result = fluid[i] - ( getBblhr(water[i], true) * time[i] * fills[i] );
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-emulsion_volume').append('<td>' + addCommas(Math.round(result)) + ' bbl</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function total_fluid_volume(target, iter, inc, print){
|
||
|
// total fluid volume = total fills * storage
|
||
|
var fills = total_fills(target, iter, inc, false);
|
||
|
var storage = parseFloat($('#storage').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-fluid_volume"><td>Total Volume Oil/Emulsion + Free Water Recovered / Operating Period</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water retained
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'storage'){
|
||
|
result = fills[i] * targetValIter;
|
||
|
} else {
|
||
|
result = fills[i] * storage;
|
||
|
}
|
||
|
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-fluid_volume').append('<td>' + addCommas(Math.round(result)) + ' bbl</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function total_fills(target, iter, inc, print){
|
||
|
// total fills = Min( ( (skimming time / min(skimming time, time for cycle) - parseInt(skimming time / min(skimming time, time for cycle) ) * min(skimming time, time for cycle), skimming time ) / time for cycle + parseInt( skimming time / min(time for cycle, skimming time) )
|
||
|
// =MIN( ( ( {skimming}/{cycle, skimming}-INT({skimming}/{cycle, skimming}) )*{cycle, skimming} ),fill ) / fill+INT({skimming}/{cycle, skimming})
|
||
|
var op_time = parseFloat($('#optime').val());
|
||
|
var cycle = time_for_cycle(target, iter, inc, false);
|
||
|
var fill = time_to_fill(target, iter, inc, false)
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-totalfillsperop"><td>Total Number of Fills in Operating Period</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water retained
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'optime'){
|
||
|
var sot = Math.min(targetValIter, cycle[i]);
|
||
|
result = Math.min(((targetValIter/sot-parseInt(targetValIter/sot))*sot),fill[i])/fill[i]+parseInt(targetValIter/sot);
|
||
|
} else {
|
||
|
var sot = Math.min(optime, cycle[i]);
|
||
|
result = Math.min(op_time/fill[i],Math.min(((op_time/Math.min(cycle[i],op_time)-parseInt(op_time/Math.min(cycle[i],op_time)))*Math.min(cycle[i],op_time)),fill[i])/fill[i]+parseInt(op_time/Math.min(cycle[i],op_time)));
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-totalfillsperop').append('<td>' + addCommas(roundNumber(result, 1)) + '</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
window.load_defaults = function(){
|
||
|
var dict = [
|
||
|
2,
|
||
|
1,
|
||
|
158,
|
||
|
1000,
|
||
|
75,
|
||
|
75,
|
||
|
2000,
|
||
|
0,
|
||
|
1000,
|
||
|
30,
|
||
|
30,
|
||
|
1000,
|
||
|
0.1,
|
||
|
10
|
||
|
];
|
||
|
$('#vars input[type="text"], #vars2 input[type="text"], #vars3 input[type="text"], #vars4 input[type="text"]').each(function(i){
|
||
|
$(this).val(dict[i])
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function oil_recovery(target, iter, inc, print){
|
||
|
// oil recovery = emulsion rate * (1 - emulsionper);
|
||
|
var recovery = emulsion_recovery(target, iter, inc, false);
|
||
|
var emulsion = parseFloat($('#emulsionper').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-oilrecovery"><td>Oil Recovery Rate</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water retained
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'emulsion'){
|
||
|
result = recover[i] * (1 - (targetValIter / 100));
|
||
|
} else {
|
||
|
result = recovery[i] * (1 - (emulsion / 100));
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-oilrecovery').append('<td>' + addCommas(Math.round(result)) + ' gpm<span>' + getBblhr(result) + ' bbl/hr</span></td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function water_retained(target, iter, inc, print){
|
||
|
// total water retained = (1 - recovery efficiency / 100) * fluid recovery rate * (1 - decant/100);
|
||
|
var recovery = parseFloat($('#recovery').val());
|
||
|
var fluid = fluid_recovery(target, iter, inc, false);
|
||
|
var decant = parseFloat($('#decant').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-waterretained"><td>Water Retained Rate</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water retained
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'recovery'){
|
||
|
result = (1 - targetValIter / 100) * fluid[i] * (1 - decant / 100);
|
||
|
} else if(target == 'decant') {
|
||
|
result = (1 - recovery / 100) * fluid[i] * (1 - targetValIter / 100);
|
||
|
} else {
|
||
|
result = (1 - recovery / 100) * fluid[i] * (1 - decant / 100);
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-waterretained').append('<td>' + addCommas(Math.round(result)) + ' gpm<span>' + getBblhr(result) + ' bbl/hr</span></td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function PF(target, iter, inc, print){
|
||
|
// PF = 53.48 * swath * speed * 1.689 * thickness * throughput / 100
|
||
|
var swath = parseFloat($('#swath').val());
|
||
|
var speed = parseFloat($('#speed').val());
|
||
|
var thickness = parseFloat($('#thickness').val());
|
||
|
var throughput = parseFloat($('#throughput').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-pf"><td>PF</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate pf
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'swath'){
|
||
|
result = 53.48 * targetValIter * speed * 1.689 * thickness * throughput / 100;
|
||
|
} else if(target == 'speed') {
|
||
|
result = 53.48 * swath * targetValIter * 1.689 * thickness * throughput / 100;
|
||
|
} else if(target == 'thickness') {
|
||
|
result = 53.48 * swath * speed * 1.689 * targetValIter * throughput / 100;
|
||
|
} else if(target == 'throughput'){
|
||
|
result = 53.48 * swath * speed * 1.689 * thickness * targetValIter / 100;
|
||
|
} else {
|
||
|
result = 53.48 * swath * speed * 1.689 * thickness * throughput / 100;
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-pf').append('<td>' + addCommas(roundNumber(result, 2)) + ' bbl/hr</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function time_for_cycle(target, iter, inc, print){
|
||
|
// time for cycle = time_to_fill + (offload / 60) + (2 * transit / 60)
|
||
|
var fill = time_to_fill(target, iter, inc, false);
|
||
|
var transit = parseFloat($('#transit').val());
|
||
|
var offload = offload_time(target, iter, inc, false);
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-cycle"><td>Time for One Full Cycle (skimming, transit, rig + derig, offload, transit)</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'offload'){
|
||
|
result = fill[i] + (targetValIter / 60) + (2 * transit / 60);
|
||
|
} else if(target == 'transit') {
|
||
|
result = fill[i] + (parseFloat(offload[i]) / 60) + (2 * targetValIter / 60);
|
||
|
} else {
|
||
|
result = fill[i] + (parseFloat(offload[i]) / 60) + (2 * transit / 60);
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-cycle').append('<td>' + addCommas(roundNumber(result, 1)) + ' hr</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function time_to_fill(target, iter, inc, print){
|
||
|
// time to fill = 0.7 * storage / (emulsion_recovery + (water_takenon - decant_rate))
|
||
|
var water = water_takenon(target, iter, inc, false);
|
||
|
var decant = decant_rate(target, iter, inc, false);
|
||
|
var emulsion = emulsion_recovery(target, iter, inc, false);
|
||
|
var storage = parseFloat($('#storage').val());
|
||
|
var op_time = parseFloat($('#optime').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-time"><td>Time To Fill Onboard Storage</td></tr>');
|
||
|
}
|
||
|
var output = new Array();
|
||
|
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'storage'){
|
||
|
result = 0.7 * targetValIter / (emulsion[i] + (water[i] - decant[i]));
|
||
|
} else {
|
||
|
result = 0.7 * storage / (emulsion[i] + (water[i] - decant[i]));
|
||
|
}
|
||
|
|
||
|
if(result > op_time){
|
||
|
//result = op_time;
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-time').append('<td>' + addCommas(roundNumber(result, 1)) + ' hr</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function decant_rate(target, iter, inc, print){
|
||
|
// decant rate = water taken * decant / 100
|
||
|
var water = water_takenon(target, iter, inc, false);
|
||
|
var decant = parseFloat($('#decant').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-decant"><td>Decant Rate</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate decant rate
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'decant'){
|
||
|
result = water[i] * targetValIter / 100;
|
||
|
} else {
|
||
|
result = water[i] * decant / 100;
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-decant').append('<td>' + addCommas(Math.round(result)) + ' gpm<span>' + getBblhr(result) + ' bbl/hr</span></td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function water_takenon(target, iter, inc, print){
|
||
|
// water taken on = fluid recovery - emulsion recovery
|
||
|
var fluid = fluid_recovery(target, iter, inc, false);
|
||
|
var emulsion = emulsion_recovery(target, iter, inc, false);
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-watertaken"><td>Free Water Recovery Rate</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate water taken on
|
||
|
for(i=0; i<iter; i++){
|
||
|
result = fluid[i] - emulsion[i];
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-watertaken').append('<td>' + addCommas(Math.round(result)) + ' gpm<span>' + getBblhr(result) + ' bbl/hr</span></td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function emulsion_recovery(target, iter, inc, print){
|
||
|
// emulsion recovery = encounter rate * throughput / 100
|
||
|
var encounter = encounter_rate(target, iter, inc, false);
|
||
|
var throughput = parseFloat($('#throughput').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-emulsion"><td>Emulsion Recovery Rate</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate emulsion recovery
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'throughput'){
|
||
|
result = encounter[i] * targetValIter / 100;
|
||
|
} else {
|
||
|
result = encounter[i] * throughput / 100;
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-emulsion').append('<td>' + addCommas(Math.round(result)) + ' gpm<span>' + getBblhr(result) + ' bbl/hr</span></td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function maximum_swath(target, iter, inc, print){
|
||
|
// maximum swath = nameplate * recovery / (63.13 * speed * thickness * throughput)
|
||
|
var throughput = parseFloat($('#throughput').val());
|
||
|
var recovery = parseFloat($('#recovery').val());
|
||
|
var thickness = parseFloat($('#thickness').val());
|
||
|
var speed = parseFloat($('#speed').val());
|
||
|
var nameplate = parseFloat($('#nameplate-pump').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-swath"><td>Maximum Effective Swath</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate maximum swath
|
||
|
for(i=0; i<iter; i++){
|
||
|
if(target != 'swath'){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
}
|
||
|
|
||
|
if(target == 'nameplate-pump') {
|
||
|
result = targetValIter * recovery / (63.13 * speed * thickness * throughput);
|
||
|
} else if(target == 'recovery') {
|
||
|
result = nameplate * targetValIter / (63.13 * speed * thickness * throughput);
|
||
|
} else if(target == 'speed') {
|
||
|
result = nameplate * recovery / (63.13 * targetValIter * thickness * throughput);
|
||
|
} else if(target == 'thickness') {
|
||
|
result = nameplate * recovery / (63.13 * speed * targetValIter * throughput);
|
||
|
} else if(target == 'throughput') {
|
||
|
result = nameplate * recovery / (63.13 * speed * thickness * targetValIter);
|
||
|
} else {
|
||
|
result = nameplate * recovery / (63.13 * speed * thickness * throughput);
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-swath').append('<td>' + addCommas(Math.round(result)) + ' ft</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function used_swath(target, iter, inc, print){
|
||
|
// display which swath was used
|
||
|
var max = maximum_swath(target, iter, inc, false);
|
||
|
var swath = parseFloat($('#swath').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-used-swath"><td>Swath Used For Calculation</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate which swath was used
|
||
|
for(i=0; i<iter; i++){
|
||
|
if(target == 'swath'){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(targetValIter > max[i]){
|
||
|
result = max[i];
|
||
|
} else {
|
||
|
result = targetValIter;
|
||
|
}
|
||
|
} else {
|
||
|
if(swath > max[i]){
|
||
|
result = max[i]
|
||
|
} else {
|
||
|
result = swath;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-used-swath').append('<td>' + addCommas(Math.round(result)) + ' ft</td>');
|
||
|
} else {
|
||
|
output.push(result);
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function fluid_recovery(target, iter, inc, print){
|
||
|
// fluid recover = encounter_rate * (throughput/100)/(recovery/100)
|
||
|
var throughput = parseFloat($('#throughput').val());
|
||
|
var recovery = parseFloat($('#recovery').val());
|
||
|
var encounter = encounter_rate(target, iter, inc, false);
|
||
|
var nameplate = parseInt($('#nameplate-pump').val());
|
||
|
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-recovery"><td>Total Fluid Recovery Rate</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
//calculate fluid recovery rate
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
|
||
|
if(target == 'throughput'){
|
||
|
result = encounter[i] * (targetValIter/100) / (recovery/100);
|
||
|
} else if(target == 'recovery') {
|
||
|
result = encounter[i] * (throughput/100) / (targetValIter/100);
|
||
|
} else {
|
||
|
result = encounter[i] * (throughput/100) / (recovery/100);
|
||
|
}
|
||
|
|
||
|
if(result > nameplate){
|
||
|
result = nameplate;
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-recovery').append('<td>' + addCommas(Math.round(result)) + ' gpm<span>' + getBblhr(result) + ' bbl/hr</span></td>')
|
||
|
} else {
|
||
|
output.push(parseFloat(result));
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function encounter_rate(target, iter, inc, print){
|
||
|
var thickness = parseFloat($('#thickness').val());
|
||
|
var speed = parseFloat($('#speed').val());
|
||
|
var nameplate = parseInt($('#nameplate-pump').val());
|
||
|
var max_swath = maximum_swath(target, iter, inc, false);
|
||
|
|
||
|
|
||
|
// setup table
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-encounter"><td>Oil/Emulsion Encounter Rate</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
// calculate encounter rate
|
||
|
for(i=0; i<iter; i++){
|
||
|
var swath = parseFloat($('#swath').val());
|
||
|
|
||
|
// encounter rate = thickness x speed x swath x 63.13
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(swath > max_swath[i]){
|
||
|
swath = max_swath[i];
|
||
|
}
|
||
|
|
||
|
if(target == 'thickness'){
|
||
|
result = targetValIter * speed * swath * 63.13;
|
||
|
} else if(target == 'speed') {
|
||
|
result = thickness * targetValIter * swath * 63.13;
|
||
|
} else if(target == 'swath') {
|
||
|
result = thickness * speed * targetValIter * 63.13;
|
||
|
} else {
|
||
|
result = thickness * speed * swath * 63.13;
|
||
|
}
|
||
|
|
||
|
if(result > nameplate){
|
||
|
//result = nameplate;
|
||
|
}
|
||
|
|
||
|
// if print is true write the result into the table if not push the value into an output var
|
||
|
if(print == true){
|
||
|
$('#results #result-encounter').append('<td>' + addCommas(Math.round(result)) + ' gpm<span>' + getBblhr(result) + ' bbl/hr</span></td>');
|
||
|
} else {
|
||
|
output.push(parseFloat(result));
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function areal_coverage_rate(target, iter, inc, print){
|
||
|
var speed = parseFloat($('#speed').val());
|
||
|
var max_swath = maximum_swath(target, iter, inc, false);
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-areal"><td>Areal Coverage Rate</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
|
||
|
for(i=0; i<iter; i++){
|
||
|
var swath = parseFloat($('#swath').val());
|
||
|
|
||
|
// aerial coverage rate = swath * speed / 430
|
||
|
if(swath > max_swath[i]){
|
||
|
swath = max_swath[i]
|
||
|
} else {
|
||
|
swath = parseFloat($('#swath').val());
|
||
|
}
|
||
|
|
||
|
targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'swath'){
|
||
|
result = targetValIter * speed / 430;
|
||
|
} else if(target == 'speed'){
|
||
|
result = swath * targetValIter / 430;
|
||
|
} else {
|
||
|
result = swath * speed / 430;
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-areal').append('<td>' + addCommas(parseFloat(roundNumber(result, 2))) + ' acres/min</td>');
|
||
|
} else {
|
||
|
output.push(parseFloat(result));
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function offload_time(target, iter, inc, print){
|
||
|
var storage = parseFloat($('#storage').val());
|
||
|
var discharge = parseFloat($('#discharge-pump').val());
|
||
|
var rig = parseFloat($('#rig').val());
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results table').append('<tr id="result-offload"><td>Time to Offload Full Tank(s)</td></tr>');
|
||
|
}
|
||
|
|
||
|
var output = new Array();
|
||
|
for(i=0; i<iter; i++){
|
||
|
var targetValIter = get_targetValIter(target, i, inc);
|
||
|
|
||
|
if(target == 'storage'){
|
||
|
result = (targetValIter * 42 / discharge) + rig;
|
||
|
} else if (target == 'discharge-pump') {
|
||
|
result = (storage * 42 / targetValIter) + rig;
|
||
|
} else {
|
||
|
result = (storage * 42 / discharge) + rig;
|
||
|
}
|
||
|
|
||
|
if(print == true){
|
||
|
$('#results #result-offload').append('<td>' + addCommas(parseFloat(roundNumber(result, 2))) + ' min</td>');
|
||
|
} else {
|
||
|
output.push(parseFloat(result));
|
||
|
}
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
|
||
|
function get_targetValIter(target, i, inc){
|
||
|
var targetVal = get_targetVal(target);
|
||
|
var targetValIter;
|
||
|
if(target == 'swath'){
|
||
|
// if the target is swath then make sure it isn't going to exceed the maximum effective swath
|
||
|
var max = maximum_swath(target, i, inc, false);
|
||
|
targetValIter = targetVal + (inc * i);
|
||
|
|
||
|
if(targetValIter > max[max.length - 1]){
|
||
|
targetValIter = max[max.length - 1];
|
||
|
}
|
||
|
} else if (target == 'decant' || target == 'emulsion'){
|
||
|
if((targetVal + (inc * i)) > 100){
|
||
|
targetValIter = 100;
|
||
|
} else {
|
||
|
targetValIter = targetVal + (inc * i);
|
||
|
}
|
||
|
} else if (target == 'optime'){
|
||
|
if((targetVal + (inc * i)) > 24){
|
||
|
targetValIter = 24;
|
||
|
} else {
|
||
|
targetValIter = targetVal + (inc * i);
|
||
|
}
|
||
|
} else {
|
||
|
targetValIter = targetVal + (inc * i);
|
||
|
}
|
||
|
|
||
|
return targetValIter;
|
||
|
}
|
||
|
|
||
|
function get_targetVal(target){
|
||
|
// get the target value
|
||
|
var targetVal = parseFloat($('#' + target).val());
|
||
|
return targetVal;
|
||
|
}
|
||
|
|
||
|
function addCommas(nStr){
|
||
|
nStr += '';
|
||
|
x = nStr.split('.');
|
||
|
x1 = x[0];
|
||
|
x2 = x.length > 1 ? '.' + x[1] : '';
|
||
|
var rgx = /(\d+)(\d{3})/;
|
||
|
while (rgx.test(x1)) {
|
||
|
x1 = x1.replace(rgx, '$1' + ',' + '$2');
|
||
|
}
|
||
|
return x1 + x2;
|
||
|
}
|
||
|
|
||
|
function getBblhr(gpm, integer){
|
||
|
if(integer == false || integer == null || integer == undefined){
|
||
|
return addCommas(parseInt(gpm * 1.43));
|
||
|
} else {
|
||
|
return Math.round(gpm * 1.43);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function roundNumber(num, dec) {
|
||
|
var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
|
||
|
return result;
|
||
|
}
|
||
|
</script>
|
||
|
<style>
|
||
|
|
||
|
.container{
|
||
|
width: 1080px !important;
|
||
|
}
|
||
|
|
||
|
textarea{
|
||
|
resize: none;
|
||
|
}
|
||
|
|
||
|
.calculate-wrapper{
|
||
|
text-align: center;
|
||
|
}
|
||
|
#calculate{
|
||
|
width: 200px;
|
||
|
}
|
||
|
|
||
|
.calculator .panel-body{
|
||
|
font-size: 12px;
|
||
|
}
|
||
|
|
||
|
/* == style.css
|
||
|
---------------------------*/
|
||
|
|
||
|
body, html{
|
||
|
font-family: arial, sans-serif;
|
||
|
font-size: 14px;
|
||
|
}
|
||
|
h1{
|
||
|
text-align: center;
|
||
|
}
|
||
|
.container p{
|
||
|
margin: 5px 0;
|
||
|
}
|
||
|
table{
|
||
|
width: 100%;
|
||
|
}
|
||
|
|
||
|
.panel-body table{
|
||
|
margin-bottom: 0;
|
||
|
}
|
||
|
|
||
|
textarea{
|
||
|
resize: none;
|
||
|
}
|
||
|
|
||
|
|
||
|
.title{
|
||
|
margin: 10px 0;
|
||
|
}
|
||
|
|
||
|
.title h1{
|
||
|
font-size: 25px;
|
||
|
font-weight: 500;
|
||
|
margin: 0 0 10px;
|
||
|
text-align: center;
|
||
|
}
|
||
|
.title img{
|
||
|
width: 100px;
|
||
|
height: 100px;
|
||
|
}
|
||
|
.title span{
|
||
|
font-size: 10px;
|
||
|
color: #676767;
|
||
|
}
|
||
|
|
||
|
.disclaimer{
|
||
|
font-size: 13px;
|
||
|
color: #7F7F7F;
|
||
|
}
|
||
|
|
||
|
.form-group.last{
|
||
|
margin-bottom: 0;
|
||
|
}
|
||
|
|
||
|
/* == breakdown */
|
||
|
.breakdown .section{
|
||
|
|
||
|
}
|
||
|
|
||
|
.breakdown .section .graph{
|
||
|
width: 100%;
|
||
|
margin-top: 10px;
|
||
|
height: 30px;
|
||
|
margin-bottom: 30px;
|
||
|
}
|
||
|
|
||
|
.breakdown .section .info{
|
||
|
font-size: 12px;
|
||
|
line-height: 20px;
|
||
|
margin-bottom: 10px;
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
|
||
|
.breakdown .section .info div{
|
||
|
float: left;
|
||
|
margin-right: 30px;
|
||
|
}
|
||
|
|
||
|
.breakdown .section .legend{
|
||
|
font-style: italic;
|
||
|
font-size: 12px;
|
||
|
line-height: 20px;
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
|
||
|
.breakdown .section .legend div{
|
||
|
float: left;
|
||
|
margin-right: 30px;
|
||
|
}
|
||
|
|
||
|
.breakdown .section .legend div .swatch{
|
||
|
display: block;
|
||
|
float: left;
|
||
|
height: 20px;
|
||
|
width: 20px;
|
||
|
margin-right: 5px;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* == wrapper */
|
||
|
#wrapper{
|
||
|
width: 980px;
|
||
|
margin: 0 auto;
|
||
|
}
|
||
|
|
||
|
/* == vars */
|
||
|
#vars{
|
||
|
float: left;
|
||
|
}
|
||
|
#vars input, #vars textarea{
|
||
|
margin-right: 99px;
|
||
|
margin-right: 110px \0/;
|
||
|
}
|
||
|
#vars textarea{
|
||
|
resize: none;
|
||
|
}
|
||
|
#vars #name{
|
||
|
width: 250px;
|
||
|
margin-right: 0;
|
||
|
}
|
||
|
#vars2{
|
||
|
float: right;
|
||
|
}
|
||
|
|
||
|
/* == experimental */
|
||
|
#experimental{
|
||
|
margin-right: 140px;
|
||
|
clear: both;
|
||
|
width: 940px;
|
||
|
margin-bottom: 0;
|
||
|
}
|
||
|
#experimental input{
|
||
|
width: 156px;
|
||
|
}
|
||
|
#experimental select{
|
||
|
width: 160px;
|
||
|
}
|
||
|
#experimental p {
|
||
|
float: left;
|
||
|
margin-right: 15px;
|
||
|
}
|
||
|
|
||
|
#results{
|
||
|
display: none;
|
||
|
}
|
||
|
|
||
|
/* == results-table */
|
||
|
|
||
|
#results-table table th:first-of-type{
|
||
|
text-align: right;
|
||
|
}
|
||
|
#results-table td span{
|
||
|
display: block;
|
||
|
font-size: 10px;
|
||
|
}
|
||
|
#results-table table th {
|
||
|
border: 1px solid lightgrey;
|
||
|
}
|
||
|
#results-table table th{
|
||
|
text-align: center;
|
||
|
}
|
||
|
#results-table table tbody tr td:first-of-type{
|
||
|
text-align: left;
|
||
|
vertical-align: middle;
|
||
|
}
|
||
|
#results-table table tbody tr td{
|
||
|
text-align: center;
|
||
|
border: 1px solid lightgrey;
|
||
|
}
|
||
|
#results-table .result-section{
|
||
|
font-weight: bold;
|
||
|
background: lightgrey;
|
||
|
}
|
||
|
#results-table .result-section td{
|
||
|
text-decoration: italic;
|
||
|
}
|
||
|
|
||
|
|
||
|
.graph{
|
||
|
height: 450px;
|
||
|
}
|
||
|
#graph1{
|
||
|
height: 300px;
|
||
|
}
|
||
|
#graph1-area{
|
||
|
height: 300px;
|
||
|
}
|
||
|
#graph1 h3{
|
||
|
font-size: 20px;
|
||
|
margin: 0 0 25px;
|
||
|
text-align: center;
|
||
|
}
|
||
|
#graph2{
|
||
|
height: 265px;
|
||
|
margin-bottom: 30px;
|
||
|
}
|
||
|
|
||
|
.dygraph-xlabel{
|
||
|
text-transform: capitalize;
|
||
|
}
|
||
|
|
||
|
#notes{
|
||
|
display: none;
|
||
|
}
|
||
|
#notes h3{
|
||
|
margin: 4px 0;
|
||
|
font-size: 20px;
|
||
|
}
|
||
|
#notes p{
|
||
|
margin: 0;
|
||
|
}
|
||
|
|
||
|
/* == clearfix */
|
||
|
.clearfix:after {
|
||
|
content: ".";
|
||
|
display: block;
|
||
|
clear: both;
|
||
|
visibility: hidden;
|
||
|
line-height: 0;
|
||
|
height: 0;
|
||
|
}
|
||
|
|
||
|
html[xmlns] .clearfix {
|
||
|
display: block;
|
||
|
}
|
||
|
|
||
|
* html .clearfix {
|
||
|
height: 1%;
|
||
|
}
|
||
|
|
||
|
/* ==== PRINT ==== */
|
||
|
@media print{
|
||
|
h1{
|
||
|
display: none;
|
||
|
}
|
||
|
#calculate{
|
||
|
display: none;
|
||
|
}
|
||
|
.container{
|
||
|
padding: 0;
|
||
|
margin-bottom: 0;
|
||
|
}
|
||
|
#experimental input{
|
||
|
width: 50px;
|
||
|
}
|
||
|
#results td{
|
||
|
height: 20px;
|
||
|
}
|
||
|
#results td span{
|
||
|
display: none;
|
||
|
}
|
||
|
#results{
|
||
|
margin-bottom: 10px;
|
||
|
}
|
||
|
#results td:nth-child(even), #results th:nth-child(even){
|
||
|
background: none;
|
||
|
}
|
||
|
#graph1{
|
||
|
clear: none;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* ==== IE ==== /*
|
||
|
|
||
|
|
||
|
/* ==== IE 7 ==== */
|
||
|
*+html #calculate{
|
||
|
padding: 6px 20px;
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="container">
|
||
|
<div class="row title">
|
||
|
<h1>Recovery System Evaluation Tool (ReSET) <small>v-160301</small></h1>
|
||
|
</div>
|
||
|
<div class="row">
|
||
|
<div class="calculator col-md-12">
|
||
|
<div class="well">
|
||
|
<div class="row">
|
||
|
<div class="col-md-4">
|
||
|
<div class="row">
|
||
|
<div class="col-md-12">
|
||
|
<div class="panel panel-default" id="vars">
|
||
|
<div class="panel-heading">Encounter Rate</div>
|
||
|
<div class="panel-body">
|
||
|
<form class="form-horizontal">
|
||
|
<div class="form-group">
|
||
|
<label for="optime" class="control-label col-md-8">Operating Period [hrs]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="optime" name="optime" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
<div class="form-group">
|
||
|
<label for="speed" class="control-label col-md-8">Speed [kts]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="speed" name="speed" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
<div class="form-group last">
|
||
|
<label for="swath" class="control-label col-md-8">Swath [ft]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="swath" name="swath" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="row">
|
||
|
<div class="col-md-12">
|
||
|
<div class="panel panel-default" id="vars4">
|
||
|
<div class="panel-heading">Environment</div>
|
||
|
<div class="panel-body">
|
||
|
<form class="form-horizontal">
|
||
|
<div class="form-group">
|
||
|
<label for="thickness" class="control-label col-md-5">Thickness [in]:</label>
|
||
|
<div class="col-md-4">
|
||
|
<input type="text" class="form-control" id="thickness" name="thickness">
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="form-group">
|
||
|
<label for="emulsionper" class="control-label col-md-5">Emulsion [%]:</label>
|
||
|
<div class="col-md-4">
|
||
|
<input type="text" class="form-control" id="emulsionper">
|
||
|
</div>
|
||
|
</div>
|
||
|
</form>
|
||
|
<p><strong>From ERSP Calculator:</strong></p>
|
||
|
<table class="table table-condensed">
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th></th>
|
||
|
<th>OP1</th>
|
||
|
<th>OP2</th>
|
||
|
<th>OP3</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td style="text-align:right">Thickness [in]:</td>
|
||
|
<td>0.1</td>
|
||
|
<td>0.05</td>
|
||
|
<td>0.025</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td style="text-align:right">Emulsion [%]:</td>
|
||
|
<td>35</td>
|
||
|
<td>55</td>
|
||
|
<td>75</td>
|
||
|
</tr>
|
||
|
</tbody></table>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="col-md-4">
|
||
|
<div class="row">
|
||
|
<div class="col-md-12">
|
||
|
<div class="panel panel-default" id="vars2">
|
||
|
<div class="panel-heading">Recovery</div>
|
||
|
<div class="panel-body">
|
||
|
<form class="form-horizontal">
|
||
|
<div class="form-group">
|
||
|
<label for="nameplate-pump" class="control-label col-md-8">Maximum Total Fluid Recovery Rate [gpm]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="nameplate-pump" name="nameplate-pump" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
<div class="form-group">
|
||
|
<label for="throughput" class="control-label col-md-8">Throughput Efficiency [%]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="throughput" name="throughput" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
<div class="form-group last">
|
||
|
<label for="recovery" class="control-label col-md-8">Recovery Efficiency [%]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="recovery" name="recovery" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="row">
|
||
|
<div class="col-md-12">
|
||
|
<div class="panel panel-default">
|
||
|
<div class="panel-heading">Isolation</div>
|
||
|
<div class="panel-body">
|
||
|
<div class="form-horizontal">
|
||
|
<div class="form-group">
|
||
|
<label for="isolate" class="control-label col-md-4">Parameter:</label>
|
||
|
<div class="col-md-8">
|
||
|
<select id="isolate" class="form-control"><option value="Operating Period ">Operating Period </option><option value="Speed ">Speed </option><option value="Swath ">Swath </option><option value="Thickness ">Thickness </option><option value="Emulsion ">Emulsion </option><option value="Maximum Total Fluid Recovery Rate ">Maximum Total Fluid Recovery Rate </option><option value="Throughput Efficiency ">Throughput Efficiency </option><option value="Recovery Efficiency ">Recovery Efficiency </option><option value="On-Board Storage ">On-Board Storage </option><option value="Percent Decant ">Percent Decant </option><option value="Decant Pump Rate ">Decant Pump Rate </option><option value="Offload Rig + Derig Time ">Offload Rig + Derig Time </option><option value="One Way Transit Time to Offload ">One Way Transit Time to Offload </option><option value="Discharge Pump Rate ">Discharge Pump Rate </option></select>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="form-group">
|
||
|
<label for="iteration" class="control-label col-md-4">Iterations:</label>
|
||
|
<div class="col-md-8">
|
||
|
<select id="iteration" class="form-control">
|
||
|
<option>1</option>
|
||
|
<option>2</option>
|
||
|
<option>3</option>
|
||
|
<option>4</option>
|
||
|
<option>5</option>
|
||
|
</select>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="form-group last">
|
||
|
<label for="increment" class="control-label col-md-4">Increment:</label>
|
||
|
<div class="col-md-8">
|
||
|
<input type="text" id="increment" class="form-control" value="1">
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="col-md-4">
|
||
|
<div class="panel panel-default" id="vars3">
|
||
|
<div class="panel-heading">Storage</div>
|
||
|
<div class="panel-body">
|
||
|
<form class="form-horizontal">
|
||
|
<div class="form-group">
|
||
|
<label for="storage" class="control-label col-md-8">On-Board Storage [bbl]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="storage" name="storage" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
<div class="form-group">
|
||
|
<label for="decant" class="control-label col-md-8">Percent Decant [%]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="decant" name="decant" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
<div class="form-group">
|
||
|
<label for="decant-pump" class="control-label col-md-8">Decant Pump Rate [gpm]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="decant-pump" name="decant-pump" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
<div class="form-group">
|
||
|
<label for="rig" class="control-label col-md-8">Offload Rig + Derig Time [min]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="rig" name="rig" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
<div class="form-group">
|
||
|
<label for="transit" class="control-label col-md-8">One Way Transit Time to Offload [min]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="transit" name="transit" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
<div class="form-group last">
|
||
|
<label for="discharge-pump" class="control-label col-md-8">Discharge Pump Rate [gpm]:</label>
|
||
|
<div class="col-md-4"><input type="text" id="discharge-pump" name="discharge-pump" maxlength="40" class="form-control"></div>
|
||
|
</div>
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="row">
|
||
|
<div class="col-md-12 calculate-wrapper">
|
||
|
<button id="calculate" class="btn btn-success" value="Calculate">Calculate</button>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="row">
|
||
|
<div class="col-md-12">
|
||
|
<div id="notes" class="panel panel-default">
|
||
|
<div class="panel-body">
|
||
|
<h3>Simulation Notes:</h3>
|
||
|
<p>If the entered Swath > MES, the calculator uses the Swath = MES for that iteration.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div id="results">
|
||
|
<div class="row breakdown"></div>
|
||
|
<div class="row">
|
||
|
<div class="col-md-12">
|
||
|
<div id="graph2" class="graph"></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="row">
|
||
|
<div class="col-md-12">
|
||
|
<div id="results-table"></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
</body></html>
|