~ubuntu-branches/ubuntu/saucy/phpmyadmin/saucy-proposed

« back to all changes in this revision

Viewing changes to js/jqplot/plugins/jqplot.pieRenderer.js

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2013-08-04 13:24:37 UTC
  • mfrom: (1.2.44)
  • Revision ID: package-import@ubuntu.com-20130804132437-jznw8efwy4hr1nms
Tags: 4:4.0.5-1
* New upstream release.
  - Fixes security issue PMASA-2013-10.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
(function(e){e.jqplot.PieRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.PieRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.PieRenderer.prototype.constructor=e.jqplot.PieRenderer;e.jqplot.PieRenderer.prototype.init=function(q,u){this.diameter=null;this.padding=20;this.sliceMargin=0;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this.dataLabelPositionFactor=0.52;this.dataLabelNudge=2;this.dataLabelCenterOn=true;this.startAngle=0;this.tickRenderer=e.jqplot.PieTickRenderer;this._drawData=true;this._type="pie";if(q.highlightMouseDown&&q.highlightMouseOver==null){q.highlightMouseOver=false}e.extend(true,this,q);if(this.sliceMargin<0){this.sliceMargin=0}this._diameter=null;this._radius=null;this._sliceAngles=[];this._highlightedPoint=null;if(this.highlightColors.length==0){for(var s=0;s<this.seriesColors.length;s++){var r=e.jqplot.getColorComponents(this.seriesColors[s]);var o=[r[0],r[1],r[2]];var t=o[0]+o[1]+o[2];for(var p=0;p<3;p++){o[p]=(t>570)?o[p]*0.8:o[p]+0.3*(255-o[p]);o[p]=parseInt(o[p],10)}this.highlightColors.push("rgb("+o[0]+","+o[1]+","+o[2]+")")}}this.highlightColorGenerator=new e.jqplot.ColorGenerator(this.highlightColors);u.postParseOptionsHooks.addOnce(m);u.postInitHooks.addOnce(g);u.eventListenerHooks.addOnce("jqplotMouseMove",b);u.eventListenerHooks.addOnce("jqplotMouseDown",a);u.eventListenerHooks.addOnce("jqplotMouseUp",l);u.eventListenerHooks.addOnce("jqplotClick",f);u.eventListenerHooks.addOnce("jqplotRightClick",n);u.postDrawHooks.addOnce(i)};e.jqplot.PieRenderer.prototype.setGridData=function(t){var p=[];var u=[];var o=this.startAngle/180*Math.PI;var s=0;this._drawData=false;for(var r=0;r<this.data.length;r++){if(this.data[r][1]!=0){this._drawData=true}p.push(this.data[r][1]);u.push([this.data[r][0]]);if(r>0){p[r]+=p[r-1]}s+=this.data[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r<p.length;r++){u[r][1]=p[r]*q;u[r][2]=this.data[r][1]/s}this.gridData=u};e.jqplot.PieRenderer.prototype.makeGridData=function(t,u){var p=[];var v=[];var s=0;var o=this.startAngle/180*Math.PI;this._drawData=false;for(var r=0;r<t.length;r++){if(this.data[r][1]!=0){this._drawData=true}p.push(t[r][1]);v.push([t[r][0]]);if(r>0){p[r]+=p[r-1]}s+=t[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r<p.length;r++){v[r][1]=p[r]*q;v[r][2]=t[r][1]/s}return v};function h(o){return Math.sin((o-(o-Math.PI)/8/Math.PI)/2)}function j(u,t,o,v,r){var w=0;var q=t-u;var s=Math.abs(q);var p=o;if(v==false){p+=r}if(p>0&&s>0.01&&s<6.282){w=parseFloat(p)/2/h(q)}return w}e.jqplot.PieRenderer.prototype.drawSlice=function(B,z,y,u,w){if(this._drawData){var p=this._radius;var A=this.fill;var x=this.lineWidth;var s=this.sliceMargin;if(this.fill==false){s+=this.lineWidth}B.save();B.translate(this._center[0],this._center[1]);var D=j(z,y,this.sliceMargin,this.fill,this.lineWidth);var o=D*Math.cos((z+y)/2);var C=D*Math.sin((z+y)/2);if((y-z)<=Math.PI){p-=D}else{p+=D}B.translate(o,C);if(w){for(var v=0,t=this.shadowDepth;v<t;v++){B.save();B.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));q(p)}for(var v=0,t=this.shadowDepth;v<t;v++){B.restore()}}else{q(p)}B.restore()}function q(r){if(y>6.282+this.startAngle){y=6.282+this.startAngle;if(z>y){z=6.281+this.startAngle}}if(z>=y){return}B.beginPath();B.fillStyle=u;B.strokeStyle=u;B.lineWidth=x;B.arc(0,0,r,z,y,false);B.lineTo(0,0);B.closePath();if(A){B.fill()}else{B.stroke()}}};e.jqplot.PieRenderer.prototype.draw=function(B,z,E,o){var W;var H=(E!=undefined)?E:{};var t=0;var s=0;var N=1;var L=new e.jqplot.ColorGenerator(this.seriesColors);if(E.legendInfo&&E.legendInfo.placement=="insideGrid"){var J=E.legendInfo;switch(J.location){case"nw":t=J.width+J.xoffset;break;case"w":t=J.width+J.xoffset;break;case"sw":t=J.width+J.xoffset;break;case"ne":t=J.width+J.xoffset;N=-1;break;case"e":t=J.width+J.xoffset;N=-1;break;case"se":t=J.width+J.xoffset;N=-1;break;case"n":s=J.height+J.yoffset;break;case"s":s=J.height+J.yoffset;N=-1;break;default:break}}var K=(H.shadow!=undefined)?H.shadow:this.shadow;var A=(H.fill!=undefined)?H.fill:this.fill;var C=B.canvas.width;var I=B.canvas.height;var Q=C-t-2*this.padding;var X=I-s-2*this.padding;var M=Math.min(Q,X);var Y=M;this._sliceAngles=[];var v=this.sliceMargin;if(this.fill==false){v+=this.lineWidth}var q;var G=0;var R,aa,Z,ab;var D=this.startAngle/180*Math.PI;for(var W=0,V=z.length;W<V;W++){aa=(W==0)?D:z[W-1][1]+D;Z=z[W][1]+D;this._sliceAngles.push([aa,Z]);q=j(aa,Z,this.sliceMargin,this.fill,this.lineWidth);if(Math.abs(Z-aa)>Math.PI){G=Math.max(q,G)}}if(this.diameter!=null&&this.diameter>0){this._diameter=this.diameter-2*G}else{this._diameter=Y-2*G}if(this._diameter<6){e.jqplot.log("Diameter of pie too small, not rendering.");return}var S=this._radius=this._diameter/2;this._center=[(C-N*t)/2+N*t+G*Math.cos(D),(I-N*s)/2+N*s+G*Math.sin(D)];if(this.shadow){for(var W=0,V=z.length;W<V;W++){ab="rgba(0,0,0,"+this.shadowAlpha+")";this.renderer.drawSlice.call(this,B,this._sliceAngles[W][0],this._sliceAngles[W][1],ab,true)}}for(var W=0;W<z.length;W++){this.renderer.drawSlice.call(this,B,this._sliceAngles[W][0],this._sliceAngles[W][1],L.next(),false);if(this.showDataLabels&&z[W][2]*100>=this.dataLabelThreshold){var F,U=(this._sliceAngles[W][0]+this._sliceAngles[W][1])/2,T;if(this.dataLabels=="label"){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,z[W][0])}else{if(this.dataLabels=="value"){F=this.dataLabelFormatString||"%d";T=e.jqplot.sprintf(F,this.data[W][1])}else{if(this.dataLabels=="percent"){F=this.dataLabelFormatString||"%d%%";T=e.jqplot.sprintf(F,z[W][2]*100)}else{if(this.dataLabels.constructor==Array){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,this.dataLabels[W])}}}}var p=(this._radius)*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var P=this._center[0]+Math.cos(U)*p+this.canvas._offsets.left;var O=this._center[1]+Math.sin(U)*p+this.canvas._offsets.top;var u=e('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">'+T+"</div>").insertBefore(o.eventCanvas._elem);if(this.dataLabelCenterOn){P-=u.width()/2;O-=u.height()/2}else{P-=u.width()*Math.sin(U/2);O-=u.height()/2}P=Math.round(P);O=Math.round(O);u.css({left:P,top:O})}}};e.jqplot.PieAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.PieAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.PieAxisRenderer.prototype.constructor=e.jqplot.PieAxisRenderer;e.jqplot.PieAxisRenderer.prototype.init=function(o){this.tickRenderer=e.jqplot.PieTickRenderer;e.extend(true,this,o);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.PieLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.PieLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.PieLegendRenderer.prototype.constructor=e.jqplot.PieLegendRenderer;e.jqplot.PieLegendRenderer.prototype.init=function(o){this.numberRows=null;this.numberColumns=null;e.extend(true,this,o)};e.jqplot.PieLegendRenderer.prototype.draw=function(){var r=this;if(this.show){var B=this._series;this._elem=e(document.createElement("table"));this._elem.addClass("jqplot-table-legend");var E={position:"absolute"};if(this.background){E.background=this.background}if(this.border){E.border=this.border}if(this.fontSize){E.fontSize=this.fontSize}if(this.fontFamily){E.fontFamily=this.fontFamily}if(this.textColor){E.textColor=this.textColor}if(this.marginTop!=null){E.marginTop=this.marginTop}if(this.marginBottom!=null){E.marginBottom=this.marginBottom}if(this.marginLeft!=null){E.marginLeft=this.marginLeft}if(this.marginRight!=null){E.marginRight=this.marginRight}this._elem.css(E);var I=false,A=false,o,y;var C=B[0];var p=new e.jqplot.ColorGenerator(C.seriesColors);if(C.show){var J=C.data;if(this.numberRows){o=this.numberRows;if(!this.numberColumns){y=Math.ceil(J.length/o)}else{y=this.numberColumns}}else{if(this.numberColumns){y=this.numberColumns;o=Math.ceil(J.length/this.numberColumns)}else{o=J.length;y=1}}var H,G;var q,w,v;var x,z,F;var D=0;var u,t;for(H=0;H<o;H++){q=e(document.createElement("tr"));q.addClass("jqplot-table-legend");if(A){q.prependTo(this._elem)}else{q.appendTo(this._elem)}for(G=0;G<y;G++){if(D<J.length){x=this.labels[D]||J[D][0].toString();F=p.next();if(!A){if(H>0){I=true}else{I=false}}else{if(H==o-1){I=false}else{I=true}}z=(I)?this.rowSpacing:"0";w=e(document.createElement("td"));w.addClass("jqplot-table-legend jqplot-table-legend-swatch");w.css({textAlign:"center",paddingTop:z});u=e(document.createElement("div"));u.addClass("jqplot-table-legend-swatch-outline");t=e(document.createElement("div"));t.addClass("jqplot-table-legend-swatch");t.css({backgroundColor:F,borderColor:F});w.append(u.append(t));v=e(document.createElement("td"));v.addClass("jqplot-table-legend jqplot-table-legend-label");v.css("paddingTop",z);if(this.escapeHtml){v.text(x)}else{v.html(x)}if(A){v.prependTo(q);w.prependTo(q)}else{w.appendTo(q);v.appendTo(q)}I=true}D++}}}}return this._elem};e.jqplot.PieRenderer.prototype.handleMove=function(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];r.target.trigger("jqplotDataMouseOver",o);if(r.series[o[0]].highlightMouseOver&&!(o[0]==r.plugins.pieRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){r.target.trigger("jqplotDataHighlight",o);d(r,o[0],o[1])}}else{if(s==null){k(r)}}};function c(s,r,p){p=p||{};p.axesDefaults=p.axesDefaults||{};p.legend=p.legend||{};p.seriesDefaults=p.seriesDefaults||{};var o=false;if(p.seriesDefaults.renderer==e.jqplot.PieRenderer){o=true}else{if(p.series){for(var q=0;q<p.series.length;q++){if(p.series[q].renderer==e.jqplot.PieRenderer){o=true}}}}if(o){p.axesDefaults.renderer=e.jqplot.PieAxisRenderer;p.legend.renderer=e.jqplot.PieLegendRenderer;p.legend.preDraw=true;p.seriesDefaults.pointLabels={show:false}}}function g(r,q,o){for(var p=0;p<this.series.length;p++){if(this.series[p].renderer.constructor==e.jqplot.PieRenderer){if(this.series[p].highlightMouseOver){this.series[p].highlightMouseDown=false}}}}function m(o){for(var p=0;p<this.series.length;p++){this.series[p].seriesColors=this.seriesColors;this.series[p].colorGenerator=e.jqplot.colorGenerator}}function d(t,r,q){var p=t.series[r];var o=t.plugins.pieRenderer.highlightCanvas;o._ctx.clearRect(0,0,o._ctx.canvas.width,o._ctx.canvas.height);p._highlightedPoint=q;t.plugins.pieRenderer.highlightedSeriesIndex=r;p.renderer.drawSlice.call(p,o._ctx,p._sliceAngles[q][0],p._sliceAngles[q][1],p.highlightColorGenerator.get(q),false)}function k(q){var o=q.plugins.pieRenderer.highlightCanvas;o._ctx.clearRect(0,0,o._ctx.canvas.width,o._ctx.canvas.height);for(var p=0;p<q.series.length;p++){q.series[p]._highlightedPoint=null}q.plugins.pieRenderer.highlightedSeriesIndex=null;q.target.trigger("jqplotDataUnhighlight")}function b(s,r,v,u,t){if(u){var q=[u.seriesIndex,u.pointIndex,u.data];var p=jQuery.Event("jqplotDataMouseOver");p.pageX=s.pageX;p.pageY=s.pageY;t.target.trigger(p,q);if(t.series[q[0]].highlightMouseOver&&!(q[0]==t.plugins.pieRenderer.highlightedSeriesIndex&&q[1]==t.series[q[0]]._highlightedPoint)){var o=jQuery.Event("jqplotDataHighlight");o.which=s.which;o.pageX=s.pageX;o.pageY=s.pageY;t.target.trigger(o,q);d(t,q[0],q[1])}}else{if(u==null){k(t)}}}function a(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];if(s.series[p[0]].highlightMouseDown&&!(p[0]==s.plugins.pieRenderer.highlightedSeriesIndex&&p[1]==s.series[p[0]]._highlightedPoint)){var o=jQuery.Event("jqplotDataHighlight");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p);d(s,p[0],p[1])}}else{if(t==null){k(s)}}}function l(q,p,t,s,r){var o=r.plugins.pieRenderer.highlightedSeriesIndex;if(o!=null&&r.series[o].highlightMouseDown){k(r)}}function f(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var o=jQuery.Event("jqplotDataClick");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p)}}function n(s,r,v,u,t){if(u){var q=[u.seriesIndex,u.pointIndex,u.data];var o=t.plugins.pieRenderer.highlightedSeriesIndex;if(o!=null&&t.series[o].highlightMouseDown){k(t)}var p=jQuery.Event("jqplotDataRightClick");p.which=s.which;p.pageX=s.pageX;p.pageY=s.pageY;t.target.trigger(p,q)}}function i(){if(this.plugins.pieRenderer&&this.plugins.pieRenderer.highlightCanvas){this.plugins.pieRenderer.highlightCanvas.resetCanvas();this.plugins.pieRenderer.highlightCanvas=null}this.plugins.pieRenderer={highlightedSeriesIndex:null};this.plugins.pieRenderer.highlightCanvas=new e.jqplot.GenericCanvas();var p=e(this.targetId+" .jqplot-data-label");if(p.length){e(p[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pieRenderer-highlight-canvas",this._plotDimensions,this))}else{this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pieRenderer-highlight-canvas",this._plotDimensions,this))}var o=this.plugins.pieRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(q){k(q.data.plot)})}e.jqplot.preInitHooks.push(c);e.jqplot.PieTickRenderer=function(){e.jqplot.AxisTickRenderer.call(this)};e.jqplot.PieTickRenderer.prototype=new e.jqplot.AxisTickRenderer();e.jqplot.PieTickRenderer.prototype.constructor=e.jqplot.PieTickRenderer})(jQuery);
 
 
b'\\ No newline at end of file'
 
