| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091 | 
							- <!DOCTYPE html>
 
- <html>
 
- <head>
 
-   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
-   <title>The source code</title>
 
-   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
 
-   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
 
-   <style type="text/css">
 
-     .highlight { display: block; background-color: #ddd; }
 
-   </style>
 
-   <script type="text/javascript">
 
-     function highlight() {
 
-       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
 
-     }
 
-   </script>
 
- </head>
 
- <body onload="prettyPrint(); highlight();">
 
-   <pre class="prettyprint lang-js"><span id='Ext-chart-series-Pie'>/**
 
- </span> * @class Ext.chart.series.Pie
 
-  *
 
-  * Creates a Pie Chart. A Pie Chart is a useful visualization technique to display quantitative information for different
 
-  * categories that also have a meaning as a whole.
 
-  * As with all other series, the Pie Series must be appended in the *series* Chart array configuration. See the Chart
 
-  * documentation for more information. A typical configuration object for the pie series could be:
 
-  *
 
-  *     @example
 
-  *     var store = Ext.create('Ext.data.JsonStore', {
 
-  *         fields: ['name', 'data'],
 
-  *         data: [
 
-  *             { 'name': 'metric one',   'data': 10 },
 
-  *             { 'name': 'metric two',   'data':  7 },
 
-  *             { 'name': 'metric three', 'data':  5 },
 
-  *             { 'name': 'metric four',  'data':  2 },
 
-  *             { 'name': 'metric five',  'data': 27 }
 
-  *         ]
 
-  *     });
 
-  *
 
-  *     Ext.create('Ext.chart.Chart', {
 
-  *         renderTo: Ext.getBody(),
 
-  *         width: 500,
 
-  *         height: 350,
 
-  *         animate: true,
 
-  *         store: store,
 
-  *         theme: 'Base:gradients',
 
-  *         series: [{
 
-  *             type: 'pie',
 
-  *             angleField: 'data',
 
-  *             showInLegend: true,
 
-  *             tips: {
 
-  *                 trackMouse: true,
 
-  *                 width: 140,
 
-  *                 height: 28,
 
-  *                 renderer: function(storeItem, item) {
 
-  *                     // calculate and display percentage on hover
 
-  *                     var total = 0;
 
-  *                     store.each(function(rec) {
 
-  *                         total += rec.get('data');
 
-  *                     });
 
-  *                     this.setTitle(storeItem.get('name') + ': ' + Math.round(storeItem.get('data') / total * 100) + '%');
 
-  *                 }
 
-  *             },
 
-  *             highlight: {
 
-  *                 segment: {
 
-  *                     margin: 20
 
-  *                 }
 
-  *             },
 
-  *             label: {
 
-  *                 field: 'name',
 
-  *                 display: 'rotate',
 
-  *                 contrast: true,
 
-  *                 font: '18px Arial'
 
-  *             }
 
-  *         }]
 
-  *     });
 
-  *
 
-  * In this configuration we set `pie` as the type for the series, set an object with specific style properties for highlighting options
 
-  * (triggered when hovering elements). We also set true to `showInLegend` so all the pie slices can be represented by a legend item.
 
-  *
 
-  * We set `data` as the value of the field to determine the angle span for each pie slice. We also set a label configuration object
 
-  * where we set the field name of the store field to be renderer as text for the label. The labels will also be displayed rotated.
 
-  *
 
-  * We set `contrast` to `true` to flip the color of the label if it is to similar to the background color. Finally, we set the font family
 
-  * and size through the `font` parameter.
 
-  *
 
-  * @xtype pie
 
-  */
 
- Ext.define('Ext.chart.series.Pie', {
 
-     /* Begin Definitions */
 
-     alternateClassName: ['Ext.chart.PieSeries', 'Ext.chart.PieChart'],
 
-     extend: 'Ext.chart.series.Series',
 
-     /* End Definitions */
 
-     type: "pie",
 
-     alias: 'series.pie',
 
-     accuracy: 100000,
 
-     rad: Math.PI * 2 / 100000,
 
- <span id='Ext-chart-series-Pie-cfg-highlightDuration'>    /**
 
- </span>     * @cfg {Number} highlightDuration
 
-      * The duration for the pie slice highlight effect.
 
-      */
 
-     highlightDuration: 150,
 
- <span id='Ext-chart-series-Pie-cfg-angleField'>    /**
 
- </span>     * @cfg {String} angleField (required)
 
-      * The store record field name to be used for the pie angles.
 
-      * The values bound to this field name must be positive real numbers.
 
-      */
 
-     angleField: false,
 
- <span id='Ext-chart-series-Pie-cfg-field'>    /**
 
- </span>     * @cfg {String} field
 
-      * Alias for {@link #angleField}.
 
-      */
 
- <span id='Ext-chart-series-Pie-cfg-xField'>    /**
 
- </span>     * @cfg {String} xField
 
-      * Alias for {@link #angleField}.
 
-      */
 
- <span id='Ext-chart-series-Pie-cfg-lengthField'>    /**
 
- </span>     * @cfg {String} lengthField
 
-      * The store record field name to be used for the pie slice lengths.
 
-      * The values bound to this field name must be positive real numbers.
 
-      */
 
-     lengthField: false,
 
- <span id='Ext-chart-series-Pie-cfg-donut'>    /**
 
- </span>     * @cfg {Boolean/Number} donut
 
-      * Whether to set the pie chart as donut chart.
 
-      * Default's false. Can be set to a particular percentage to set the radius
 
-      * of the donut chart.
 
-      */
 
-     donut: false,
 
- <span id='Ext-chart-series-Pie-cfg-showInLegend'>    /**
 
- </span>     * @cfg {Boolean} showInLegend
 
-      * Whether to add the pie chart elements as legend items. Default's false.
 
-      */
 
-     showInLegend: false,
 
- <span id='Ext-chart-series-Pie-cfg-colorSet'>    /**
 
- </span>     * @cfg {Array} colorSet
 
-      * An array of color values which will be used, in order, as the pie slice fill colors.
 
-      */
 
- <span id='Ext-chart-series-Pie-cfg-style'>    /**
 
- </span>     * @cfg {Object} style
 
-      * An object containing styles for overriding series styles from Theming.
 
-      */
 
-     style: {},
 
-     constructor: function(config) {
 
-         this.callParent(arguments);
 
-         var me = this,
 
-             chart = me.chart,
 
-             surface = chart.surface,
 
-             store = chart.store,
 
-             shadow = chart.shadow, i, l, cfg;
 
-         config.highlightCfg = Ext.merge({
 
-             segment: {
 
-                 margin: 20
 
-             }
 
-         }, config.highlightCfg);
 
-         Ext.apply(me, config, {
 
-             shadowAttributes: [{
 
-                 "stroke-width": 6,
 
-                 "stroke-opacity": 1,
 
-                 stroke: 'rgb(200, 200, 200)',
 
-                 translate: {
 
-                     x: 1.2,
 
-                     y: 2
 
-                 }
 
-             },
 
-             {
 
-                 "stroke-width": 4,
 
-                 "stroke-opacity": 1,
 
-                 stroke: 'rgb(150, 150, 150)',
 
-                 translate: {
 
-                     x: 0.9,
 
-                     y: 1.5
 
-                 }
 
-             },
 
-             {
 
-                 "stroke-width": 2,
 
-                 "stroke-opacity": 1,
 
-                 stroke: 'rgb(100, 100, 100)',
 
-                 translate: {
 
-                     x: 0.6,
 
-                     y: 1
 
-                 }
 
-             }]
 
-         });
 
-         me.group = surface.getGroup(me.seriesId);
 
-         if (shadow) {
 
-             for (i = 0, l = me.shadowAttributes.length; i < l; i++) {
 
-                 me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i));
 
-             }
 
-         }
 
-         surface.customAttributes.segment = function(opt) {
 
-             //Browsers will complain if we create a path
 
-             //element that has no path commands. So ensure a dummy 
 
-             //path command for an empty path.
 
-             var ans = me.getSegment(opt);
 
-             if (!ans.path || ans.path.length === 0) {
 
-                 ans.path = ['M', 0, 0];
 
-             }
 
-             return ans;
 
-         };
 
-         me.__excludes = me.__excludes || [];
 
-     },
 
-     // @private updates some onbefore render parameters.
 
-     initialize: function() {
 
-         var me = this,
 
-             store = me.chart.getChartStore(),
 
-             data = store.data.items,
 
-             i, ln, rec;
 
-         //Add yFields to be used in Legend.js
 
-         me.yField = [];
 
-         if (me.label.field) {
 
-             for (i = 0, ln = data.length; i < ln; i++) {
 
-                 rec = data[i];
 
-                 me.yField.push(rec.get(me.label.field));
 
-             }
 
-         }
 
-     },
 
-     // @private returns an object with properties for a PieSlice.
 
-     getSegment: function(opt) {
 
-         var me = this,
 
-             rad = me.rad,
 
-             cos = Math.cos,
 
-             sin = Math.sin,
 
-             x = me.centerX,
 
-             y = me.centerY,
 
-             x1 = 0, x2 = 0, x3 = 0, x4 = 0,
 
-             y1 = 0, y2 = 0, y3 = 0, y4 = 0,
 
-             x5 = 0, y5 = 0, x6 = 0, y6 = 0,
 
-             delta = 1e-2,
 
-             startAngle = opt.startAngle,
 
-             endAngle = opt.endAngle,
 
-             midAngle = (startAngle + endAngle) / 2 * rad,
 
-             margin = opt.margin || 0,
 
-             a1 = Math.min(startAngle, endAngle) * rad,
 
-             a2 = Math.max(startAngle, endAngle) * rad,
 
-             c1 = cos(a1), s1 = sin(a1),
 
-             c2 = cos(a2), s2 = sin(a2),
 
-             cm = cos(midAngle), sm = sin(midAngle),
 
-             flag = 0, hsqr2 = 0.7071067811865476; // sqrt(0.5)
 
-         if (a2 - a1 < delta) {
 
-             return {path: ""};
 
-         }
 
-         if (margin !== 0) {
 
-             x += margin * cm;
 
-             y += margin * sm;
 
-         }
 
-         x2 = x + opt.endRho * c1;
 
-         y2 = y + opt.endRho * s1;
 
-         x4 = x + opt.endRho * c2;
 
-         y4 = y + opt.endRho * s2;
 
-         x6 = x + opt.endRho * cm;
 
-         y6 = y + opt.endRho * sm;
 
-         if (opt.startRho !== 0) {
 
-             x1 = x + opt.startRho * c1;
 
-             y1 = y + opt.startRho * s1;
 
-     
 
-             x3 = x + opt.startRho * c2;
 
-             y3 = y + opt.startRho * s2;
 
-     
 
-             x5 = x + opt.startRho * cm;
 
-             y5 = y + opt.startRho * sm;
 
-             return {
 
-                 path: [
 
-                     ["M", x2, y2],
 
-                     ["A", opt.endRho, opt.endRho, 0, 0, 1, x6, y6], ["L", x6, y6],
 
-                     ["A", opt.endRho, opt.endRho, 0, flag, 1, x4, y4], ["L", x4, y4],
 
-                     ["L", x3, y3],
 
-                     ["A", opt.startRho, opt.startRho, 0, flag, 0, x5, y5], ["L", x5, y5],
 
-                     ["A", opt.startRho, opt.startRho, 0, 0, 0, x1, y1], ["L", x1, y1],
 
-                     ["Z"]
 
-                 ]
 
-             };
 
-         } else {
 
-             return {
 
-                 path: [
 
-                     ["M", x, y],
 
-                     ["L", x2, y2],
 
-                     ["A", opt.endRho, opt.endRho, 0, 0, 1, x6, y6], ["L", x6, y6],
 
-                     ["A", opt.endRho, opt.endRho, 0, flag, 1, x4, y4], ["L", x4, y4],
 
-                     ["L", x, y],
 
-                     ["Z"]
 
-                 ]
 
-             };
 
-         }
 
-     },
 
-     // @private utility function to calculate the middle point of a pie slice.
 
-     calcMiddle: function(item) {
 
-         var me = this,
 
-             rad = me.rad,
 
-             slice = item.slice,
 
-             x = me.centerX,
 
-             y = me.centerY,
 
-             startAngle = slice.startAngle,
 
-             endAngle = slice.endAngle,
 
-             donut = +me.donut,
 
-             midAngle = -(startAngle + endAngle) * rad / 2,
 
-             r = (item.endRho + item.startRho) / 2,
 
-             xm = x + r * Math.cos(midAngle),
 
-             ym = y - r * Math.sin(midAngle);
 
-         item.middle = {
 
-             x: xm,
 
-             y: ym
 
-         };
 
-     },
 
- <span id='Ext-chart-series-Pie-method-drawSeries'>    /**
 
- </span>     * Draws the series for the current chart.
 
-      */
 
-     drawSeries: function() {
 
-         var me = this,
 
-             store = me.chart.getChartStore(),
 
-             data = store.data.items,
 
-             record,
 
-             group = me.group,
 
-             animate = me.chart.animate,
 
-             field = me.angleField || me.field || me.xField,
 
-             lenField = [].concat(me.lengthField),
 
-             totalLenField = 0,
 
-             chart = me.chart,
 
-             surface = chart.surface,
 
-             chartBBox = chart.chartBBox,
 
-             enableShadows = chart.shadow,
 
-             shadowGroups = me.shadowGroups,
 
-             shadowAttributes = me.shadowAttributes,
 
-             lnsh = shadowGroups.length,
 
-             layers = lenField.length,
 
-             rhoAcum = 0,
 
-             donut = +me.donut,
 
-             layerTotals = [],
 
-             items = [],
 
-             totalField = 0,
 
-             maxLenField = 0,
 
-             angle = 0,
 
-             seriesStyle = me.seriesStyle,
 
-             colorArrayStyle = me.colorArrayStyle,
 
-             colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0,
 
-             rendererAttributes,
 
-             shadowAttr,
 
-             shadows,
 
-             shadow,
 
-             shindex,
 
-             centerX,
 
-             centerY,
 
-             deltaRho,
 
-             first = 0,
 
-             slice,
 
-             slices,
 
-             sprite,
 
-             value,
 
-             item,
 
-             lenValue,
 
-             ln,
 
-             i,
 
-             j,
 
-             endAngle,
 
-             path,
 
-             p,
 
-             spriteOptions, bbox;
 
-         Ext.apply(seriesStyle, me.style || {});
 
-         me.setBBox();
 
-         bbox = me.bbox;
 
-         //override theme colors
 
-         if (me.colorSet) {
 
-             colorArrayStyle = me.colorSet;
 
-             colorArrayLength = colorArrayStyle.length;
 
-         }
 
-         //if not store or store is empty then there's nothing to draw
 
-         if (!store || !store.getCount() || me.seriesIsHidden) {
 
-             me.hide();
 
-             me.items = [];
 
-             return;
 
-         }
 
-         me.unHighlightItem();
 
-         me.cleanHighlights();
 
-         centerX = me.centerX = chartBBox.x + (chartBBox.width / 2);
 
-         centerY = me.centerY = chartBBox.y + (chartBBox.height / 2);
 
-         me.radius = Math.min(centerX - chartBBox.x, centerY - chartBBox.y);
 
-         me.slices = slices = [];
 
-         me.items = items = [];
 
-         for (i = 0, ln = data.length; i < ln; i++) {
 
-             record = data[i];
 
-             if (this.__excludes && this.__excludes[i]) {
 
-                 //hidden series
 
-                 continue;
 
-             }
 
-             totalField += +record.get(field);
 
-             if (lenField[0]) {
 
-                 for (j = 0, totalLenField = 0; j < layers; j++) {
 
-                     totalLenField += +record.get(lenField[j]);
 
-                 }
 
-                 layerTotals[i] = totalLenField;
 
-                 maxLenField = Math.max(maxLenField, totalLenField);
 
-             }
 
-         }
 
-         totalField = totalField || 1;
 
-         for (i = 0, ln = data.length; i < ln; i++) {
 
-             record = data[i];
 
-             if (this.__excludes && this.__excludes[i]) {
 
-                 value = 0;
 
-             } else {
 
-                 value = record.get(field);
 
-                 if (first == 0) {
 
-                     first = 1;
 
-                 }
 
-             }
 
-             // First slice
 
-             if (first == 1) {
 
-                 first = 2;
 
-                 me.firstAngle = angle = me.accuracy * value / totalField / 2;
 
-                 for (j = 0; j < i; j++) {
 
-                     slices[j].startAngle = slices[j].endAngle = me.firstAngle;
 
-                 }
 
-             }
 
-             endAngle = angle - me.accuracy * value / totalField;
 
-             slice = {
 
-                 series: me,
 
-                 value: value,
 
-                 startAngle: angle,
 
-                 endAngle: endAngle,
 
-                 storeItem: record
 
-             };
 
-             if (lenField[0]) {
 
-                 lenValue = +layerTotals[i];
 
-                 //removing the floor will break Opera 11.6*
 
-                 slice.rho = Math.floor(me.radius / maxLenField * lenValue);
 
-             } else {
 
-                 slice.rho = me.radius;
 
-             }
 
-             slices[i] = slice;
 
-             // Do not remove this closure for the sake of https://sencha.jira.com/browse/EXTJSIV-5836
 
-             (function () {
 
-                 angle = endAngle;
 
-             })();
 
-         }
 
-         //do all shadows first.
 
-         if (enableShadows) {
 
-             for (i = 0, ln = slices.length; i < ln; i++) {
 
-                 slice = slices[i];
 
-                 slice.shadowAttrs = [];
 
-                 for (j = 0, rhoAcum = 0, shadows = []; j < layers; j++) {
 
-                     sprite = group.getAt(i * layers + j);
 
-                     deltaRho = lenField[j] ? store.getAt(i).get(lenField[j]) / layerTotals[i] * slice.rho: slice.rho;
 
-                     //set pie slice properties
 
-                     rendererAttributes = {
 
-                         segment: {
 
-                             startAngle: slice.startAngle,
 
-                             endAngle: slice.endAngle,
 
-                             margin: 0,
 
-                             rho: slice.rho,
 
-                             startRho: rhoAcum + (deltaRho * donut / 100),
 
-                             endRho: rhoAcum + deltaRho
 
-                         },
 
-                         hidden: !slice.value && (slice.startAngle % me.accuracy) == (slice.endAngle % me.accuracy)
 
-                     };
 
-                     //create shadows
 
-                     for (shindex = 0, shadows = []; shindex < lnsh; shindex++) {
 
-                         shadowAttr = shadowAttributes[shindex];
 
-                         shadow = shadowGroups[shindex].getAt(i);
 
-                         if (!shadow) {
 
-                             shadow = chart.surface.add(Ext.apply({}, {
 
-                                 type: 'path',
 
-                                 group: shadowGroups[shindex],
 
-                                 strokeLinejoin: "round"
 
-                             }, rendererAttributes, shadowAttr));
 
-                         }
 
-                         shadowAttr = me.renderer(shadow, store.getAt(i), Ext.apply({}, rendererAttributes, shadowAttr), i, store);
 
-                         if (animate) {
 
-                             me.onAnimate(shadow, {
 
-                                 to: shadowAttr
 
-                             });
 
-                         } else {
 
-                             shadow.setAttributes(shadowAttr, true);
 
-                         }
 
-                         shadows.push(shadow);
 
-                     }
 
-                     slice.shadowAttrs[j] = shadows;
 
-                 }
 
-             }
 
-         }
 
-         //do pie slices after.
 
-         for (i = 0, ln = slices.length; i < ln; i++) {
 
-             slice = slices[i];
 
-             for (j = 0, rhoAcum = 0; j < layers; j++) {
 
-                 sprite = group.getAt(i * layers + j);
 
-                 deltaRho = lenField[j] ? store.getAt(i).get(lenField[j]) / layerTotals[i] * slice.rho: slice.rho;
 
-                 //set pie slice properties
 
-                 rendererAttributes = Ext.apply({
 
-                     segment: {
 
-                         startAngle: slice.startAngle,
 
-                         endAngle: slice.endAngle,
 
-                         margin: 0,
 
-                         rho: slice.rho,
 
-                         startRho: rhoAcum + (deltaRho * donut / 100),
 
-                         endRho: rhoAcum + deltaRho
 
-                     },
 
-                     hidden: (!slice.value && (slice.startAngle % me.accuracy) == (slice.endAngle % me.accuracy))
 
-                 }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[(layers > 1? j : i) % colorArrayLength] } || {}));
 
-                 item = Ext.apply({},
 
-                 rendererAttributes.segment, {
 
-                     slice: slice,
 
-                     series: me,
 
-                     storeItem: slice.storeItem,
 
-                     index: i
 
-                 });
 
-                 me.calcMiddle(item);
 
-                 if (enableShadows) {
 
-                     item.shadows = slice.shadowAttrs[j];
 
-                 }
 
-                 items[i] = item;
 
-                 // Create a new sprite if needed (no height)
 
-                 if (!sprite) {
 
-                     spriteOptions = Ext.apply({
 
-                         type: "path",
 
-                         group: group,
 
-                         middle: item.middle
 
-                     }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[(layers > 1? j : i) % colorArrayLength] } || {}));
 
-                     sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes));
 
