Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / docs / source / Area.html
1 <!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-chart.series.Area'>/**
2 </span> * @class Ext.chart.series.Area
3  * @extends Ext.chart.series.Cartesian
4  * 
5  &lt;p&gt;
6     Creates a Stacked Area Chart. The stacked area chart is useful when displaying multiple aggregated layers of information.
7     As with all other series, the Area Series must be appended in the *series* Chart array configuration. See the Chart 
8     documentation for more information. A typical configuration object for the area series could be:
9  &lt;/p&gt;
10 {@img Ext.chart.series.Area/Ext.chart.series.Area.png Ext.chart.series.Area chart series} 
11   &lt;pre&gt;&lt;code&gt;
12    var store = Ext.create('Ext.data.JsonStore', {
13         fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
14         data: [
15             {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
16             {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
17             {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
18             {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
19             {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}                                                
20         ]
21     });
22     
23     Ext.create('Ext.chart.Chart', {
24         renderTo: Ext.getBody(),
25         width: 500,
26         height: 300,
27         store: store,
28         axes: [{
29             type: 'Numeric',
30             grid: true,
31             position: 'left',
32             fields: ['data1', 'data2', 'data3', 'data4', 'data5'],
33             title: 'Sample Values',
34             grid: {
35                 odd: {
36                     opacity: 1,
37                     fill: '#ddd',
38                     stroke: '#bbb',
39                     'stroke-width': 1
40                 }
41             },
42             minimum: 0,
43             adjustMinimumByMajorUnit: 0
44         }, {
45             type: 'Category',
46             position: 'bottom',
47             fields: ['name'],
48             title: 'Sample Metrics',
49             grid: true,
50             label: {
51                 rotate: {
52                     degrees: 315
53                 }
54             }
55         }],
56         series: [{
57             type: 'area',
58             highlight: false,
59             axis: 'left',
60             xField: 'name',
61             yField: ['data1', 'data2', 'data3', 'data4', 'data5'],
62             style: {
63                 opacity: 0.93
64             }
65         }]
66     });
67    &lt;/code&gt;&lt;/pre&gt;
68  
69   
70  &lt;p&gt;
71   In this configuration we set `area` as the type for the series, set highlighting options to true for highlighting elements on hover, 
72   take the left axis to measure the data in the area series, set as xField (x values) the name field of each element in the store, 
73   and as yFields (aggregated layers) seven data fields from the same store. Then we override some theming styles by adding some opacity 
74   to the style object.
75  &lt;/p&gt;
76   
77  * @xtype area
78  * 
79  */
80 Ext.define('Ext.chart.series.Area', {
81
82     /* Begin Definitions */
83
84     extend: 'Ext.chart.series.Cartesian',
85     
86     alias: 'series.area',
87
88     requires: ['Ext.chart.axis.Axis', 'Ext.draw.Color', 'Ext.fx.Anim'],
89
90     /* End Definitions */
91
92     type: 'area',
93
94     // @private Area charts are alyways stacked
95     stacked: true,
96
97 <span id='Ext-chart.series.Area-cfg-style'>    /**
98 </span>     * @cfg {Object} style 
99      * Append styling properties to this object for it to override theme properties.
100      */
101     style: {},
102
103     constructor: function(config) {
104         this.callParent(arguments);
105         var me = this,
106             surface = me.chart.surface,
107             i, l;
108         Ext.apply(me, config, {
109             __excludes: [],
110             highlightCfg: {
111                 lineWidth: 3,
112                 stroke: '#55c',
113                 opacity: 0.8,
114                 color: '#f00'
115             }
116         });
117         if (me.highlight) {
118             me.highlightSprite = surface.add({
119                 type: 'path',
120                 path: ['M', 0, 0],
121                 zIndex: 1000,
122                 opacity: 0.3,
123                 lineWidth: 5,
124                 hidden: true,
125                 stroke: '#444'
126             });
127         }
128         me.group = surface.getGroup(me.seriesId);
129     },
130
131     // @private Shrinks dataSets down to a smaller size
132     shrink: function(xValues, yValues, size) {
133         var len = xValues.length,
134             ratio = Math.floor(len / size),
135             i, j,
136             xSum = 0,
137             yCompLen = this.areas.length,
138             ySum = [],
139             xRes = [],
140             yRes = [];
141         //initialize array
142         for (j = 0; j &lt; yCompLen; ++j) {
143             ySum[j] = 0;
144         }
145         for (i = 0; i &lt; len; ++i) {
146             xSum += xValues[i];
147             for (j = 0; j &lt; yCompLen; ++j) {
148                 ySum[j] += yValues[i][j];
149             }
150             if (i % ratio == 0) {
151                 //push averages
152                 xRes.push(xSum/ratio);
153                 for (j = 0; j &lt; yCompLen; ++j) {
154                     ySum[j] /= ratio;
155                 }
156                 yRes.push(ySum);
157                 //reset sum accumulators
158                 xSum = 0;
159                 for (j = 0, ySum = []; j &lt; yCompLen; ++j) {
160                     ySum[j] = 0;
161                 }
162             }
163         }
164         return {
165             x: xRes,
166             y: yRes
167         };
168     },
169
170     // @private Get chart and data boundaries
171     getBounds: function() {
172         var me = this,
173             chart = me.chart,
174             store = chart.substore || chart.store,
175             areas = [].concat(me.yField),
176             areasLen = areas.length,
177             xValues = [],
178             yValues = [],
179             infinity = Infinity,
180             minX = infinity,
181             minY = infinity,
182             maxX = -infinity,
183             maxY = -infinity,
184             math = Math,
185             mmin = math.min,
186             mmax = math.max,
187             bbox, xScale, yScale, xValue, yValue, areaIndex, acumY, ln, sumValues, clipBox, areaElem;
188
189         me.setBBox();
190         bbox = me.bbox;
191
192         // Run through the axis
193         if (me.axis) {
194             axis = chart.axes.get(me.axis);
195             if (axis) {
196                 out = axis.calcEnds();
197                 minY = out.from || axis.prevMin;
198                 maxY = mmax(out.to || axis.prevMax, 0);
199             }
200         }
201
202         if (me.yField &amp;&amp; !Ext.isNumber(minY)) {
203             axis = Ext.create('Ext.chart.axis.Axis', {
204                 chart: chart,
205                 fields: [].concat(me.yField)
206             });
207             out = axis.calcEnds();
208             minY = out.from || axis.prevMin;
209             maxY = mmax(out.to || axis.prevMax, 0);
210         }
211
212         if (!Ext.isNumber(minY)) {
213             minY = 0;
214         }
215         if (!Ext.isNumber(maxY)) {
216             maxY = 0;
217         }
218
219         store.each(function(record, i) {
220             xValue = record.get(me.xField);
221             yValue = [];
222             if (typeof xValue != 'number') {
223                 xValue = i;
224             }
225             xValues.push(xValue);
226             acumY = 0;
227             for (areaIndex = 0; areaIndex &lt; areasLen; areaIndex++) {
228                 areaElem = record.get(areas[areaIndex]);
229                 if (typeof areaElem == 'number') {
230                     minY = mmin(minY, areaElem);
231                     yValue.push(areaElem);
232                     acumY += areaElem;
233                 }
234             }
235             minX = mmin(minX, xValue);
236             maxX = mmax(maxX, xValue);
237             maxY = mmax(maxY, acumY);
238             yValues.push(yValue);
239         }, me);
240
241         xScale = bbox.width / (maxX - minX);
242         yScale = bbox.height / (maxY - minY);
243
244         ln = xValues.length;
245         if ((ln &gt; bbox.width) &amp;&amp; me.areas) {
246             sumValues = me.shrink(xValues, yValues, bbox.width);
247             xValues = sumValues.x;
248             yValues = sumValues.y;
249         }
250
251         return {
252             bbox: bbox,
253             minX: minX,
254             minY: minY,
255             xValues: xValues,
256             yValues: yValues,
257             xScale: xScale,
258             yScale: yScale,
259             areasLen: areasLen
260         };
261     },
262
263     // @private Build an array of paths for the chart
264     getPaths: function() {
265         var me = this,
266             chart = me.chart,
267             store = chart.substore || chart.store,
268             first = true,
269             bounds = me.getBounds(),
270             bbox = bounds.bbox,
271             items = me.items = [],
272             componentPaths = [],
273             componentPath,
274             paths = [],
275             i, ln, x, y, xValue, yValue, acumY, areaIndex, prevAreaIndex, areaElem, path;
276
277         ln = bounds.xValues.length;
278         // Start the path
279         for (i = 0; i &lt; ln; i++) {
280             xValue = bounds.xValues[i];
281             yValue = bounds.yValues[i];
282             x = bbox.x + (xValue - bounds.minX) * bounds.xScale;
283             acumY = 0;
284             for (areaIndex = 0; areaIndex &lt; bounds.areasLen; areaIndex++) {
285                 // Excluded series
286                 if (me.__excludes[areaIndex]) {
287                     continue;
288                 }
289                 if (!componentPaths[areaIndex]) {
290                     componentPaths[areaIndex] = [];
291                 }
292                 areaElem = yValue[areaIndex];
293                 acumY += areaElem;
294                 y = bbox.y + bbox.height - (acumY - bounds.minY) * bounds.yScale;
295                 if (!paths[areaIndex]) {
296                     paths[areaIndex] = ['M', x, y];
297                     componentPaths[areaIndex].push(['L', x, y]);
298                 } else {
299                     paths[areaIndex].push('L', x, y);
300                     componentPaths[areaIndex].push(['L', x, y]);
301                 }
302                 if (!items[areaIndex]) {
303                     items[areaIndex] = {
304                         pointsUp: [],
305                         pointsDown: [],
306                         series: me
307                     };
308                 }
309                 items[areaIndex].pointsUp.push([x, y]);
310             }
311         }
312         
313         // Close the paths
314         for (areaIndex = 0; areaIndex &lt; bounds.areasLen; areaIndex++) {
315             // Excluded series
316             if (me.__excludes[areaIndex]) {
317                 continue;
318             }
319             path = paths[areaIndex];
320             // Close bottom path to the axis
321             if (areaIndex == 0 || first) {
322                 first = false;
323                 path.push('L', x, bbox.y + bbox.height,
324                           'L', bbox.x, bbox.y + bbox.height,
325                           'Z');
326             }
327             // Close other paths to the one before them
328             else {
329                 componentPath = componentPaths[prevAreaIndex];
330                 componentPath.reverse();
331                 path.push('L', x, componentPath[0][2]);
332                 for (i = 0; i &lt; ln; i++) {
333                     path.push(componentPath[i][0],
334                               componentPath[i][1],
335                               componentPath[i][2]);
336                     items[areaIndex].pointsDown[ln -i -1] = [componentPath[i][1], componentPath[i][2]];
337                 }
338                 path.push('L', bbox.x, path[2], 'Z');
339             }
340             prevAreaIndex = areaIndex;
341         }
342         return {
343             paths: paths,
344             areasLen: bounds.areasLen
345         };
346     },
347
348 <span id='Ext-chart.series.Area-method-drawSeries'>    /**
349 </span>     * Draws the series for the current chart.
350      */
351     drawSeries: function() {
352         var me = this,
353             chart = me.chart,
354             store = chart.substore || chart.store,
355             surface = chart.surface,
356             animate = chart.animate,
357             group = me.group,
358             endLineStyle = Ext.apply(me.seriesStyle, me.style),
359             colorArrayStyle = me.colorArrayStyle,
360             colorArrayLength = colorArrayStyle &amp;&amp; colorArrayStyle.length || 0,
361             areaIndex, areaElem, paths, path, rendererAttributes;
362
363         me.unHighlightItem();
364         me.cleanHighlights();
365
366         if (!store || !store.getCount()) {
367             return;
368         }
369         
370         paths = me.getPaths();
371
372         if (!me.areas) {
373             me.areas = [];
374         }
375
376         for (areaIndex = 0; areaIndex &lt; paths.areasLen; areaIndex++) {
377             // Excluded series
378             if (me.__excludes[areaIndex]) {
379                 continue;
380             }
381             if (!me.areas[areaIndex]) {
382                 me.items[areaIndex].sprite = me.areas[areaIndex] = surface.add(Ext.apply({}, {
383                     type: 'path',
384                     group: group,
385                     // 'clip-rect': me.clipBox,
386                     path: paths.paths[areaIndex],
387                     stroke: endLineStyle.stroke || colorArrayStyle[areaIndex % colorArrayLength],
388                     fill: colorArrayStyle[areaIndex % colorArrayLength]
389                 }, endLineStyle || {}));
390             }
391             areaElem = me.areas[areaIndex];
392             path = paths.paths[areaIndex];
393             if (animate) {
394                 //Add renderer to line. There is not a unique record associated with this.
395                 rendererAttributes = me.renderer(areaElem, false, { 
396                     path: path,
397                     // 'clip-rect': me.clipBox,
398                     fill: colorArrayStyle[areaIndex % colorArrayLength],
399                     stroke: endLineStyle.stroke || colorArrayStyle[areaIndex % colorArrayLength]
400                 }, areaIndex, store);
401                 //fill should not be used here but when drawing the special fill path object
402                 me.animation = me.onAnimate(areaElem, {
403                     to: rendererAttributes
404                 });
405             } else {
406                 rendererAttributes = me.renderer(areaElem, false, { 
407                     path: path,
408                     // 'clip-rect': me.clipBox,
409                     hidden: false,
410                     fill: colorArrayStyle[areaIndex % colorArrayLength],
411                     stroke: endLineStyle.stroke || colorArrayStyle[areaIndex % colorArrayLength]
412                 }, areaIndex, store);
413                 me.areas[areaIndex].setAttributes(rendererAttributes, true);
414             }
415         }
416         me.renderLabels();
417         me.renderCallouts();
418     },
419
420     // @private
421     onAnimate: function(sprite, attr) {
422         sprite.show();
423         return this.callParent(arguments);
424     },
425
426     // @private
427     onCreateLabel: function(storeItem, item, i, display) {
428         var me = this,
429             group = me.labelsGroup,
430             config = me.label,
431             bbox = me.bbox,
432             endLabelStyle = Ext.apply(config, me.seriesLabelStyle);
433
434         return me.chart.surface.add(Ext.apply({
435             'type': 'text',
436             'text-anchor': 'middle',
437             'group': group,
438             'x': item.point[0],
439             'y': bbox.y + bbox.height / 2
440         }, endLabelStyle || {}));
441     },
442
443     // @private
444     onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {
445         var me = this,
446             chart = me.chart,
447             resizing = chart.resizing,
448             config = me.label,
449             format = config.renderer,
450             field = config.field,
451             bbox = me.bbox,
452             x = item.point[0],
453             y = item.point[1],
454             bb, width, height;
455         
456         label.setAttributes({
457             text: format(storeItem.get(field[index])),
458             hidden: true
459         }, true);
460         
461         bb = label.getBBox();
462         width = bb.width / 2;
463         height = bb.height / 2;
464         
465         x = x - width &lt; bbox.x? bbox.x + width : x;
466         x = (x + width &gt; bbox.x + bbox.width) ? (x - (x + width - bbox.x - bbox.width)) : x;
467         y = y - height &lt; bbox.y? bbox.y + height : y;
468         y = (y + height &gt; bbox.y + bbox.height) ? (y - (y + height - bbox.y - bbox.height)) : y;
469
470         if (me.chart.animate &amp;&amp; !me.chart.resizing) {
471             label.show(true);
472             me.onAnimate(label, {
473                 to: {
474                     x: x,
475                     y: y
476                 }
477             });
478         } else {
479             label.setAttributes({
480                 x: x,
481                 y: y
482             }, true);
483             if (resizing) {
484                 me.animation.on('afteranimate', function() {
485                     label.show(true);
486                 });
487             } else {
488                 label.show(true);
489             }
490         }
491     },
492
493     // @private
494     onPlaceCallout : function(callout, storeItem, item, i, display, animate, index) {
495         var me = this,
496             chart = me.chart,
497             surface = chart.surface,
498             resizing = chart.resizing,
499             config = me.callouts,
500             items = me.items,
501             prev = (i == 0) ? false : items[i -1].point,
502             next = (i == items.length -1) ? false : items[i +1].point,
503             cur = item.point,
504             dir, norm, normal, a, aprev, anext,
505             bbox = callout.label.getBBox(),
506             offsetFromViz = 30,
507             offsetToSide = 10,
508             offsetBox = 3,
509             boxx, boxy, boxw, boxh,
510             p, clipRect = me.clipRect,
511             x, y;
512
513         //get the right two points
514         if (!prev) {
515             prev = cur;
516         }
517         if (!next) {
518             next = cur;
519         }
520         a = (next[1] - prev[1]) / (next[0] - prev[0]);
521         aprev = (cur[1] - prev[1]) / (cur[0] - prev[0]);
522         anext = (next[1] - cur[1]) / (next[0] - cur[0]);
523         
524         norm = Math.sqrt(1 + a * a);
525         dir = [1 / norm, a / norm];
526         normal = [-dir[1], dir[0]];
527         
528         //keep the label always on the outer part of the &quot;elbow&quot;
529         if (aprev &gt; 0 &amp;&amp; anext &lt; 0 &amp;&amp; normal[1] &lt; 0 || aprev &lt; 0 &amp;&amp; anext &gt; 0 &amp;&amp; normal[1] &gt; 0) {
530             normal[0] *= -1;
531             normal[1] *= -1;
532         } else if (Math.abs(aprev) &lt; Math.abs(anext) &amp;&amp; normal[0] &lt; 0 || Math.abs(aprev) &gt; Math.abs(anext) &amp;&amp; normal[0] &gt; 0) {
533             normal[0] *= -1;
534             normal[1] *= -1;
535         }
536
537         //position
538         x = cur[0] + normal[0] * offsetFromViz;
539         y = cur[1] + normal[1] * offsetFromViz;
540         
541         //box position and dimensions
542         boxx = x + (normal[0] &gt; 0? 0 : -(bbox.width + 2 * offsetBox));
543         boxy = y - bbox.height /2 - offsetBox;
544         boxw = bbox.width + 2 * offsetBox;
545         boxh = bbox.height + 2 * offsetBox;
546         
547         //now check if we're out of bounds and invert the normal vector correspondingly
548         //this may add new overlaps between labels (but labels won't be out of bounds).
549         if (boxx &lt; clipRect[0] || (boxx + boxw) &gt; (clipRect[0] + clipRect[2])) {
550             normal[0] *= -1;
551         }
552         if (boxy &lt; clipRect[1] || (boxy + boxh) &gt; (clipRect[1] + clipRect[3])) {
553             normal[1] *= -1;
554         }
555
556         //update positions
557         x = cur[0] + normal[0] * offsetFromViz;
558         y = cur[1] + normal[1] * offsetFromViz;
559         
560         //update box position and dimensions
561         boxx = x + (normal[0] &gt; 0? 0 : -(bbox.width + 2 * offsetBox));
562         boxy = y - bbox.height /2 - offsetBox;
563         boxw = bbox.width + 2 * offsetBox;
564         boxh = bbox.height + 2 * offsetBox;
565         
566         //set the line from the middle of the pie to the box.
567         callout.lines.setAttributes({
568             path: [&quot;M&quot;, cur[0], cur[1], &quot;L&quot;, x, y, &quot;Z&quot;]
569         }, true);
570         //set box position
571         callout.box.setAttributes({
572             x: boxx,
573             y: boxy,
574             width: boxw,
575             height: boxh
576         }, true);
577         //set text position
578         callout.label.setAttributes({
579             x: x + (normal[0] &gt; 0? offsetBox : -(bbox.width + offsetBox)),
580             y: y
581         }, true);
582         for (p in callout) {
583             callout[p].show(true);
584         }
585     },
586     
587     isItemInPoint: function(x, y, item, i) {
588         var me = this,
589             pointsUp = item.pointsUp,
590             pointsDown = item.pointsDown,
591             abs = Math.abs,
592             dist = Infinity, p, pln, point;
593         
594         for (p = 0, pln = pointsUp.length; p &lt; pln; p++) {
595             point = [pointsUp[p][0], pointsUp[p][1]];
596             if (dist &gt; abs(x - point[0])) {
597                 dist = abs(x - point[0]);
598             } else {
599                 point = pointsUp[p -1];
600                 if (y &gt;= point[1] &amp;&amp; (!pointsDown.length || y &lt;= (pointsDown[p -1][1]))) {
601                     item.storeIndex = p -1;
602                     item.storeField = me.yField[i];
603                     item.storeItem = me.chart.store.getAt(p -1);
604                     item._points = pointsDown.length? [point, pointsDown[p -1]] : [point];
605                     return true;
606                 } else {
607                     break;
608                 }
609             }
610         }
611         return false;
612     },
613
614 <span id='Ext-chart.series.Area-method-highlightSeries'>    /**
615 </span>     * Highlight this entire series.
616      * @param {Object} item Info about the item; same format as returned by #getItemForPoint.
617      */
618     highlightSeries: function() {
619         var area, to, fillColor;
620         if (this._index !== undefined) {
621             area = this.areas[this._index];
622             if (area.__highlightAnim) {
623                 area.__highlightAnim.paused = true;
624             }
625             area.__highlighted = true;
626             area.__prevOpacity = area.__prevOpacity || area.attr.opacity || 1;
627             area.__prevFill = area.__prevFill || area.attr.fill;
628             area.__prevLineWidth = area.__prevLineWidth || area.attr.lineWidth;
629             fillColor = Ext.draw.Color.fromString(area.__prevFill);
630             to = {
631                 lineWidth: (area.__prevLineWidth || 0) + 2
632             };
633             if (fillColor) {
634                 to.fill = fillColor.getLighter(0.2).toString();
635             }
636             else {
637                 to.opacity = Math.max(area.__prevOpacity - 0.3, 0);
638             }
639             if (this.chart.animate) {
640                 area.__highlightAnim = Ext.create('Ext.fx.Anim', Ext.apply({
641                     target: area,
642                     to: to
643                 }, this.chart.animate));
644             }
645             else {
646                 area.setAttributes(to, true);
647             }
648         }
649     },
650
651 <span id='Ext-chart.series.Area-method-unHighlightSeries'>    /**
652 </span>     * UnHighlight this entire series.
653      * @param {Object} item Info about the item; same format as returned by #getItemForPoint.
654      */
655     unHighlightSeries: function() {
656         var area;
657         if (this._index !== undefined) {
658             area = this.areas[this._index];
659             if (area.__highlightAnim) {
660                 area.__highlightAnim.paused = true;
661             }
662             if (area.__highlighted) {
663                 area.__highlighted = false;
664                 area.__highlightAnim = Ext.create('Ext.fx.Anim', {
665                     target: area,
666                     to: {
667                         fill: area.__prevFill,
668                         opacity: area.__prevOpacity,
669                         lineWidth: area.__prevLineWidth
670                     }
671                 });
672             }
673         }
674     },
675
676 <span id='Ext-chart.series.Area-method-highlightItem'>    /**
677 </span>     * Highlight the specified item. If no item is provided the whole series will be highlighted.
678      * @param item {Object} Info about the item; same format as returned by #getItemForPoint
679      */
680     highlightItem: function(item) {
681         var me = this,
682             points, path;
683         if (!item) {
684             this.highlightSeries();
685             return;
686         }
687         points = item._points;
688         path = points.length == 2? ['M', points[0][0], points[0][1], 'L', points[1][0], points[1][1]]
689                 : ['M', points[0][0], points[0][1], 'L', points[0][0], me.bbox.y + me.bbox.height];
690         me.highlightSprite.setAttributes({
691             path: path,
692             hidden: false
693         }, true);
694     },
695
696 <span id='Ext-chart.series.Area-method-unHighlightItem'>    /**
697 </span>     * un-highlights the specified item. If no item is provided it will un-highlight the entire series.
698      * @param item {Object} Info about the item; same format as returned by #getItemForPoint
699      */
700     unHighlightItem: function(item) {
701         if (!item) {
702             this.unHighlightSeries();
703         }
704
705         if (this.highlightSprite) {
706             this.highlightSprite.hide(true);
707         }
708     },
709
710     // @private
711     hideAll: function() {
712         if (!isNaN(this._index)) {
713             this.__excludes[this._index] = true;
714             this.areas[this._index].hide(true);
715             this.drawSeries();
716         }
717     },
718
719     // @private
720     showAll: function() {
721         if (!isNaN(this._index)) {
722             this.__excludes[this._index] = false;
723             this.areas[this._index].show(true);
724             this.drawSeries();
725         }
726     },
727
728 <span id='Ext-chart.series.Area-method-getLegendColor'>    /**
729 </span>     * Returns the color of the series (to be displayed as color for the series legend item).
730      * @param item {Object} Info about the item; same format as returned by #getItemForPoint
731      */
732     getLegendColor: function(index) {
733         var me = this;
734         return me.colorArrayStyle[index % me.colorArrayStyle.length];
735     }
736 });
737 </pre></pre></body></html>