1
/**
 
2
 * jqPlot
 
3
 * Pure JavaScript plotting plugin using jQuery
 
4
 *
 
5
 * Version: 1.0.4
 
6
 * Revision: 1121
 
7
 *
 
8
 * Copyright (c) 2009-2012 Chris Leonello
 
9
 * jqPlot is currently available for use in all personal or commercial projects 
 
10
 * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL 
 
11
 * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can 
 
12
 * choose the license that best suits your project and use it accordingly. 
 
13
 *
 
14
 * Although not required, the author would appreciate an email letting him 
 
15
 * know of any substantial use of jqPlot.  You can reach the author at: 
 
16
 * chris at jqplot dot com or see http://www.jqplot.com/info.php .
 
17
 *
 
18
 * If you are feeling kind and generous, consider supporting the project by
 
19
 * making a donation at: http://www.jqplot.com/donate.php .
 
20
 *
 
21
 * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
 
22
 *
 
23
 *     version 2007.04.27
 
24
 *     author Ash Searle
 
25
 *     http://hexmen.com/blog/2007/03/printf-sprintf/
 
26
 *     http://hexmen.com/js/sprintf.js
 
27
 *     The author (Ash Searle) has placed this code in the public domain:
 
28
 *     "This code is unrestricted: you are free to use it however you like."
 
29
 * 
 
30
 */
 
