docs: function () {
  		
  		var 
  			// Get positions - either an integer or a percentage string must be given
  			getLength = function (length, relativeTo) {
  				return (/%$/).test(length) ?
  					relativeTo * parseInt(length, 10) / 100 :
  					parseInt(length, 10);
  			},
  			
  			sum = 0,
  			series = this,
  			chart = series.chart,
  			options = series.options,
  			reversed = options.reversed,
  			plotWidth = chart.plotWidth,
  			plotHeight = chart.plotHeight,
  			cumulative = 0, // start at top
  			center = options.center,
  			centerX = getLength(center[0], plotWidth),
  			centerY = getLength(center[1], plotHeight),
  			width = getLength(options.width, plotWidth),
  			tempWidth,
  			getWidthAt,
  			height = getLength(options.height, plotHeight),
  			neckWidth = getLength(options.neckWidth, plotWidth),
  			neckHeight = getLength(options.neckHeight, plotHeight),
  			neckY = height - neckHeight,
  			data = series.data,
  			path,
  			fraction,
  			half = options.dataLabels.position === 'left' ? 1 : 0,
  
  			x1, 
  			y1, 
  			x2, 
  			x3, 
  			y3, 
  			x4, 
  			y5;
  
  		// Return the width at a specific y coordinate
  		series.getWidthAt = getWidthAt = function (y) {
  			return y > height - neckHeight || height === neckHeight ?
  				neckWidth :
  				neckWidth + (width - neckWidth) * ((height - neckHeight - y) / (height - neckHeight));
  		};
  		series.getX = function (y, half) {
  					return centerX + (half ? -1 : 1) * ((getWidthAt(reversed ? plotHeight - y : y) / 2) + options.dataLabels.distance);
  		};
  
  		// Expose
  		series.center = [centerX, centerY, height];
  		series.centerX = centerX;
  
  		/*
  		 * Individual point coordinate naming:
  		 *
  		 * x1,y1 _________________ x2,y1
  		 *  \                         /
  		 *   \                       /
  		 *    \                     /
  		 *     \                   /
  		 *      \                 /
  		 *     x3,y3 _________ x4,y3
  		 *
  		 * Additional for the base of the neck:
  		 *
  		 *       |               |
  		 *       |               |
  		 *       |               |
  		 *     x3,y5 _________ x4,y5
  		 */
  
  
  
  
  		// get the total sum
  		each(data, function (point) {
  			sum += point.y;
  		});
  
  		each(data, function (point) {
  			// set start and end positions
  			y5 = null;
  			fraction = sum ? point.y / sum : 0;
  			y1 = centerY - height / 2 + cumulative * height;
  			y3 = y1 + fraction * height;
  			//tempWidth = neckWidth + (width - neckWidth) * ((height - neckHeight - y1) / (height - neckHeight));
  			tempWidth = getWidthAt(y1);
  			x1 = centerX - tempWidth / 2;
  			x2 = x1 + tempWidth;
  			tempWidth = getWidthAt(y3);
  			x3 = centerX - tempWidth / 2;
  			x4 = x3 + tempWidth;
  
  			// the entire point is within the neck
  			if (y1 > neckY) {
  				x1 = x3 = centerX - neckWidth / 2;
  				x2 = x4 = centerX + neckWidth / 2;
  			
  			// the base of the neck
  			} else if (y3 > neckY) {
  				y5 = y3;
  
  				tempWidth = getWidthAt(neckY);
  				x3 = centerX - tempWidth / 2;
  				x4 = x3 + tempWidth;
  
  				y3 = neckY;
  			}
  
  			if (reversed) {
  				y1 = height - y1;
  				y3 = height - y3;
  				y5 = (y5 ? height - y5 : null);
  			}
  			// save the path
  			path = [
  				'M',
  				x1, y1,
  				'L',
  				x2, y1,
  				x4, y3
  			];
  			if (y5) {
  				path.push(x4, y5, x3, y5);
  			}
  			path.push(x3, y3, 'Z');
  
  			// prepare for using shared dr
  			point.shapeType = 'path';
  			point.shapeArgs = { d: path };
  
  
  			// for tooltips and data labels
  			point.percentage = fraction * 100;
  			point.plotX = centerX;
  			point.plotY = (y1 + (y5 || y3)) / 2;
  
  			// Placement of tooltips and data labels
  			point.tooltipPos = [
  				centerX,
  				point.plotY
  			];
  
  			// Slice is a noop on funnel points
  			point.slice = noop;
  			
  			// Mimicking pie data label placement logic
  			point.half = half;
  
  			cumulative += fraction;
  		});		
  	}