Add analytics
[bus.git] / busui / owa / modules / base / js / includes / jquery / flot / jquery.flot.pie.js
blob:a/busui/owa/modules/base/js/includes/jquery/flot/jquery.flot.pie.js -> blob:b/busui/owa/modules/base/js/includes/jquery/flot/jquery.flot.pie.js
--- a/busui/owa/modules/base/js/includes/jquery/flot/jquery.flot.pie.js
+++ b/busui/owa/modules/base/js/includes/jquery/flot/jquery.flot.pie.js
@@ -1,1 +1,753 @@
-
+/*

+Flot plugin for rendering pie charts. The plugin assumes the data is 

+coming is as a single data value for each series, and each of those 

+values is a positive value or zero (negative numbers don't make 

+any sense and will cause strange effects). The data values do 

+NOT need to be passed in as percentage values because it 

+internally calculates the total and percentages.

+

+* Created by Brian Medendorp, June 2009

+* Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars

+

+* Changes:

+	2009-10-22: lineJoin set to round

+	2009-10-23: IE full circle fix, donut

+	2009-11-11: Added basic hover from btburnett3 - does not work in IE, and center is off in Chrome and Opera

+	2009-11-17: Added IE hover capability submitted by Anthony Aragues

+	2009-11-18: Added bug fix submitted by Xavi Ivars (issues with arrays when other JS libraries are included as well)

+		

+

+Available options are:

+series: {

+	pie: {

+		show: true/false

+		radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'

+		innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect

+		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

+		tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)

+		offset: {

+			top: integer value to move the pie up or down

+			left: integer value to move the pie left or right, or 'auto'

+		},

+		stroke: {

+			color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')

+			width: integer pixel width of the stroke

+		},

+		label: {

+			show: true/false, or 'auto'

+			formatter:  a user-defined function that modifies the text/style of the label text

+			radius: 0-1 for percentage of fullsize, or a specified pixel length

+			background: {

+				color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')

+				opacity: 0-1

+			},

+			threshold: 0-1 for the percentage value at which to hide labels (if they're too small)

+		},

+		combine: {

+			threshold: 0-1 for the percentage value at which to combine slices (if they're too small)

+			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

+			label: any text value of what the combined slice should be labeled

+		}

+		highlight: {

+			opacity: 0-1

+		}

+	}

+}

+

+More detail and specific examples can be found in the included HTML file.

+

+*/

+