31
(function($) {
 
32
    /**
 
33
     * Class: $.jqplot.PieRenderer
 
34
     * Plugin renderer to draw a pie chart.
 
35
     * x values, if present, will be used as slice labels.
 
36
     * y values give slice size.
 
37
     * 
 
38
     * To use this renderer, you need to include the 
 
39
     * pie renderer plugin, for example:
 
40
     * 
 
41
     * > <script type="text/javascript" src="plugins/jqplot.pieRenderer.js"></script>
 
42
     * 
 
43
     * Properties described here are passed into the $.jqplot function
 
44
     * as options on the series renderer.  For example:
 
45
     * 
 
46
     * > plot2 = $.jqplot('chart2', [s1, s2], {
 
47
     * >     seriesDefaults: {
 
48
     * >         renderer:$.jqplot.PieRenderer,
 
49
     * >         rendererOptions:{
 
50
     * >              sliceMargin: 2,
 
51
     * >              startAngle: -90
 
52
     * >          }
 
53
     * >      }
 
54
     * > });
 
55
     * 
 
56
     * A pie plot will trigger events on the plot target
 
57
     * according to user interaction.  All events return the event object,
 
58
     * the series index, the point (slice) index, and the point data for 
 
59
     * the appropriate slice.
 
60
     * 
 
61
     * 'jqplotDataMouseOver' - triggered when user mouseing over a slice.
 
62
     * 'jqplotDataHighlight' - triggered the first time user mouses over a slice,
 
63
     * if highlighting is enabled.
 
64
     * 'jqplotDataUnhighlight' - triggered when a user moves the mouse out of
 
65
     * a highlighted slice.
 
66
     * 'jqplotDataClick' - triggered when the user clicks on a slice.
 
67
     * 'jqplotDataRightClick' - tiggered when the user right clicks on a slice if
 
68
     * the "captureRightClick" option is set to true on the plot.
 
69
     */
 
70
    $.jqplot.PieRenderer = function(){
 
71
        $.jqplot.LineRenderer.call(this);
 
72
    };
 
73
    
 
74
    $.jqplot.PieRenderer.prototype = new $.jqplot.LineRenderer();
 
75
    $.jqplot.PieRenderer.prototype.constructor = $.jqplot.PieRenderer;
 
76
    
 
77
    // called with scope of a series
 
78
    $.jqplot.PieRenderer.prototype.init = function(options, plot) {
 
79
        // Group: Properties
 
80
        //
 
81
        // prop: diameter
 
82
        // Outer diameter of the pie, auto computed by default
 
83
        this.diameter = null;
 
84
        // prop: padding
 
85
        // padding between the pie and plot edges, legend, etc.
 
86
        this.padding = 20;
 
87
        // prop: sliceMargin
 
88
        // angular spacing between pie slices in degrees.
 
89
        this.sliceMargin = 0;
 
90
        // prop: fill
 
91
        // true or false, wether to fil the slices.
 
92
        this.fill = true;
 
93
        // prop: shadowOffset
 
94
        // offset of the shadow from the slice and offset of 
 
95
        // each succesive stroke of the shadow from the last.
 
96
        this.shadowOffset = 2;
 
97
        // prop: shadowAlpha
 
98
        // transparency of the shadow (0 = transparent, 1 = opaque)
 
99
        this.shadowAlpha = 0.07;
 
100
        // prop: shadowDepth
 
101
        // number of strokes to apply to the shadow, 
 
102
        // each stroke offset shadowOffset from the last.
 
103
        this.shadowDepth = 5;
 
104
        // prop: highlightMouseOver
 
105
        // True to highlight slice when moused over.
 
106
        // This must be false to enable highlightMouseDown to highlight when clicking on a slice.
 
107
        this.highlightMouseOver = true;
 
108
        // prop: highlightMouseDown
 
109
        // True to highlight when a mouse button is pressed over a slice.
 
110
        // This will be disabled if highlightMouseOver is true.
 
111
        this.highlightMouseDown = false;
 
112
        // prop: highlightColors
 
113
        // an array of colors to use when highlighting a slice.
 
114
        this.highlightColors = [];
 
115
        // prop: dataLabels
 
116
        // Either 'label', 'value', 'percent' or an array of labels to place on the pie slices.
 
117
        // Defaults to percentage of each pie slice.
 
118
        this.dataLabels = 'percent';
 
119
        // prop: showDataLabels
 
120
        // true to show data labels on slices.
 
121
        this.showDataLabels = false;
 
122
        // prop: dataLabelFormatString
 
123
        // Format string for data labels.  If none, '%s' is used for "label" and for arrays, '%d' for value and '%d%%' for percentage.
 
124
        this.dataLabelFormatString = null;
 
125
        // prop: dataLabelThreshold
 
126
        // Threshhold in percentage (0-100) of pie area, below which no label will be displayed.
 
127
        // This applies to all label types, not just to percentage labels.
 
128
        this.dataLabelThreshold = 3;
 
129
        // prop: dataLabelPositionFactor
 
130
        // A Multiplier (0-1) of the pie radius which controls position of label on slice.
 
131
        // Increasing will slide label toward edge of pie, decreasing will slide label toward center of pie.
 
132
        this.dataLabelPositionFactor = 0.52;
 
133
        // prop: dataLabelNudge
 
134
        // Number of pixels to slide the label away from (+) or toward (-) the center of the pie.
 
135
        this.dataLabelNudge = 2;
 
136
        // prop: dataLabelCenterOn
 
137
        // True to center the data label at its position.
 
138
        // False to set the inside facing edge of the label at its position.
 
139
        this.dataLabelCenterOn = true;
 
140
        // prop: startAngle
 
141
        // Angle to start drawing pie in degrees.  
 
142
        // According to orientation of canvas coordinate system:
 
143
        // 0 = on the positive x axis
 
144
        // -90 = on the positive y axis.
 
145
        // 90 = on the negaive y axis.
 
146
        // 180 or - 180 = on the negative x axis.
 
147
        this.startAngle = 0;
 
148
        this.tickRenderer = $.jqplot.PieTickRenderer;
 
149
        // Used as check for conditions where pie shouldn't be drawn.
 
150
        this._drawData = true;
 
151
        this._type = 'pie';
 
152
        
 
153
        // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver
 
154
        if (options.highlightMouseDown && options.highlightMouseOver == null) {
 
155
            options.highlightMouseOver = false;
 
156
        }
 
157
        
 
158
        $.extend(true, this, options);
 
159
 
 
160
        if (this.sliceMargin < 0) {
 
161
            this.sliceMargin = 0;
 
162
        }
 
163
 
 
164
        this._diameter = null;
 
165
        this._radius = null;
 
166
        // array of [start,end] angles arrays, one for each slice.  In radians.
 
167
        this._sliceAngles = [];
 
168
        // index of the currenty highlighted point, if any
 
169
        this._highlightedPoint = null;
 
170
        
 
171
        // set highlight colors if none provided
 
172
        if (this.highlightColors.length == 0) {
 
173
            for (var i=0; i<this.seriesColors.length; i++){
 
174
                var rgba = $.jqplot.getColorComponents(this.seriesColors[i]);
 
175
                var newrgb = [rgba[0], rgba[1], rgba[2]];
 
176
                var sum = newrgb[0] + newrgb[1] + newrgb[2];
 
177
                for (var j=0; j<3; j++) {
 
178
                    // when darkening, lowest color component can be is 60.
 
179
                    newrgb[j] = (sum > 570) ?  newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]);
 
180
                    newrgb[j] = parseInt(newrgb[j], 10);
 
181
                }
 
182
                this.highlightColors.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')');
 
183
            }
 
184
        }
 