-                 }
 
-                 slice.sprite = slice.sprite || [];
 
-                 item.sprite = sprite;
 
-                 slice.sprite.push(sprite);
 
-                 slice.point = [item.middle.x, item.middle.y];
 
-                 if (animate) {
 
-                     rendererAttributes = me.renderer(sprite, store.getAt(i), rendererAttributes, i, store);
 
-                     sprite._to = rendererAttributes;
 
-                     sprite._animating = true;
 
-                     me.onAnimate(sprite, {
 
-                         to: rendererAttributes,
 
-                         listeners: {
 
-                             afteranimate: {
 
-                                 fn: function() {
 
-                                     this._animating = false;
 
-                                 },
 
-                                 scope: sprite
 
-                             }
 
-                         }
 
-                     });
 
-                 } else {
 
-                     rendererAttributes = me.renderer(sprite, store.getAt(i), Ext.apply(rendererAttributes, {
 
-                         hidden: false
 
-                     }), i, store);
 
-                     sprite.setAttributes(rendererAttributes, true);
 
-                 }
 
-                 rhoAcum += deltaRho;
 
-             }
 
-         }
 
-         // Hide unused bars
 
-         ln = group.getCount();
 
-         for (i = 0; i < ln; i++) {
 
-             if (!slices[(i / layers) >> 0] && group.getAt(i)) {
 
-                 group.getAt(i).hide(true);
 
-             }
 
-         }
 