+(function ($) 

+{

+	function init(plot) // this is the "body" of the plugin

+	{

+		var canvas = null;

+		var target = null;

+		var maxRadius = null;

+		var centerLeft = null;

+		var centerTop = null;

+		var total = 0;

+		var redraw = true;

+		var redrawAttempts = 10;

+		var shrink = 0.95;

+		var legendWidth = 0;

+		var processed = false;

+		var raw = false;

+		

+		// interactive variables	

+		var highlights = [];	

+	

+		// add hook to determine if pie plugin in enabled, and then perform necessary operations

+		plot.hooks.processOptions.push(checkPieEnabled);

+		plot.hooks.bindEvents.push(bindEvents);	

+

+		// check to see if the pie plugin is enabled

+		function checkPieEnabled(plot, options)

+		{

+			if (options.series.pie.show)

+			{

+				//disable grid

+				options.grid.show = false;

+				

+				// set labels.show

+				if (options.series.pie.label.show=='auto')

+					if (options.legend.show)

+						options.series.pie.label.show = false;

+					else

+						options.series.pie.label.show = true;

+				

+				// set radius

+				if (options.series.pie.radius=='auto')

+					if (options.series.pie.label.show)

+						options.series.pie.radius = 3/4;

+					else

+						options.series.pie.radius = 1;

+						

+				// ensure sane tilt

+				if (options.series.pie.tilt>1)

+					options.series.pie.tilt=1;

+				if (options.series.pie.tilt<0)

+					options.series.pie.tilt=0;

+			

+				// add processData hook to do transformations on the data

+				plot.hooks.processDatapoints.push(processDatapoints);

+				plot.hooks.drawOverlay.push(drawOverlay);	

+				

+				// add draw hook

+				plot.hooks.draw.push(draw);

+			}

+		}

+	

+		// bind hoverable events

+		function bindEvents(plot, eventHolder) 		

+		{		

+			var options = plot.getOptions();

+			

+			if (options.series.pie.show && options.grid.hoverable)

+				eventHolder.unbind('mousemove').mousemove(onMouseMove);

+				

+			if (options.series.pie.show && options.grid.clickable)

+				eventHolder.unbind('click').click(onClick);

+		}	

+		

+

+		// debugging function that prints out an object

+		function alertObject(obj)

+		{

+			var msg = '';

+			function traverse(obj, depth)

+			{

+				if (!depth)

+					depth = 0;

+				for (var i = 0; i < obj.length; ++i)

+				{

+					for (var j=0; j<depth; j++)

+						msg += '\t';

+				

+					if( typeof obj[i] == "object")

+					{	// its an object

+						msg += ''+i+':\n';

+						traverse(obj[i], depth+1);

+					}

+					else

+					{	// its a value

+						msg += ''+i+': '+obj[i]+'\n';

+					}

+				}

+			}

+			traverse(obj);

+			alert(msg);

+		}

+		

+		function calcTotal(data)

+		{

+			for (var i = 0; i < data.length; ++i)

+			{

+				var item = parseFloat(data[i].data[0][1]);

+				if (item)

+					total += item;

+			}

+		}	

+		

+		function processDatapoints(plot, series, data, datapoints) 

+		{	

+			if (!processed)

+			{

+				processed = true;

+			

+				canvas = plot.getCanvas();

+				target = $(canvas).parent();

+				options = plot.getOptions();

+			

+				plot.setData(combine(plot.getData()));

+			}

+		}

+		

+		function setupPie()

+		{

+			legendWidth = target.children().filter('.legend').children().width();

+		

+			// calculate maximum radius and center point

+			maxRadius =  Math.min(canvas.width,(canvas.height/options.series.pie.tilt))/2;

+			centerTop = (canvas.height/2)+options.series.pie.offset.top;

+			centerLeft = (canvas.width/2);

+			

+			if (options.series.pie.offset.left=='auto')

+				if (options.legend.position.match('w'))

+					centerLeft += legendWidth/2;

+				else

+					centerLeft -= legendWidth/2;

+			else

+				centerLeft += options.series.pie.offset.left;

+					

+			if (centerLeft<maxRadius)

+				centerLeft = maxRadius;

+			else if (centerLeft>canvas.width-maxRadius)

+				centerLeft = canvas.width-maxRadius;

+		}

+		

+		function fixData(data)

+		{

+			for (var i = 0; i < data.length; ++i)

+			{

+				if (typeof(data[i].data)=='number')

+					data[i].data = [[1,data[i].data]];

+				else if (typeof(data[i].data)=='undefined' || typeof(data[i].data[0])=='undefined')

+				{

+					if (typeof(data[i].data)!='undefined' && typeof(data[i].data.label)!='undefined')

+						data[i].label = data[i].data.label; // fix weirdness coming from flot

+					data[i].data = [[1,0]];

+					

+				}

+			}

+			return data;

+		}

+		

+		function combine(data)

+		{

+			data = fixData(data);

+			calcTotal(data);

+			var combined = 0;

+			var numCombined = 0;

+			var color = options.series.pie.combine.color;

+			

+			var newdata = [];

+			for (var i = 0; i < data.length; ++i)

+			{

+				// make sure its a number

+				data[i].data[0][1] = parseFloat(data[i].data[0][1]);

+				if (!data[i].data[0][1])

+					data[i].data[0][1] = 0;

+					

+				if (data[i].data[0][1]/total<=options.series.pie.combine.threshold)

+				{

+					combined += data[i].data[0][1];

+					numCombined++;

+					if (!color)

+						color = data[i].color;

+				}				

+				else

+				{

+					newdata.push({

+						data: [[1,data[i].data[0][1]]], 

+						color: data[i].color, 

+						label: data[i].label,

+						angle: (data[i].data[0][1]*(Math.PI*2))/total,

+						percent: (data[i].data[0][1]/total*100)

+					});

+				}

+			}

+			if (numCombined>0)

+				newdata.push({

+					data: [[1,combined]], 

+					color: color, 

+					label: options.series.pie.combine.label,

+					angle: (combined*(Math.PI*2))/total,

+					percent: (combined/total*100)

+				});

+			return newdata;

+		}		

+		

+		function draw(plot, newCtx)

+		{

+			if (!target) return; // if no series were passed

+			ctx = newCtx;

+		

+			setupPie();

+			var slices = plot.getData();

+		

+			var attempts = 0;

+			while (redraw && attempts<redrawAttempts)

+			{

+				redraw = false;

+				if (attempts>0)

+					maxRadius *= shrink;

+				attempts += 1;

+				clear();

+				if (options.series.pie.tilt<=0.8)

+					drawShadow();

+				drawPie();

+			}

+			if (attempts >= redrawAttempts) {

+				clear();

+				target.prepend('<div class="error">Could not draw pie with labels contained inside canvas</div>');

+			}

+			

+			if ( plot.setSeries && plot.insertLegend )

+			{

+				plot.setSeries(slices);

+				plot.insertLegend();

+			}

+			

+			// we're actually done at this point, just defining internal functions at this point

+			

+			function clear()

+			{

+				ctx.clearRect(0,0,canvas.width,canvas.height);

+				target.children().filter('.pieLabel, .pieLabelBackground').remove();

+			}

+			

+			function drawShadow()

+			{

+				var shadowLeft = 5;

+				var shadowTop = 15;

+				var edge = 10;

+				var alpha = 0.02;

+			

+				// set radius

+				if (options.series.pie.radius>1)

+					var radius = options.series.pie.radius;

+				else

+					var radius = maxRadius * options.series.pie.radius;

+					

+				if (radius>=(canvas.width/2)-shadowLeft || radius*options.series.pie.tilt>=(canvas.height/2)-shadowTop || radius<=edge)

+					return;	// shadow would be outside canvas, so don't draw it

+			

+				ctx.save();

+				ctx.translate(shadowLeft,shadowTop);

+				ctx.globalAlpha = alpha;

+				ctx.fillStyle = '#000';

+

+				// center and rotate to starting position

+				ctx.translate(centerLeft,centerTop);

+				ctx.scale(1, options.series.pie.tilt);

+				

+				//radius -= edge;

+				for (var i=1; i<=edge; i++)

+				{

+					ctx.beginPath();

+					ctx.arc(0,0,radius,0,Math.PI*2,false);

+					ctx.fill();

+					radius -= i;

+				}	

+				

+				ctx.restore();

+			}

+			

+			function drawPie()

+			{

+				startAngle = Math.PI*options.series.pie.startAngle;

+				

+				// set radius

+				if (options.series.pie.radius>1)

+					var radius = options.series.pie.radius;

+				else

+					var radius = maxRadius * options.series.pie.radius;

+				

+				// center and rotate to starting position

+				ctx.save();

+				ctx.translate(centerLeft,centerTop);

+				ctx.scale(1, options.series.pie.tilt);

+				//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera

+				

+				// draw slices

+				ctx.save();

+				var currentAngle = startAngle;

+				for (var i = 0; i < slices.length; ++i)

+				{

+					slices[i].startAngle = currentAngle;

+					drawSlice(slices[i].angle, slices[i].color, true);

+				}

+				ctx.restore();

+				

+				// draw slice outlines

+				ctx.save();

+				ctx.lineWidth = options.series.pie.stroke.width;

+				currentAngle = startAngle;

+				for (var i = 0; i < slices.length; ++i)

+					drawSlice(slices[i].angle, options.series.pie.stroke.color, false);

+				ctx.restore();

+					

+				// draw donut hole

+				drawDonutHole(ctx);

+				

+				// draw labels

+				if (options.series.pie.label.show)

+					drawLabels();

+				

+				// restore to original state

+				ctx.restore();

+				

+				function drawSlice(angle, color, fill)

+				{	

+					if (angle<=0)

+						return;

+				

+					if (fill)

+						ctx.fillStyle = color;

+					else

+					{

+						ctx.strokeStyle = color;

+						ctx.lineJoin = 'round';

+					}

+						

+					ctx.beginPath();

+					if (angle!=Math.PI*2)

+						ctx.moveTo(0,0); // Center of the pie

+					else if ($.browser.msie)

+						angle -= 0.0001;

+					//ctx.arc(0,0,radius,0,angle,false); // This doesn't work properly in Opera

+					ctx.arc(0,0,radius,currentAngle,currentAngle+angle,false);

+					ctx.closePath();

+					//ctx.rotate(angle); // This doesn't work properly in Opera

+					currentAngle += angle;

+					

+					if (fill)

+						ctx.fill();

+					else

+						ctx.stroke();

+				}

+				

+				function drawLabels()

+				{

+					var currentAngle = startAngle;

+					

+					// set radius

+					if (options.series.pie.label.radius>1)

+						var radius = options.series.pie.label.radius;

+					else

+						var radius = maxRadius * options.series.pie.label.radius;

+					

+					for (var i = 0; i < slices.length; ++i)

+					{

+						if (slices[i].percent >= options.series.pie.label.threshold*100)

+							drawLabel(slices[i], currentAngle, i);

+						currentAngle += slices[i].angle;

+					}

+					

+					function drawLabel(slice, startAngle, index)

+					{

+						if (slice.data[0][1]==0)

+							return;

+							

+						// format label text

+						var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;

+						if (lf)

+							text = lf(slice.label, slice);

+						else

+							text = slice.label;

+						if (plf)

+							text = plf(text, slice);

+							

+						var halfAngle = ((startAngle+slice.angle) + startAngle)/2;

+						var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);

+						var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;

+						

+						var html = '<span class="pieLabel" id="pieLabel'+index+'" style="position:absolute;top:' + y + 'px;left:' + x + 'px;">' + text + "</span>";

+						target.append(html);

+						var label = target.children('#pieLabel'+index);

+						var labelTop = (y - label.height()/2);

+						var labelLeft = (x - label.width()/2);

+						label.css('top', labelTop);

+						label.css('left', labelLeft);

+						

+						// check to make sure that the label is not outside the canvas

+						if (0-labelTop>0 || 0-labelLeft>0 || canvas.height-(labelTop+label.height())<0 || canvas.width-(labelLeft+label.width())<0)

+							redraw = true;

+						

+						if (options.series.pie.label.background.opacity != 0) {

+							// put in the transparent background separately to avoid blended labels and label boxes

+							var c = options.series.pie.label.background.color;

+							if (c == null) {

+								c = slice.color;

+							}

+							var pos = 'top:'+labelTop+'px;left:'+labelLeft+'px;';

+							$('<div class="pieLabelBackground" style="position:absolute;width:' + label.width() + 'px;height:' + label.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').insertBefore(label).css('opacity', options.series.pie.label.background.opacity);

+						}

+					} // end individual label function

+				} // end drawLabels function

+			} // end drawPie function

+		} // end draw function

+		

+		// Placed here because it needs to be accessed from multiple locations 

+		function drawDonutHole(layer)

+		{

+			// draw donut hole

+			if(options.series.pie.innerRadius > 0)

+			{

+				// subtract the center

+				layer.save();

+				innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;

+				layer.globalCompositeOperation = 'destination-out'; // this does not work with excanvas, but it will fall back to using the stroke color

+				layer.beginPath();

+				layer.fillStyle = options.series.pie.stroke.color;

+				layer.arc(0,0,innerRadius,0,Math.PI*2,false);

+				layer.fill();

+				layer.closePath();

+				layer.restore();

+				

+				// add inner stroke

+				layer.save();

+				layer.beginPath();

+				layer.strokeStyle = options.series.pie.stroke.color;

+				layer.arc(0,0,innerRadius,0,Math.PI*2,false);

+				layer.stroke();

+				layer.closePath();

+				layer.restore();

+				// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.

+			}

+		}

+		

+		//-- Additional Interactive related functions --

+		

+		function isPointInPoly(poly, pt)

+		{

+			for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)

+				((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))

+				&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])

+				&& (c = !c);

+			return c;

+		}