185
        
 
186
        this.highlightColorGenerator = new $.jqplot.ColorGenerator(this.highlightColors);
 
187
        
 
188
        plot.postParseOptionsHooks.addOnce(postParseOptions);
 
189
        plot.postInitHooks.addOnce(postInit);
 
190
        plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove);
 
191
        plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown);
 
192
        plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp);
 
193
        plot.eventListenerHooks.addOnce('jqplotClick', handleClick);
 
194
        plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick);
 
195
        plot.postDrawHooks.addOnce(postPlotDraw);
 
196
    };
 
197
    
 
198
    $.jqplot.PieRenderer.prototype.setGridData = function(plot) {
 
199
        // set gridData property.  This will hold angle in radians of each data point.
 
200
        var stack = [];
 
201
        var td = [];
 
202
        var sa = this.startAngle/180*Math.PI;
 
203
        var tot = 0;
 
204
        // don't know if we have any valid data yet, so set plot to not draw.
 
205
        this._drawData = false;
 
206
        for (var i=0; i<this.data.length; i++){
 
207
            if (this.data[i][1] != 0) {
 
208
                // we have data, O.K. to draw.
 
209
                this._drawData = true;
 
210
            }
 
211
            stack.push(this.data[i][1]);
 
212
            td.push([this.data[i][0]]);
 
213
            if (i>0) {
 
214
                stack[i] += stack[i-1];
 
215
            }
 
216
            tot += this.data[i][1];
 
217
        }
 
218
        var fact = Math.PI*2/stack[stack.length - 1];
 
219
        
 
220
        for (var i=0; i<stack.length; i++) {
 
221
            td[i][1] = stack[i] * fact;
 
222
            td[i][2] = this.data[i][1]/tot;
 
223
        }
 
224
        this.gridData = td;
 
225
    };
 
