Anonymous avatar Anonymous committed 8086a03

Improve slice margin handling and fixed bug with single slice pies.

Comments (0)

Files changed (2)

examples/pieTest4.html

 <script class="code" type="text/javascript">$(document).ready(function(){
 	jQuery.jqplot.config.enablePlugins = true;
 	plot1 = jQuery.jqplot('chart1', 
-		[[['Verwerkende FruedenStrudle industrie', 9],['Retail', 8], ['Primaire producent', 7], 
+		[[['Verwerkende industrie', 9],['Retail', 8], ['Primaire producent', 7], 
 		['Out of home', 6],['Groothandel', 5], ['Grondstof', 4], ['Consument', 3], ['Bewerkende industrie', 2]]], 
 		{
 			title: ' ', 
-			seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4 } }, 
-			legend: { show:true, location: 'e' }
+			seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4, showDataLabels: true } }, 
+			legend: { show:true }
 		}
 	);
 });
     ['Out of home', 0],['Groothandel', 0], ['Grondstof', 0], ['Consument', 3], ['Bewerkende industrie', 2]]], 
     {
       title: ' ', 
-      seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4 } }, 
-      legend: { show:true, location: 'ne', rendererOptions: {numberRows: 1}, placement:'inside'}
+      seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4, showDataLabels: true } }, 
+      legend: { show:true }
     }
   );
 });
     ['Out of home', 0],['Groothandel', 0], ['Grondstof', 0], ['Consument', 0], ['Bewerkende industrie', 2]]], 
     {
       title: ' ', 
-      seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4 } }, 
-      legend: { show:true, location: 's' }
+      seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4, showDataLabels: true } }, 
+      legend: { show:true }
     }
   );
 
     ['Out of home', 0],['Groothandel', 0], ['Grondstof', 0], ['Consument', 0], ['Bewerkende industrie', 1]]], 
     {
       title: ' ', 
-      seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4 } }, 
-      legend: { show:true, location: 'n' }
+      seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4, showDataLabels: true } }, 
+      legend: { show:true }
     }
   );
 
 
 <script class="code" type="text/javascript">$(document).ready(function(){
   plot5 = jQuery.jqplot('chart5', 
-    [[['Verwerkende FruedenStrudel industrie', 100],['Retail', 0], ['Primaire producent', 0], 
+    [[['Verwerkende industrie', 100],['Retail', 0], ['Primaire producent', 0], 
     ['Out of home', 0],['Groothandel', 0], ['Grondstof', 0], ['Consument', 0], ['Bewerkende industrie', 1]]], 
     {
       title: ' ', 
-      seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4 } }, 
-      legend: { show:true, location: 'nw' }
+      seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4, showDataLabels: true } }, 
+      legend: { show:true }
     }
   );
 
     [[['Verwerkende industrie', 100]]], 
     {
       title: ' ', 
-      seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4 } }, 
-      legend: { show:true, location: 'se' }
+      seriesDefaults: {shadow: false, renderer: jQuery.jqplot.PieRenderer, rendererOptions: { sliceMargin: 4, showDataLabels: true } }, 
+      legend: { show:true }
     }
   );
 

src/plugins/jqplot.pieRenderer.js

         }
         
         $.extend(true, this, options);
+
+        if (this.sliceMargin < 0) {
+            this.sliceMargin = 0;
+        }
+
         this._diameter = null;
         this._radius = null;
         // array of [start,end] angles arrays, one for each slice.  In radians.
         }
         return td;
     };