+		

+		function findNearbySlice(mouseX, mouseY)

+		{

+			var slices = plot.getData(),

+				options = plot.getOptions(),

+				radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;

+			

+			for (var i = 0; i < slices.length; ++i) 

+			{

+				var s = slices[i];	

+				

+				if(s.pie.show)

+				{

+					ctx.save();

+					ctx.beginPath();

+					ctx.moveTo(0,0); // Center of the pie

+					//ctx.scale(1, options.series.pie.tilt);	// this actually seems to break everything when here.

+					ctx.arc(0,0,radius,s.startAngle,s.startAngle+s.angle,false);

+					ctx.closePath();

+					x = mouseX-centerLeft;

+					y = mouseY-centerTop;

+					if(ctx.isPointInPath)

+					{

+						if (ctx.isPointInPath(mouseX-centerLeft, mouseY-centerTop))

+						{

+							//alert('found slice!');

+							ctx.restore();

+							return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};

+						}

+					}

+					else

+					{

+						// excanvas for IE doesn;t support isPointInPath, this is a workaround. 

+						p1X = (radius * Math.cos(s.startAngle));

+						p1Y = (radius * Math.sin(s.startAngle));

+						p2X = (radius * Math.cos(s.startAngle+(s.angle/4)));

+						p2Y = (radius * Math.sin(s.startAngle+(s.angle/4)));

+						p3X = (radius * Math.cos(s.startAngle+(s.angle/2)));

+						p3Y = (radius * Math.sin(s.startAngle+(s.angle/2)));

+						p4X = (radius * Math.cos(s.startAngle+(s.angle/1.5)));

+						p4Y = (radius * Math.sin(s.startAngle+(s.angle/1.5)));

+						p5X = (radius * Math.cos(s.startAngle+s.angle));

+						p5Y = (radius * Math.sin(s.startAngle+s.angle));

+						arrPoly = [[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]];

+						arrPoint = [x,y];

+						// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?

+						if(isPointInPoly(arrPoly, arrPoint))

+						{

+							ctx.restore();

+							return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};

+						}			

+					}

+					ctx.restore();

+				}