226
    
 
227
    $.jqplot.PieRenderer.prototype.makeGridData = function(data, plot) {
 
228
        var stack = [];
 
229
        var td = [];
 
230
        var tot = 0;
 
231
        var sa = this.startAngle/180*Math.PI;
 
232
        // don't know if we have any valid data yet, so set plot to not draw.
 
233
        this._drawData = false;
 
234
        for (var i=0; i<data.length; i++){
 
235
            if (this.data[i][1] != 0) {
 
236
                // we have data, O.K. to draw.
 
237
                this._drawData = true;
 
238
            }
 
239
            stack.push(data[i][1]);
 
240
            td.push([data[i][0]]);
 
241
            if (i>0) {
 
242
                stack[i] += stack[i-1];
 
243
            }
 
244
            tot += data[i][1];
 
245
        }
 
246
        var fact = Math.PI*2/stack[stack.length - 1];
 
247
        
 
248
        for (var i=0; i<stack.length; i++) {
 
249
            td[i][1] = stack[i] * fact;
 
250
            td[i][2] = data[i][1]/tot;
 
251
        }
 
252
        return td;
 
253
    };
 
254
 
 
255
    function calcRadiusAdjustment(ang) {
 
256
        return Math.sin((ang - (ang-Math.PI) / 8 / Math.PI )/2.0);
 
257
    }
 
258
 
 
259
    function calcRPrime(ang1, ang2, sliceMargin, fill, lineWidth) {
 
260
        var rprime = 0;
 
261
        var ang = ang2 - ang1;
 
262
        var absang = Math.abs(ang);
 
263
        var sm = sliceMargin;
 
264
        if (fill == false) {
 
265
            sm += lineWidth;
 
266
        }
 
267
 
 
268
        if (sm > 0 && absang > 0.01 && absang < 6.282) {
 
269
            rprime = parseFloat(sm) / 2.0 / calcRadiusAdjustment(ang);
 
270
        }
 
271
 
 
272
        return rprime;
 
273
    }
 
274
    
 
275
    $.jqplot.PieRenderer.prototype.drawSlice = function (ctx, ang1, ang2, color, isShadow) {
 
276
        if (this._drawData) {
 
277
            var r = this._radius;
 
278
            var fill = this.fill;
 
279
            var lineWidth = this.lineWidth;
 
280
            var sm = this.sliceMargin;
 
281
            if (this.fill == false) {
 
282
                sm += this.lineWidth;
 
283
            }
 
284
            ctx.save();
 
285
            ctx.translate(this._center[0], this._center[1]);
 
286
            
 
287
            var rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth);
 
288
 
 
289
            var transx = rprime * Math.cos((ang1 + ang2) / 2.0);
 
290
            var transy = rprime * Math.sin((ang1 + ang2) / 2.0);
 
291
 
 
292
            if ((ang2 - ang1) <= Math.PI) {
 
293
                r -= rprime;  
 
294
            }
 
295
            else {
 
296
                r += rprime;
 
297
            }
 
298
 
 
299
            ctx.translate(transx, transy);
 
300
            
 
301
            if (isShadow) {
 
302
                for (var i=0, l=this.shadowDepth; i<l; i++) {
 
303
                    ctx.save();
 
304
                    ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));
 
305
                    doDraw(r);
 
306
                }
 
307
                for (var i=0, l=this.shadowDepth; i<l; i++) {
 
308
                    ctx.restore();
 
309
                }
 
310
            }
 
311
    
 
312
            else {
 
313
                doDraw(r);
 
314
            }
 
315
            ctx.restore();
 
316
        }
 
317
    
 
318
        function doDraw (rad) {
 
319
            // Fix for IE and Chrome that can't seem to draw circles correctly.
 
320
            // ang2 should always be <= 2 pi since that is the way the data is converted.
 
321
            // 2Pi = 6.2831853, Pi = 3.1415927
 
322
             if (ang2 > 6.282 + this.startAngle) {
 
323
                ang2 = 6.282 + this.startAngle;
 
324
                if (ang1 > ang2) {
 
325
                    ang1 = 6.281 + this.startAngle;
 
326
                }
 
327
            }
 
328
            // Fix for IE, where it can't seem to handle 0 degree angles.  Also avoids
 
329
            // ugly line on unfilled pies.
 
330
            if (ang1 >= ang2) {
 
331
                return;
 
332
            }            
 
333
        
 
334
            ctx.beginPath();  
 
335
            ctx.fillStyle = color;
 
336
            ctx.strokeStyle = color;
 
337
            ctx.lineWidth = lineWidth;
 
338
            ctx.arc(0, 0, rad, ang1, ang2, false);
 
339
            ctx.lineTo(0,0);
 
340
            ctx.closePath();
 
341
        
 
342
            if (fill) {
 
343
                ctx.fill();
 
344
            }
 
345
            else {
 
346
                ctx.stroke();
 
347
            }
 
348
        }
 
349
    };
 
350
    
 
351
    // called with scope of series
 
352
    $.jqplot.PieRenderer.prototype.draw = function (ctx, gd, options, plot) {
 
353
        var i;
 
354
        var opts = (options != undefined) ? options : {};
 
355
        // offset and direction of offset due to legend placement
 
356
        var offx = 0;
 
357
        var offy = 0;
 
358
        var trans = 1;
 
359
        var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors);
 
360
        if (options.legendInfo && options.legendInfo.placement == 'insideGrid') {
 
361
            var li = options.legendInfo;
 
362
            switch (li.location) {
 
363
                case 'nw':
 
364
                    offx = li.width + li.xoffset;
 
365
                    break;
 
366
                case 'w':
 
367
                    offx = li.width + li.xoffset;
 
368
                    break;
 
369
                case 'sw':
 
370
                    offx = li.width + li.xoffset;
 
371
                    break;
 
372
                case 'ne':
 
373
                    offx = li.width + li.xoffset;
 
374
                    trans = -1;
 
375
                    break;
 
376
                case 'e':
 
377
                    offx = li.width + li.xoffset;
 
378
                    trans = -1;
 
379
                    break;
 
380
                case 'se':
 
381
                    offx = li.width + li.xoffset;
 
382
                    trans = -1;
 
383
                    break;
 
384
                case 'n':
 
385
                    offy = li.height + li.yoffset;
 
386
                    break;
 
387
                case 's':
 
388
                    offy = li.height + li.yoffset;
 
389
                    trans = -1;
 
390
                    break;
 
391
                default:
 
392
                    break;
 
393
            }
 
394
        }
 
395
        
 
396
        var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
 
397
        var fill = (opts.fill != undefined) ? opts.fill : this.fill;
 
398
        var cw = ctx.canvas.width;
 
399
        var ch = ctx.canvas.height;
 
400
        var w = cw - offx - 2 * this.padding;
 
401
        var h = ch - offy - 2 * this.padding;
 
402
        var mindim = Math.min(w,h);
 
403
        var d = mindim;
 
404
        
 
405
        // Fixes issue #272.  Thanks hugwijst!
 
406
        // reset slice angles array.
 
407
        this._sliceAngles = [];
 
408
 
 
409
        var sm = this.sliceMargin;
 
