diff --git a/morris.coffee b/morris.coffee index 29519dd..49f1490 100644 --- a/morris.coffee +++ b/morris.coffee @@ -26,8 +26,32 @@ class Morris.Line if @options.data is undefined or @options.data.length is 0 return @el.addClass 'graph-initialised' - @precalc() - @redraw() + + # the raphael drawing instance + @r = new Raphael(@el[0]) + + # Some instance variables for later + @pointGrow = Raphael.animation r: @options.pointSize + 3, 25, 'linear' + @pointShrink = Raphael.animation r: @options.pointSize, 25, 'linear' + @elementWidth = null + @elementHeight = null + @dirty = false + # column hilight events + @prevHilight = null + @el.mousemove (evt) => + @updateHilight evt.pageX + if @options.hideHover + @el.mouseout (evt) => + @hilight null + touchHandler = (evt) => + touch = evt.originalEvent.touches[0] or evt.originalEvent.changedTouches[0] + @updateHilight touch.pageX + return touch + @el.bind 'touchstart', touchHandler + @el.bind 'touchmove', touchHandler + @el.bind 'touchend', touchHandler + + @setData(@options.data) # Default configuration # @@ -72,11 +96,11 @@ class Morris.Line xLabels: 'auto' xLabelFormat: null - # Do any necessary pre-processing for a new dataset + # Pre-process data # - precalc: -> + setData: (data, redraw = true) -> # shallow copy & sort data - @options.data = @options.data.slice(0) + @options.data = data.slice(0) @options.data.sort (a, b) => (a[@options.xkey] < b[@options.xkey]) - (b[@options.xkey] < a[@options.xkey]) # extract labels @columnLabels = $.map @options.data, (d) => d[@options.xkey] @@ -133,25 +157,8 @@ class Morris.Line else @precision = 0 - # Some instance variables for later - @pointGrow = Raphael.animation r: @options.pointSize + 3, 25, 'linear' - @pointShrink = Raphael.animation r: @options.pointSize, 25, 'linear' - @elementWidth = null - @elementHeight = null - # column hilight events - @prevHilight = null - @el.mousemove (evt) => - @updateHilight evt.pageX - if @options.hideHover - @el.mouseout (evt) => - @hilight null - touchHandler = (evt) => - touch = evt.originalEvent.touches[0] or evt.originalEvent.changedTouches[0] - @updateHilight touch.pageX - return touch - @el.bind 'touchstart', touchHandler - @el.bind 'touchmove', touchHandler - @el.bind 'touchend', touchHandler + @dirty = true + @redraw() if redraw # Do any size-related calculations # @@ -159,7 +166,10 @@ class Morris.Line w = @el.width() h = @el.height() - if @elementWidth != w or @elementHeight != h + if @elementWidth != w or @elementHeight != h or @dirty + @elementWidth = w + @elementHeight = h + @dirty = false # calculate grid dimensions @maxYLabelWidth = Math.max( @measureText(@yLabelFormat(@options.ymin), @options.gridTextSize).width, @@ -197,12 +207,7 @@ class Morris.Line # Clear and redraw the graph # redraw: -> - # remove child elements (get rid of old drawings) - @el.empty() - - # the raphael drawing instance - @r = new Raphael(@el[0]) - + @r.clear() @calc() @drawGrid() @drawSeries() diff --git a/morris.js b/morris.js index 64998e9..e2038b5 100644 --- a/morris.js +++ b/morris.js @@ -19,6 +19,9 @@ this.transY = __bind(this.transY, this); this.transX = __bind(this.transX, this); + + var touchHandler, + _this = this; if (!(this instanceof Morris.Line)) { return new Morris.Line(options); } @@ -38,8 +41,35 @@ return; } this.el.addClass('graph-initialised'); - this.precalc(); - this.redraw(); + this.r = new Raphael(this.el[0]); + this.pointGrow = Raphael.animation({ + r: this.options.pointSize + 3 + }, 25, 'linear'); + this.pointShrink = Raphael.animation({ + r: this.options.pointSize + }, 25, 'linear'); + this.elementWidth = null; + this.elementHeight = null; + this.dirty = false; + this.prevHilight = null; + this.el.mousemove(function(evt) { + return _this.updateHilight(evt.pageX); + }); + if (this.options.hideHover) { + this.el.mouseout(function(evt) { + return _this.hilight(null); + }); + } + touchHandler = function(evt) { + var touch; + touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0]; + _this.updateHilight(touch.pageX); + return touch; + }; + this.el.bind('touchstart', touchHandler); + this.el.bind('touchmove', touchHandler); + this.el.bind('touchend', touchHandler); + this.setData(this.options.data); } Line.prototype.defaults = { @@ -78,10 +108,13 @@ xLabelFormat: null }; - Line.prototype.precalc = function() { - var d, series_data, touchHandler, ykey, ymax, ymin, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2, _results, + Line.prototype.setData = function(data, redraw) { + var d, series_data, ykey, ymax, ymin, _i, _j, _k, _len, _len1, _ref, _ref1, _ref2, _results, _this = this; - this.options.data = this.options.data.slice(0); + if (redraw == null) { + redraw = true; + } + this.options.data = data.slice(0); this.options.data.sort(function(a, b) { return (a[_this.options.xkey] < b[_this.options.xkey]) - (b[_this.options.xkey] < a[_this.options.xkey]); }); @@ -158,32 +191,10 @@ } else { this.precision = 0; } - this.pointGrow = Raphael.animation({ - r: this.options.pointSize + 3 - }, 25, 'linear'); - this.pointShrink = Raphael.animation({ - r: this.options.pointSize - }, 25, 'linear'); - this.elementWidth = null; - this.elementHeight = null; - this.prevHilight = null; - this.el.mousemove(function(evt) { - return _this.updateHilight(evt.pageX); - }); - if (this.options.hideHover) { - this.el.mouseout(function(evt) { - return _this.hilight(null); - }); + this.dirty = true; + if (redraw) { + return this.redraw(); } - touchHandler = function(evt) { - var touch; - touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0]; - _this.updateHilight(touch.pageX); - return touch; - }; - this.el.bind('touchstart', touchHandler); - this.el.bind('touchmove', touchHandler); - return this.el.bind('touchend', touchHandler); }; Line.prototype.calc = function() { @@ -191,7 +202,10 @@ _this = this; w = this.el.width(); h = this.el.height(); - if (this.elementWidth !== w || this.elementHeight !== h) { + if (this.elementWidth !== w || this.elementHeight !== h || this.dirty) { + this.elementWidth = w; + this.elementHeight = h; + this.dirty = false; this.maxYLabelWidth = Math.max(this.measureText(this.yLabelFormat(this.options.ymin), this.options.gridTextSize).width, this.measureText(this.yLabelFormat(this.options.ymax), this.options.gridTextSize).width); this.left = this.maxYLabelWidth + this.options.marginLeft; this.width = this.el.width() - this.left - this.options.marginRight; @@ -244,8 +258,7 @@ }; Line.prototype.redraw = function() { - this.el.empty(); - this.r = new Raphael(this.el[0]); + this.r.clear(); this.calc(); this.drawGrid(); this.drawSeries(); diff --git a/morris.min.js b/morris.min.js index 964b2c5..236dec6 100644 --- a/morris.min.js +++ b/morris.min.js @@ -1,2 +1,2 @@ // Generated by CoffeeScript 1.3.3 -(function(){var a,b,c,d,e=function(a,b){return function(){return a.apply(b,arguments)}};a=jQuery,b={},b.Line=function(){function c(c){this.updateHilight=e(this.updateHilight,this),this.hilight=e(this.hilight,this),this.updateHover=e(this.updateHover,this),this.transY=e(this.transY,this),this.transX=e(this.transX,this);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);if(this.el===null||this.el.length===0)throw new Error("Graph placeholder not found.");this.options=a.extend({},this.defaults,c),typeof this.options.units=="string"&&(this.options.postUnits=c.units);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,preUnits:"",postUnits:"",dateFormat:function(a){return(new Date(a)).toString()},xLabels:"auto",xLabelFormat:null},c.prototype.precalc=function(){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=this;this.options.data=this.options.data.slice(0),this.options.data.sort(function(a,b){return(a[r.options.xkey]=0;p<=0?a++:a--)q.push(a);return q}.apply(this),this.options.parseTime&&(this.columnLabels=a.map(this.columnLabels,function(a){return typeof a=="number"?r.options.dateFormat(a):a})),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"&&(g=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),g):this.options.ymax=g),typeof this.options.ymin=="string"&&this.options.ymin.slice(0,4)==="auto"&&(h=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),h):this.options.ymin=h),this.yInterval=(this.options.ymax-this.options.ymin)/(this.options.numLines-1),this.yInterval>0&&this.yInterval<1?this.precision=-Math.floor(Math.log(this.yInterval)/Math.log(10)):this.precision=0,this.pointGrow=Raphael.animation({r:this.options.pointSize+3},25,"linear"),this.pointShrink=Raphael.animation({r:this.options.pointSize},25,"linear"),this.elementWidth=null,this.elementHeight=null,this.prevHilight=null,this.el.mousemove(function(a){return r.updateHilight(a.pageX)}),this.options.hideHover&&this.el.mouseout(function(a){return r.hilight(null)}),e=function(a){var b;return b=a.originalEvent.touches[0]||a.originalEvent.changedTouches[0],r.updateHilight(b.pageX),b},this.el.bind("touchstart",e),this.el.bind("touchmove",e),this.el.bind("touchend",e)},c.prototype.calc=function(){var b,c,d,e,f,g,h,i,j=this;e=this.el.width(),b=this.el.height();if(this.elementWidth!==e||this.elementHeight!==b){this.maxYLabelWidth=Math.max(this.measureText(this.yLabelFormat(this.options.ymin),this.options.gridTextSize).width,this.measureText(this.yLabelFormat(this.options.ymax),this.options.gridTextSize).width),this.left=this.maxYLabelWidth+this.options.marginLeft,this.width=this.el.width()-this.left-this.options.marginRight,this.height=this.el.height()-this.options.marginTop-this.options.marginBottom,this.dx=this.width/(this.xmax-this.xmin),this.dy=this.height/(this.options.ymax-this.options.ymin),this.columns=function(){var a,b,c,d;c=this.xvals,d=[];for(a=0,b=c.length;a=g;h=n+=r)j=parseFloat(h.toFixed(this.precision)),l=this.transY(j),this.r.text(this.left-this.options.marginLeft/2,l,this.yLabelFormat(j)).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),this.r.path("M"+this.left+","+l+"H"+(this.left+this.width)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth);m=this.options.marginTop+this.height+this.options.marginBottom/2,k=50,i=null,a=function(a,b){var c,d;return c=w.r.text(w.transX(b),m,a).attr("font-size",w.options.gridTextSize).attr("fill",w.options.gridTextColor),d=c.getBBox(),(i===null||i<=d.x)&&d.x>=0&&d.x+d.width=t;d=0<=t?++p:--p)f=this.columnLabels[this.columnLabels.length-d-1],v.push(a(f,d));return v},c.prototype.drawSeries=function(){var a,b,c,d,e,f,g,h,i,j;for(d=f=h=this.seriesCoords.length-1;h<=0?f<=0:f>=0;d=h<=0?++f:--f)c=this.seriesCoords[d],c.length>1&&(e=this.createPath(c,this.options.marginTop,this.left,this.options.marginTop+this.height,this.left+this.width),this.r.path(e).attr("stroke",this.options.lineColors[d]).attr("stroke-width",this.options.lineWidth));this.seriesPoints=function(){var a,b,c;c=[];for(d=a=0,b=this.seriesCoords.length-1;0<=b?a<=b:a>=b;d=0<=b?++a:--a)c.push([]);return c}.call(this),j=[];for(d=g=i=this.seriesCoords.length-1;i<=0?g<=0:g>=0;d=i<=0?++g:--g)j.push(function(){var c,e,f,g;f=this.seriesCoords[d],g=[];for(c=0,e=f.length;c=u;k=0<=u?++t:--t)g=h[k],k===0?o+="M"+g.x+","+g.y:(i=j[k],m=h[k-1],n=j[k-1],l=(g.x-m.x)/4,p=m.x+l,r=Math.min(e,m.y+l*n),q=g.x-l,s=Math.min(e,g.y-l*i),o+="C"+p+","+r+","+q+","+s+","+g.x+","+g.y)}else o="M"+a.map(h,function(a){return""+a.x+","+a.y}).join("L");return o},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.drawHover=function(){var a,b,c,d,e;this.hoverHeight=this.options.hoverFontSize*1.5*(this.series.length+1),this.hover=this.r.rect(-10,-this.hoverHeight/2-this.options.hoverPaddingY,20,this.hoverHeight+this.options.hoverPaddingY*2,10).attr("fill",this.options.hoverFillColor).attr("stroke",this.options.hoverBorderColor).attr("stroke-width",this.options.hoverBorderWidth).attr("opacity",this.options.hoverOpacity),this.xLabel=this.r.text(0,this.options.hoverFontSize*.75-this.hoverHeight/2,"").attr("fill",this.options.hoverLabelColor).attr("font-weight","bold").attr("font-size",this.options.hoverFontSize),this.hoverSet=this.r.set(),this.hoverSet.push(this.hover),this.hoverSet.push(this.xLabel),this.yLabels=[],e=[];for(a=c=0,d=this.series.length-1;0<=d?c<=d:c>=d;a=0<=d?++c:--c)b=this.r.text(0,this.options.hoverFontSize*1.5*(a+1.5)-this.hoverHeight/2,"").attr("fill",this.options.lineColors[a]).attr("font-size",this.options.hoverFontSize),this.yLabels.push(b),e.push(this.hoverSet.push(b));return e},c.prototype.updateHover=function(b){var c,d,e,f,g,h,i=this;this.hoverSet.show(),this.xLabel.attr("text",this.columnLabels[b]);for(c=g=0,h=this.series.length-1;0<=h?g<=h:g>=h;c=0<=h?++g:--g)this.yLabels[c].attr("text",""+this.seriesLabels[c]+": "+this.yLabelFormat(this.series[c][b]));return d=Math.max.apply(null,a.map(this.yLabels,function(a){return a.getBBox().width})),d=Math.max(d,this.xLabel.getBBox().width),this.hover.attr("width",d+this.options.hoverPaddingX*2),this.hover.attr("x",-this.options.hoverPaddingX-d/2),f=Math.min.apply(null,a.map(this.series,function(a){return i.transY(a[b])})),f>this.hoverHeight+this.options.hoverPaddingY*2+this.options.hoverMargin+this.options.marginTop?f=f-this.hoverHeight/2-this.options.hoverPaddingY-this.options.hoverMargin:f=f+this.hoverHeight/2+this.options.hoverPaddingY+this.options.hoverMargin,f=Math.max(this.options.marginTop+this.hoverHeight/2+this.options.hoverPaddingY,f),f=Math.min(this.options.marginTop+this.height-this.hoverHeight/2-this.options.hoverPaddingY,f),e=Math.min(this.left+this.width-d/2-this.options.hoverPaddingX,this.columns[b]),e=Math.max(this.left+d/2+this.options.hoverPaddingX,e),this.hoverSet.attr("transform","t"+e+","+f)},c.prototype.hideHover=function(){return this.hoverSet.hide()},c.prototype.hilight=function(a){var b,c,d,e,f;if(this.prevHilight!==null&&this.prevHilight!==a)for(b=c=0,e=this.seriesPoints.length-1;0<=e?c<=e:c>=e;b=0<=e?++c:--c)this.seriesPoints[b][this.prevHilight]&&this.seriesPoints[b][this.prevHilight].animate(this.pointShrink);if(a!==null&&this.prevHilight!==a){for(b=d=0,f=this.seriesPoints.length-1;0<=f?d<=f:d>=f;b=0<=f?++d:--d)this.seriesPoints[b][a]&&this.seriesPoints[b][a].animate(this.pointGrow);this.updateHover(a)}this.prevHilight=a;if(a===null)return this.hideHover()},c.prototype.updateHilight=function(a){var b,c,d,e;a-=this.el.offset().left,e=[];for(b=c=d=this.hoverMargins.length;d<=0?c<=0:c>=0;b=d<=0?++c:--c){if(b===0||this.hoverMargins[b-1]>a){this.hilight(b);break}e.push(void 0)}return e},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.yLabelFormat=function(a){return""+this.options.preUnits+b.commas(a)+this.options.postUnits},c}(),b.parseDate=function(a){var b,c,d,e,f,g,h,i,j,k,l;return typeof a=="number"?a:(c=a.match(/^(\d+) Q(\d)$/),e=a.match(/^(\d+)-(\d+)$/),f=a.match(/^(\d+)-(\d+)-(\d+)$/),h=a.match(/^(\d+) W(\d+)$/),i=a.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)(Z|([+-])(\d\d):?(\d\d))?$/),j=a.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)(Z|([+-])(\d\d):?(\d\d))?$/),c?(new Date(parseInt(c[1],10),parseInt(c[2],10)*3-1,1)).getTime():e?(new Date(parseInt(e[1],10),parseInt(e[2],10)-1,1)).getTime():f?(new Date(parseInt(f[1],10),parseInt(f[2],10)-1,parseInt(f[3],10))).getTime():h?(k=new Date(parseInt(h[1],10),0,1),k.getDay()!==4&&k.setMonth(0,1+(4-k.getDay()+7)%7),k.getTime()+parseInt(h[2],10)*6048e5):i?i[6]?(g=0,i[6]!=="Z"&&(g=parseInt(i[8],10)*60+parseInt(i[9],10),i[7]==="+"&&(g=0-g)),Date.UTC(parseInt(i[1],10),parseInt(i[2],10)-1,parseInt(i[3],10),parseInt(i[4],10),parseInt(i[5],10)+g)):(new Date(parseInt(i[1],10),parseInt(i[2],10)-1,parseInt(i[3],10),parseInt(i[4],10),parseInt(i[5],10))).getTime():j?(l=parseFloat(j[6]),b=Math.floor(l),d=Math.round((l-b)*1e3),j[8]?(g=0,j[8]!=="Z"&&(g=parseInt(j[10],10)*60+parseInt(j[11],10),j[9]==="+"&&(g=0-g)),Date.UTC(parseInt(j[1],10),parseInt(j[2],10)-1,parseInt(j[3],10),parseInt(j[4],10),parseInt(j[5],10)+g,b,d)):(new Date(parseInt(j[1],10),parseInt(j[2],10)-1,parseInt(j[3],10),parseInt(j[4],10),parseInt(j[5],10),b,d)).getTime()):(new Date(parseInt(a,10),0,1)).getTime())},b.commas=function(a){var b,c,d,e;return a===null?"n/a":(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)},b.pad2=function(a){return(a<10?"0":"")+a},b.labelSeries=function(c,d,e,f,g){var h,i,j,k,l,m,n,o,p,q,r;j=200*(d-c)/e,i=new Date(c),n=b.LABEL_SPECS[f];if(n===void 0){r=b.AUTO_LABEL_ORDER;for(p=0,q=r.length;p=m.span){n=m;break}}}n===void 0&&(n=b.LABEL_SPECS.second),g&&(n=a.extend({},n,{fmt:g})),h=n.start(i),l=[];while((o=h.getTime())<=d)o>=c&&l.push([n.fmt(h),o]),n.incr(h);return l},c=function(a){return{span:a*60*1e3,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours())},fmt:function(a){return""+b.pad2(a.getHours())+":"+b.pad2(a.getMinutes())},incr:function(b){return b.setMinutes(b.getMinutes()+a)}}},d=function(a){return{span:a*1e3,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours(),a.getMinutes())},fmt:function(a){return""+b.pad2(a.getHours())+":"+b.pad2(a.getMinutes())+":"+b.pad2(a.getSeconds())},incr:function(b){return b.setSeconds(b.getSeconds()+a)}}},b.LABEL_SPECS={year:{span:1728e7,start:function(a){return new Date(a.getFullYear(),0,1)},fmt:function(a){return""+a.getFullYear()},incr:function(a){return a.setFullYear(a.getFullYear()+1)}},month:{span:24192e5,start:function(a){return new Date(a.getFullYear(),a.getMonth(),1)},fmt:function(a){return""+a.getFullYear()+"-"+b.pad2(a.getMonth()+1)},incr:function(a){return a.setMonth(a.getMonth()+1)}},day:{span:864e5,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate())},fmt:function(a){return""+a.getFullYear()+"-"+b.pad2(a.getMonth()+1)+"-"+b.pad2(a.getDate())},incr:function(a){return a.setDate(a.getDate()+1)}},hour:c(60),"30min":c(30),"15min":c(15),"10min":c(10),"5min":c(5),minute:c(1),"30sec":d(30),"15sec":d(15),"10sec":d(10),"5sec":d(5),second:d(1)},b.AUTO_LABEL_ORDER=["year","month","day","hour","30min","15min","10min","5min","minute","30sec","15sec","10sec","5sec","second"],window.Morris=b}).call(this); \ No newline at end of file +(function(){var a,b,c,d,e=function(a,b){return function(){return a.apply(b,arguments)}};a=jQuery,b={},b.Line=function(){function c(c){this.updateHilight=e(this.updateHilight,this),this.hilight=e(this.hilight,this),this.updateHover=e(this.updateHover,this),this.transY=e(this.transY,this),this.transX=e(this.transX,this);var d,f=this;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);if(this.el===null||this.el.length===0)throw new Error("Graph placeholder not found.");this.options=a.extend({},this.defaults,c),typeof this.options.units=="string"&&(this.options.postUnits=c.units);if(this.options.data===void 0||this.options.data.length===0)return;this.el.addClass("graph-initialised"),this.r=new Raphael(this.el[0]),this.pointGrow=Raphael.animation({r:this.options.pointSize+3},25,"linear"),this.pointShrink=Raphael.animation({r:this.options.pointSize},25,"linear"),this.elementWidth=null,this.elementHeight=null,this.dirty=!1,this.prevHilight=null,this.el.mousemove(function(a){return f.updateHilight(a.pageX)}),this.options.hideHover&&this.el.mouseout(function(a){return f.hilight(null)}),d=function(a){var b;return b=a.originalEvent.touches[0]||a.originalEvent.changedTouches[0],f.updateHilight(b.pageX),b},this.el.bind("touchstart",d),this.el.bind("touchmove",d),this.el.bind("touchend",d),this.setData(this.options.data)}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,preUnits:"",postUnits:"",dateFormat:function(a){return(new Date(a)).toString()},xLabels:"auto",xLabelFormat:null},c.prototype.setData=function(c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s=this;d==null&&(d=!0),this.options.data=c.slice(0),this.options.data.sort(function(a,b){return(a[s.options.xkey]=0;q<=0?a++:a--)r.push(a);return r}.apply(this),this.options.parseTime&&(this.columnLabels=a.map(this.columnLabels,function(a){return typeof a=="number"?s.options.dateFormat(a):a})),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"&&(h=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),h):this.options.ymax=h),typeof this.options.ymin=="string"&&this.options.ymin.slice(0,4)==="auto"&&(i=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),i):this.options.ymin=i),this.yInterval=(this.options.ymax-this.options.ymin)/(this.options.numLines-1),this.yInterval>0&&this.yInterval<1?this.precision=-Math.floor(Math.log(this.yInterval)/Math.log(10)):this.precision=0,this.dirty=!0;if(d)return this.redraw()},c.prototype.calc=function(){var b,c,d,e,f,g,h,i,j=this;e=this.el.width(),b=this.el.height();if(this.elementWidth!==e||this.elementHeight!==b||this.dirty){this.elementWidth=e,this.elementHeight=b,this.dirty=!1,this.maxYLabelWidth=Math.max(this.measureText(this.yLabelFormat(this.options.ymin),this.options.gridTextSize).width,this.measureText(this.yLabelFormat(this.options.ymax),this.options.gridTextSize).width),this.left=this.maxYLabelWidth+this.options.marginLeft,this.width=this.el.width()-this.left-this.options.marginRight,this.height=this.el.height()-this.options.marginTop-this.options.marginBottom,this.dx=this.width/(this.xmax-this.xmin),this.dy=this.height/(this.options.ymax-this.options.ymin),this.columns=function(){var a,b,c,d;c=this.xvals,d=[];for(a=0,b=c.length;a=g;h=n+=r)j=parseFloat(h.toFixed(this.precision)),l=this.transY(j),this.r.text(this.left-this.options.marginLeft/2,l,this.yLabelFormat(j)).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),this.r.path("M"+this.left+","+l+"H"+(this.left+this.width)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth);m=this.options.marginTop+this.height+this.options.marginBottom/2,k=50,i=null,a=function(a,b){var c,d;return c=w.r.text(w.transX(b),m,a).attr("font-size",w.options.gridTextSize).attr("fill",w.options.gridTextColor),d=c.getBBox(),(i===null||i<=d.x)&&d.x>=0&&d.x+d.width=t;d=0<=t?++p:--p)f=this.columnLabels[this.columnLabels.length-d-1],v.push(a(f,d));return v},c.prototype.drawSeries=function(){var a,b,c,d,e,f,g,h,i,j;for(d=f=h=this.seriesCoords.length-1;h<=0?f<=0:f>=0;d=h<=0?++f:--f)c=this.seriesCoords[d],c.length>1&&(e=this.createPath(c,this.options.marginTop,this.left,this.options.marginTop+this.height,this.left+this.width),this.r.path(e).attr("stroke",this.options.lineColors[d]).attr("stroke-width",this.options.lineWidth));this.seriesPoints=function(){var a,b,c;c=[];for(d=a=0,b=this.seriesCoords.length-1;0<=b?a<=b:a>=b;d=0<=b?++a:--a)c.push([]);return c}.call(this),j=[];for(d=g=i=this.seriesCoords.length-1;i<=0?g<=0:g>=0;d=i<=0?++g:--g)j.push(function(){var c,e,f,g;f=this.seriesCoords[d],g=[];for(c=0,e=f.length;c=u;k=0<=u?++t:--t)g=h[k],k===0?o+="M"+g.x+","+g.y:(i=j[k],m=h[k-1],n=j[k-1],l=(g.x-m.x)/4,p=m.x+l,r=Math.min(e,m.y+l*n),q=g.x-l,s=Math.min(e,g.y-l*i),o+="C"+p+","+r+","+q+","+s+","+g.x+","+g.y)}else o="M"+a.map(h,function(a){return""+a.x+","+a.y}).join("L");return o},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.drawHover=function(){var a,b,c,d,e;this.hoverHeight=this.options.hoverFontSize*1.5*(this.series.length+1),this.hover=this.r.rect(-10,-this.hoverHeight/2-this.options.hoverPaddingY,20,this.hoverHeight+this.options.hoverPaddingY*2,10).attr("fill",this.options.hoverFillColor).attr("stroke",this.options.hoverBorderColor).attr("stroke-width",this.options.hoverBorderWidth).attr("opacity",this.options.hoverOpacity),this.xLabel=this.r.text(0,this.options.hoverFontSize*.75-this.hoverHeight/2,"").attr("fill",this.options.hoverLabelColor).attr("font-weight","bold").attr("font-size",this.options.hoverFontSize),this.hoverSet=this.r.set(),this.hoverSet.push(this.hover),this.hoverSet.push(this.xLabel),this.yLabels=[],e=[];for(a=c=0,d=this.series.length-1;0<=d?c<=d:c>=d;a=0<=d?++c:--c)b=this.r.text(0,this.options.hoverFontSize*1.5*(a+1.5)-this.hoverHeight/2,"").attr("fill",this.options.lineColors[a]).attr("font-size",this.options.hoverFontSize),this.yLabels.push(b),e.push(this.hoverSet.push(b));return e},c.prototype.updateHover=function(b){var c,d,e,f,g,h,i=this;this.hoverSet.show(),this.xLabel.attr("text",this.columnLabels[b]);for(c=g=0,h=this.series.length-1;0<=h?g<=h:g>=h;c=0<=h?++g:--g)this.yLabels[c].attr("text",""+this.seriesLabels[c]+": "+this.yLabelFormat(this.series[c][b]));return d=Math.max.apply(null,a.map(this.yLabels,function(a){return a.getBBox().width})),d=Math.max(d,this.xLabel.getBBox().width),this.hover.attr("width",d+this.options.hoverPaddingX*2),this.hover.attr("x",-this.options.hoverPaddingX-d/2),f=Math.min.apply(null,a.map(this.series,function(a){return i.transY(a[b])})),f>this.hoverHeight+this.options.hoverPaddingY*2+this.options.hoverMargin+this.options.marginTop?f=f-this.hoverHeight/2-this.options.hoverPaddingY-this.options.hoverMargin:f=f+this.hoverHeight/2+this.options.hoverPaddingY+this.options.hoverMargin,f=Math.max(this.options.marginTop+this.hoverHeight/2+this.options.hoverPaddingY,f),f=Math.min(this.options.marginTop+this.height-this.hoverHeight/2-this.options.hoverPaddingY,f),e=Math.min(this.left+this.width-d/2-this.options.hoverPaddingX,this.columns[b]),e=Math.max(this.left+d/2+this.options.hoverPaddingX,e),this.hoverSet.attr("transform","t"+e+","+f)},c.prototype.hideHover=function(){return this.hoverSet.hide()},c.prototype.hilight=function(a){var b,c,d,e,f;if(this.prevHilight!==null&&this.prevHilight!==a)for(b=c=0,e=this.seriesPoints.length-1;0<=e?c<=e:c>=e;b=0<=e?++c:--c)this.seriesPoints[b][this.prevHilight]&&this.seriesPoints[b][this.prevHilight].animate(this.pointShrink);if(a!==null&&this.prevHilight!==a){for(b=d=0,f=this.seriesPoints.length-1;0<=f?d<=f:d>=f;b=0<=f?++d:--d)this.seriesPoints[b][a]&&this.seriesPoints[b][a].animate(this.pointGrow);this.updateHover(a)}this.prevHilight=a;if(a===null)return this.hideHover()},c.prototype.updateHilight=function(a){var b,c,d,e;a-=this.el.offset().left,e=[];for(b=c=d=this.hoverMargins.length;d<=0?c<=0:c>=0;b=d<=0?++c:--c){if(b===0||this.hoverMargins[b-1]>a){this.hilight(b);break}e.push(void 0)}return e},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.yLabelFormat=function(a){return""+this.options.preUnits+b.commas(a)+this.options.postUnits},c}(),b.parseDate=function(a){var b,c,d,e,f,g,h,i,j,k,l;return typeof a=="number"?a:(c=a.match(/^(\d+) Q(\d)$/),e=a.match(/^(\d+)-(\d+)$/),f=a.match(/^(\d+)-(\d+)-(\d+)$/),h=a.match(/^(\d+) W(\d+)$/),i=a.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)(Z|([+-])(\d\d):?(\d\d))?$/),j=a.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)(Z|([+-])(\d\d):?(\d\d))?$/),c?(new Date(parseInt(c[1],10),parseInt(c[2],10)*3-1,1)).getTime():e?(new Date(parseInt(e[1],10),parseInt(e[2],10)-1,1)).getTime():f?(new Date(parseInt(f[1],10),parseInt(f[2],10)-1,parseInt(f[3],10))).getTime():h?(k=new Date(parseInt(h[1],10),0,1),k.getDay()!==4&&k.setMonth(0,1+(4-k.getDay()+7)%7),k.getTime()+parseInt(h[2],10)*6048e5):i?i[6]?(g=0,i[6]!=="Z"&&(g=parseInt(i[8],10)*60+parseInt(i[9],10),i[7]==="+"&&(g=0-g)),Date.UTC(parseInt(i[1],10),parseInt(i[2],10)-1,parseInt(i[3],10),parseInt(i[4],10),parseInt(i[5],10)+g)):(new Date(parseInt(i[1],10),parseInt(i[2],10)-1,parseInt(i[3],10),parseInt(i[4],10),parseInt(i[5],10))).getTime():j?(l=parseFloat(j[6]),b=Math.floor(l),d=Math.round((l-b)*1e3),j[8]?(g=0,j[8]!=="Z"&&(g=parseInt(j[10],10)*60+parseInt(j[11],10),j[9]==="+"&&(g=0-g)),Date.UTC(parseInt(j[1],10),parseInt(j[2],10)-1,parseInt(j[3],10),parseInt(j[4],10),parseInt(j[5],10)+g,b,d)):(new Date(parseInt(j[1],10),parseInt(j[2],10)-1,parseInt(j[3],10),parseInt(j[4],10),parseInt(j[5],10),b,d)).getTime()):(new Date(parseInt(a,10),0,1)).getTime())},b.commas=function(a){var b,c,d,e;return a===null?"n/a":(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)},b.pad2=function(a){return(a<10?"0":"")+a},b.labelSeries=function(c,d,e,f,g){var h,i,j,k,l,m,n,o,p,q,r;j=200*(d-c)/e,i=new Date(c),n=b.LABEL_SPECS[f];if(n===void 0){r=b.AUTO_LABEL_ORDER;for(p=0,q=r.length;p=m.span){n=m;break}}}n===void 0&&(n=b.LABEL_SPECS.second),g&&(n=a.extend({},n,{fmt:g})),h=n.start(i),l=[];while((o=h.getTime())<=d)o>=c&&l.push([n.fmt(h),o]),n.incr(h);return l},c=function(a){return{span:a*60*1e3,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours())},fmt:function(a){return""+b.pad2(a.getHours())+":"+b.pad2(a.getMinutes())},incr:function(b){return b.setMinutes(b.getMinutes()+a)}}},d=function(a){return{span:a*1e3,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours(),a.getMinutes())},fmt:function(a){return""+b.pad2(a.getHours())+":"+b.pad2(a.getMinutes())+":"+b.pad2(a.getSeconds())},incr:function(b){return b.setSeconds(b.getSeconds()+a)}}},b.LABEL_SPECS={year:{span:1728e7,start:function(a){return new Date(a.getFullYear(),0,1)},fmt:function(a){return""+a.getFullYear()},incr:function(a){return a.setFullYear(a.getFullYear()+1)}},month:{span:24192e5,start:function(a){return new Date(a.getFullYear(),a.getMonth(),1)},fmt:function(a){return""+a.getFullYear()+"-"+b.pad2(a.getMonth()+1)},incr:function(a){return a.setMonth(a.getMonth()+1)}},day:{span:864e5,start:function(a){return new Date(a.getFullYear(),a.getMonth(),a.getDate())},fmt:function(a){return""+a.getFullYear()+"-"+b.pad2(a.getMonth()+1)+"-"+b.pad2(a.getDate())},incr:function(a){return a.setDate(a.getDate()+1)}},hour:c(60),"30min":c(30),"15min":c(15),"10min":c(10),"5min":c(5),minute:c(1),"30sec":d(30),"15sec":d(15),"10sec":d(10),"5sec":d(5),second:d(1)},b.AUTO_LABEL_ORDER=["year","month","day","hour","30min","15min","10min","5min","minute","30sec","15sec","10sec","5sec","second"],window.Morris=b}).call(this); \ No newline at end of file