+
+    function calcRadiusAdjustment(ang) {
+        return Math.sin((ang - (ang-Math.PI) / 8 / Math.PI )/2.0);
+    }
     
     $.jqplot.PieRenderer.prototype.drawSlice = function (ctx, ang1, ang2, color, isShadow) {
         if (this._drawData) {
             ctx.save();
             ctx.translate(this._center[0], this._center[1]);
             var rprime = 0;
-            if (Math.abs(ang2-ang1) > 0) {
-                rprime = parseFloat(sm) / 2.0 / Math.sin((ang2 - ang1)/2.0);
+            var ang = ang2 - ang1;
+            var absang = Math.abs(ang);
+            if (this.sliceMargin > 0 && absang > 0.01 && absang < 6.282) {
+                rprime = parseFloat(sm) / 2.0 / calcRadiusAdjustment(ang);
             }
+
             var transx = rprime * Math.cos((ang1 + ang2) / 2.0);
             var transy = rprime * Math.sin((ang1 + ang2) / 2.0);
+
             if ((ang2 - ang1) <= Math.PI) {
                 r -= rprime;  
             }
             else {
                 r += rprime;
             }
+
             ctx.translate(transx, transy);
             
             if (isShadow) {
         function doDraw (rad) {
             // Fix for IE and Chrome that can't seem to draw circles correctly.
             // ang2 should always be <= 2 pi since that is the way the data is converted.
+            // 2Pi = 6.2831853, Pi = 3.1415927
              if (ang2 > 6.282 + this.startAngle) {
                 ang2 = 6.282 + this.startAngle;
                 if (ang1 > ang2) {
         var h = ch - offy - 2 * this.padding;
         var mindim = Math.min(w,h);
         var d = mindim;
-        // this._diameter = this.diameter || d;
-        this._diameter = this.diameter  || d; // - this.sliceMargin;
-
-        var r = this._radius = this._diameter/2;
-        var sa = this.startAngle / 180 * Math.PI;
         this._center = [(cw - trans * offx)/2 + trans * offx, (ch - trans*offy)/2 + trans * offy];
         
         // Fixes issue #272.  Thanks hugwijst!
         // reset slice angles array.
         this._sliceAngles = [];
+
+        var sm = this.sliceMargin;
+        if (this.fill == false) {
+            sm += this.lineWidth;
+        }
         
+        var rprime = 0;
+        var maxrprime = 0;
+
+        var ang, ang1, ang2, shadowColor;
+        var sa = this.startAngle / 180 * Math.PI;
+
+        // have to pre-draw shadows, so loop throgh here and calculate some values also.
+        for (var i=0, l=gd.length; i<l; i++) {
+            ang1 = (i == 0) ? sa : gd[i-1][1] + sa;
+            ang2 = gd[i][1] + sa;
+
+            this._sliceAngles.push([ang1, ang2]);
+
+            var ang = ang2 - ang1;
+            var absang = Math.abs(ang);
+
+            if (this.sliceMargin > 0 && absang > 0.01 && absang < 6.282) {
+                rprime = parseFloat(sm) / 2.0 / calcRadiusAdjustment(ang);
+            }
+
+
+            if (absang > Math.PI) {
+                maxrprime = Math.max(rprime, maxrprime);  
+            }
+        }
+
+        if (this.diameter != null && this.diameter > 0) {
+            this._diameter = this.diameter - 2*maxrprime;
+        }
+        else {
+            this._diameter = d - 2*maxrprime;
+        }
+
+        // Need to check for undersized pie.  This can happen if
+        // plot area too small and legend is too big.
+        if (this._diameter < 6) {
+            $.jqplot.log('Diameter of pie too small, not rendering.');
+            return;
+        }
+
+        var r = this._radius = this._diameter/2;
+
         if (this.shadow) {
-            var shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')';
-            for (var i=0; i<gd.length; i++) {
-                var ang1 = (i == 0) ? sa : gd[i-1][1] + sa;
-                // Adjust ang1 and ang2 for sliceMargin
-                // ang1 += this.sliceMargin/180*Math.PI;
-                this.renderer.drawSlice.call (this, ctx, ang1, gd[i][1]+sa, shadowColor, true);
+            for (var i=0, l=gd.length; i<l; i++) {
+                shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')';
+                this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], shadowColor, true);
             }
-            
         }
+        
         for (var i=0; i<gd.length; i++) {
-            var ang1 = (i == 0) ? sa : gd[i-1][1] + sa;
-            // Adjust ang1 and ang2 for sliceMargin
-            // ang1 += this.sliceMargin/180*Math.PI;
-            var ang2 = gd[i][1] + sa;
-            this._sliceAngles.push([ang1, ang2]);
                       
-            this.renderer.drawSlice.call (this, ctx, ang1, ang2, colorGenerator.next(), false);
+            this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], colorGenerator.next(), false);
         
             if (this.showDataLabels && gd[i][2]*100 >= this.dataLabelThreshold) {
-                var fstr, avgang = (ang1+ang2)/2, label;
+                var fstr, avgang = (this._sliceAngles[i][0] + this._sliceAngles[i][1])/2, label;
             
                 if (this.dataLabels == 'label') {
                     fstr = this.dataLabelFormatString || '%s';
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.