The pie plugin was a little too clever in its use of closures. In
processDatapoints it set canvas, target, and options for use in other
functions. Since options was not declared this meant that it became
global. Pages containing multiple pie plots therefore saw a range of
weird effects resulting from earlier plots receiving some of the options
set by later ones. Resolves#1128, resolves#1073, resolves#1055.
If an explicit numeric offset was provided, we should not override it.
The clipping is only meant to apply to the case where the center is
moved to make room for the legend in 'auto' mode, anyway.
This resolves#534 by handling the case where data is a string, whether
it is provided alone or as a pair. We can also eliminate the old and
unnecessary check for undefined values.
The canvasWidth, canvasHeight, legendWidth and legendHeight variables
existed only to share data between the setupPie and draw functions. Now
that setupPie has been folded into draw, they're no longer necessary.
This code is only used to prepare the plot for drawing; inlining it is
cleaner and will allow us to get rid of some plugin-global variables
that existed only to give setupPie a way to share data with the draw
function.
The redraw flag starts out as true, then is immediately set to false on
draw. If labels are enabled, drawPie calls drawLabels, which calls
drawLabel for each label. Any label that can't fit sets redraw back to
true, so the whole process can repeat.
This isn't the most obvious mechanism, and forces one to remember to do
things like setting redraw back to true after drawing, so the plot can
redraw itself on resize or when setting new data.
Instead we now have drawPie return true when it drew successfully, and
false otherwise, which the same happening in drawLabels and drawLabel.
Instead of checking the flag, we now just check the return value.
This has the added benefit of slightly improving performance in the case
where several redraws are necessary, since it now short-circuits out of
the draw loop as soon as one label fails to fit.
In plugins we should never add hooks conditionally; the condition should
remain within individual hooks, so the plugin can be toggled at any
time.
Ideally we should also 'inline' the hook functions, since they're used
nowhere else. But since that would involve a lot of code changes, we'll
put it off until the broader cleanup effort scheduled for 0.9.0.
Rounding errors are introduced when calculating the percentage when the total is 100 (for example if percentages have already been calculated). Calculating (total/100) first eliminates the error in this case.
When a pie's labels don't fit within its container, the pie is redrawn
with a smaller radius until the labels fit, or a fixed number of retry
attempts are exhausted. The redraw flag was not reset on success,
however, which prevented the pie from being redrawn again after a resize
or update.
When a slice equals (or comes close enough that it is equal in
floating-point representation) 100% of the pie, it was no longer drawn
by Excanvas. This is because of a long-standing issue where VML won't
draw an arc whose begin and end are the same. Rather than some hack,
like adding/subtracting a small value, we'll simply draw two arcs for
every slice, with each covering half of the slice's angle.
Substitute zero when .width() returns undefined, since legendWidth is
used in numeric calculations that break when it is undefined. This
became a problem with the release of jQuery 1.8.0, which returns
undefined instead of null when an element doesn't exist. This was fixed
in 1.8.1, but this is good practice anyway.