410
        if (this.fill == false) {
 
411
            sm += this.lineWidth;
 
412
        }
 
413
        
 
414
        var rprime;
 
415
        var maxrprime = 0;
 
416
 
 
417
        var ang, ang1, ang2, shadowColor;
 
418
        var sa = this.startAngle / 180 * Math.PI;
 
419
 
 
420
        // have to pre-draw shadows, so loop throgh here and calculate some values also.
 
421
        for (var i=0, l=gd.length; i<l; i++) {
 
422
            ang1 = (i == 0) ? sa : gd[i-1][1] + sa;
 
423
            ang2 = gd[i][1] + sa;
 
424
 
 
425
            this._sliceAngles.push([ang1, ang2]);
 
426
 
 
427
            rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth);
 
428
 
 
429
            if (Math.abs(ang2-ang1) > Math.PI) {
 
430
                maxrprime = Math.max(rprime, maxrprime);  
 
431
            }
 
432
        }
 
433
 
 
434
        if (this.diameter != null && this.diameter > 0) {
 
435
            this._diameter = this.diameter - 2*maxrprime;
 
436
        }
 
437
        else {
 
438
            this._diameter = d - 2*maxrprime;
 
439
        }
 
440
 
 
441
        // Need to check for undersized pie.  This can happen if
 
442
        // plot area too small and legend is too big.
 
443
        if (this._diameter < 6) {
 
444
            $.jqplot.log('Diameter of pie too small, not rendering.');
 
445
            return;
 
446
        }
 
447
 
 
448
        var r = this._radius = this._diameter/2;
 
449
 
 
450
        this._center = [(cw - trans * offx)/2 + trans * offx + maxrprime * Math.cos(sa), (ch - trans*offy)/2 + trans * offy + maxrprime * Math.sin(sa)];
 
451
 
 
452
        if (this.shadow) {
 
453
            for (var i=0, l=gd.length; i<l; i++) {
 
454
                shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')';
 
455
                this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], shadowColor, true);
 
456
            }
 
457
        }
 
458
        
 
459
        for (var i=0; i<gd.length; i++) {
 
460
                      
 
461
            this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], colorGenerator.next(), false);
 
462
        
 
463
            if (this.showDataLabels && gd[i][2]*100 >= this.dataLabelThreshold) {
 
464
                var fstr, avgang = (this._sliceAngles[i][0] + this._sliceAngles[i][1])/2, label;
 
465
            
 
466
                if (this.dataLabels == 'label') {
 
467
                    fstr = this.dataLabelFormatString || '%s';
 
468
                    label = $.jqplot.sprintf(fstr, gd[i][0]);
 
469
                }
 
470
                else if (this.dataLabels == 'value') {
 
471
                    fstr = this.dataLabelFormatString || '%d';
 
472
                    label = $.jqplot.sprintf(fstr, this.data[i][1]);
 
473
                }
 
474
                else if (this.dataLabels == 'percent') {
 
475
                    fstr = this.dataLabelFormatString || '%d%%';
 
476
                    label = $.jqplot.sprintf(fstr, gd[i][2]*100);
 
477
                }
 
478
                else if (this.dataLabels.constructor == Array) {
 
479
                    fstr = this.dataLabelFormatString || '%s';
 
480
                    label = $.jqplot.sprintf(fstr, this.dataLabels[i]);
 
481
                }
 
482
            
 
483
                var fact = (this._radius ) * this.dataLabelPositionFactor + this.sliceMargin + this.dataLabelNudge;
 
484
            
 
485
                var x = this._center[0] + Math.cos(avgang) * fact + this.canvas._offsets.left;
 
486
                var y = this._center[1] + Math.sin(avgang) * fact + this.canvas._offsets.top;
 
487
            
 
488
                var labelelem = $('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">' + label + '</div>').insertBefore(plot.eventCanvas._elem);
 
489
                if (this.dataLabelCenterOn) {
 
490
                    x -= labelelem.width()/2;
 
491
                    y -= labelelem.height()/2;
 
492
                }
 
493
                else {
 
494
                    x -= labelelem.width() * Math.sin(avgang/2);
 
495
                    y -= labelelem.height()/2;
 
496
                }
 
497
                x = Math.round(x);
 
498
                y = Math.round(y);
 
499
                labelelem.css({left: x, top: y});
 
500
            }
 
501
        }            
 
502
    };
 
503
    
 
504
    $.jqplot.PieAxisRenderer = function() {
 
505
        $.jqplot.LinearAxisRenderer.call(this);
 
506
    };
 
507
    
 
508
    $.jqplot.PieAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer();
 
509
    $.jqplot.PieAxisRenderer.prototype.constructor = $.jqplot.PieAxisRenderer;
 
510
        
 
511
    
 
512
    // There are no traditional axes on a pie chart.  We just need to provide
 
513
    // dummy objects with properties so the plot will render.
 
514
    // called with scope of axis object.
 
515
    $.jqplot.PieAxisRenderer.prototype.init = function(options){
 
516
        //
 
517
        this.tickRenderer = $.jqplot.PieTickRenderer;
 
518
        $.extend(true, this, options);
 
519
        // I don't think I'm going to need _dataBounds here.
 
520
        // have to go Axis scaling in a way to fit chart onto plot area
 
521
        // and provide u2p and p2u functionality for mouse cursor, etc.
 
522
        // for convienence set _dataBounds to 0 and 100 and
 
523
        // set min/max to 0 and 100.
 
524
        this._dataBounds = {min:0, max:100};
 
525
        this.min = 0;
 
526
        this.max = 100;
 
527
        this.showTicks = false;
 
528
        this.ticks = [];
 
529
        this.showMark = false;
 
530
        this.show = false; 
 
531
    };
 
532
    
 
533
    
 
534
    
 
535
    
 
536
    $.jqplot.PieLegendRenderer = function(){
 
537
        $.jqplot.TableLegendRenderer.call(this);
 
538
    };
 
539
    
 
540
    $.jqplot.PieLegendRenderer.prototype = new $.jqplot.TableLegendRenderer();
 
541
    $.jqplot.PieLegendRenderer.prototype.constructor = $.jqplot.PieLegendRenderer;
 
542
    
 
543
    /**
 
544
     * Class: $.jqplot.PieLegendRenderer
 
545
     * Legend Renderer specific to pie plots.  Set by default
 
546
     * when user creates a pie plot.
 
547
     */
 
548
    $.jqplot.PieLegendRenderer.prototype.init = function(options) {
 
549
        // Group: Properties
 
550
        //
 
551
        // prop: numberRows
 
552
        // Maximum number of rows in the legend.  0 or null for unlimited.
 
553
        this.numberRows = null;
 
554
        // prop: numberColumns
 
555
        // Maximum number of columns in the legend.  0 or null for unlimited.
 
556
        this.numberColumns = null;
 
557
        $.extend(true, this, options);
 
558
    };
 
559
    
 
560
    // called with context of legend
 