+			}

+			

+			return null;

+		}

+

+		function onMouseMove(e) 

+		{

+			triggerClickHoverEvent('plothover', e);

+		}

+		

+        function onClick(e) 

+		{

+			triggerClickHoverEvent('plotclick', e);

+        }

+

+		// trigger click or hover event (they send the same parameters so we share their code)

+		function triggerClickHoverEvent(eventname, e) 

+		{

+			var offset = plot.offset(),

+				canvasX = parseInt(e.pageX - offset.left),

+				canvasY =  parseInt(e.pageY - offset.top),

+				item = findNearbySlice(canvasX, canvasY);

+			

+			if (options.grid.autoHighlight) 

+			{

+				// clear auto-highlights

+				for (var i = 0; i < highlights.length; ++i) 

+				{

+					var h = highlights[i];

+					if (h.auto == eventname && !(item && h.series == item.series))

+						unhighlight(h.series);

+				}

+			}

+			

+			// if no slice was found, quit

+			if (!item) 

+				return;

+				

+			// highlight the slice

+			highlight(item.series, eventname);

+				

+			// trigger any hover bind events

+			var pos = { pageX: e.pageX, pageY: e.pageY };

+			target.trigger(eventname, [ pos, item ]);	

+		}

+

+		function highlight(s, auto) 

