diff --git a/morris.coffee b/morris.coffee index f35acf0..51fbed1 100644 --- a/morris.coffee +++ b/morris.coffee @@ -145,20 +145,20 @@ class Morris.Line .attr('stroke', @options.gridLineColor) .attr('stroke-width', @options.gridStrokeWidth) - # draw x axis labels - prevLabelMargin = null - xLabelMargin = 50 # make this an option? - for i in [Math.ceil(@xmin)..Math.floor(@xmax)] - labelText = if @options.parseTime then i else @columnLabels[@columnLabels.length-i-1] - label = @r.text(transX(i), @options.marginTop + height + @options.marginBottom / 2, labelText) - .attr('font-size', @options.gridTextSize) - .attr('fill', @options.gridTextColor) - labelBox = label.getBBox() - # ensure a minimum of `xLabelMargin` pixels between labels - if prevLabelMargin is null or prevLabelMargin <= labelBox.x - prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin - else - label.remove() + ## draw x axis labels + #prevLabelMargin = null + #xLabelMargin = 50 # make this an option? + #for i in [Math.ceil(@xmin)..Math.floor(@xmax)] + # labelText = if @options.parseTime then i else @columnLabels[@columnLabels.length-i-1] + # label = @r.text(transX(i), @options.marginTop + height + @options.marginBottom / 2, labelText) + # .attr('font-size', @options.gridTextSize) + # .attr('fill', @options.gridTextColor) + # labelBox = label.getBBox() + # # ensure a minimum of `xLabelMargin` pixels between labels + # if prevLabelMargin is null or prevLabelMargin <= labelBox.x + # prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin + # else + # label.remove() # draw the actual series columns = (transX(x) for x in @xvals) @@ -306,42 +306,35 @@ class Morris.Line return ret parseYear: (date) -> - s = date.toString() - m = s.match /^(\d+) Q(\d)$/ - n = s.match /^(\d+)-(\d+)$/ - o = s.match /^(\d+)-(\d+)-(\d+)$/ - p = s.match /^(\d+) W(\d+)$/ + if typeof date is 'number' + return date + m = date.match /^(\d+) Q(\d)$/ + n = date.match /^(\d+)-(\d+)$/ + o = date.match /^(\d+)-(\d+)-(\d+)$/ + p = date.match /^(\d+) W(\d+)$/ if m - parseInt(m[1], 10) + (parseInt(m[2], 10) * 3 - 1) / 12 + new Date( + parseInt(m[1], 10), + parseInt(m[2], 10) * 3 - 1).getTime() + else if n + new Date( + parseInt(n[1], 10), + parseInt(n[2], 10) - 1).getTime() + else if o + new Date( + parseInt(o[1], 10), + parseInt(o[2], 10) - 1, + parseInt(o[3], 10)).getTime() else if p # calculate number of weeks in year given - year = parseInt(p[1], 10); - y1 = new Date(year, 0, 1); - y2 = new Date(year+1, 0, 1); + ret = new Date(parseInt(p[1], 10), 0, 1); # first thursday in year (ISO 8601 standard) - if y1.getDay() isnt 4 - y1.setMonth(0, 1 + ((4 - y1.getDay()) + 7) % 7); - # first thursday in following year - if y2.getDay() isnt 4 - y2.setMonth(0, 1 + ((4 - y2.getDay()) + 7) % 7); - # Number of weeks between thursdays - weeks = Math.ceil((y2 - y1) / 604800000); - parseInt(p[1], 10) + (parseInt(p[2], 10) - 1) / weeks; - else if n - parseInt(n[1], 10) + (parseInt(n[2], 10) - 1) / 12 - else if o - # parse to a timestamp - year = parseInt(o[1], 10); - month = parseInt(o[2], 10); - day = parseInt(o[3], 10); - timestamp = new Date(year, month - 1, day).getTime(); - # get timestamps for the beginning and end of the year - y1 = new Date(year, 0, 1).getTime(); - y2 = new Date(year+1, 0, 1).getTime(); - # calculate a decimal-year value - year + (timestamp - y1) / (y2 - y1); + if ret.getDay() isnt 4 + ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7); + # add weeks + ret.getTime() + parseInt(p[2], 10) * 604800000 else - parseInt(date, 10) + new Date(parseInt(date, 10)) # make long numbers prettier by inserting commas # eg: commas(1234567) -> '1,234,567' diff --git a/morris.js b/morris.js index 5781ab9..84ca600 100644 --- a/morris.js +++ b/morris.js @@ -105,7 +105,7 @@ }; Line.prototype.redraw = function() { - var c, circle, columns, coords, dx, dy, firstY, height, hideHover, hilight, hover, hoverHeight, hoverMargins, hoverSet, i, label, labelBox, labelText, lastY, left, lineY, maxYLabelWidth, path, pointGrow, pointShrink, prevHilight, prevLabelMargin, s, seriesCoords, seriesPoints, touchHandler, transX, transY, updateHilight, updateHover, v, width, x, xLabel, xLabelMargin, y, yInterval, yLabel, yLabels, _i, _j, _len, _len2, _ref, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, + var c, circle, columns, coords, dx, dy, firstY, height, hideHover, hilight, hover, hoverHeight, hoverMargins, hoverSet, i, lastY, left, lineY, maxYLabelWidth, path, pointGrow, pointShrink, prevHilight, s, seriesCoords, seriesPoints, touchHandler, transX, transY, updateHilight, updateHover, v, width, x, xLabel, y, yInterval, yLabel, yLabels, _i, _j, _len, _len2, _ref, _ref2, _ref3, _ref4, _ref5, _this = this; this.el.empty(); this.r = new Raphael(this.el[0]); @@ -134,32 +134,20 @@ this.r.text(left - this.options.marginLeft / 2, y, v + this.options.units).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end'); this.r.path("M" + left + "," + y + 'H' + (left + width)).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth); } - prevLabelMargin = null; - xLabelMargin = 50; - for (i = _ref = Math.ceil(this.xmin), _ref2 = Math.floor(this.xmax); _ref <= _ref2 ? i <= _ref2 : i >= _ref2; _ref <= _ref2 ? i++ : i--) { - labelText = this.options.parseTime ? i : this.columnLabels[this.columnLabels.length - i - 1]; - label = this.r.text(transX(i), this.options.marginTop + height + this.options.marginBottom / 2, labelText).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor); - labelBox = label.getBBox(); - if (prevLabelMargin === null || prevLabelMargin <= labelBox.x) { - prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin; - } else { - label.remove(); - } - } columns = (function() { - var _i, _len, _ref3, _results; - _ref3 = this.xvals; + var _i, _len, _ref, _results; + _ref = this.xvals; _results = []; - for (_i = 0, _len = _ref3.length; _i < _len; _i++) { - x = _ref3[_i]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + x = _ref[_i]; _results.push(transX(x)); } return _results; }).call(this); seriesCoords = []; - _ref3 = this.series; - for (_i = 0, _len = _ref3.length; _i < _len; _i++) { - s = _ref3[_i]; + _ref = this.series; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + s = _ref[_i]; seriesCoords.push($.map(s, function(y, i) { return { x: columns[i], @@ -167,7 +155,7 @@ }; })); } - for (i = _ref4 = seriesCoords.length - 1; _ref4 <= 0 ? i <= 0 : i >= 0; _ref4 <= 0 ? i++ : i--) { + for (i = _ref2 = seriesCoords.length - 1; _ref2 <= 0 ? i <= 0 : i >= 0; _ref2 <= 0 ? i++ : i--) { coords = seriesCoords[i]; if (coords.length > 1) { path = this.createPath(coords, this.options.marginTop, left, this.options.marginTop + height, left + width); @@ -175,17 +163,17 @@ } } seriesPoints = (function() { - var _ref5, _results; + var _ref3, _results; _results = []; - for (i = 0, _ref5 = seriesCoords.length - 1; 0 <= _ref5 ? i <= _ref5 : i >= _ref5; 0 <= _ref5 ? i++ : i--) { + for (i = 0, _ref3 = seriesCoords.length - 1; 0 <= _ref3 ? i <= _ref3 : i >= _ref3; 0 <= _ref3 ? i++ : i--) { _results.push([]); } return _results; })(); - for (i = _ref5 = seriesCoords.length - 1; _ref5 <= 0 ? i <= 0 : i >= 0; _ref5 <= 0 ? i++ : i--) { - _ref6 = seriesCoords[i]; - for (_j = 0, _len2 = _ref6.length; _j < _len2; _j++) { - c = _ref6[_j]; + for (i = _ref3 = seriesCoords.length - 1; _ref3 <= 0 ? i <= 0 : i >= 0; _ref3 <= 0 ? i++ : i--) { + _ref4 = seriesCoords[i]; + for (_j = 0, _len2 = _ref4.length; _j < _len2; _j++) { + c = _ref4[_j]; circle = this.r.circle(c.x, c.y, this.options.pointSize).attr('fill', this.options.lineColors[i]).attr('stroke-width', 1).attr('stroke', '#ffffff'); seriesPoints[i].push(circle); } @@ -197,16 +185,16 @@ hoverSet.push(hover); hoverSet.push(xLabel); yLabels = []; - for (i = 0, _ref7 = this.series.length - 1; 0 <= _ref7 ? i <= _ref7 : i >= _ref7; 0 <= _ref7 ? i++ : i--) { + for (i = 0, _ref5 = this.series.length - 1; 0 <= _ref5 ? i <= _ref5 : i >= _ref5; 0 <= _ref5 ? i++ : i--) { yLabel = this.r.text(0, this.options.hoverFontSize * 1.5 * (i + 1.5) - hoverHeight / 2, '').attr('fill', this.options.lineColors[i]).attr('font-size', this.options.hoverFontSize); yLabels.push(yLabel); hoverSet.push(yLabel); } updateHover = function(index) { - var i, maxLabelWidth, xloc, yloc, _ref8; + var i, maxLabelWidth, xloc, yloc, _ref6; hoverSet.show(); xLabel.attr('text', _this.columnLabels[index]); - for (i = 0, _ref8 = _this.series.length - 1; 0 <= _ref8 ? i <= _ref8 : i >= _ref8; 0 <= _ref8 ? i++ : i--) { + for (i = 0, _ref6 = _this.series.length - 1; 0 <= _ref6 ? i <= _ref6 : i >= _ref6; 0 <= _ref6 ? i++ : i--) { yLabels[i].attr('text', "" + _this.seriesLabels[i] + ": " + (_this.commas(_this.series[i][index])) + _this.options.units); } maxLabelWidth = Math.max.apply(null, $.map(yLabels, function(l) { @@ -243,14 +231,14 @@ r: this.options.pointSize }, 25, 'linear'); hilight = function(index) { - var i, _ref8, _ref9; + var i, _ref6, _ref7; if (prevHilight !== null && prevHilight !== index) { - for (i = 0, _ref8 = seriesPoints.length - 1; 0 <= _ref8 ? i <= _ref8 : i >= _ref8; 0 <= _ref8 ? i++ : i--) { + for (i = 0, _ref6 = seriesPoints.length - 1; 0 <= _ref6 ? i <= _ref6 : i >= _ref6; 0 <= _ref6 ? i++ : i--) { seriesPoints[i][prevHilight].animate(pointShrink); } } if (index !== null && prevHilight !== index) { - for (i = 0, _ref9 = seriesPoints.length - 1; 0 <= _ref9 ? i <= _ref9 : i >= _ref9; 0 <= _ref9 ? i++ : i--) { + for (i = 0, _ref7 = seriesPoints.length - 1; 0 <= _ref7 ? i <= _ref7 : i >= _ref7; 0 <= _ref7 ? i++ : i--) { seriesPoints[i][index].animate(pointGrow); } updateHover(index); @@ -259,10 +247,10 @@ if (index === null) return hideHover(); }; updateHilight = function(x) { - var hoverIndex, _ref8, _results; + var hoverIndex, _ref6, _results; x -= _this.el.offset().left; _results = []; - for (hoverIndex = _ref8 = hoverMargins.length; _ref8 <= 0 ? hoverIndex <= 0 : hoverIndex >= 0; _ref8 <= 0 ? hoverIndex++ : hoverIndex--) { + for (hoverIndex = _ref6 = hoverMargins.length; _ref6 <= 0 ? hoverIndex <= 0 : hoverIndex >= 0; _ref6 <= 0 ? hoverIndex++ : hoverIndex--) { if (hoverIndex === 0 || hoverMargins[hoverIndex - 1] > x) { hilight(hoverIndex); break; @@ -343,34 +331,24 @@ }; Line.prototype.parseYear = function(date) { - var day, m, month, n, o, p, s, timestamp, weeks, y1, y2, year; - s = date.toString(); - m = s.match(/^(\d+) Q(\d)$/); - n = s.match(/^(\d+)-(\d+)$/); - o = s.match(/^(\d+)-(\d+)-(\d+)$/); - p = s.match(/^(\d+) W(\d+)$/); + var m, n, o, p, ret; + if (typeof date === 'number') return date; + m = date.match(/^(\d+) Q(\d)$/); + n = date.match(/^(\d+)-(\d+)$/); + o = date.match(/^(\d+)-(\d+)-(\d+)$/); + p = date.match(/^(\d+) W(\d+)$/); if (m) { - return parseInt(m[1], 10) + (parseInt(m[2], 10) * 3 - 1) / 12; - } else if (p) { - year = parseInt(p[1], 10); - y1 = new Date(year, 0, 1); - y2 = new Date(year + 1, 0, 1); - if (y1.getDay() !== 4) y1.setMonth(0, 1 + ((4 - y1.getDay()) + 7) % 7); - if (y2.getDay() !== 4) y2.setMonth(0, 1 + ((4 - y2.getDay()) + 7) % 7); - weeks = Math.ceil((y2 - y1) / 604800000); - return parseInt(p[1], 10) + (parseInt(p[2], 10) - 1) / weeks; + return new Date(parseInt(m[1], 10), parseInt(m[2], 10) * 3 - 1).getTime(); } else if (n) { - return parseInt(n[1], 10) + (parseInt(n[2], 10) - 1) / 12; + return new Date(parseInt(n[1], 10), parseInt(n[2], 10) - 1).getTime(); } else if (o) { - year = parseInt(o[1], 10); - month = parseInt(o[2], 10); - day = parseInt(o[3], 10); - timestamp = new Date(year, month - 1, day).getTime(); - y1 = new Date(year, 0, 1).getTime(); - y2 = new Date(year + 1, 0, 1).getTime(); - return year + (timestamp - y1) / (y2 - y1); + return new Date(parseInt(o[1], 10), parseInt(o[2], 10) - 1, parseInt(o[3], 10)).getTime(); + } else if (p) { + ret = new Date(parseInt(p[1], 10), 0, 1); + if (ret.getDay() !== 4) ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7); + return ret.getTime() + parseInt(p[2], 10) * 604800000; } else { - return parseInt(date, 10); + return new Date(parseInt(date, 10)); } }; diff --git a/morris.min.js b/morris.min.js index 9cf7297..86f48d8 100644 --- a/morris.min.js +++ b/morris.min.js @@ -1 +1 @@ -((function(){var a,b;a=jQuery,b={},b.Line=function(){function c(c){if(!(this instanceof b.Line))return new b.Line(c);typeof c.element=="string"?this.el=a(document.getElementById(c.element)):this.el=a(c.element),this.options=a.extend({},this.defaults,c);if(this.options.data===void 0||this.options.data.length===0)return;this.el.addClass("graph-initialised"),this.precalc(),this.redraw()}return c.prototype.defaults={lineWidth:3,pointSize:4,lineColors:["#0b62a4","#7A92A3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],ymax:"auto",ymin:"auto 0",marginTop:25,marginRight:25,marginBottom:30,marginLeft:25,numLines:5,gridLineColor:"#aaa",gridTextColor:"#888",gridTextSize:12,gridStrokeWidth:.5,hoverPaddingX:10,hoverPaddingY:5,hoverMargin:10,hoverFillColor:"#fff",hoverBorderColor:"#ccc",hoverBorderWidth:2,hoverOpacity:.95,hoverLabelColor:"#444",hoverFontSize:12,smooth:!0,hideHover:!1,parseTime:!0,units:""},c.prototype.precalc=function(){var b,c,d,e,f,g,h,i,j,k=this;this.options.data.sort(function(a,b){return(a[k.options.xkey]=0;i<=0?a++:a--)j.push(a);return j}.apply(this),this.xmin=Math.min.apply(null,this.xvals),this.xmax=Math.max.apply(null,this.xvals),this.xmin===this.xmax&&(this.xmin-=1,this.xmax+=1),typeof this.options.ymax=="string"&&this.options.ymax.slice(0,4)==="auto"&&(c=Math.max.apply(null,Array.prototype.concat.apply([],this.series)),this.options.ymax.length>5?this.options.ymax=Math.max(parseInt(this.options.ymax.slice(5),10),c):this.options.ymax=c);if(typeof this.options.ymin=="string"&&this.options.ymin.slice(0,4)==="auto")return d=Math.min.apply(null,Array.prototype.concat.apply([],this.series)),this.options.ymin.length>5?this.options.ymin=Math.min(parseInt(this.options.ymin.slice(5),10),d):this.options.ymin=d},c.prototype.redraw=function(){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,_,ba,bb,bc,bd=this;this.el.empty(),this.r=new Raphael(this.el[0]),w=Math.max(this.measureText(this.options.ymin+this.options.units,this.options.gridTextSize).width,this.measureText(this.options.ymax+this.options.units,this.options.gridTextSize).width),u=w+this.options.marginLeft,L=this.el.width()-u-this.options.marginRight,i=this.el.height()-this.options.marginTop-this.options.marginBottom,f=L/(this.xmax-this.xmin),g=i/(this.options.ymax-this.options.ymin),G=function(a){return bd.xvals.length===1?u+L/2:u+(a-bd.xmin)*f},H=function(a){return bd.options.marginTop+i-(a-bd.options.ymin)*g},Q=(this.options.ymax-this.options.ymin)/(this.options.numLines-1),h=Math.ceil(this.options.ymin/Q)*Q,t=Math.floor(this.options.ymax/Q)*Q;for(v=h;h<=t?v<=t:v>=t;v+=Q)K=Math.floor(v),P=H(K),this.r.text(u-this.options.marginLeft/2,P,K+this.options.units).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),this.r.path("M"+u+","+P+"H"+(u+L)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth);B=null,O=50;for(p=X=Math.ceil(this.xmin),Y=Math.floor(this.xmax);X<=Y?p<=Y:p>=Y;X<=Y?p++:p--)s=this.options.parseTime?p:this.columnLabels[this.columnLabels.length-p-1],q=this.r.text(G(p),this.options.marginTop+i+this.options.marginBottom/2,s).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor),r=q.getBBox(),B===null||B<=r.x?B=r.x+r.width+O:q.remove();d=function(){var a,b,c,d;c=this.xvals,d=[];for(a=0,b=c.length;a=0;_<=0?p++:p--)e=D[p],e.length>1&&(x=this.createPath(e,this.options.marginTop,u,this.options.marginTop+i,u+L),this.r.path(x).attr("stroke",this.options.lineColors[p]).attr("stroke-width",this.options.lineWidth));E=function(){var a,b;b=[];for(p=0,a=D.length-1;0<=a?p<=a:p>=a;0<=a?p++:p--)b.push([]);return b}();for(p=ba=D.length-1;ba<=0?p<=0:p>=0;ba<=0?p++:p--){bb=D[p];for(U=0,W=bb.length;U=bc;0<=bc?p++:p--)R=this.r.text(0,this.options.hoverFontSize*1.5*(p+1.5)-m/2,"").attr("fill",this.options.lineColors[p]).attr("font-size",this.options.hoverFontSize),S.push(R),o.push(R);return J=function(b){var c,e,f,g,h;o.show(),N.attr("text",bd.columnLabels[b]);for(c=0,h=bd.series.length-1;0<=h?c<=h:c>=h;0<=h?c++:c--)S[c].attr("text",""+bd.seriesLabels[c]+": "+bd.commas(bd.series[c][b])+bd.options.units);return e=Math.max.apply(null,a.map(S,function(a){return a.getBBox().width})),e=Math.max(e,N.getBBox().width),l.attr("width",e+bd.options.hoverPaddingX*2),l.attr("x",-bd.options.hoverPaddingX-e/2),g=Math.min.apply(null,a.map(bd.series,function(a){return H(a[b])})),g>m+bd.options.hoverPaddingY*2+bd.options.hoverMargin+bd.options.marginTop?g=g-m/2-bd.options.hoverPaddingY-bd.options.hoverMargin:g=g+m/2+bd.options.hoverPaddingY+bd.options.hoverMargin,g=Math.max(bd.options.marginTop+m/2+bd.options.hoverPaddingY,g),g=Math.min(bd.options.marginTop+i-m/2-bd.options.hoverPaddingY,g),f=Math.min(u+L-e/2-bd.options.hoverPaddingX,d[b]),f=Math.max(u+e/2+bd.options.hoverPaddingX,f),o.attr("transform","t"+f+","+g)},j=function(){return o.hide()},n=a.map(d.slice(1),function(a,b){return(a+d[b])/2}),A=null,y=Raphael.animation({r:this.options.pointSize+3},25,"linear"),z=Raphael.animation({r:this.options.pointSize},25,"linear"),k=function(a){var b,c,d;if(A!==null&&A!==a)for(b=0,c=E.length-1;0<=c?b<=c:b>=c;0<=c?b++:b--)E[b][A].animate(z);if(a!==null&&A!==a){for(b=0,d=E.length-1;0<=d?b<=d:b>=d;0<=d?b++:b--)E[b][a].animate(y);J(a)}A=a;if(a===null)return j()},I=function(a){var b,c,d;a-=bd.el.offset().left,d=[];for(b=c=n.length;c<=0?b<=0:b>=0;c<=0?b++:b--){if(b===0||n[b-1]>a){k(b);break}d.push(void 0)}return d},this.el.mousemove(function(a){return I(a.pageX)}),this.options.hideHover&&this.el.mouseout(function(a){return k(null)}),F=function(a){var b;return b=a.originalEvent.touches[0]||a.originalEvent.changedTouches[0],I(b.pageX),b},this.el.bind("touchstart",F),this.el.bind("touchmove",F),this.el.bind("touchend",F),k(this.options.hideHover?null:0)},c.prototype.createPath=function(b,c,d,e,f){var g,h,i,j,k,l,m,n,o,p,q,r,s;n="";if(this.options.smooth){i=this.gradients(b);for(j=0,s=b.length-1;0<=s?j<=s:j>=s;0<=s?j++:j--)g=b[j],j===0?n+="M"+g.x+","+g.y:(h=i[j],l=b[j-1],m=i[j-1],k=(g.x-l.x)/4,o=l.x+k,q=Math.min(e,l.y+k*m),p=g.x-k,r=Math.min(e,g.y-k*h),n+="C"+o+","+q+","+p+","+r+","+g.x+","+g.y)}else n="M"+a.map(b,function(a){return""+a.x+","+a.y}).join("L");return n},c.prototype.gradients=function(b){return a.map(b,function(a,c){return c===0?(b[1].y-a.y)/(b[1].x-a.x):c===b.length-1?(a.y-b[c-1].y)/(a.x-b[c-1].x):(b[c+1].y-b[c-1].y)/(b[c+1].x-b[c-1].x)})},c.prototype.measureText=function(a,b){var c,d;return b==null&&(b=12),d=this.r.text(100,100,a).attr("font-size",b),c=d.getBBox(),d.remove(),c},c.prototype.parseYear=function(a){var b,c,d,e,f,g,h,i,j,k,l,m;return h=a.toString(),c=h.match(/^(\d+) Q(\d)$/),e=h.match(/^(\d+)-(\d+)$/),f=h.match(/^(\d+)-(\d+)-(\d+)$/),g=h.match(/^(\d+) W(\d+)$/),c?parseInt(c[1],10)+(parseInt(c[2],10)*3-1)/12:g?(m=parseInt(g[1],10),k=new Date(m,0,1),l=new Date(m+1,0,1),k.getDay()!==4&&k.setMonth(0,1+(4-k.getDay()+7)%7),l.getDay()!==4&&l.setMonth(0,1+(4-l.getDay()+7)%7),j=Math.ceil((l-k)/6048e5),parseInt(g[1],10)+(parseInt(g[2],10)-1)/j):e?parseInt(e[1],10)+(parseInt(e[2],10)-1)/12:f?(m=parseInt(f[1],10),d=parseInt(f[2],10),b=parseInt(f[3],10),i=(new Date(m,d-1,b)).getTime(),k=(new Date(m,0,1)).getTime(),l=(new Date(m+1,0,1)).getTime(),m+(i-k)/(l-k)):parseInt(a,10)},c.prototype.commas=function(a){var b,c,d,e;return d=a<0?"-":"",b=Math.abs(a),c=Math.floor(b).toFixed(0),d+=c.replace(/(?=(?:\d{3})+$)(?!^)/g,","),e=b.toString(),e.length>c.length&&(d+=e.slice(c.length)),d},c}(),window.Morris=b})).call(this); \ No newline at end of file +((function(){var a,b;a=jQuery,b={},b.Line=function(){function c(c){if(!(this instanceof b.Line))return new b.Line(c);typeof c.element=="string"?this.el=a(document.getElementById(c.element)):this.el=a(c.element),this.options=a.extend({},this.defaults,c);if(this.options.data===void 0||this.options.data.length===0)return;this.el.addClass("graph-initialised"),this.precalc(),this.redraw()}return c.prototype.defaults={lineWidth:3,pointSize:4,lineColors:["#0b62a4","#7A92A3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],ymax:"auto",ymin:"auto 0",marginTop:25,marginRight:25,marginBottom:30,marginLeft:25,numLines:5,gridLineColor:"#aaa",gridTextColor:"#888",gridTextSize:12,gridStrokeWidth:.5,hoverPaddingX:10,hoverPaddingY:5,hoverMargin:10,hoverFillColor:"#fff",hoverBorderColor:"#ccc",hoverBorderWidth:2,hoverOpacity:.95,hoverLabelColor:"#444",hoverFontSize:12,smooth:!0,hideHover:!1,parseTime:!0,units:""},c.prototype.precalc=function(){var b,c,d,e,f,g,h,i,j,k=this;this.options.data.sort(function(a,b){return(a[k.options.xkey]=0;i<=0?a++:a--)j.push(a);return j}.apply(this),this.xmin=Math.min.apply(null,this.xvals),this.xmax=Math.max.apply(null,this.xvals),this.xmin===this.xmax&&(this.xmin-=1,this.xmax+=1),typeof this.options.ymax=="string"&&this.options.ymax.slice(0,4)==="auto"&&(c=Math.max.apply(null,Array.prototype.concat.apply([],this.series)),this.options.ymax.length>5?this.options.ymax=Math.max(parseInt(this.options.ymax.slice(5),10),c):this.options.ymax=c);if(typeof this.options.ymin=="string"&&this.options.ymin.slice(0,4)==="auto")return d=Math.min.apply(null,Array.prototype.concat.apply([],this.series)),this.options.ymin.length>5?this.options.ymin=Math.min(parseInt(this.options.ymin.slice(5),10),d):this.options.ymin=d},c.prototype.redraw=function(){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X=this;this.el.empty(),this.r=new Raphael(this.el[0]),t=Math.max(this.measureText(this.options.ymin+this.options.units,this.options.gridTextSize).width,this.measureText(this.options.ymax+this.options.units,this.options.gridTextSize).width),r=t+this.options.marginLeft,H=this.el.width()-r-this.options.marginRight,i=this.el.height()-this.options.marginTop-this.options.marginBottom,f=H/(this.xmax-this.xmin),g=i/(this.options.ymax-this.options.ymin),C=function(a){return X.xvals.length===1?r+H/2:r+(a-X.xmin)*f},D=function(a){return X.options.marginTop+i-(a-X.options.ymin)*g},L=(this.options.ymax-this.options.ymin)/(this.options.numLines-1),h=Math.ceil(this.options.ymin/L)*L,q=Math.floor(this.options.ymax/L)*L;for(s=h;h<=q?s<=q:s>=q;s+=L)G=Math.floor(s),K=D(G),this.r.text(r-this.options.marginLeft/2,K,G+this.options.units).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),this.r.path("M"+r+","+K+"H"+(r+H)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth);d=function(){var a,b,c,d;c=this.xvals,d=[];for(a=0,b=c.length;a=0;T<=0?p++:p--)e=z[p],e.length>1&&(u=this.createPath(e,this.options.marginTop,r,this.options.marginTop+i,r+H),this.r.path(u).attr("stroke",this.options.lineColors[p]).attr("stroke-width",this.options.lineWidth));A=function(){var a,b;b=[];for(p=0,a=z.length-1;0<=a?p<=a:p>=a;0<=a?p++:p--)b.push([]);return b}();for(p=U=z.length-1;U<=0?p<=0:p>=0;U<=0?p++:p--){V=z[p];for(P=0,R=V.length;P=W;0<=W?p++:p--)M=this.r.text(0,this.options.hoverFontSize*1.5*(p+1.5)-m/2,"").attr("fill",this.options.lineColors[p]).attr("font-size",this.options.hoverFontSize),N.push(M),o.push(M);return F=function(b){var c,e,f,g,h;o.show(),J.attr("text",X.columnLabels[b]);for(c=0,h=X.series.length-1;0<=h?c<=h:c>=h;0<=h?c++:c--)N[c].attr("text",""+X.seriesLabels[c]+": "+X.commas(X.series[c][b])+X.options.units);return e=Math.max.apply(null,a.map(N,function(a){return a.getBBox().width})),e=Math.max(e,J.getBBox().width),l.attr("width",e+X.options.hoverPaddingX*2),l.attr("x",-X.options.hoverPaddingX-e/2),g=Math.min.apply(null,a.map(X.series,function(a){return D(a[b])})),g>m+X.options.hoverPaddingY*2+X.options.hoverMargin+X.options.marginTop?g=g-m/2-X.options.hoverPaddingY-X.options.hoverMargin:g=g+m/2+X.options.hoverPaddingY+X.options.hoverMargin,g=Math.max(X.options.marginTop+m/2+X.options.hoverPaddingY,g),g=Math.min(X.options.marginTop+i-m/2-X.options.hoverPaddingY,g),f=Math.min(r+H-e/2-X.options.hoverPaddingX,d[b]),f=Math.max(r+e/2+X.options.hoverPaddingX,f),o.attr("transform","t"+f+","+g)},j=function(){return o.hide()},n=a.map(d.slice(1),function(a,b){return(a+d[b])/2}),x=null,v=Raphael.animation({r:this.options.pointSize+3},25,"linear"),w=Raphael.animation({r:this.options.pointSize},25,"linear"),k=function(a){var b,c,d;if(x!==null&&x!==a)for(b=0,c=A.length-1;0<=c?b<=c:b>=c;0<=c?b++:b--)A[b][x].animate(w);if(a!==null&&x!==a){for(b=0,d=A.length-1;0<=d?b<=d:b>=d;0<=d?b++:b--)A[b][a].animate(v);F(a)}x=a;if(a===null)return j()},E=function(a){var b,c,d;a-=X.el.offset().left,d=[];for(b=c=n.length;c<=0?b<=0:b>=0;c<=0?b++:b--){if(b===0||n[b-1]>a){k(b);break}d.push(void 0)}return d},this.el.mousemove(function(a){return E(a.pageX)}),this.options.hideHover&&this.el.mouseout(function(a){return k(null)}),B=function(a){var b;return b=a.originalEvent.touches[0]||a.originalEvent.changedTouches[0],E(b.pageX),b},this.el.bind("touchstart",B),this.el.bind("touchmove",B),this.el.bind("touchend",B),k(this.options.hideHover?null:0)},c.prototype.createPath=function(b,c,d,e,f){var g,h,i,j,k,l,m,n,o,p,q,r,s;n="";if(this.options.smooth){i=this.gradients(b);for(j=0,s=b.length-1;0<=s?j<=s:j>=s;0<=s?j++:j--)g=b[j],j===0?n+="M"+g.x+","+g.y:(h=i[j],l=b[j-1],m=i[j-1],k=(g.x-l.x)/4,o=l.x+k,q=Math.min(e,l.y+k*m),p=g.x-k,r=Math.min(e,g.y-k*h),n+="C"+o+","+q+","+p+","+r+","+g.x+","+g.y)}else n="M"+a.map(b,function(a){return""+a.x+","+a.y}).join("L");return n},c.prototype.gradients=function(b){return a.map(b,function(a,c){return c===0?(b[1].y-a.y)/(b[1].x-a.x):c===b.length-1?(a.y-b[c-1].y)/(a.x-b[c-1].x):(b[c+1].y-b[c-1].y)/(b[c+1].x-b[c-1].x)})},c.prototype.measureText=function(a,b){var c,d;return b==null&&(b=12),d=this.r.text(100,100,a).attr("font-size",b),c=d.getBBox(),d.remove(),c},c.prototype.parseYear=function(a){var b,c,d,e,f;return typeof a=="number"?a:(b=a.match(/^(\d+) Q(\d)$/),c=a.match(/^(\d+)-(\d+)$/),d=a.match(/^(\d+)-(\d+)-(\d+)$/),e=a.match(/^(\d+) W(\d+)$/),b?(new Date(parseInt(b[1],10),parseInt(b[2],10)*3-1)).getTime():c?(new Date(parseInt(c[1],10),parseInt(c[2],10)-1)).getTime():d?(new Date(parseInt(d[1],10),parseInt(d[2],10)-1,parseInt(d[3],10))).getTime():e?(f=new Date(parseInt(e[1],10),0,1),f.getDay()!==4&&f.setMonth(0,1+(4-f.getDay()+7)%7),f.getTime()+parseInt(e[2],10)*6048e5):new Date(parseInt(a,10)))},c.prototype.commas=function(a){var b,c,d,e;return d=a<0?"-":"",b=Math.abs(a),c=Math.floor(b).toFixed(0),d+=c.replace(/(?=(?:\d{3})+$)(?!^)/g,","),e=b.toString(),e.length>c.length&&(d+=e.slice(c.length)),d},c}(),window.Morris=b})).call(this); \ No newline at end of file