561
    $.jqplot.PieLegendRenderer.prototype.draw = function() {
 
562
        var legend = this;
 
563
        if (this.show) {
 
564
            var series = this._series;
 
565
 
 
566
 
 
567
            this._elem = $(document.createElement('table'));
 
568
            this._elem.addClass('jqplot-table-legend');
 
569
 
 
570
            var ss = {position:'absolute'};
 
571
            if (this.background) {
 
572
                ss['background'] = this.background;
 
573
            }
 
574
            if (this.border) {
 
575
                ss['border'] = this.border;
 
576
            }
 
577
            if (this.fontSize) {
 
578
                ss['fontSize'] = this.fontSize;
 
579
            }
 
580
            if (this.fontFamily) {
 
581
                ss['fontFamily'] = this.fontFamily;
 
582
            }
 
583
            if (this.textColor) {
 
584
                ss['textColor'] = this.textColor;
 
585
            }
 
586
            if (this.marginTop != null) {
 
587
                ss['marginTop'] = this.marginTop;
 
588
            }
 
589
            if (this.marginBottom != null) {
 
590
                ss['marginBottom'] = this.marginBottom;
 
591
            }
 
592
            if (this.marginLeft != null) {
 
593
                ss['marginLeft'] = this.marginLeft;
 
594
            }
 
595
            if (this.marginRight != null) {
 
596
                ss['marginRight'] = this.marginRight;
 
597
            }
 
598
 
 
599
            this._elem.css(ss);
 
600
 
 
601
            // Pie charts legends don't go by number of series, but by number of data points
 
602
            // in the series.  Refactor things here for that.
 
603
            
 
604
            var pad = false, 
 
605
                reverse = false,
 
606
                nr, 
 
607
                nc;
 
608
            var s = series[0];
 
609
            var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors);
 
610
            
 
611
            if (s.show) {
 
612
                var pd = s.data;
 
613
                if (this.numberRows) {
 
614
                    nr = this.numberRows;
 
615
                    if (!this.numberColumns){
 
616
                        nc = Math.ceil(pd.length/nr);
 
617
                    }
 
618
                    else{
 
619
                        nc = this.numberColumns;
 
620
                    }
 
621
                }
 
622
                else if (this.numberColumns) {
 
623
                    nc = this.numberColumns;
 
624
                    nr = Math.ceil(pd.length/this.numberColumns);
 
625
                }
 
626
                else {
 
627
                    nr = pd.length;
 
628
                    nc = 1;
 
629
                }
 
630
                
 
631
                var i, j;
 
632
                var tr, td1, td2; 
 
633
                var lt, rs, color;
 
634
                var idx = 0; 
 
635
                var div0, div1;   
 
636
                
 
637
                for (i=0; i<nr; i++) {
 
638
                    tr = $(document.createElement('tr'));
 
639
                    tr.addClass('jqplot-table-legend');
 
640
                    
 
641
                    if (reverse){
 
642
                        tr.prependTo(this._elem);
 
643
                    }
 
644
                    
 
645
                    else{
 
646
                        tr.appendTo(this._elem);
 
647
                    }
 
648
                    
 
649
                    for (j=0; j<nc; j++) {
 
650
                        if (idx < pd.length){
 
651
                            lt = this.labels[idx] || pd[idx][0].toString();
 
652
                            color = colorGenerator.next();
 
653
                            if (!reverse){
 
654
                                if (i>0){
 
655
                                    pad = true;
 
656
                                }
 
657
                                else{
 
658
                                    pad = false;
 
659
                                }
 
660
                            }
 
661
                            else{
 
662
                                if (i == nr -1){
 
663
                                    pad = false;
 
664
                                }
 
665
                                else{
 
666
                                    pad = true;
 
667
                                }
 
668
                            }
 
669
                            rs = (pad) ? this.rowSpacing : '0';
 
670
 
 
671
 
 
672
 
 
673
                            td1 = $(document.createElement('td'));
 
674
                            td1.addClass('jqplot-table-legend jqplot-table-legend-swatch');
 
675
                            td1.css({textAlign: 'center', paddingTop: rs});
 
676
 
 
677
                            div0 = $(document.createElement('div'));
 
678
                            div0.addClass('jqplot-table-legend-swatch-outline');
 
679
                            div1 = $(document.createElement('div'));
 
680
                            div1.addClass('jqplot-table-legend-swatch');
 
681
                            div1.css({backgroundColor: color, borderColor: color});
 
682
                            td1.append(div0.append(div1));
 
683
 
 
684
                            td2 = $(document.createElement('td'));
 
685
                            td2.addClass('jqplot-table-legend jqplot-table-legend-label');
 
686
                            td2.css('paddingTop', rs);
 
687
 
 
688
                            if (this.escapeHtml){
 
689
                                td2.text(lt);
 
690
                            }
 
691
                            else {
 
692
                                td2.html(lt);
 
693
                            }
 
694
                            if (reverse) {
 
695
                                td2.prependTo(tr);
 
696
                                td1.prependTo(tr);
 
697
                            }
 
698
                            else {
 
699
                                td1.appendTo(tr);
 
700
                                td2.appendTo(tr);
 
701
                            }
 
702
                            pad = true;
 
703
                        }
 
704
                        idx++;
 
705
                    }   
 
706
                }
 
707
            }
 
708
        }
 
709
        return this._elem;                
 
710
    };
 
711
    
 
712
    $.jqplot.PieRenderer.prototype.handleMove = function(ev, gridpos, datapos, neighbor, plot) {
 
713
        if (neighbor) {
 
714
            var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
 
715
            plot.target.trigger('jqplotDataMouseOver', ins);
 
716
            if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
 
717
                plot.target.trigger('jqplotDataHighlight', ins);
 
718
                highlight (plot, ins[0], ins[1]);
 
719
            }
 
720
        }
 
721
        else if (neighbor == null) {
 
722
            unhighlight (plot);
 
723
        }
 
724
    };
 
725
    
 
726
    
 
727
    // this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]);
 
728
    
 
729
    // setup default renderers for axes and legend so user doesn't have to
 
730
    // called with scope of plot
 
731
    function preInit(target, data, options) {
 
732
        options = options || {};
 
733
        options.axesDefaults = options.axesDefaults || {};
 
734
        options.legend = options.legend || {};
 
735
        options.seriesDefaults = options.seriesDefaults || {};
 
736
        // only set these if there is a pie series
 
737
        var setopts = false;
 
738
        if (options.seriesDefaults.renderer == $.jqplot.PieRenderer) {
 
739
            setopts = true;
 
740
        }
 
741
        else if (options.series) {
 
742
            for (var i=0; i < options.series.length; i++) {
 
743
                if (options.series[i].renderer == $.jqplot.PieRenderer) {
 
744
                    setopts = true;
 
745
                }
 
746
            }
 
747
        }
 
748
        
 
749
        if (setopts) {
 
750
            options.axesDefaults.renderer = $.jqplot.PieAxisRenderer;
 
751
            options.legend.renderer = $.jqplot.PieLegendRenderer;
 
752
            options.legend.preDraw = true;
 
753
            options.seriesDefaults.pointLabels = {show: false};
 
754
        }
 
755
    }
 