+		{

+			if (typeof s == "number")

+				s = series[s];

+

+			var i = indexOfHighlight(s);

+			if (i == -1) 

+			{

+				highlights.push({ series: s, auto: auto });

+				plot.triggerRedrawOverlay();

+			}

+			else if (!auto)

+				highlights[i].auto = false;

+		}

+

+		function unhighlight(s) 

+		{

+			if (s == null) 

+			{

+				highlights = [];

+				plot.triggerRedrawOverlay();

+			}

+			

+			if (typeof s == "number")

+				s = series[s];

+

+			var i = indexOfHighlight(s);

+			if (i != -1) 

+			{

+				highlights.splice(i, 1);

+				plot.triggerRedrawOverlay();

+			}

+		}

+

+		function indexOfHighlight(s) 

+		{

+			for (var i = 0; i < highlights.length; ++i) 

+			{

+				var h = highlights[i];

+				if (h.series == s)

+					return i;

+			}

+			return -1;

+		}

+

+		function drawOverlay(plot, octx) 

+		{

+			//alert(options.series.pie.radius);

+			var options = plot.getOptions();

+			//alert(options.series.pie.radius);

+			

+			var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;

+

+			octx.save();

+			octx.translate(centerLeft, centerTop);

+			octx.scale(1, options.series.pie.tilt);

+			

+			for (i = 0; i < highlights.length; ++i) 

+				drawHighlight(highlights[i].series);

+			

+			drawDonutHole(octx);

+

+			octx.restore();

+

+			function drawHighlight(series) 

+			{

+				if (series.angle < 0) return;

+				

+				//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();

+				octx.fillStyle = "rgba(255, 255, 255, "+options.series.pie.highlight.opacity+")"; // this is temporary until we have access to parseColor

+				

+				octx.beginPath();

+				if (series.angle!=Math.PI*2)

+					octx.moveTo(0,0); // Center of the pie

+				octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle,false);

+				octx.closePath();

+				octx.fill();

+			}

