From ceab6882167b203cb6513fb3b11ea1ccf06c2f1b Mon Sep 17 00:00:00 2001 From: Mark Abbott Date: Sun, 4 Mar 2012 13:36:44 +0000 Subject: [PATCH 1/4] Add functionality to support Week Numbers --- morris.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/morris.js b/morris.js index a5c6f32..8753a5b 100644 --- a/morris.js +++ b/morris.js @@ -319,8 +319,11 @@ m = s.match(/^(\d+) Q(\d)$/); n = s.match(/^(\d+)-(\d+)$/); o = s.match(/^(\d+)-(\d+)-(\d+)$/); + p = s.match(/^(\d+) W(\d)$/); if (m) { return parseInt(m[1], 10) + (parseInt(m[2], 10) * 3 - 1) / 12; + } else if (p) { + return parseInt(p[1], 10) + (parseInt(p[2], 10) - 1) / 53; } else if (n) { return parseInt(n[1], 10) + (parseInt(n[2], 10) - 1) / 12; } else if (o) { From 6be7b1904cb84d75ea2ceb3c5ad0c0e40a0bef63 Mon Sep 17 00:00:00 2001 From: Mark Abbott Date: Sun, 4 Mar 2012 16:11:48 +0000 Subject: [PATCH 2/4] Converted draft code to Coffeescript, and added calculation for number of weeks in the year --- example.html | 43 +++++++++++++++++++++++++++++++++++++++++++ morris.coffee | 12 ++++++++++++ morris.js | 12 +++++++++--- morris.min.js | 2 +- 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/example.html b/example.html index 916bb16..3fa2297 100644 --- a/example.html +++ b/example.html @@ -59,6 +59,49 @@ }); }); +

Formatting Dates With Weeks

+
+

Formatting Dates with YYYY-MM

