flot-rails 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/README.md +2 -2
  2. data/lib/flot/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/excanvas.js +1428 -1427
  4. data/vendor/assets/javascripts/excanvas.min.js +1 -1
  5. data/vendor/assets/javascripts/jquery.colorhelpers.js +179 -179
  6. data/vendor/assets/javascripts/jquery.colorhelpers.min.js +21 -1
  7. data/vendor/assets/javascripts/jquery.flot.canvas.js +317 -0
  8. data/vendor/assets/javascripts/jquery.flot.canvas.min.js +28 -0
  9. data/vendor/assets/javascripts/jquery.flot.categories.js +190 -0
  10. data/vendor/assets/javascripts/jquery.flot.categories.min.js +44 -0
  11. data/vendor/assets/javascripts/jquery.flot.crosshair.js +176 -167
  12. data/vendor/assets/javascripts/jquery.flot.crosshair.min.js +59 -1
  13. data/vendor/assets/javascripts/jquery.flot.errorbars.js +353 -0
  14. data/vendor/assets/javascripts/jquery.flot.errorbars.min.js +63 -0
  15. data/vendor/assets/javascripts/jquery.flot.fillbetween.js +226 -183
  16. data/vendor/assets/javascripts/jquery.flot.fillbetween.min.js +30 -1
  17. data/vendor/assets/javascripts/jquery.flot.image.js +241 -238
  18. data/vendor/assets/javascripts/jquery.flot.image.min.js +53 -1
  19. data/vendor/assets/javascripts/jquery.flot.js +2980 -2599
  20. data/vendor/assets/javascripts/jquery.flot.min.js +26 -4
  21. data/vendor/assets/javascripts/jquery.flot.navigate.js +345 -336
  22. data/vendor/assets/javascripts/jquery.flot.navigate.min.js +96 -1
  23. data/vendor/assets/javascripts/jquery.flot.pie.js +561 -499
  24. data/vendor/assets/javascripts/jquery.flot.pie.min.js +56 -1
  25. data/vendor/assets/javascripts/jquery.flot.resize.js +60 -60
  26. data/vendor/assets/javascripts/jquery.flot.resize.min.js +21 -1
  27. data/vendor/assets/javascripts/jquery.flot.selection.js +360 -344
  28. data/vendor/assets/javascripts/jquery.flot.selection.min.js +79 -1
  29. data/vendor/assets/javascripts/jquery.flot.stack.js +188 -184
  30. data/vendor/assets/javascripts/jquery.flot.stack.min.js +36 -1
  31. data/vendor/assets/javascripts/jquery.flot.symbol.js +71 -70
  32. data/vendor/assets/javascripts/jquery.flot.symbol.min.js +14 -1
  33. data/vendor/assets/javascripts/jquery.flot.threshold.js +142 -103
  34. data/vendor/assets/javascripts/jquery.flot.threshold.min.js +43 -1
  35. data/vendor/assets/javascripts/jquery.flot.time.js +424 -0
  36. data/vendor/assets/javascripts/jquery.flot.time.min.js +9 -0
  37. metadata +25 -7
