diff --git a/morris.coffee b/morris.coffee index 05cb609..4ac638b 100644 --- a/morris.coffee +++ b/morris.coffee @@ -58,6 +58,8 @@ class Morris.Line # Do any necessary pre-processing for a new dataset # precalc: -> + # sort data + @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] @seriesLabels = @options.labels diff --git a/morris.js b/morris.js index d4f71cb..620c4eb 100644 --- a/morris.js +++ b/morris.js @@ -48,6 +48,9 @@ Line.prototype.precalc = function() { var ykey, ymax, _i, _len, _ref, _this = this; + this.options.data.sort(function(a, b) { + return (a[_this.options.xkey] < b[_this.options.xkey]) - (b[_this.options.xkey] < a[_this.options.xkey]); + }); this.columnLabels = $.map(this.options.data, function(d) { return d[_this.options.xkey]; }); diff --git a/morris.min.js b/morris.min.js index 7b19a4a..e042681 100644 --- a/morris.min.js +++ b/morris.min.js @@ -1 +1 @@ -((function(){var a;a={},a.Line=function(){function b(b){if(!(this instanceof a.Line))return new a.Line(b);typeof b.element=="string"?this.el=$(document.getElementById(b.element)):this.el=$(b.element),this.options=$.extend({},this.defaults,b);if(this.options.data===void 0||this.options.data.length===0)return;this.el.addClass("graph-initialised"),this.precalc(),this.redraw()}return b.prototype.defaults={lineWidth:3,pointSize:4,lineColors:["#0b62a4","#7A92A3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],ymax:"auto",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},b.prototype.precalc=function(){var a,b,c,d,e,f=this;this.columnLabels=$.map(this.options.data,function(a){return a[f.options.xkey]}),this.seriesLabels=this.options.labels,this.series=[],e=this.options.ykeys;for(c=0,d=e.length;c5?this.options.ymax=Math.max(parseInt(this.options.ymax.slice(5),10),b):this.options.ymax=b},b.prototype.redraw=function(){var 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,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=this;this.el.empty(),this.r=new Raphael(this.el[0]),q=this.measureText(this.options.ymax,this.options.gridTextSize).width+this.options.marginLeft,G=this.el.width()-q-this.options.marginRight,g=this.el.height()-this.options.marginTop-this.options.marginBottom,e=G/(this.xmax-this.xmin),f=g/this.options.ymax,B=function(a){return Z.xvals.length===1?q+G/2:q+(a-Z.xmin)*e},C=function(a){return Z.options.marginTop+g-a*f},r=g/(this.options.numLines-1);for(n=0,R=this.options.numLines-1;0<=R?n<=R:n>=R;0<=R?n++:n--)K=this.options.marginTop+n*r,F=Math.round((this.options.numLines-1-n)*this.options.ymax/(this.options.numLines-1)),this.r.text(q-this.options.marginLeft/2,K,F).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),this.r.path("M"+q+","+K+"H"+(q+G)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth);w=null,J=50;for(n=S=Math.ceil(this.xmin),T=Math.floor(this.xmax);S<=T?n<=T:n>=T;S<=T?n++:n--)o=this.r.text(B(n),this.options.marginTop+g+this.options.marginBottom/2,n).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor),p=o.getBBox(),w===null||w<=p.x?w=p.x+p.width+J:o.remove();c=function(){var a,b,c,d;c=this.xvals,d=[];for(a=0,b=c.length;a=0;V<=0?n++:n--)d=y[n],d.length>1&&(s=this.createPath(d,this.options.marginTop,q,this.options.marginTop+g,q+G),this.r.path(s).attr("stroke",this.options.lineColors[n]).attr("stroke-width",this.options.lineWidth));z=function(){var a,b;b=[];for(n=0,a=y.length-1;0<=a?n<=a:n>=a;0<=a?n++:n--)b.push([]);return b}();for(n=W=y.length-1;W<=0?n<=0:n>=0;W<=0?n++:n--){X=y[n];for(O=0,Q=X.length;O=Y;0<=Y?n++:n--)L=this.r.text(0,this.options.hoverFontSize*1.5*(n+1.5)-k/2,"").attr("fill",this.options.lineColors[n]).attr("font-size",this.options.hoverFontSize),M.push(L),m.push(L);return E=function(a){var b,d,e,f,h;m.show(),I.attr("text",Z.columnLabels[a]);for(b=0,h=Z.series.length-1;0<=h?b<=h:b>=h;0<=h?b++:b--)M[b].attr("text",""+Z.seriesLabels[b]+": "+Z.commas(Z.series[b][a]));return d=Math.max.apply(null,$.map(M,function(a){return a.getBBox().width})),d=Math.max(d,I.getBBox().width),j.attr("width",d+Z.options.hoverPaddingX*2),j.attr("x",-Z.options.hoverPaddingX-d/2),f=Math.min.apply(null,$.map(Z.series,function(b){return C(b[a])})),f>k+Z.options.hoverPaddingY*2+Z.options.hoverMargin+Z.options.marginTop?f=f-k/2-Z.options.hoverPaddingY-Z.options.hoverMargin:f=f+k/2+Z.options.hoverPaddingY+Z.options.hoverMargin,f=Math.max(Z.options.marginTop+k/2+Z.options.hoverPaddingY,f),f=Math.min(Z.options.marginTop+g-k/2-Z.options.hoverPaddingY,f),e=Math.min(q+G-d/2-Z.options.hoverPaddingX,c[a]),e=Math.max(q+d/2+Z.options.hoverPaddingX,e),m.attr("transform","t"+e+","+f)},h=function(){return m.hide()},l=$.map(c.slice(1),function(a,b){return(a+c[b])/2}),v=null,t=Raphael.animation({r:this.options.pointSize+3},25,"linear"),u=Raphael.animation({r:this.options.pointSize},25,"linear"),i=function(a){var b,c,d;if(v!==null&&v!==a)for(b=0,d=z.length-1;0<=d?b<=d:b>=d;0<=d?b++:b--)z[b][v].animate(u);if(a!==null&&v!==a){for(b=0,c=z.length-1;0<=c?b<=c:b>=c;0<=c?b++:b--)z[b][a].animate(t);E(a)}v=a;if(a===null)return h()},D=function(a){var b,c,d;a-=Z.el.offset().left,d=[];for(b=c=l.length;c<=0?b<=0:b>=0;c<=0?b++:b--){if(b===0||l[b-1]>a){i(b);break}d.push(void 0)}return d},this.el.mousemove(function(a){return D(a.pageX)}),A=function(a){var b;return b=a.originalEvent.touches[0]||a.originalEvent.changedTouches[0],D(b.pageX),b},this.el.bind("touchstart",A),this.el.bind("touchmove",A),this.el.bind("touchend",A),i(0)},b.prototype.createPath=function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r;m="";if(this.options.smooth){h=this.gradients(a);for(i=0,r=a.length-1;0<=r?i<=r:i>=r;0<=r?i++:i--)f=a[i],i===0?m+="M"+f.x+","+f.y:(g=h[i],k=a[i-1],l=h[i-1],j=(f.x-k.x)/4,n=k.x+j,p=Math.min(d,k.y+j*l),o=f.x-j,q=Math.min(d,f.y-j*g),m+="C"+n+","+p+","+o+","+q+","+f.x+","+f.y)}else m="M"+$.map(a,function(a){return""+a.x+","+a.y}).join("L");return m},b.prototype.gradients=function(a){return $.map(a,function(b,c){return c===0?(a[1].y-b.y)/(a[1].x-b.x):c===a.length-1?(b.y-a[c-1].y)/(b.x-a[c-1].x):(a[c+1].y-a[c-1].y)/(a[c+1].x-a[c-1].x)})},b.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},b.prototype.parseYear=function(a){var b,c,d,e,f,g,h,i,j,k;return g=a.toString(),c=g.match(/^(\d+) Q(\d)$/),e=g.match(/^(\d+)-(\d+)$/),f=g.match(/^(\d+)-(\d+)-(\d+)$/),c?parseInt(c[1],10)+(parseInt(c[2],10)*3-1)/12:e?parseInt(e[1],10)+(parseInt(e[2],10)-1)/12:f?(k=parseInt(f[1],10),d=parseInt(f[2],10),b=parseInt(f[3],10),h=(new Date(k,d-1,b)).getTime(),i=(new Date(k,0,1)).getTime(),j=(new Date(k+1,0,1)).getTime(),k+(h-i)/(j-i)):parseInt(a,10)},b.prototype.commas=function(a){return Math.max(0,a).toFixed(0).replace(/(?=(?:\d{3})+$)(?!^)/g,",")},b}(),window.Morris=a})).call(this); \ No newline at end of file +((function(){var a;a={},a.Line=function(){function b(b){if(!(this instanceof a.Line))return new a.Line(b);typeof b.element=="string"?this.el=$(document.getElementById(b.element)):this.el=$(b.element),this.options=$.extend({},this.defaults,b);if(this.options.data===void 0||this.options.data.length===0)return;this.el.addClass("graph-initialised"),this.precalc(),this.redraw()}return b.prototype.defaults={lineWidth:3,pointSize:4,lineColors:["#0b62a4","#7A92A3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],ymax:"auto",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},b.prototype.precalc=function(){var a,b,c,d,e,f=this;this.options.data.sort(function(a,b){return(a[f.options.xkey]5?this.options.ymax=Math.max(parseInt(this.options.ymax.slice(5),10),b):this.options.ymax=b},b.prototype.redraw=function(){var 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,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=this;this.el.empty(),this.r=new Raphael(this.el[0]),q=this.measureText(this.options.ymax,this.options.gridTextSize).width+this.options.marginLeft,G=this.el.width()-q-this.options.marginRight,g=this.el.height()-this.options.marginTop-this.options.marginBottom,e=G/(this.xmax-this.xmin),f=g/this.options.ymax,B=function(a){return Z.xvals.length===1?q+G/2:q+(a-Z.xmin)*e},C=function(a){return Z.options.marginTop+g-a*f},r=g/(this.options.numLines-1);for(n=0,R=this.options.numLines-1;0<=R?n<=R:n>=R;0<=R?n++:n--)K=this.options.marginTop+n*r,F=Math.round((this.options.numLines-1-n)*this.options.ymax/(this.options.numLines-1)),this.r.text(q-this.options.marginLeft/2,K,F).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),this.r.path("M"+q+","+K+"H"+(q+G)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth);w=null,J=50;for(n=S=Math.ceil(this.xmin),T=Math.floor(this.xmax);S<=T?n<=T:n>=T;S<=T?n++:n--)o=this.r.text(B(n),this.options.marginTop+g+this.options.marginBottom/2,n).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor),p=o.getBBox(),w===null||w<=p.x?w=p.x+p.width+J:o.remove();c=function(){var a,b,c,d;c=this.xvals,d=[];for(a=0,b=c.length;a=0;V<=0?n++:n--)d=y[n],d.length>1&&(s=this.createPath(d,this.options.marginTop,q,this.options.marginTop+g,q+G),this.r.path(s).attr("stroke",this.options.lineColors[n]).attr("stroke-width",this.options.lineWidth));z=function(){var a,b;b=[];for(n=0,a=y.length-1;0<=a?n<=a:n>=a;0<=a?n++:n--)b.push([]);return b}();for(n=W=y.length-1;W<=0?n<=0:n>=0;W<=0?n++:n--){X=y[n];for(O=0,Q=X.length;O=Y;0<=Y?n++:n--)L=this.r.text(0,this.options.hoverFontSize*1.5*(n+1.5)-k/2,"").attr("fill",this.options.lineColors[n]).attr("font-size",this.options.hoverFontSize),M.push(L),m.push(L);return E=function(a){var b,d,e,f,h;m.show(),I.attr("text",Z.columnLabels[a]);for(b=0,h=Z.series.length-1;0<=h?b<=h:b>=h;0<=h?b++:b--)M[b].attr("text",""+Z.seriesLabels[b]+": "+Z.commas(Z.series[b][a]));return d=Math.max.apply(null,$.map(M,function(a){return a.getBBox().width})),d=Math.max(d,I.getBBox().width),j.attr("width",d+Z.options.hoverPaddingX*2),j.attr("x",-Z.options.hoverPaddingX-d/2),f=Math.min.apply(null,$.map(Z.series,function(b){return C(b[a])})),f>k+Z.options.hoverPaddingY*2+Z.options.hoverMargin+Z.options.marginTop?f=f-k/2-Z.options.hoverPaddingY-Z.options.hoverMargin:f=f+k/2+Z.options.hoverPaddingY+Z.options.hoverMargin,f=Math.max(Z.options.marginTop+k/2+Z.options.hoverPaddingY,f),f=Math.min(Z.options.marginTop+g-k/2-Z.options.hoverPaddingY,f),e=Math.min(q+G-d/2-Z.options.hoverPaddingX,c[a]),e=Math.max(q+d/2+Z.options.hoverPaddingX,e),m.attr("transform","t"+e+","+f)},h=function(){return m.hide()},l=$.map(c.slice(1),function(a,b){return(a+c[b])/2}),v=null,t=Raphael.animation({r:this.options.pointSize+3},25,"linear"),u=Raphael.animation({r:this.options.pointSize},25,"linear"),i=function(a){var b,c,d;if(v!==null&&v!==a)for(b=0,d=z.length-1;0<=d?b<=d:b>=d;0<=d?b++:b--)z[b][v].animate(u);if(a!==null&&v!==a){for(b=0,c=z.length-1;0<=c?b<=c:b>=c;0<=c?b++:b--)z[b][a].animate(t);E(a)}v=a;if(a===null)return h()},D=function(a){var b,c,d;a-=Z.el.offset().left,d=[];for(b=c=l.length;c<=0?b<=0:b>=0;c<=0?b++:b--){if(b===0||l[b-1]>a){i(b);break}d.push(void 0)}return d},this.el.mousemove(function(a){return D(a.pageX)}),A=function(a){var b;return b=a.originalEvent.touches[0]||a.originalEvent.changedTouches[0],D(b.pageX),b},this.el.bind("touchstart",A),this.el.bind("touchmove",A),this.el.bind("touchend",A),i(0)},b.prototype.createPath=function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r;m="";if(this.options.smooth){h=this.gradients(a);for(i=0,r=a.length-1;0<=r?i<=r:i>=r;0<=r?i++:i--)f=a[i],i===0?m+="M"+f.x+","+f.y:(g=h[i],k=a[i-1],l=h[i-1],j=(f.x-k.x)/4,n=k.x+j,p=Math.min(d,k.y+j*l),o=f.x-j,q=Math.min(d,f.y-j*g),m+="C"+n+","+p+","+o+","+q+","+f.x+","+f.y)}else m="M"+$.map(a,function(a){return""+a.x+","+a.y}).join("L");return m},b.prototype.gradients=function(a){return $.map(a,function(b,c){return c===0?(a[1].y-b.y)/(a[1].x-b.x):c===a.length-1?(b.y-a[c-1].y)/(b.x-a[c-1].x):(a[c+1].y-a[c-1].y)/(a[c+1].x-a[c-1].x)})},b.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},b.prototype.parseYear=function(a){var b,c,d,e,f,g,h,i,j,k;return g=a.toString(),c=g.match(/^(\d+) Q(\d)$/),e=g.match(/^(\d+)-(\d+)$/),f=g.match(/^(\d+)-(\d+)-(\d+)$/),c?parseInt(c[1],10)+(parseInt(c[2],10)*3-1)/12:e?parseInt(e[1],10)+(parseInt(e[2],10)-1)/12:f?(k=parseInt(f[1],10),d=parseInt(f[2],10),b=parseInt(f[3],10),h=(new Date(k,d-1,b)).getTime(),i=(new Date(k,0,1)).getTime(),j=(new Date(k+1,0,1)).getTime(),k+(h-i)/(j-i)):parseInt(a,10)},b.prototype.commas=function(a){return Math.max(0,a).toFixed(0).replace(/(?=(?:\d{3})+$)(?!^)/g,",")},b}(),window.Morris=a})).call(this); \ No newline at end of file