+			

+		}	

+		

+	} // end init (plugin body)

+	

+	// define pie specific options and their default values

+	var options = {

+		series: {

+			pie: {

+				show: false,

+				radius: 'auto',	// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)

+				innerRadius:0, /* for donut */

+				startAngle: 3/2,

+				tilt: 1,

+				offset: {

+					top: 0,

+					left: 'auto'

+				},

+				stroke: {

+					color: '#FFF',

+					width: 1

+				},

+				label: {

+					show: 'auto',

+					formatter: function(label, slice){

+						return '<div style="font-size:x-small;text-align:center;padding:2px;color:'+slice.color+';">'+label+'<br/>'+Math.round(slice.percent)+'%</div>';

+					},	// formatter function

+					radius: 1,	// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)

+					background: {

+						color: null,

+						opacity: 0

+					},

+					threshold: 0	// percentage at which to hide the label (i.e. the slice is too narrow)

+				},

+				combine: {

+					threshold: -1,	// percentage at which to combine little slices into one larger slice

+					color: null,	// color to give the new slice (auto-generated if null)

+					label: 'Other'	// label to give the new slice

+				},

+				highlight: {

+					//color: '#FFF',		// will add this functionality once parseColor is available

+					opacity: 0.5

+				}

+			}

+		}

+	};

+    

+	$.plot.plugins.push({

+		init: init,

+		options: options,

+		name: "pie",

+		version: "1.0"

+	});

+})(jQuery);