-         if (enableShadows) {
 
-             lnsh = shadowGroups.length;
 
-             for (shindex = 0; shindex < ln; shindex++) {
 
-                 if (!slices[(shindex / layers) >> 0]) {
 
-                     for (j = 0; j < lnsh; j++) {
 
-                         if (shadowGroups[j].getAt(shindex)) {
 
-                             shadowGroups[j].getAt(shindex).hide(true);
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         me.renderLabels();
 
-         me.renderCallouts();
 
-     },
 
-     // @private callback for when creating a label sprite.
 
-     onCreateLabel: function(storeItem, item, i, display) {
 
-         var me = this,
 
-             group = me.labelsGroup,
 
-             config = me.label,
 
-             centerX = me.centerX,
 
-             centerY = me.centerY,
 
-             middle = item.middle,
 
-             endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config || {});
 
-         return me.chart.surface.add(Ext.apply({
 
-             'type': 'text',
 
-             'text-anchor': 'middle',
 
-             'group': group,
 
-             'x': middle.x,
 
-             'y': middle.y
 
-         }, endLabelStyle));
 
-     },
 
-     // @private callback for when placing a label sprite.
 
-     onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {
 
-         var me = this,
 
-             chart = me.chart,
 
-             resizing = chart.resizing,
 
-             config = me.label,
 
-             format = config.renderer,
 
-             field = [].concat(config.field),
 
-             centerX = me.centerX,
 
-             centerY = me.centerY,
 
-             middle = item.middle,
 
-             opt = {
 
-                 x: middle.x,
 
-                 y: middle.y
 
-             },
 
-             x = middle.x - centerX,
 
-             y = middle.y - centerY,
 
-             from = {},
 
-             rho = 1,
 
-             theta = Math.atan2(y, x || 1),
 
-             dg = theta * 180 / Math.PI,
 
-             prevDg;
 
-         opt.hidden = false;
 
-         if (this.__excludes && this.__excludes[i]) {
 
-             opt.hidden = true;
 
-         }
 
-         function fixAngle(a) {
 
-             if (a < 0) {
 
-                 a += 360;
 
-             }
 
-             return a % 360;
 
-         }
 
-         label.setAttributes({
 
-             text: format(storeItem.get(field[index]))
 
-         }, true);
 
-         switch (display) {
 
-         case 'outside':
 
-             rho = Math.sqrt(x * x + y * y) * 2;
 
-             //update positions
 
-             opt.x = rho * Math.cos(theta) + centerX;
 
-             opt.y = rho * Math.sin(theta) + centerY;
 
-             break;
 
-         case 'rotate':
 
-             dg = fixAngle(dg);
 
-             dg = (dg > 90 && dg < 270) ? dg + 180: dg;
 
-             prevDg = label.attr.rotation.degrees;
 
-             if (prevDg != null && Math.abs(prevDg - dg) > 180 * 0.5) {
 
-                 if (dg > prevDg) {
 
-                     dg -= 360;
 
-                 } else {
 
-                     dg += 360;
 
-                 }
 
-                 dg = dg % 360;
 
-             } else {
 
-                 dg = fixAngle(dg);
 
-             }
 
-             //update rotation angle
 
-             opt.rotate = {
 
-                 degrees: dg,
 
-                 x: opt.x,
 
-                 y: opt.y
 
-             };
 
-             break;
 
-         default:
 
-             break;
 
-         }
 
-         //ensure the object has zero translation
 
-         opt.translate = {
 
-             x: 0, y: 0
 
-         };
 
-         if (animate && !resizing && (display != 'rotate' || prevDg != null)) {
 
-             me.onAnimate(label, {
 
-                 to: opt
 
-             });
 
-         } else {
 
-             label.setAttributes(opt, true);
 
-         }
 
-         label._from = from;
 
-     },
 
-     // @private callback for when placing a callout sprite.
 
-     onPlaceCallout: function(callout, storeItem, item, i, display, animate, index) {
 
-         var me = this,
 
-             chart = me.chart,
 
-             centerX = me.centerX,
 
-             centerY = me.centerY,
 
-             middle = item.middle,
 
-             opt = {
 
-                 x: middle.x,
 
-                 y: middle.y
 
-             },
 
-             x = middle.x - centerX,
 
-             y = middle.y - centerY,
 
-             rho = 1,
 
-             rhoCenter,
 
-             theta = Math.atan2(y, x || 1),
 
-             bbox = callout.label.getBBox(),
 
-             offsetFromViz = 20,
 
-             offsetToSide = 10,
 
-             offsetBox = 10,
 
-             p;
 
-         //should be able to config this.
 
-         rho = item.endRho + offsetFromViz;
 
-         rhoCenter = (item.endRho + item.startRho) / 2 + (item.endRho - item.startRho) / 3;
 
-         //update positions
 
-         opt.x = rho * Math.cos(theta) + centerX;
 
-         opt.y = rho * Math.sin(theta) + centerY;
 
-         x = rhoCenter * Math.cos(theta);
 
-         y = rhoCenter * Math.sin(theta);
 
-         if (chart.animate) {
 
-             //set the line from the middle of the pie to the box.
 
-             me.onAnimate(callout.lines, {
 
-                 to: {
 
-                     path: ["M", x + centerX, y + centerY, "L", opt.x, opt.y, "Z", "M", opt.x, opt.y, "l", x > 0 ? offsetToSide: -offsetToSide, 0, "z"]
 
-                 }
 
-             });
 
-             //set box position
 
-             me.onAnimate(callout.box, {
 
-                 to: {
 
-                     x: opt.x + (x > 0 ? offsetToSide: -(offsetToSide + bbox.width + 2 * offsetBox)),
 
-                     y: opt.y + (y > 0 ? ( - bbox.height - offsetBox / 2) : ( - bbox.height - offsetBox / 2)),
 
-                     width: bbox.width + 2 * offsetBox,
 
-                     height: bbox.height + 2 * offsetBox
 
-                 }
 
-             });
 
-             //set text position
 
-             me.onAnimate(callout.label, {
 
-                 to: {
 
-                     x: opt.x + (x > 0 ? (offsetToSide + offsetBox) : -(offsetToSide + bbox.width + offsetBox)),
 
-                     y: opt.y + (y > 0 ? -bbox.height / 4: -bbox.height / 4)
 
-                 }
 
-             });
 
-         } else {
 
-             //set the line from the middle of the pie to the box.
 
-             callout.lines.setAttributes({
 
-                 path: ["M", x + centerX, y + centerY, "L", opt.x, opt.y, "Z", "M", opt.x, opt.y, "l", x > 0 ? offsetToSide: -offsetToSide, 0, "z"]
 
-             },
 
-             true);
 
-             //set box position
 
-             callout.box.setAttributes({
 
-                 x: opt.x + (x > 0 ? offsetToSide: -(offsetToSide + bbox.width + 2 * offsetBox)),
 
-                 y: opt.y + (y > 0 ? ( - bbox.height - offsetBox / 2) : ( - bbox.height - offsetBox / 2)),
 
-                 width: bbox.width + 2 * offsetBox,
 
-                 height: bbox.height + 2 * offsetBox
 
-             },
 
-             true);
 
-             //set text position
 
-             callout.label.setAttributes({
 
-                 x: opt.x + (x > 0 ? (offsetToSide + offsetBox) : -(offsetToSide + bbox.width + offsetBox)),
 
-                 y: opt.y + (y > 0 ? -bbox.height / 4: -bbox.height / 4)
 
-             },
 
-             true);
 
-         }
 
-         for (p in callout) {
 
-             callout[p].show(true);
 
-         }
 
-     },
 
-     // @private handles sprite animation for the series.
 
-     onAnimate: function(sprite, attr) {
 
-         sprite.show();
 
-         return this.callParent(arguments);
 
-     },
 
-     isItemInPoint: function(x, y, item, i) {
 
-         var me = this,
 
-             cx = me.centerX,
 
-             cy = me.centerY,
 
-             abs = Math.abs,
 
-             dx = abs(x - cx),
 
-             dy = abs(y - cy),
 
-             startAngle = item.startAngle,
 
-             endAngle = item.endAngle,
 
-             rho = Math.sqrt(dx * dx + dy * dy),
 
-             angle = Math.atan2(y - cy, x - cx) / me.rad;
 
-         // normalize to the same range of angles created by drawSeries
 
-         if (angle > me.firstAngle) {
 
-             angle -= me.accuracy;
 
-         }
 
-         return (angle <= startAngle && angle > endAngle
 
-                 && rho >= item.startRho && rho <= item.endRho);
 
-     },
 
-     // @private hides all elements in the series.
 
-     hideAll: function(index) {
 
-         var i, l, shadow, shadows, sh, lsh, sprite;
 
-         index = (isNaN(this._index) ? index : this._index) || 0;
 
-         this.__excludes = this.__excludes || [];
 
-         this.__excludes[index] = true;
 
-         sprite = this.slices[index].sprite;
 
-         for (sh = 0, lsh = sprite.length; sh < lsh; sh++) {
 
-             sprite[sh].setAttributes({
 
-                 hidden: true
 
-             }, true);
 
-         }
 
-         if (this.slices[index].shadowAttrs) {
 
-             for (i = 0, shadows = this.slices[index].shadowAttrs, l = shadows.length; i < l; i++) {
 
-                 shadow = shadows[i];
 
-                 for (sh = 0, lsh = shadow.length; sh < lsh; sh++) {
 
-                     shadow[sh].setAttributes({
 
-                         hidden: true
 
-                     }, true);
 
-                 }
 
-             }
 
-         }
 
-         this.drawSeries();
 
-     },
 
-     // @private shows all elements in the series.
 
-     showAll: function(index) {
 
-         index = (isNaN(this._index) ? index : this._index) || 0;
 
-         this.__excludes[index] = false;
 
-         this.drawSeries();
 
-     },
 
- <span id='Ext-chart-series-Pie-method-highlightItem'>    /**
 
- </span>     * Highlight the specified item. If no item is provided the whole series will be highlighted.
 
-      * @param item {Object} Info about the item; same format as returned by #getItemForPoint
 
-      */
 
-     highlightItem: function(item) {
 
-         var me = this,
 
-             rad = me.rad,
 
-             highlightSegment,
 
-             animate,
 
-             attrs,
 
-             i,
 
-             shadows,
 
-             shadow,
 
-             ln,
 
-             to,
 
-             itemHighlightSegment,
 
-             prop,
 
-             group,
 
-             display,
 
-             label,
 
-             middle,
 
-             r,
 
-             x,
 
-             y;
 
-         item = item || this.items[this._index];
 
-         //TODO(nico): sometimes in IE itemmouseover is triggered
 
-         //twice without triggering itemmouseout in between. This
 
-         //fixes the highlighting bug. Eventually, events should be
 
-         //changed to trigger one itemmouseout between two itemmouseovers.
 
-         this.unHighlightItem();
 
-         if (!item || me.animating || (item.sprite && item.sprite._animating)) {
 
-             return;
 
-         }
 
-         me.callParent([item]);
 
-         if (!me.highlight) {
 
-             return;
 
-         }
 
-         if ('segment' in me.highlightCfg) {
 
-             highlightSegment = me.highlightCfg.segment;
 
-             animate = me.chart.animate;
 
-             //animate labels
 
-             if (me.labelsGroup) {
 
-                 group = me.labelsGroup;
 
-                 display = me.label.display;
 
-                 label = group.getAt(item.index);
 
-                 middle = (item.startAngle + item.endAngle) / 2 * rad;
 
-                 r = highlightSegment.margin || 0;
 
-                 x = r * Math.cos(middle);
 
-                 y = r * Math.sin(middle);
 
-                 //TODO(nico): rounding to 1e-10
 
-                 //gives the right translation. Translation
 
-                 //was buggy for very small numbers. In this
 
-                 //case we're not looking to translate to very small
 
-                 //numbers but not to translate at all.
 
-                 if (Math.abs(x) < 1e-10) {
 
-                     x = 0;
 
-                 }
 
-                 if (Math.abs(y) < 1e-10) {
 
-                     y = 0;
 
-                 }
 
-                 if (animate) {
 
-                     label.stopAnimation();
 
-                     label.animate({
 
-                         to: {
 
-                             translate: {
 
-                                 x: x,
 
-                                 y: y
 
-                             }
 
-                         },
 
-                         duration: me.highlightDuration
 
-                     });
 
-                 }
 
-                 else {
 
-                     label.setAttributes({
 
-                         translate: {
 
-                             x: x,
 
-                             y: y
 
-                         }
 
-                     }, true);
 
-                 }
 
-             }
 
-             //animate shadows
 
-             if (me.chart.shadow && item.shadows) {
 
-                 i = 0;
 
-                 shadows = item.shadows;
 
-                 ln = shadows.length;
 
-                 for (; i < ln; i++) {
 
-                     shadow = shadows[i];
 
-                     to = {};
 
-                     itemHighlightSegment = item.sprite._from.segment;
 
-                     for (prop in itemHighlightSegment) {
 
-                         if (! (prop in highlightSegment)) {
 
-                             to[prop] = itemHighlightSegment[prop];
 
-                         }
 
-                     }
 
-                     attrs = {
 
-                         segment: Ext.applyIf(to, me.highlightCfg.segment)
 
-                     };
 
-                     if (animate) {
 
-                         shadow.stopAnimation();
 
-                         shadow.animate({
 
-                             to: attrs,
 
-                             duration: me.highlightDuration
 
-                         });
 
-                     }
 
-                     else {
 
-                         shadow.setAttributes(attrs, true);
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-     },
 
- <span id='Ext-chart-series-Pie-method-unHighlightItem'>    /**
 
- </span>     * Un-highlights the specified item. If no item is provided it will un-highlight the entire series.
 
-      * @param item {Object} Info about the item; same format as returned by #getItemForPoint
 
-      */
 
-     unHighlightItem: function() {
 
-         var me = this,
 
-             items,
 
-             animate,
 
-             shadowsEnabled,
 
-             group,
 
-             len,
 
-             i,
 
-             j,
 
-             display,
 
-             shadowLen,
 
-             p,
 
-             to,
 
-             ihs,
 
-             hs,
 
-             sprite,
 
-             shadows,
 
-             shadow,
 
-             item,
 
-             label,
 
-             attrs;
 
-         if (!me.highlight) {
 
-             return;
 
-         }
 
-         if (('segment' in me.highlightCfg) && me.items) {
 
-             items = me.items;
 
-             animate = me.chart.animate;
 
-             shadowsEnabled = !!me.chart.shadow;
 
-             group = me.labelsGroup;
 
-             len = items.length;
 
-             i = 0;
 
-             j = 0;
 
-             display = me.label.display;
 
-             for (; i < len; i++) {
 
-                 item = items[i];
 
-                 if (!item) {
 
-                     continue;
 
-                 }
 
-                 sprite = item.sprite;
 
-                 if (sprite && sprite._highlighted) {
 
-                     //animate labels
 
-                     if (group) {
 
-                         label = group.getAt(item.index);
 
-                         attrs = Ext.apply({
 
-                             translate: {
 
-                                 x: 0,
 
-                                 y: 0
 
-                             }
 
-                         },
 
-                         display == 'rotate' ? {
 
-                             rotate: {
 
-                                 x: label.attr.x,
 
-                                 y: label.attr.y,
 
-                                 degrees: label.attr.rotation.degrees
 
-                             }
 
-                         }: {});
 
-                         if (animate) {
 
-                             label.stopAnimation();
 
-                             label.animate({
 
-                                 to: attrs,
 
-                                 duration: me.highlightDuration
 
-                             });
 
-                         }
 
-                         else {
 
-                             label.setAttributes(attrs, true);
 
-                         }
 
-                     }
 
-                     if (shadowsEnabled) {
 
-                         shadows = item.shadows;
 
-                         shadowLen = shadows.length;
 
-                         for (; j < shadowLen; j++) {
 
-                             to = {};
 
-                             ihs = item.sprite._to.segment;
 
-                             hs = item.sprite._from.segment;
 
-                             Ext.apply(to, hs);
 
-                             for (p in ihs) {
 
-                                 if (! (p in hs)) {
 
-                                     to[p] = ihs[p];
 
-                                 }
 
-                             }
 
-                             shadow = shadows[j];
 
-                             if (animate) {
 
-                                 shadow.stopAnimation();
 
-                                 shadow.animate({
 
-                                     to: {
 
-                                         segment: to
 
-                                     },
 
-                                     duration: me.highlightDuration
 
-                                 });
 
-                             }
 
-                             else {
 
-                                 shadow.setAttributes({ segment: to }, true);
 
-                             }
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         me.callParent(arguments);
 
-     },
 
- <span id='Ext-chart-series-Pie-method-getLegendColor'>    /**
 
- </span>     * Returns the color of the series (to be displayed as color for the series legend item).
 
-      * @param item {Object} Info about the item; same format as returned by #getItemForPoint
 
-      */
 
-     getLegendColor: function(index) {
 
-         var me = this;
 
-         return (me.colorSet && me.colorSet[index % me.colorSet.length]) || me.colorArrayStyle[index % me.colorArrayStyle.length];
 
-     }
 
- });
 
- </pre>
 
- </body>
 
- </html>
 
 
  |