756
    
 
757
    function postInit(target, data, options) {
 
758
        for (var i=0; i<this.series.length; i++) {
 
759
            if (this.series[i].renderer.constructor == $.jqplot.PieRenderer) {
 
760
                // don't allow mouseover and mousedown at same time.
 
761
                if (this.series[i].highlightMouseOver) {
 
762
                    this.series[i].highlightMouseDown = false;
 
763
                }
 
764
            }
 
765
        }
 
766
    }
 
767
    
 
768
    // called with scope of plot
 
769
    function postParseOptions(options) {
 
770
        for (var i=0; i<this.series.length; i++) {
 
771
            this.series[i].seriesColors = this.seriesColors;
 
772
            this.series[i].colorGenerator = $.jqplot.colorGenerator;
 
773
        }
 
774
    }
 
775
    
 
776
    function highlight (plot, sidx, pidx) {
 
777
        var s = plot.series[sidx];
 
778
        var canvas = plot.plugins.pieRenderer.highlightCanvas;
 
779
        canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height);
 
780
        s._highlightedPoint = pidx;
 
781
        plot.plugins.pieRenderer.highlightedSeriesIndex = sidx;
 
782
        s.renderer.drawSlice.call(s, canvas._ctx, s._sliceAngles[pidx][0], s._sliceAngles[pidx][1], s.highlightColorGenerator.get(pidx), false);
 
783
    }
 
784
    
 
785
    function unhighlight (plot) {
 
786
        var canvas = plot.plugins.pieRenderer.highlightCanvas;
 
787
        canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height);
 
788
        for (var i=0; i<plot.series.length; i++) {
 
789
            plot.series[i]._highlightedPoint = null;
 
790
        }
 
791
        plot.plugins.pieRenderer.highlightedSeriesIndex = null;
 
792
        plot.target.trigger('jqplotDataUnhighlight');
 
793
    }
 
794
 
 
795
    function handleMove(ev, gridpos, datapos, neighbor, plot) {
 
796
        if (neighbor) {
 
797
            var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
 
798
            var evt1 = jQuery.Event('jqplotDataMouseOver');
 
799
            evt1.pageX = ev.pageX;
 
800
            evt1.pageY = ev.pageY;
 
801
            plot.target.trigger(evt1, ins);
 
802
            if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
 
803
                var evt = jQuery.Event('jqplotDataHighlight');
 
804
                evt.which = ev.which;
 
805
                evt.pageX = ev.pageX;
 
806
                evt.pageY = ev.pageY;
 
807
                plot.target.trigger(evt, ins);
 
808
                highlight (plot, ins[0], ins[1]);
 
809
            }
 
810
        }
 
811
        else if (neighbor == null) {
 
812
            unhighlight (plot);
 
813
        }
 
814
    } 
 
815
    
 
816
    function handleMouseDown(ev, gridpos, datapos, neighbor, plot) {
 
817
        if (neighbor) {
 
818
            var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
 
819
            if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
 
820
                var evt = jQuery.Event('jqplotDataHighlight');
 
821
                evt.which = ev.which;
 
822
                evt.pageX = ev.pageX;
 
823
                evt.pageY = ev.pageY;
 
824
                plot.target.trigger(evt, ins);
 
825
                highlight (plot, ins[0], ins[1]);
 
826
            }
 
827
        }
 
828
        else if (neighbor == null) {
 
829
            unhighlight (plot);
 
830
        }
 
831
    }
 
832
    
 
833
    function handleMouseUp(ev, gridpos, datapos, neighbor, plot) {
 
834
        var idx = plot.plugins.pieRenderer.highlightedSeriesIndex;
 
835
        if (idx != null && plot.series[idx].highlightMouseDown) {
 
836
            unhighlight(plot);
 
837
        }
 
838
    }
 
839
    
 
840
    function handleClick(ev, gridpos, datapos, neighbor, plot) {
 
841
        if (neighbor) {
 
842
            var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
 
843
            var evt = jQuery.Event('jqplotDataClick');
 
844
            evt.which = ev.which;
 
845
            evt.pageX = ev.pageX;
 
846
            evt.pageY = ev.pageY;
 
847
            plot.target.trigger(evt, ins);
 
848
        }
 
849
    }
 
850
    
 
851
    function handleRightClick(ev, gridpos, datapos, neighbor, plot) {
 
852
        if (neighbor) {
 
853
            var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
 
854
            var idx = plot.plugins.pieRenderer.highlightedSeriesIndex;
 
855
            if (idx != null && plot.series[idx].highlightMouseDown) {
 
856
                unhighlight(plot);
 
857
            }
 
858
            var evt = jQuery.Event('jqplotDataRightClick');
 
859
            evt.which = ev.which;
 
860
            evt.pageX = ev.pageX;
 
861
            evt.pageY = ev.pageY;
 
862
            plot.target.trigger(evt, ins);
 
863
        }
 
864
    }    
 
865
    
 
866
    // called within context of plot
 
867
    // create a canvas which we can draw on.
 
868
    // insert it before the eventCanvas, so eventCanvas will still capture events.
 
869
    function postPlotDraw() {
 
870
        // Memory Leaks patch    
 
871
        if (this.plugins.pieRenderer && this.plugins.pieRenderer.highlightCanvas) {
 
872
            this.plugins.pieRenderer.highlightCanvas.resetCanvas();
 
873
            this.plugins.pieRenderer.highlightCanvas = null;
 
874
        }
 
875
 
 
876
        this.plugins.pieRenderer = {highlightedSeriesIndex:null};
 
877
        this.plugins.pieRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
 
878
        
 
879
        // do we have any data labels?  if so, put highlight canvas before those
 
880
        var labels = $(this.targetId+' .jqplot-data-label');
 
881
        if (labels.length) {
 
882
            $(labels[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this));
 
883
        }
 
884
        // else put highlight canvas before event canvas.
 
885
        else {
 
886
            this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this));
 
887
        }
 
888
        
 
889
        var hctx = this.plugins.pieRenderer.highlightCanvas.setContext();
 
890
        this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
 
891
    }
 
892
    
 
893
    $.jqplot.preInitHooks.push(preInit);
 
894
    
 
895
    $.jqplot.PieTickRenderer = function() {
 
896
        $.jqplot.AxisTickRenderer.call(this);
 
897
    };
 
898
    
 
899
    $.jqplot.PieTickRenderer.prototype = new $.jqplot.AxisTickRenderer();
 
900
    $.jqplot.PieTickRenderer.prototype.constructor = $.jqplot.PieTickRenderer;
 
901
    
 
902
})(jQuery);
 
903
    
 
904
    
 
 
b'\\ No newline at end of file'