@@ -1 +1,56 @@
1
- (function(b){function c(D){var h=null;var L=null;var n=null;var B=null;var p=null;var M=0;var F=true;var o=10;var w=0.95;var A=0;var d=false;var z=false;var j=[];D.hooks.processOptions.push(g);D.hooks.bindEvents.push(e);function g(O,N){if(N.series.pie.show){N.grid.show=false;if(N.series.pie.label.show=="auto"){if(N.legend.show){N.series.pie.label.show=false}else{N.series.pie.label.show=true}}if(N.series.pie.radius=="auto"){if(N.series.pie.label.show){N.series.pie.radius=3/4}else{N.series.pie.radius=1}}if(N.series.pie.tilt>1){N.series.pie.tilt=1}if(N.series.pie.tilt<0){N.series.pie.tilt=0}O.hooks.processDatapoints.push(E);O.hooks.drawOverlay.push(H);O.hooks.draw.push(r)}}function e(P,N){var O=P.getOptions();if(O.series.pie.show&&O.grid.hoverable){N.unbind("mousemove").mousemove(t)}if(O.series.pie.show&&O.grid.clickable){N.unbind("click").click(l)}}function G(O){var P="";function N(S,T){if(!T){T=0}for(var R=0;R<S.length;++R){for(var Q=0;Q<T;Q++){P+="\t"}if(typeof S[R]=="object"){P+=""+R+":\n";N(S[R],T+1)}else{P+=""+R+": "+S[R]+"\n"}}}N(O);alert(P)}function q(P){for(var N=0;N<P.length;++N){var O=parseFloat(P[N].data[0][1]);if(O){M+=O}}}function E(Q,N,O,P){if(!d){d=true;h=Q.getCanvas();L=b(h).parent();a=Q.getOptions();Q.setData(K(Q.getData()))}}function I(){A=L.children().filter(".legend").children().width();n=Math.min(h.width,(h.height/a.series.pie.tilt))/2;p=(h.height/2)+a.series.pie.offset.top;B=(h.width/2);if(a.series.pie.offset.left=="auto"){if(a.legend.position.match("w")){B+=A/2}else{B-=A/2}}else{B+=a.series.pie.offset.left}if(B<n){B=n}else{if(B>h.width-n){B=h.width-n}}}function v(O){for(var N=0;N<O.length;++N){if(typeof(O[N].data)=="number"){O[N].data=[[1,O[N].data]]}else{if(typeof(O[N].data)=="undefined"||typeof(O[N].data[0])=="undefined"){if(typeof(O[N].data)!="undefined"&&typeof(O[N].data.label)!="undefined"){O[N].label=O[N].data.label}O[N].data=[[1,0]]}}}return O}function K(Q){Q=v(Q);q(Q);var P=0;var S=0;var N=a.series.pie.combine.color;var R=[];for(var O=0;O<Q.length;++O){Q[O].data[0][1]=parseFloat(Q[O].data[0][1]);if(!Q[O].data[0][1]){Q[O].data[0][1]=0}if(Q[O].data[0][1]/M<=a.series.pie.combine.threshold){P+=Q[O].data[0][1];S++;if(!N){N=Q[O].color}}else{R.push({data:[[1,Q[O].data[0][1]]],color:Q[O].color,label:Q[O].label,angle:(Q[O].data[0][1]*(Math.PI*2))/M,percent:(Q[O].data[0][1]/M*100)})}}if(S>0){R.push({data:[[1,P]],color:N,label:a.series.pie.combine.label,angle:(P*(Math.PI*2))/M,percent:(P/M*100)})}return R}function r(S,Q){if(!L){return}ctx=Q;I();var T=S.getData();var P=0;while(F&&P<o){F=false;if(P>0){n*=w}P+=1;N();if(a.series.pie.tilt<=0.8){O()}R()}if(P>=o){N();L.prepend('<div class="error">Could not draw pie with labels contained inside canvas</div>')}if(S.setSeries&&S.insertLegend){S.setSeries(T);S.insertLegend()}function N(){ctx.clearRect(0,0,h.width,h.height);L.children().filter(".pieLabel, .pieLabelBackground").remove()}function O(){var Z=5;var Y=15;var W=10;var X=0.02;if(a.series.pie.radius>1){var U=a.series.pie.radius}else{var U=n*a.series.pie.radius}if(U>=(h.width/2)-Z||U*a.series.pie.tilt>=(h.height/2)-Y||U<=W){return}ctx.save();ctx.translate(Z,Y);ctx.globalAlpha=X;ctx.fillStyle="#000";ctx.translate(B,p);ctx.scale(1,a.series.pie.tilt);for(var V=1;V<=W;V++){ctx.beginPath();ctx.arc(0,0,U,0,Math.PI*2,false);ctx.fill();U-=V}ctx.restore()}function R(){startAngle=Math.PI*a.series.pie.startAngle;if(a.series.pie.radius>1){var U=a.series.pie.radius}else{var U=n*a.series.pie.radius}ctx.save();ctx.translate(B,p);ctx.scale(1,a.series.pie.tilt);ctx.save();var Y=startAngle;for(var W=0;W<T.length;++W){T[W].startAngle=Y;X(T[W].angle,T[W].color,true)}ctx.restore();ctx.save();ctx.lineWidth=a.series.pie.stroke.width;Y=startAngle;for(var W=0;W<T.length;++W){X(T[W].angle,a.series.pie.stroke.color,false)}ctx.restore();J(ctx);if(a.series.pie.label.show){V()}ctx.restore();function X(ab,Z,aa){if(ab<=0){return}if(aa){ctx.fillStyle=Z}else{ctx.strokeStyle=Z;ctx.lineJoin="round"}ctx.beginPath();if(Math.abs(ab-Math.PI*2)>1e-9){ctx.moveTo(0,0)}else{if(b.browser.msie){ab-=0.0001}}ctx.arc(0,0,U,Y,Y+ab,false);ctx.closePath();Y+=ab;if(aa){ctx.fill()}else{ctx.stroke()}}function V(){var ac=startAngle;if(a.series.pie.label.radius>1){var Z=a.series.pie.label.radius}else{var Z=n*a.series.pie.label.radius}for(var ab=0;ab<T.length;++ab){if(T[ab].percent>=a.series.pie.label.threshold*100){aa(T[ab],ac,ab)}ac+=T[ab].angle}function aa(ap,ai,ag){if(ap.data[0][1]==0){return}var ar=a.legend.labelFormatter,aq,ae=a.series.pie.label.formatter;if(ar){aq=ar(ap.label,ap)}else{aq=ap.label}if(ae){aq=ae(aq,ap)}var aj=((ai+ap.angle)+ai)/2;var ao=B+Math.round(Math.cos(aj)*Z);var am=p+Math.round(Math.sin(aj)*Z)*a.series.pie.tilt;var af='<span class="pieLabel" id="pieLabel'+ag+'" style="position:absolute;top:'+am+"px;left:"+ao+'px;">'+aq+"</span>";L.append(af);var an=L.children("#pieLabel"+ag);var ad=(am-an.height()/2);var ah=(ao-an.width()/2);an.css("top",ad);an.css("left",ah);if(0-ad>0||0-ah>0||h.height-(ad+an.height())<0||h.width-(ah+an.width())<0){F=true}if(a.series.pie.label.background.opacity!=0){var ak=a.series.pie.label.background.color;if(ak==null){ak=ap.color}var al="top:"+ad+"px;left:"+ah+"px;";b('<div class="pieLabelBackground" style="position:absolute;width:'+an.width()+"px;height:"+an.height()+"px;"+al+"background-color:"+ak+';"> </div>').insertBefore(an).css("opacity",a.series.pie.label.background.opacity)}}}}}function J(N){if(a.series.pie.innerRadius>0){N.save();innerRadius=a.series.pie.innerRadius>1?a.series.pie.innerRadius:n*a.series.pie.innerRadius;N.globalCompositeOperation="destination-out";N.beginPath();N.fillStyle=a.series.pie.stroke.color;N.arc(0,0,innerRadius,0,Math.PI*2,false);N.fill();N.closePath();N.restore();N.save();N.beginPath();N.strokeStyle=a.series.pie.stroke.color;N.arc(0,0,innerRadius,0,Math.PI*2,false);N.stroke();N.closePath();N.restore()}}function s(Q,R){for(var S=false,P=-1,N=Q.length,O=N-1;++P<N;O=P){((Q[P][1]<=R[1]&&R[1]<Q[O][1])||(Q[O][1]<=R[1]&&R[1]<Q[P][1]))&&(R[0]<(Q[O][0]-Q[P][0])*(R[1]-Q[P][1])/(Q[O][1]-Q[P][1])+Q[P][0])&&(S=!S)}return S}function u(R,P){var T=D.getData(),O=D.getOptions(),N=O.series.pie.radius>1?O.series.pie.radius:n*O.series.pie.radius;for(var Q=0;Q<T.length;++Q){var S=T[Q];if(S.pie.show){ctx.save();ctx.beginPath();ctx.moveTo(0,0);ctx.arc(0,0,N,S.startAngle,S.startAngle+S.angle,false);ctx.closePath();x=R-B;y=P-p;if(ctx.isPointInPath){if(ctx.isPointInPath(R-B,P-p)){ctx.restore();return{datapoint:[S.percent,S.data],dataIndex:0,series:S,seriesIndex:Q}}}else{p1X=(N*Math.cos(S.startAngle));p1Y=(N*Math.sin(S.startAngle));p2X=(N*Math.cos(S.startAngle+(S.angle/4)));p2Y=(N*Math.sin(S.startAngle+(S.angle/4)));p3X=(N*Math.cos(S.startAngle+(S.angle/2)));p3Y=(N*Math.sin(S.startAngle+(S.angle/2)));p4X=(N*Math.cos(S.startAngle+(S.angle/1.5)));p4Y=(N*Math.sin(S.startAngle+(S.angle/1.5)));p5X=(N*Math.cos(S.startAngle+S.angle));p5Y=(N*Math.sin(S.startAngle+S.angle));arrPoly=[[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]];arrPoint=[x,y];if(s(arrPoly,arrPoint)){ctx.restore();return{datapoint:[S.percent,S.data],dataIndex:0,series:S,seriesIndex:Q}}}ctx.restore()}}return null}function t(N){m("plothover",N)}function l(N){m("plotclick",N)}function m(N,T){var O=D.offset(),R=parseInt(T.pageX-O.left),P=parseInt(T.pageY-O.top),V=u(R,P);if(a.grid.autoHighlight){for(var Q=0;Q<j.length;++Q){var S=j[Q];if(S.auto==N&&!(V&&S.series==V.series)){f(S.series)}}}if(V){k(V.series,N)}var U={pageX:T.pageX,pageY:T.pageY};L.trigger(N,[U,V])}function k(O,P){if(typeof O=="number"){O=series[O]}var N=C(O);if(N==-1){j.push({series:O,auto:P});D.triggerRedrawOverlay()}else{if(!P){j[N].auto=false}}}function f(O){if(O==null){j=[];D.triggerRedrawOverlay()}if(typeof O=="number"){O=series[O]}var N=C(O);if(N!=-1){j.splice(N,1);D.triggerRedrawOverlay()}}function C(P){for(var N=0;N<j.length;++N){var O=j[N];if(O.series==P){return N}}return -1}function H(Q,R){var P=Q.getOptions();var N=P.series.pie.radius>1?P.series.pie.radius:n*P.series.pie.radius;R.save();R.translate(B,p);R.scale(1,P.series.pie.tilt);for(i=0;i<j.length;++i){O(j[i].series)}J(R);R.restore();function O(S){if(S.angle<0){return}R.fillStyle="rgba(255, 255, 255, "+P.series.pie.highlight.opacity+")";R.beginPath();if(Math.abs(S.angle-Math.PI*2)>1e-9){R.moveTo(0,0)}R.arc(0,0,N,S.startAngle,S.startAngle+S.angle,false);R.closePath();R.fill()}}}var a={series:{pie:{show:false,radius:"auto",innerRadius:0,startAngle:3/2,tilt:1,offset:{top:0,left:"auto"},stroke:{color:"#FFF",width:1},label:{show:"auto",formatter:function(d,e){return'<div style="font-size:x-small;text-align:center;padding:2px;color:'+e.color+';">'+d+"<br/>"+Math.round(e.percent)+"%</div>"},radius:1,background:{color:null,opacity:0},threshold:0},combine:{threshold:-1,color:null,label:"Other"},highlight:{opacity:0.5}}}};b.plot.plugins.push({init:c,options:a,name:"pie",version:"1.0"})})(jQuery);
1
+ /* Flot plugin for rendering pie charts.
2
+
3
+ Copyright (c) 2007-2013 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ The plugin assumes that each series has a single data value, and that each
7
+ value is a positive integer or zero. Negative numbers don't make sense for a
8
+ pie chart, and have unpredictable results. The values do NOT need to be
9
+ passed in as percentages; the plugin will calculate the total and per-slice
10
+ percentages internally.
11
+
12
+ * Created by Brian Medendorp
13
+
14
+ * Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars
15
+
16
+ The plugin supports these options:
17
+
18
+ series: {
19
+ pie: {
20
+ show: true/false
21
+ radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
22
+ innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
23
+ startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
24
+ tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
25
+ offset: {
26
+ top: integer value to move the pie up or down
27
+ left: integer value to move the pie left or right, or 'auto'
28
+ },
29
+ stroke: {
30
+ color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
31
+ width: integer pixel width of the stroke
32
+ },
33
+ label: {
34
+ show: true/false, or 'auto'
35
+ formatter: a user-defined function that modifies the text/style of the label text
36
+ radius: 0-1 for percentage of fullsize, or a specified pixel length
37
+ background: {
38
+ color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
39
+ opacity: 0-1
40
+ },
41
+ threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
42
+ },
43
+ combine: {
44
+ threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
45
+ color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
46
+ label: any text value of what the combined slice should be labeled
47
+ }
48
+ highlight: {
49
+ opacity: 0-1
50
+ }
51
+ }
52
+ }
53
+
54
+ More detail and specific examples can be found in the included HTML file.
55
+
56
+ */(function(e){function r(r){function p(t,n,r){l||(l=!0,s=t.getCanvas(),o=e(s).parent(),i=t.getOptions(),t.setData(d(t.getData())))}function d(t){var n=0,r=0,s=0,o=i.series.pie.combine.color,u=[];for(var a=0;a<t.length;++a){var f=t[a].data;e.isArray(f)?e.isNumeric(f[1])?f[1]=+f[1]:f[1]=0:e.isNumeric(f)?f=[1,+f]:f=[1,0],t[a].data=[f]}for(var a=0;a<t.length;++a)n+=t[a].data[0][1];for(var a=0;a<t.length;++a){var f=t[a].data[0][1];f/n<=i.series.pie.combine.threshold&&(r+=f,s++,o||(o=t[a].color))}for(var a=0;a<t.length;++a){var f=t[a].data[0][1];(s<2||f/n>i.series.pie.combine.threshold)&&u.push({data:[[1,f]],color:t[a].color,label:t[a].label,angle:f*Math.PI*2/n,percent:f/(n/100)})}return s>1&&u.push({data:[[1,r]],color:o,label:i.series.pie.combine.label,angle:r*Math.PI*2/n,percent:r/(n/100)}),u}function v(r,s){function y(){c.clearRect(0,0,h,p),o.children().filter(".pieLabel, .pieLabelBackground").remove()}function b(){var e=i.series.pie.shadow.left,t=i.series.pie.shadow.top,n=10,r=i.series.pie.shadow.alpha,s=i.series.pie.radius>1?i.series.pie.radius:u*i.series.pie.radius;if(s>=h/2-e||s*i.series.pie.tilt>=p/2-t||s<=n)return;c.save(),c.translate(e,t),c.globalAlpha=r,c.fillStyle="#000",c.translate(a,f),c.scale(1,i.series.pie.tilt);for(var o=1;o<=n;o++)c.beginPath(),c.arc(0,0,s,0,Math.PI*2,!1),c.fill(),s-=o;c.restore()}function w(){function l(e,t,i){if(e<=0||isNaN(e))return;i?c.fillStyle=t:(c.strokeStyle=t,c.lineJoin="round"),c.beginPath(),Math.abs(e-Math.PI*2)>1e-9&&c.moveTo(0,0),c.arc(0,0,n,r,r+e/2,!1),c.arc(0,0,n,r+e/2,r+e,!1),c.closePath(),r+=e,i?c.fill():c.stroke()}function d(){function l(t,n,s){if(t.data[0][1]==0)return!0;var u=i.legend.labelFormatter,l,c=i.series.pie.label.formatter;u?l=u(t.label,t):l=t.label,c&&(l=c(l,t));var d=(n+t.angle+n)/2,v=a+Math.round(Math.cos(d)*r),m=f+Math.round(Math.sin(d)*r)*i.series.pie.tilt,g="<span class='pieLabel' id='pieLabel"+s+"' style='position:absolute;top:"+m+"px;left:"+v+"px;'>"+l+"</span>";o.append(g);var y=o.children("#pieLabel"+s),b=m-y.height()/2,w=v-y.width()/2;y.css("top",b),y.css("left",w);if(0-b>0||0-w>0||p-(b+y.height())<0||h-(w+y.width())<0)return!1;if(i.series.pie.label.background.opacity!=0){var E=i.series.pie.label.background.color;E==null&&(E=t.color);var S="top:"+b+"px;left:"+w+"px;";e("<div class='pieLabelBackground' style='position:absolute;width:"+y.width()+"px;height:"+y.height()+"px;"+S+"background-color:"+E+";'></div>").css("opacity",i.series.pie.label.background.opacity).insertBefore(y)}return!0}var n=t,r=i.series.pie.label.radius>1?i.series.pie.label.radius:u*i.series.pie.label.radius;for(var s=0;s<v.length;++s){if(v[s].percent>=i.series.pie.label.threshold*100&&!l(v[s],n,s))return!1;n+=v[s].angle}return!0}var t=Math.PI*i.series.pie.startAngle,n=i.series.pie.radius>1?i.series.pie.radius:u*i.series.pie.radius;c.save(),c.translate(a,f),c.scale(1,i.series.pie.tilt),c.save();var r=t;for(var s=0;s<v.length;++s)v[s].startAngle=r,l(v[s].angle,v[s].color,!0);c.restore();if(i.series.pie.stroke.width>0){c.save(),c.lineWidth=i.series.pie.stroke.width,r=t;for(var s=0;s<v.length;++s)l(v[s].angle,i.series.pie.stroke.color,!1);c.restore()}return m(c),c.restore(),i.series.pie.label.show?d():!0}if(!o)return;var h=r.getPlaceholder().width(),p=r.getPlaceholder().height(),d=o.children().filter(".legend").children().width()||0;c=s,l=!1,u=Math.min(h,p/i.series.pie.tilt)/2,f=p/2+i.series.pie.offset.top,a=h/2,i.series.pie.offset.left=="auto"?i.legend.position.match("w")?a+=d/2:a-=d/2:a+=i.series.pie.offset.left,a<u?a=u:a>h-u&&(a=h-u);var v=r.getData(),g=0;do g>0&&(u*=n),g+=1,y(),i.series.pie.tilt<=.8&&b();while(!w()&&g<t);g>=t&&(y(),o.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>")),r.setSeries&&r.insertLegend&&(r.setSeries(v),r.insertLegend())}function m(e){if(i.series.pie.innerRadius>0){e.save();var t=i.series.pie.innerRadius>1?i.series.pie.innerRadius:u*i.series.pie.innerRadius;e.globalCompositeOperation="destination-out",e.beginPath(),e.fillStyle=i.series.pie.stroke.color,e.arc(0,0,t,0,Math.PI*2,!1),e.fill(),e.closePath(),e.restore(),e.save(),e.beginPath(),e.strokeStyle=i.series.pie.stroke.color,e.arc(0,0,t,0,Math.PI*2,!1),e.stroke(),e.closePath(),e.restore()}}function g(e,t){for(var n=!1,r=-1,i=e.length,s=i-1;++r<i;s=r)(e[r][1]<=t[1]&&t[1]<e[s][1]||e[s][1]<=t[1]&&t[1]<e[r][1])&&t[0]<(e[s][0]-e[r][0])*(t[1]-e[r][1])/(e[s][1]-e[r][1])+e[r][0]&&(n=!n);return n}function y(e,t){var n=r.getData(),i=r.getOptions(),s=i.series.pie.radius>1?i.series.pie.radius:u*i.series.pie.radius,o,l;for(var h=0;h<n.length;++h){var p=n[h];if(p.pie.show){c.save(),c.beginPath(),c.moveTo(0,0),c.arc(0,0,s,p.startAngle,p.startAngle+p.angle/2,!1),c.arc(0,0,s,p.startAngle+p.angle/2,p.startAngle+p.angle,!1),c.closePath(),o=e-a,l=t-f;if(c.isPointInPath){if(c.isPointInPath(e-a,t-f))return c.restore(),{datapoint:[p.percent,p.data],dataIndex:0,series:p,seriesIndex:h}}else{var d=s*Math.cos(p.startAngle),v=s*Math.sin(p.startAngle),m=s*Math.cos(p.startAngle+p.angle/4),y=s*Math.sin(p.startAngle+p.angle/4),b=s*Math.cos(p.startAngle+p.angle/2),w=s*Math.sin(p.startAngle+p.angle/2),E=s*Math.cos(p.startAngle+p.angle/1.5),S=s*Math.sin(p.startAngle+p.angle/1.5),x=s*Math.cos(p.startAngle+p.angle),T=s*Math.sin(p.startAngle+p.angle),N=[[0,0],[d,v],[m,y],[b,w],[E,S],[x,T]],C=[o,l];if(g(N,C))return c.restore(),{datapoint:[p.percent,p.data],dataIndex:0,series:p,seriesIndex:h}}c.restore()}}return null}function b(e){E("plothover",e)}function w(e){E("plotclick",e)}function E(e,t){var n=r.offset(),s=parseInt(t.pageX-n.left),u=parseInt(t.pageY-n.top),a=y(s,u);if(i.grid.autoHighlight)for(var f=0;f<h.length;++f){var l=h[f];l.auto==e&&(!a||l.series!=a.series)&&x(l.series)}a&&S(a.series,e);var c={pageX:t.pageX,pageY:t.pageY};o.trigger(e,[c,a])}function S(e,t){var n=T(e);n==-1?(h.push({series:e,auto:t}),r.triggerRedrawOverlay()):t||(h[n].auto=!1)}function x(e){e==null&&(h=[],r.triggerRedrawOverlay());var t=T(e);t!=-1&&(h.splice(t,1),r.triggerRedrawOverlay())}function T(e){for(var t=0;t<h.length;++t){var n=h[t];if(n.series==e)return t}return-1}function N(e,t){function s(e){if(e.angle<=0||isNaN(e.angle))return;t.fillStyle="rgba(255, 255, 255, "+n.series.pie.highlight.opacity+")",t.beginPath(),Math.abs(e.angle-Math.PI*2)>1e-9&&t.moveTo(0,0),t.arc(0,0,r,e.startAngle,e.startAngle+e.angle/2,!1),t.arc(0,0,r,e.startAngle+e.angle/2,e.startAngle+e.angle,!1),t.closePath(),t.fill()}var n=e.getOptions(),r=n.series.pie.radius>1?n.series.pie.radius:u*n.series.pie.radius;t.save(),t.translate(a,f),t.scale(1,n.series.pie.tilt);for(var i=0;i<h.length;++i)s(h[i].series);m(t),t.restore()}var s=null,o=null,u=null,a=null,f=null,l=!1,c=null,h=[];r.hooks.processOptions.push(function(e,t){t.series.pie.show&&(t.grid.show=!1,t.series.pie.label.show=="auto"&&(t.legend.show?t.series.pie.label.show=!1:t.series.pie.label.show=!0),t.series.pie.radius=="auto"&&(t.series.pie.label.show?t.series.pie.radius=.75:t.series.pie.radius=1),t.series.pie.tilt>1?t.series.pie.tilt=1:t.series.pie.tilt<0&&(t.series.pie.tilt=0))}),r.hooks.bindEvents.push(function(e,t){var n=e.getOptions();n.series.pie.show&&(n.grid.hoverable&&t.unbind("mousemove").mousemove(b),n.grid.clickable&&t.unbind("click").click(w))}),r.hooks.processDatapoints.push(function(e,t,n,r){var i=e.getOptions();i.series.pie.show&&p(e,t,n,r)}),r.hooks.drawOverlay.push(function(e,t){var n=e.getOptions();n.series.pie.show&&N(e,t)}),r.hooks.draw.push(function(e,t){var n=e.getOptions();n.series.pie.show&&v(e,t)})}var t=10,n=.95,i={series:{pie:{show:!1,radius:"auto",innerRadius:0,startAngle:1.5,tilt:1,shadow:{left:5,top:15,alpha:.02},offset:{top:0,left:"auto"},stroke:{color:"#fff",width:1},label:{show:"auto",formatter:function(e,t){return"<div style='font-size:x-small;text-align:center;padding:2px;color:"+t.color+";'>"+e+"<br/>"+Math.round(t.percent)+"%</div>"},radius:1,background:{color:null,opacity:0},threshold:0},combine:{threshold:-1,color:null,label:"Other"},highlight:{opacity:.5}}}};e.plot.plugins.push({init:r,options:i,name:"pie",version:"1.1"})})(jQuery);
@@ -1,60 +1,60 @@
1
- /*
2
- Flot plugin for automatically redrawing plots when the placeholder
3
- size changes, e.g. on window resizes.
4
-
5
- It works by listening for changes on the placeholder div (through the
6
- jQuery resize event plugin) - if the size changes, it will redraw the
7
- plot.
8
-
9
- There are no options. If you need to disable the plugin for some
10
- plots, you can just fix the size of their placeholders.
11
- */
12
-
13
-
14
- /* Inline dependency:
15
- * jQuery resize event - v1.1 - 3/14/2010
16
- * http://benalman.com/projects/jquery-resize-plugin/
17
- *
18
- * Copyright (c) 2010 "Cowboy" Ben Alman
19
- * Dual licensed under the MIT and GPL licenses.
20
- * http://benalman.com/about/license/
21
- */
22
- (function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
23
-
24
-
25
- (function ($) {
26
- var options = { }; // no options
27
-
28
- function init(plot) {
29
- function onResize() {
30
- var placeholder = plot.getPlaceholder();
31
-
32
- // somebody might have hidden us and we can't plot
33
- // when we don't have the dimensions
34
- if (placeholder.width() == 0 || placeholder.height() == 0)
35
- return;
36
-
37
- plot.resize();
38
- plot.setupGrid();
39
- plot.draw();
40
- }
41
-
42
- function bindEvents(plot, eventHolder) {
43
- plot.getPlaceholder().resize(onResize);
44
- }
45
-
46
- function shutdown(plot, eventHolder) {
47
- plot.getPlaceholder().unbind("resize", onResize);
48
- }
49
-
50
- plot.hooks.bindEvents.push(bindEvents);
51
- plot.hooks.shutdown.push(shutdown);
52
- }
53
-
54
- $.plot.plugins.push({
55
- init: init,
56
- options: options,
57
- name: 'resize',
58
- version: '1.0'
59
- });
60
- })(jQuery);
1
+ /* Flot plugin for automatically redrawing plots as the placeholder resizes.
2
+
3
+ Copyright (c) 2007-2013 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ It works by listening for changes on the placeholder div (through the jQuery
7
+ resize event plugin) - if the size changes, it will redraw the plot.
8
+
9
+ There are no options. If you need to disable the plugin for some plots, you
10
+ can just fix the size of their placeholders.
11
+
12
+ */
13
+
14
+ /* Inline dependency:
15
+ * jQuery resize event - v1.1 - 3/14/2010
16
+ * http://benalman.com/projects/jquery-resize-plugin/
17
+ *
18
+ * Copyright (c) 2010 "Cowboy" Ben Alman
19
+ * Dual licensed under the MIT and GPL licenses.
20
+ * http://benalman.com/about/license/
21
+ */
22
+
23
+ (function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
24
+
25
+ (function ($) {
26
+ var options = { }; // no options
27
+
28
+ function init(plot) {
29
+ function onResize() {
30
+ var placeholder = plot.getPlaceholder();
31
+
32
+ // somebody might have hidden us and we can't plot
33
+ // when we don't have the dimensions
34
+ if (placeholder.width() == 0 || placeholder.height() == 0)
35
+ return;
36
+
37
+ plot.resize();
38
+ plot.setupGrid();
39
+ plot.draw();
40
+ }
41
+
42
+ function bindEvents(plot, eventHolder) {
43
+ plot.getPlaceholder().resize(onResize);
44
+ }
45
+
46
+ function shutdown(plot, eventHolder) {
47
+ plot.getPlaceholder().unbind("resize", onResize);
48
+ }
49
+
50
+ plot.hooks.bindEvents.push(bindEvents);
51
+ plot.hooks.shutdown.push(shutdown);
52
+ }
53
+
54
+ $.plot.plugins.push({
55
+ init: init,
56
+ options: options,
57
+ name: 'resize',
58
+ version: '1.0'
59
+ });
60
+ })(jQuery);
@@ -1 +1,21 @@
1
- (function(n,p,u){var w=n([]),s=n.resize=n.extend(n.resize,{}),o,l="setTimeout",m="resize",t=m+"-special-event",v="delay",r="throttleWindow";s[v]=250;s[r]=true;n.event.special[m]={setup:function(){if(!s[r]&&this[l]){return false}var a=n(this);w=w.add(a);n.data(this,t,{w:a.width(),h:a.height()});if(w.length===1){q()}},teardown:function(){if(!s[r]&&this[l]){return false}var a=n(this);w=w.not(a);a.removeData(t);if(!w.length){clearTimeout(o)}},add:function(b){if(!s[r]&&this[l]){return false}var c;function a(d,h,g){var f=n(this),e=n.data(this,t);e.w=h!==u?h:f.width();e.h=g!==u?g:f.height();c.apply(this,arguments)}if(n.isFunction(b)){c=b;return a}else{c=b.handler;b.handler=a}}};function q(){o=p[l](function(){w.each(function(){var d=n(this),a=d.width(),b=d.height(),c=n.data(this,t);if(a!==c.w||b!==c.h){d.trigger(m,[c.w=a,c.h=b])}});q()},s[v])}})(jQuery,this);(function(b){var a={};function c(f){function e(){var h=f.getPlaceholder();if(h.width()==0||h.height()==0){return}f.resize();f.setupGrid();f.draw()}function g(i,h){i.getPlaceholder().resize(e)}function d(i,h){i.getPlaceholder().unbind("resize",e)}f.hooks.bindEvents.push(g);f.hooks.shutdown.push(d)}b.plot.plugins.push({init:c,options:a,name:"resize",version:"1.0"})})(jQuery);
1
+ /* Flot plugin for automatically redrawing plots as the placeholder resizes.
2
+
3
+ Copyright (c) 2007-2013 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ It works by listening for changes on the placeholder div (through the jQuery
7
+ resize event plugin) - if the size changes, it will redraw the plot.
8
+
9
+ There are no options. If you need to disable the plugin for some plots, you
10
+ can just fix the size of their placeholders.
11
+
12
+ */
13
+ /* Inline dependency:
14
+ * jQuery resize event - v1.1 - 3/14/2010
15
+ * http://benalman.com/projects/jquery-resize-plugin/
16
+ *
17
+ * Copyright (c) 2010 "Cowboy" Ben Alman
18
+ * Dual licensed under the MIT and GPL licenses.
19
+ * http://benalman.com/about/license/
20
+ */(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
21
+ (function(e){function n(e){function t(){var t=e.getPlaceholder();if(t.width()==0||t.height()==0)return;e.resize(),e.setupGrid(),e.draw()}function n(e,n){e.getPlaceholder().resize(t)}function r(e,n){e.getPlaceholder().unbind("resize",t)}e.hooks.bindEvents.push(n),e.hooks.shutdown.push(r)}var t={};e.plot.plugins.push({init:n,options:t,name:"resize",version:"1.0"})})(jQuery);
@@ -1,344 +1,360 @@
1
- /*
2
- Flot plugin for selecting regions.
3
-
4
- The plugin defines the following options:
5
-
6
- selection: {
7
- mode: null or "x" or "y" or "xy",
8
- color: color
9
- }
10
-
11
- Selection support is enabled by setting the mode to one of "x", "y" or
12
- "xy". In "x" mode, the user will only be able to specify the x range,
13
- similarly for "y" mode. For "xy", the selection becomes a rectangle
14
- where both ranges can be specified. "color" is color of the selection
15
- (if you need to change the color later on, you can get to it with
16
- plot.getOptions().selection.color).
17
-
18
- When selection support is enabled, a "plotselected" event will be
19
- emitted on the DOM element you passed into the plot function. The
20
- event handler gets a parameter with the ranges selected on the axes,
21
- like this:
22
-
23
- placeholder.bind("plotselected", function(event, ranges) {
24
- alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
25
- // similar for yaxis - with multiple axes, the extra ones are in
26
- // x2axis, x3axis, ...
27
- });
28
-
29
- The "plotselected" event is only fired when the user has finished
30
- making the selection. A "plotselecting" event is fired during the
31
- process with the same parameters as the "plotselected" event, in case
32
- you want to know what's happening while it's happening,
33
-
34
- A "plotunselected" event with no arguments is emitted when the user
35
- clicks the mouse to remove the selection.
36
-
37
- The plugin allso adds the following methods to the plot object:
38
-
39
- - setSelection(ranges, preventEvent)
40
-
41
- Set the selection rectangle. The passed in ranges is on the same
42
- form as returned in the "plotselected" event. If the selection mode
43
- is "x", you should put in either an xaxis range, if the mode is "y"
44
- you need to put in an yaxis range and both xaxis and yaxis if the
45
- selection mode is "xy", like this:
46
-
47
- setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
48
-
49
- setSelection will trigger the "plotselected" event when called. If
50
- you don't want that to happen, e.g. if you're inside a
51
- "plotselected" handler, pass true as the second parameter. If you
52
- are using multiple axes, you can specify the ranges on any of those,
53
- e.g. as x2axis/x3axis/... instead of xaxis, the plugin picks the
54
- first one it sees.
55
-
56
- - clearSelection(preventEvent)
57
-
58
- Clear the selection rectangle. Pass in true to avoid getting a
59
- "plotunselected" event.
60
-
61
- - getSelection()
62
-
63
- Returns the current selection in the same format as the
64
- "plotselected" event. If there's currently no selection, the
65
- function returns null.
66
-
67
- */
68
-
69
- (function ($) {
70
- function init(plot) {
71
- var selection = {
72
- first: { x: -1, y: -1}, second: { x: -1, y: -1},
73
- show: false,
74
- active: false
75
- };
76
-
77
- // FIXME: The drag handling implemented here should be
78
- // abstracted out, there's some similar code from a library in
79
- // the navigation plugin, this should be massaged a bit to fit
80
- // the Flot cases here better and reused. Doing this would
81
- // make this plugin much slimmer.
82
- var savedhandlers = {};
83
-
84
- var mouseUpHandler = null;
85
-
86
- function onMouseMove(e) {
87
- if (selection.active) {
88
- updateSelection(e);
89
-
90
- plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
91
- }
92
- }
93
-
94
- function onMouseDown(e) {
95
- if (e.which != 1) // only accept left-click
96
- return;
97
-
98
- // cancel out any text selections
99
- document.body.focus();
100
-
101
- // prevent text selection and drag in old-school browsers
102
- if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
103
- savedhandlers.onselectstart = document.onselectstart;
104
- document.onselectstart = function () { return false; };
105
- }
106
- if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
107
- savedhandlers.ondrag = document.ondrag;
108
- document.ondrag = function () { return false; };
109
- }
110
-
111
- setSelectionPos(selection.first, e);
112
-
113
- selection.active = true;
114
-
115
- // this is a bit silly, but we have to use a closure to be
116
- // able to whack the same handler again
117
- mouseUpHandler = function (e) { onMouseUp(e); };
118
-
119
- $(document).one("mouseup", mouseUpHandler);
120
- }
121
-
122
- function onMouseUp(e) {
123
- mouseUpHandler = null;
124
-
125
- // revert drag stuff for old-school browsers
126
- if (document.onselectstart !== undefined)
127
- document.onselectstart = savedhandlers.onselectstart;
128
- if (document.ondrag !== undefined)
129
- document.ondrag = savedhandlers.ondrag;
130
-
131
- // no more dragging
132
- selection.active = false;
133
- updateSelection(e);
134
-
135
- if (selectionIsSane())
136
- triggerSelectedEvent();
137
- else {
138
- // this counts as a clear
139
- plot.getPlaceholder().trigger("plotunselected", [ ]);
140
- plot.getPlaceholder().trigger("plotselecting", [ null ]);
141
- }
142
-
143
- return false;
144
- }
145
-
146
- function getSelection() {
147
- if (!selectionIsSane())
148
- return null;
149
-
150
- var r = {}, c1 = selection.first, c2 = selection.second;
151
- $.each(plot.getAxes(), function (name, axis) {
152
- if (axis.used) {
153
- var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);
154
- r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
155
- }
156
- });
157
- return r;
158
- }
159
-
160
- function triggerSelectedEvent() {
161
- var r = getSelection();
162
-
163
- plot.getPlaceholder().trigger("plotselected", [ r ]);
164
-
165
- // backwards-compat stuff, to be removed in future
166
- if (r.xaxis && r.yaxis)
167
- plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
168
- }
169
-
170
- function clamp(min, value, max) {
171
- return value < min ? min: (value > max ? max: value);
172
- }
173
-
174
- function setSelectionPos(pos, e) {
175
- var o = plot.getOptions();
176
- var offset = plot.getPlaceholder().offset();
177
- var plotOffset = plot.getPlotOffset();
178
- pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
179
- pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
180
-
181
- if (o.selection.mode == "y")
182
- pos.x = pos == selection.first ? 0 : plot.width();
183
-
184
- if (o.selection.mode == "x")
185
- pos.y = pos == selection.first ? 0 : plot.height();
186
- }
187
-
188
- function updateSelection(pos) {
189
- if (pos.pageX == null)
190
- return;
191
-
192
- setSelectionPos(selection.second, pos);
193
- if (selectionIsSane()) {
194
- selection.show = true;
195
- plot.triggerRedrawOverlay();
196
- }
197
- else
198
- clearSelection(true);
199
- }
200
-
201
- function clearSelection(preventEvent) {
202
- if (selection.show) {
203
- selection.show = false;
204
- plot.triggerRedrawOverlay();
205
- if (!preventEvent)
206
- plot.getPlaceholder().trigger("plotunselected", [ ]);
207
- }
208
- }
209
-
210
- // function taken from markings support in Flot
211
- function extractRange(ranges, coord) {
212
- var axis, from, to, key, axes = plot.getAxes();
213
-
214
- for (var k in axes) {
215
- axis = axes[k];
216
- if (axis.direction == coord) {
217
- key = coord + axis.n + "axis";
218
- if (!ranges[key] && axis.n == 1)
219
- key = coord + "axis"; // support x1axis as xaxis
220
- if (ranges[key]) {
221
- from = ranges[key].from;
222
- to = ranges[key].to;
223
- break;
224
- }
225
- }
226
- }
227
-
228
- // backwards-compat stuff - to be removed in future
229
- if (!ranges[key]) {
230
- axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
231
- from = ranges[coord + "1"];
232
- to = ranges[coord + "2"];
233
- }
234
-
235
- // auto-reverse as an added bonus
236
- if (from != null && to != null && from > to) {
237
- var tmp = from;
238
- from = to;
239
- to = tmp;
240
- }
241
-
242
- return { from: from, to: to, axis: axis };
243
- }
244
-
245
- function setSelection(ranges, preventEvent) {
246
- var axis, range, o = plot.getOptions();
247
-
248
- if (o.selection.mode == "y") {
249
- selection.first.x = 0;
250
- selection.second.x = plot.width();
251
- }
252
- else {
253
- range = extractRange(ranges, "x");
254
-
255
- selection.first.x = range.axis.p2c(range.from);
256
- selection.second.x = range.axis.p2c(range.to);
257
- }
258
-
259
- if (o.selection.mode == "x") {
260
- selection.first.y = 0;
261
- selection.second.y = plot.height();
262
- }
263
- else {
264
- range = extractRange(ranges, "y");
265
-
266
- selection.first.y = range.axis.p2c(range.from);
267
- selection.second.y = range.axis.p2c(range.to);
268
- }
269
-
270
- selection.show = true;
271
- plot.triggerRedrawOverlay();
272
- if (!preventEvent && selectionIsSane())
273
- triggerSelectedEvent();
274
- }
275
-
276
- function selectionIsSane() {
277
- var minSize = 5;
278
- return Math.abs(selection.second.x - selection.first.x) >= minSize &&
279
- Math.abs(selection.second.y - selection.first.y) >= minSize;
280
- }
281
-
282
- plot.clearSelection = clearSelection;
283
- plot.setSelection = setSelection;
284
- plot.getSelection = getSelection;
285
-
286
- plot.hooks.bindEvents.push(function(plot, eventHolder) {
287
- var o = plot.getOptions();
288
- if (o.selection.mode != null) {
289
- eventHolder.mousemove(onMouseMove);
290
- eventHolder.mousedown(onMouseDown);
291
- }
292
- });
293
-
294
-
295
- plot.hooks.drawOverlay.push(function (plot, ctx) {
296
- // draw selection
297
- if (selection.show && selectionIsSane()) {
298
- var plotOffset = plot.getPlotOffset();
299
- var o = plot.getOptions();
300
-
301
- ctx.save();
302
- ctx.translate(plotOffset.left, plotOffset.top);
303
-
304
- var c = $.color.parse(o.selection.color);
305
-
306
- ctx.strokeStyle = c.scale('a', 0.8).toString();
307
- ctx.lineWidth = 1;
308
- ctx.lineJoin = "round";
309
- ctx.fillStyle = c.scale('a', 0.4).toString();
310
-
311
- var x = Math.min(selection.first.x, selection.second.x),
312
- y = Math.min(selection.first.y, selection.second.y),
313
- w = Math.abs(selection.second.x - selection.first.x),
314
- h = Math.abs(selection.second.y - selection.first.y);
315
-
316
- ctx.fillRect(x, y, w, h);
317
- ctx.strokeRect(x, y, w, h);
318
-
319
- ctx.restore();
320
- }
321
- });
322
-
323
- plot.hooks.shutdown.push(function (plot, eventHolder) {
324
- eventHolder.unbind("mousemove", onMouseMove);
325
- eventHolder.unbind("mousedown", onMouseDown);
326
-
327
- if (mouseUpHandler)
328
- $(document).unbind("mouseup", mouseUpHandler);
329
- });
330
-
331
- }
332
-
333
- $.plot.plugins.push({
334
- init: init,
335
- options: {
336
- selection: {
337
- mode: null, // one of null, "x", "y" or "xy"
338
- color: "#e8cfac"
339
- }
340
- },
341
- name: 'selection',
342
- version: '1.1'
343
- });
344
- })(jQuery);
1
+ /* Flot plugin for selecting regions of a plot.
2
+
3
+ Copyright (c) 2007-2013 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ The plugin supports these options:
7
+
8
+ selection: {
9
+ mode: null or "x" or "y" or "xy",
10
+ color: color,
11
+ shape: "round" or "miter" or "bevel",
12
+ minSize: number of pixels
13
+ }
14
+
15
+ Selection support is enabled by setting the mode to one of "x", "y" or "xy".
16
+ In "x" mode, the user will only be able to specify the x range, similarly for
17
+ "y" mode. For "xy", the selection becomes a rectangle where both ranges can be
18
+ specified. "color" is color of the selection (if you need to change the color
19
+ later on, you can get to it with plot.getOptions().selection.color). "shape"
20
+ is the shape of the corners of the selection.
21
+
22
+ "minSize" is the minimum size a selection can be in pixels. This value can
23
+ be customized to determine the smallest size a selection can be and still
24
+ have the selection rectangle be displayed. When customizing this value, the
25
+ fact that it refers to pixels, not axis units must be taken into account.
26
+ Thus, for example, if there is a bar graph in time mode with BarWidth set to 1
27
+ minute, setting "minSize" to 1 will not make the minimum selection size 1
28
+ minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent
29
+ "plotunselected" events from being fired when the user clicks the mouse without
30
+ dragging.
31
+
32
+ When selection support is enabled, a "plotselected" event will be emitted on
33
+ the DOM element you passed into the plot function. The event handler gets a
34
+ parameter with the ranges selected on the axes, like this:
35
+
36
+ placeholder.bind( "plotselected", function( event, ranges ) {
37
+ alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
38
+ // similar for yaxis - with multiple axes, the extra ones are in
39
+ // x2axis, x3axis, ...
40
+ });
41
+
42
+ The "plotselected" event is only fired when the user has finished making the
43
+ selection. A "plotselecting" event is fired during the process with the same
44
+ parameters as the "plotselected" event, in case you want to know what's
45
+ happening while it's happening,
46
+
47
+ A "plotunselected" event with no arguments is emitted when the user clicks the
48
+ mouse to remove the selection. As stated above, setting "minSize" to 0 will
49
+ destroy this behavior.
50
+
51
+ The plugin allso adds the following methods to the plot object:
52
+
53
+ - setSelection( ranges, preventEvent )
54
+
55
+ Set the selection rectangle. The passed in ranges is on the same form as
56
+ returned in the "plotselected" event. If the selection mode is "x", you
57
+ should put in either an xaxis range, if the mode is "y" you need to put in
58
+ an yaxis range and both xaxis and yaxis if the selection mode is "xy", like
59
+ this:
60
+
61
+ setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
62
+
63
+ setSelection will trigger the "plotselected" event when called. If you don't
64
+ want that to happen, e.g. if you're inside a "plotselected" handler, pass
65
+ true as the second parameter. If you are using multiple axes, you can
66
+ specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of
67
+ xaxis, the plugin picks the first one it sees.
68
+
69
+ - clearSelection( preventEvent )
70
+
71
+ Clear the selection rectangle. Pass in true to avoid getting a
72
+ "plotunselected" event.
73
+
74
+ - getSelection()
75
+
76
+ Returns the current selection in the same format as the "plotselected"
77
+ event. If there's currently no selection, the function returns null.
78
+
79
+ */
80
+
81
+ (function ($) {
82
+ function init(plot) {
83
+ var selection = {
84
+ first: { x: -1, y: -1}, second: { x: -1, y: -1},
85
+ show: false,
86
+ active: false
87
+ };
88
+
89
+ // FIXME: The drag handling implemented here should be
90
+ // abstracted out, there's some similar code from a library in
91
+ // the navigation plugin, this should be massaged a bit to fit
92
+ // the Flot cases here better and reused. Doing this would
93
+ // make this plugin much slimmer.
94
+ var savedhandlers = {};
95
+
96
+ var mouseUpHandler = null;
97
+
98
+ function onMouseMove(e) {
99
+ if (selection.active) {
100
+ updateSelection(e);
101
+
102
+ plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
103
+ }
104
+ }
105
+
106
+ function onMouseDown(e) {
107
+ if (e.which != 1) // only accept left-click
108
+ return;
109
+
110
+ // cancel out any text selections
111
+ document.body.focus();
112
+
113
+ // prevent text selection and drag in old-school browsers
114
+ if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
115
+ savedhandlers.onselectstart = document.onselectstart;
116
+ document.onselectstart = function () { return false; };
117
+ }
118
+ if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
119
+ savedhandlers.ondrag = document.ondrag;
120
+ document.ondrag = function () { return false; };
121
+ }
122
+
123
+ setSelectionPos(selection.first, e);
124
+
125
+ selection.active = true;
126
+
127
+ // this is a bit silly, but we have to use a closure to be
128
+ // able to whack the same handler again
129
+ mouseUpHandler = function (e) { onMouseUp(e); };
130
+
131
+ $(document).one("mouseup", mouseUpHandler);
132
+ }
133
+
134
+ function onMouseUp(e) {
135
+ mouseUpHandler = null;
136
+
137
+ // revert drag stuff for old-school browsers
138
+ if (document.onselectstart !== undefined)
139
+ document.onselectstart = savedhandlers.onselectstart;
140
+ if (document.ondrag !== undefined)
141
+ document.ondrag = savedhandlers.ondrag;
142
+
143
+ // no more dragging
144
+ selection.active = false;
145
+ updateSelection(e);
146
+
147
+ if (selectionIsSane())
148
+ triggerSelectedEvent();
149
+ else {
150
+ // this counts as a clear
151
+ plot.getPlaceholder().trigger("plotunselected", [ ]);
152
+ plot.getPlaceholder().trigger("plotselecting", [ null ]);
153
+ }
154
+
155
+ return false;
156
+ }
157
+
158
+ function getSelection() {
159
+ if (!selectionIsSane())
160
+ return null;
161
+
162
+ if (!selection.show) return null;
163
+
164
+ var r = {}, c1 = selection.first, c2 = selection.second;
165
+ $.each(plot.getAxes(), function (name, axis) {
166
+ if (axis.used) {
167
+ var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);
168
+ r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
169
+ }
170
+ });
171
+ return r;
172
+ }
173
+
174
+ function triggerSelectedEvent() {
175
+ var r = getSelection();
176
+
177
+ plot.getPlaceholder().trigger("plotselected", [ r ]);
178
+
179
+ // backwards-compat stuff, to be removed in future
180
+ if (r.xaxis && r.yaxis)
181
+ plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
182
+ }
183
+
184
+ function clamp(min, value, max) {
185
+ return value < min ? min: (value > max ? max: value);
186
+ }
187
+
188
+ function setSelectionPos(pos, e) {
189
+ var o = plot.getOptions();
190
+ var offset = plot.getPlaceholder().offset();
191
+ var plotOffset = plot.getPlotOffset();
192
+ pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
193
+ pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
194
+
195
+ if (o.selection.mode == "y")
196
+ pos.x = pos == selection.first ? 0 : plot.width();
197
+
198
+ if (o.selection.mode == "x")
199
+ pos.y = pos == selection.first ? 0 : plot.height();
200
+ }
201
+
202
+ function updateSelection(pos) {
203
+ if (pos.pageX == null)
204
+ return;
205
+
206
+ setSelectionPos(selection.second, pos);
207
+ if (selectionIsSane()) {
208
+ selection.show = true;
209
+ plot.triggerRedrawOverlay();
210
+ }
211
+ else
212
+ clearSelection(true);
213
+ }
214
+
215
+ function clearSelection(preventEvent) {
216
+ if (selection.show) {
217
+ selection.show = false;
218
+ plot.triggerRedrawOverlay();
219
+ if (!preventEvent)
220
+ plot.getPlaceholder().trigger("plotunselected", [ ]);
221
+ }
222
+ }
223
+
224
+ // function taken from markings support in Flot
225
+ function extractRange(ranges, coord) {
226
+ var axis, from, to, key, axes = plot.getAxes();
227
+
228
+ for (var k in axes) {
229
+ axis = axes[k];
230
+ if (axis.direction == coord) {
231
+ key = coord + axis.n + "axis";
232
+ if (!ranges[key] && axis.n == 1)
233
+ key = coord + "axis"; // support x1axis as xaxis
234
+ if (ranges[key]) {
235
+ from = ranges[key].from;
236
+ to = ranges[key].to;
237
+ break;
238
+ }
239
+ }
240
+ }
241
+
242
+ // backwards-compat stuff - to be removed in future
243
+ if (!ranges[key]) {
244
+ axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
245
+ from = ranges[coord + "1"];
246
+ to = ranges[coord + "2"];
247
+ }
248
+
249
+ // auto-reverse as an added bonus
250
+ if (from != null && to != null && from > to) {
251
+ var tmp = from;
252
+ from = to;
253
+ to = tmp;
254
+ }
255
+
256
+ return { from: from, to: to, axis: axis };
257
+ }
258
+
259
+ function setSelection(ranges, preventEvent) {
260
+ var axis, range, o = plot.getOptions();
261
+
262
+ if (o.selection.mode == "y") {
263
+ selection.first.x = 0;
264
+ selection.second.x = plot.width();
265
+ }
266
+ else {
267
+ range = extractRange(ranges, "x");
268
+
269
+ selection.first.x = range.axis.p2c(range.from);
270
+ selection.second.x = range.axis.p2c(range.to);
271
+ }
272
+
273
+ if (o.selection.mode == "x") {
274
+ selection.first.y = 0;
275
+ selection.second.y = plot.height();
276
+ }
277
+ else {
278
+ range = extractRange(ranges, "y");
279
+
280
+ selection.first.y = range.axis.p2c(range.from);
281
+ selection.second.y = range.axis.p2c(range.to);
282
+ }
283
+
284
+ selection.show = true;
285
+ plot.triggerRedrawOverlay();
286
+ if (!preventEvent && selectionIsSane())
287
+ triggerSelectedEvent();
288
+ }
289
+
290
+ function selectionIsSane() {
291
+ var minSize = plot.getOptions().selection.minSize;
292
+ return Math.abs(selection.second.x - selection.first.x) >= minSize &&
293
+ Math.abs(selection.second.y - selection.first.y) >= minSize;
294
+ }
295
+
296
+ plot.clearSelection = clearSelection;
297
+ plot.setSelection = setSelection;
298
+ plot.getSelection = getSelection;
299
+
300
+ plot.hooks.bindEvents.push(function(plot, eventHolder) {
301
+ var o = plot.getOptions();
302
+ if (o.selection.mode != null) {
303
+ eventHolder.mousemove(onMouseMove);
304
+ eventHolder.mousedown(onMouseDown);
305
+ }
306
+ });
307
+
308
+
309
+ plot.hooks.drawOverlay.push(function (plot, ctx) {
310
+ // draw selection
311
+ if (selection.show && selectionIsSane()) {
312
+ var plotOffset = plot.getPlotOffset();
313
+ var o = plot.getOptions();
314
+
315
+ ctx.save();
316
+ ctx.translate(plotOffset.left, plotOffset.top);
317
+
318
+ var c = $.color.parse(o.selection.color);
319
+
320
+ ctx.strokeStyle = c.scale('a', 0.8).toString();
321
+ ctx.lineWidth = 1;
322
+ ctx.lineJoin = o.selection.shape;
323
+ ctx.fillStyle = c.scale('a', 0.4).toString();
324
+
325
+ var x = Math.min(selection.first.x, selection.second.x) + 0.5,
326
+ y = Math.min(selection.first.y, selection.second.y) + 0.5,
327
+ w = Math.abs(selection.second.x - selection.first.x) - 1,
328
+ h = Math.abs(selection.second.y - selection.first.y) - 1;
329
+
330
+ ctx.fillRect(x, y, w, h);
331
+ ctx.strokeRect(x, y, w, h);
332
+
333
+ ctx.restore();
334
+ }
335
+ });
336
+
337
+ plot.hooks.shutdown.push(function (plot, eventHolder) {
338
+ eventHolder.unbind("mousemove", onMouseMove);
339
+ eventHolder.unbind("mousedown", onMouseDown);
340
+
341
+ if (mouseUpHandler)
342
+ $(document).unbind("mouseup", mouseUpHandler);
343
+ });
344
+
345
+ }
346
+
347
+ $.plot.plugins.push({
348
+ init: init,
349
+ options: {
350
+ selection: {
351
+ mode: null, // one of null, "x", "y" or "xy"
352
+ color: "#e8cfac",
353
+ shape: "round", // one of "round", "miter", or "bevel"
354
+ minSize: 5 // minimum number of pixels
355
+ }
356
+ },
357
+ name: 'selection',
358
+ version: '1.1'
359
+ });
360
+ })(jQuery);