diff --git a/morris.coffee b/morris.coffee index ebcbfd0..206c188 100644 --- a/morris.coffee +++ b/morris.coffee @@ -288,8 +288,20 @@ class Morris.Line m = s.match /^(\d+) Q(\d)$/ n = s.match /^(\d+)-(\d+)$/ o = s.match /^(\d+)-(\d+)-(\d+)$/ + p = s.match /^(\d+) W(\d+)$/ if m parseInt(m[1], 10) + (parseInt(m[2], 10) * 3 - 1) / 12 + 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); + if y1.getDay() isnt 4 + y1.setMonth(0, 1 + ((4 - y1.getDay()) + 7) % 7); + if y2.getDay() isnt 4 + y2.setMonth(0, 1 + ((4 - y2.getDay()) + 7) % 7); + weeks = 1 + 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 diff --git a/morris.js b/morris.js index 8753a5b..cdedec2 100644 --- a/morris.js +++ b/morris.js @@ -314,16 +314,22 @@ }; Line.prototype.parseYear = function(date) { - var day, m, month, n, o, s, timestamp, y1, y2, year; + 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)$/); + p = s.match(/^(\d+) W(\d+)$/); if (m) { return parseInt(m[1], 10) + (parseInt(m[2], 10) * 3 - 1) / 12; } else if (p) { - return parseInt(p[1], 10) + (parseInt(p[2], 10) - 1) / 53; + 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 = 1 + Math.ceil((y2 - y1) / 604800000); + return parseInt(p[1], 10) + (parseInt(p[2], 10) - 1) / weeks; } else if (n) { return parseInt(n[1], 10) + (parseInt(n[2], 10) - 1) / 12; } else if (o) { diff --git a/morris.min.js b/morris.min.js index 7e1b86c..88cb022 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",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},c.prototype.precalc=function(){var b,c,d,e,f,g=this;this.options.data.sort(function(a,b){return(a[g.options.xkey]5?this.options.ymax=Math.max(parseInt(this.options.ymax.slice(5),10),c):this.options.ymax=c},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,_=this;this.el.empty(),this.r=new Raphael(this.el[0]),r=this.measureText(this.options.ymax,this.options.gridTextSize).width+this.options.marginLeft,H=this.el.width()-r-this.options.marginRight,h=this.el.height()-this.options.marginTop-this.options.marginBottom,f=H/(this.xmax-this.xmin),g=h/this.options.ymax,C=function(a){return _.xvals.length===1?r+H/2:r+(a-_.xmin)*f},D=function(a){return _.options.marginTop+h-a*g},s=h/(this.options.numLines-1);for(o=0,S=this.options.numLines-1;0<=S?o<=S:o>=S;0<=S?o++:o--)L=this.options.marginTop+o*s,G=Math.round((this.options.numLines-1-o)*this.options.ymax/(this.options.numLines-1)),this.r.text(r-this.options.marginLeft/2,L,G).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),this.r.path("M"+r+","+L+"H"+(r+H)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth);x=null,K=50;for(o=T=Math.ceil(this.xmin),U=Math.floor(this.xmax);T<=U?o<=U:o>=U;T<=U?o++:o--)p=this.r.text(C(o),this.options.marginTop+h+this.options.marginBottom/2,o).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor),q=p.getBBox(),x===null||x<=q.x?x=q.x+q.width+K:p.remove();d=function(){var a,b,c,d;c=this.xvals,d=[];for(a=0,b=c.length;a=0;W<=0?o++:o--)e=z[o],e.length>1&&(t=this.createPath(e,this.options.marginTop,r,this.options.marginTop+h,r+H),this.r.path(t).attr("stroke",this.options.lineColors[o]).attr("stroke-width",this.options.lineWidth));A=function(){var a,b;b=[];for(o=0,a=z.length-1;0<=a?o<=a:o>=a;0<=a?o++:o--)b.push([]);return b}();for(o=X=z.length-1;X<=0?o<=0:o>=0;X<=0?o++:o--){Y=z[o];for(P=0,R=Y.length;P=Z;0<=Z?o++:o--)M=this.r.text(0,this.options.hoverFontSize*1.5*(o+1.5)-l/2,"").attr("fill",this.options.lineColors[o]).attr("font-size",this.options.hoverFontSize),N.push(M),n.push(M);return F=function(b){var c,e,f,g,i;n.show(),J.attr("text",_.columnLabels[b]);for(c=0,i=_.series.length-1;0<=i?c<=i:c>=i;0<=i?c++:c--)N[c].attr("text",""+_.seriesLabels[c]+": "+_.commas(_.series[c][b]));return e=Math.max.apply(null,a.map(N,function(a){return a.getBBox().width})),e=Math.max(e,J.getBBox().width),k.attr("width",e+_.options.hoverPaddingX*2),k.attr("x",-_.options.hoverPaddingX-e/2),g=Math.min.apply(null,a.map(_.series,function(a){return D(a[b])})),g>l+_.options.hoverPaddingY*2+_.options.hoverMargin+_.options.marginTop?g=g-l/2-_.options.hoverPaddingY-_.options.hoverMargin:g=g+l/2+_.options.hoverPaddingY+_.options.hoverMargin,g=Math.max(_.options.marginTop+l/2+_.options.hoverPaddingY,g),g=Math.min(_.options.marginTop+h-l/2-_.options.hoverPaddingY,g),f=Math.min(r+H-e/2-_.options.hoverPaddingX,d[b]),f=Math.max(r+e/2+_.options.hoverPaddingX,f),n.attr("transform","t"+f+","+g)},i=function(){return n.hide()},m=a.map(d.slice(1),function(a,b){return(a+d[b])/2}),w=null,u=Raphael.animation({r:this.options.pointSize+3},25,"linear"),v=Raphael.animation({r:this.options.pointSize},25,"linear"),j=function(a){var b,c,d;if(w!==null&&w!==a)for(b=0,d=A.length-1;0<=d?b<=d:b>=d;0<=d?b++:b--)A[b][w].animate(v);if(a!==null&&w!==a){for(b=0,c=A.length-1;0<=c?b<=c:b>=c;0<=c?b++:b--)A[b][a].animate(u);F(a)}w=a;if(a===null)return i()},E=function(a){var b,c,d;a-=_.el.offset().left,d=[];for(b=c=m.length;c<=0?b<=0:b>=0;c<=0?b++:b--){if(b===0||m[b-1]>a){j(b);break}d.push(void 0)}return d},this.el.mousemove(function(a){return E(a.pageX)}),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),j(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;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)},c.prototype.commas=function(a){return Math.max(0,a).toFixed(0).replace(/(?=(?:\d{3})+$)(?!^)/g,",")},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",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},c.prototype.precalc=function(){var b,c,d,e,f,g=this;this.options.data.sort(function(a,b){return(a[g.options.xkey]5?this.options.ymax=Math.max(parseInt(this.options.ymax.slice(5),10),c):this.options.ymax=c},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,_=this;this.el.empty(),this.r=new Raphael(this.el[0]),r=this.measureText(this.options.ymax,this.options.gridTextSize).width+this.options.marginLeft,H=this.el.width()-r-this.options.marginRight,h=this.el.height()-this.options.marginTop-this.options.marginBottom,f=H/(this.xmax-this.xmin),g=h/this.options.ymax,C=function(a){return _.xvals.length===1?r+H/2:r+(a-_.xmin)*f},D=function(a){return _.options.marginTop+h-a*g},s=h/(this.options.numLines-1);for(o=0,S=this.options.numLines-1;0<=S?o<=S:o>=S;0<=S?o++:o--)L=this.options.marginTop+o*s,G=Math.round((this.options.numLines-1-o)*this.options.ymax/(this.options.numLines-1)),this.r.text(r-this.options.marginLeft/2,L,G).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),this.r.path("M"+r+","+L+"H"+(r+H)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth);x=null,K=50;for(o=T=Math.ceil(this.xmin),U=Math.floor(this.xmax);T<=U?o<=U:o>=U;T<=U?o++:o--)p=this.r.text(C(o),this.options.marginTop+h+this.options.marginBottom/2,o).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor),q=p.getBBox(),x===null||x<=q.x?x=q.x+q.width+K:p.remove();d=function(){var a,b,c,d;c=this.xvals,d=[];for(a=0,b=c.length;a=0;W<=0?o++:o--)e=z[o],e.length>1&&(t=this.createPath(e,this.options.marginTop,r,this.options.marginTop+h,r+H),this.r.path(t).attr("stroke",this.options.lineColors[o]).attr("stroke-width",this.options.lineWidth));A=function(){var a,b;b=[];for(o=0,a=z.length-1;0<=a?o<=a:o>=a;0<=a?o++:o--)b.push([]);return b}();for(o=X=z.length-1;X<=0?o<=0:o>=0;X<=0?o++:o--){Y=z[o];for(P=0,R=Y.length;P=Z;0<=Z?o++:o--)M=this.r.text(0,this.options.hoverFontSize*1.5*(o+1.5)-l/2,"").attr("fill",this.options.lineColors[o]).attr("font-size",this.options.hoverFontSize),N.push(M),n.push(M);return F=function(b){var c,e,f,g,i;n.show(),J.attr("text",_.columnLabels[b]);for(c=0,i=_.series.length-1;0<=i?c<=i:c>=i;0<=i?c++:c--)N[c].attr("text",""+_.seriesLabels[c]+": "+_.commas(_.series[c][b]));return e=Math.max.apply(null,a.map(N,function(a){return a.getBBox().width})),e=Math.max(e,J.getBBox().width),k.attr("width",e+_.options.hoverPaddingX*2),k.attr("x",-_.options.hoverPaddingX-e/2),g=Math.min.apply(null,a.map(_.series,function(a){return D(a[b])})),g>l+_.options.hoverPaddingY*2+_.options.hoverMargin+_.options.marginTop?g=g-l/2-_.options.hoverPaddingY-_.options.hoverMargin:g=g+l/2+_.options.hoverPaddingY+_.options.hoverMargin,g=Math.max(_.options.marginTop+l/2+_.options.hoverPaddingY,g),g=Math.min(_.options.marginTop+h-l/2-_.options.hoverPaddingY,g),f=Math.min(r+H-e/2-_.options.hoverPaddingX,d[b]),f=Math.max(r+e/2+_.options.hoverPaddingX,f),n.attr("transform","t"+f+","+g)},i=function(){return n.hide()},m=a.map(d.slice(1),function(a,b){return(a+d[b])/2}),w=null,u=Raphael.animation({r:this.options.pointSize+3},25,"linear"),v=Raphael.animation({r:this.options.pointSize},25,"linear"),j=function(a){var b,c,d;if(w!==null&&w!==a)for(b=0,d=A.length-1;0<=d?b<=d:b>=d;0<=d?b++:b--)A[b][w].animate(v);if(a!==null&&w!==a){for(b=0,c=A.length-1;0<=c?b<=c:b>=c;0<=c?b++:b--)A[b][a].animate(u);F(a)}w=a;if(a===null)return i()},E=function(a){var b,c,d;a-=_.el.offset().left,d=[];for(b=c=m.length;c<=0?b<=0:b>=0;c<=0?b++:b--){if(b===0||m[b-1]>a){j(b);break}d.push(void 0)}return d},this.el.mousemove(function(a){return E(a.pageX)}),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),j(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=1+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){return Math.max(0,a).toFixed(0).replace(/(?=(?:\d{3})+$)(?!^)/g,",")},c}(),window.Morris=b})).call(this); \ No newline at end of file From 6fb708aceae3d30d56a1afe0b6abd86b868a9d79 Mon Sep 17 00:00:00 2001 From: Mark Abbott Date: Sun, 4 Mar 2012 17:01:09 +0000 Subject: [PATCH 3/4] Added extra comments to the Coffeescript to describe the calculations that are going on --- morris.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/morris.coffee b/morris.coffee index 206c188..40a847e 100644 --- a/morris.coffee +++ b/morris.coffee @@ -296,10 +296,13 @@ class Morris.Line year = parseInt(p[1], 10); y1 = new Date(year, 0, 1); y2 = new Date(year+1, 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 = 1 + Math.ceil((y2 - y1) / 604800000); parseInt(p[1], 10) + (parseInt(p[2], 10) - 1) / weeks; else if n From b67c1b23588e7761d8d558fc8c8d23dae3ad8a47 Mon Sep 17 00:00:00 2001 From: Mark Abbott Date: Sun, 4 Mar 2012 17:03:11 +0000 Subject: [PATCH 4/4] Fixed bug where number of weeks was miscalculated --- morris.coffee | 2 +- morris.js | 2 +- morris.min.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/morris.coffee b/morris.coffee index 40a847e..458cf14 100644 --- a/morris.coffee +++ b/morris.coffee @@ -303,7 +303,7 @@ class Morris.Line if y2.getDay() isnt 4 y2.setMonth(0, 1 + ((4 - y2.getDay()) + 7) % 7); # Number of weeks between thursdays - weeks = 1 + Math.ceil((y2 - y1) / 604800000); + 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 diff --git a/morris.js b/morris.js index cdedec2..8c0c5aa 100644 --- a/morris.js +++ b/morris.js @@ -328,7 +328,7 @@ 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 = 1 + Math.ceil((y2 - y1) / 604800000); + weeks = Math.ceil((y2 - y1) / 604800000); return parseInt(p[1], 10) + (parseInt(p[2], 10) - 1) / weeks; } else if (n) { return parseInt(n[1], 10) + (parseInt(n[2], 10) - 1) / 12; diff --git a/morris.min.js b/morris.min.js index 88cb022..d9c735e 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",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},c.prototype.precalc=function(){var b,c,d,e,f,g=this;this.options.data.sort(function(a,b){return(a[g.options.xkey]5?this.options.ymax=Math.max(parseInt(this.options.ymax.slice(5),10),c):this.options.ymax=c},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,_=this;this.el.empty(),this.r=new Raphael(this.el[0]),r=this.measureText(this.options.ymax,this.options.gridTextSize).width+this.options.marginLeft,H=this.el.width()-r-this.options.marginRight,h=this.el.height()-this.options.marginTop-this.options.marginBottom,f=H/(this.xmax-this.xmin),g=h/this.options.ymax,C=function(a){return _.xvals.length===1?r+H/2:r+(a-_.xmin)*f},D=function(a){return _.options.marginTop+h-a*g},s=h/(this.options.numLines-1);for(o=0,S=this.options.numLines-1;0<=S?o<=S:o>=S;0<=S?o++:o--)L=this.options.marginTop+o*s,G=Math.round((this.options.numLines-1-o)*this.options.ymax/(this.options.numLines-1)),this.r.text(r-this.options.marginLeft/2,L,G).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),this.r.path("M"+r+","+L+"H"+(r+H)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth);x=null,K=50;for(o=T=Math.ceil(this.xmin),U=Math.floor(this.xmax);T<=U?o<=U:o>=U;T<=U?o++:o--)p=this.r.text(C(o),this.options.marginTop+h+this.options.marginBottom/2,o).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor),q=p.getBBox(),x===null||x<=q.x?x=q.x+q.width+K:p.remove();d=function(){var a,b,c,d;c=this.xvals,d=[];for(a=0,b=c.length;a=0;W<=0?o++:o--)e=z[o],e.length>1&&(t=this.createPath(e,this.options.marginTop,r,this.options.marginTop+h,r+H),this.r.path(t).attr("stroke",this.options.lineColors[o]).attr("stroke-width",this.options.lineWidth));A=function(){var a,b;b=[];for(o=0,a=z.length-1;0<=a?o<=a:o>=a;0<=a?o++:o--)b.push([]);return b}();for(o=X=z.length-1;X<=0?o<=0:o>=0;X<=0?o++:o--){Y=z[o];for(P=0,R=Y.length;P=Z;0<=Z?o++:o--)M=this.r.text(0,this.options.hoverFontSize*1.5*(o+1.5)-l/2,"").attr("fill",this.options.lineColors[o]).attr("font-size",this.options.hoverFontSize),N.push(M),n.push(M);return F=function(b){var c,e,f,g,i;n.show(),J.attr("text",_.columnLabels[b]);for(c=0,i=_.series.length-1;0<=i?c<=i:c>=i;0<=i?c++:c--)N[c].attr("text",""+_.seriesLabels[c]+": "+_.commas(_.series[c][b]));return e=Math.max.apply(null,a.map(N,function(a){return a.getBBox().width})),e=Math.max(e,J.getBBox().width),k.attr("width",e+_.options.hoverPaddingX*2),k.attr("x",-_.options.hoverPaddingX-e/2),g=Math.min.apply(null,a.map(_.series,function(a){return D(a[b])})),g>l+_.options.hoverPaddingY*2+_.options.hoverMargin+_.options.marginTop?g=g-l/2-_.options.hoverPaddingY-_.options.hoverMargin:g=g+l/2+_.options.hoverPaddingY+_.options.hoverMargin,g=Math.max(_.options.marginTop+l/2+_.options.hoverPaddingY,g),g=Math.min(_.options.marginTop+h-l/2-_.options.hoverPaddingY,g),f=Math.min(r+H-e/2-_.options.hoverPaddingX,d[b]),f=Math.max(r+e/2+_.options.hoverPaddingX,f),n.attr("transform","t"+f+","+g)},i=function(){return n.hide()},m=a.map(d.slice(1),function(a,b){return(a+d[b])/2}),w=null,u=Raphael.animation({r:this.options.pointSize+3},25,"linear"),v=Raphael.animation({r:this.options.pointSize},25,"linear"),j=function(a){var b,c,d;if(w!==null&&w!==a)for(b=0,d=A.length-1;0<=d?b<=d:b>=d;0<=d?b++:b--)A[b][w].animate(v);if(a!==null&&w!==a){for(b=0,c=A.length-1;0<=c?b<=c:b>=c;0<=c?b++:b--)A[b][a].animate(u);F(a)}w=a;if(a===null)return i()},E=function(a){var b,c,d;a-=_.el.offset().left,d=[];for(b=c=m.length;c<=0?b<=0:b>=0;c<=0?b++:b--){if(b===0||m[b-1]>a){j(b);break}d.push(void 0)}return d},this.el.mousemove(function(a){return E(a.pageX)}),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),j(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=1+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){return Math.max(0,a).toFixed(0).replace(/(?=(?:\d{3})+$)(?!^)/g,",")},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",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},c.prototype.precalc=function(){var b,c,d,e,f,g=this;this.options.data.sort(function(a,b){return(a[g.options.xkey]5?this.options.ymax=Math.max(parseInt(this.options.ymax.slice(5),10),c):this.options.ymax=c},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,_=this;this.el.empty(),this.r=new Raphael(this.el[0]),r=this.measureText(this.options.ymax,this.options.gridTextSize).width+this.options.marginLeft,H=this.el.width()-r-this.options.marginRight,h=this.el.height()-this.options.marginTop-this.options.marginBottom,f=H/(this.xmax-this.xmin),g=h/this.options.ymax,C=function(a){return _.xvals.length===1?r+H/2:r+(a-_.xmin)*f},D=function(a){return _.options.marginTop+h-a*g},s=h/(this.options.numLines-1);for(o=0,S=this.options.numLines-1;0<=S?o<=S:o>=S;0<=S?o++:o--)L=this.options.marginTop+o*s,G=Math.round((this.options.numLines-1-o)*this.options.ymax/(this.options.numLines-1)),this.r.text(r-this.options.marginLeft/2,L,G).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),this.r.path("M"+r+","+L+"H"+(r+H)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth);x=null,K=50;for(o=T=Math.ceil(this.xmin),U=Math.floor(this.xmax);T<=U?o<=U:o>=U;T<=U?o++:o--)p=this.r.text(C(o),this.options.marginTop+h+this.options.marginBottom/2,o).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor),q=p.getBBox(),x===null||x<=q.x?x=q.x+q.width+K:p.remove();d=function(){var a,b,c,d;c=this.xvals,d=[];for(a=0,b=c.length;a=0;W<=0?o++:o--)e=z[o],e.length>1&&(t=this.createPath(e,this.options.marginTop,r,this.options.marginTop+h,r+H),this.r.path(t).attr("stroke",this.options.lineColors[o]).attr("stroke-width",this.options.lineWidth));A=function(){var a,b;b=[];for(o=0,a=z.length-1;0<=a?o<=a:o>=a;0<=a?o++:o--)b.push([]);return b}();for(o=X=z.length-1;X<=0?o<=0:o>=0;X<=0?o++:o--){Y=z[o];for(P=0,R=Y.length;P=Z;0<=Z?o++:o--)M=this.r.text(0,this.options.hoverFontSize*1.5*(o+1.5)-l/2,"").attr("fill",this.options.lineColors[o]).attr("font-size",this.options.hoverFontSize),N.push(M),n.push(M);return F=function(b){var c,e,f,g,i;n.show(),J.attr("text",_.columnLabels[b]);for(c=0,i=_.series.length-1;0<=i?c<=i:c>=i;0<=i?c++:c--)N[c].attr("text",""+_.seriesLabels[c]+": "+_.commas(_.series[c][b]));return e=Math.max.apply(null,a.map(N,function(a){return a.getBBox().width})),e=Math.max(e,J.getBBox().width),k.attr("width",e+_.options.hoverPaddingX*2),k.attr("x",-_.options.hoverPaddingX-e/2),g=Math.min.apply(null,a.map(_.series,function(a){return D(a[b])})),g>l+_.options.hoverPaddingY*2+_.options.hoverMargin+_.options.marginTop?g=g-l/2-_.options.hoverPaddingY-_.options.hoverMargin:g=g+l/2+_.options.hoverPaddingY+_.options.hoverMargin,g=Math.max(_.options.marginTop+l/2+_.options.hoverPaddingY,g),g=Math.min(_.options.marginTop+h-l/2-_.options.hoverPaddingY,g),f=Math.min(r+H-e/2-_.options.hoverPaddingX,d[b]),f=Math.max(r+e/2+_.options.hoverPaddingX,f),n.attr("transform","t"+f+","+g)},i=function(){return n.hide()},m=a.map(d.slice(1),function(a,b){return(a+d[b])/2}),w=null,u=Raphael.animation({r:this.options.pointSize+3},25,"linear"),v=Raphael.animation({r:this.options.pointSize},25,"linear"),j=function(a){var b,c,d;if(w!==null&&w!==a)for(b=0,d=A.length-1;0<=d?b<=d:b>=d;0<=d?b++:b--)A[b][w].animate(v);if(a!==null&&w!==a){for(b=0,c=A.length-1;0<=c?b<=c:b>=c;0<=c?b++:b--)A[b][a].animate(u);F(a)}w=a;if(a===null)return i()},E=function(a){var b,c,d;a-=_.el.offset().left,d=[];for(b=c=m.length;c<=0?b<=0:b>=0;c<=0?b++:b--){if(b===0||m[b-1]>a){j(b);break}d.push(void 0)}return d},this.el.mousemove(function(a){return E(a.pageX)}),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),j(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){return Math.max(0,a).toFixed(0).replace(/(?=(?:\d{3})+$)(?!^)/g,",")},c}(),window.Morris=b})).call(this); \ No newline at end of file