4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-chart-series-Pie'>/**
19 </span> * @class Ext.chart.series.Pie
20 * @extends Ext.chart.series.Series
22 * Creates a Pie Chart. A Pie Chart is a useful visualization technique to display quantitative information for different
23 * categories that also have a meaning as a whole.
24 * As with all other series, the Pie Series must be appended in the *series* Chart array configuration. See the Chart
25 * documentation for more information. A typical configuration object for the pie series could be:
28 * var store = Ext.create('Ext.data.JsonStore', {
29 * fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
31 * { 'name': 'metric one', 'data1': 10, 'data2': 12, 'data3': 14, 'data4': 8, 'data5': 13 },
32 * { 'name': 'metric two', 'data1': 7, 'data2': 8, 'data3': 16, 'data4': 10, 'data5': 3 },
33 * { 'name': 'metric three', 'data1': 5, 'data2': 2, 'data3': 14, 'data4': 12, 'data5': 7 },
34 * { 'name': 'metric four', 'data1': 2, 'data2': 14, 'data3': 6, 'data4': 1, 'data5': 23 },
35 * { 'name': 'metric five', 'data1': 27, 'data2': 38, 'data3': 36, 'data4': 13, 'data5': 33 }
39 * Ext.create('Ext.chart.Chart', {
40 * renderTo: Ext.getBody(),
45 * theme: 'Base:gradients',
54 * renderer: function(storeItem, item) {
55 * // calculate and display percentage on hover
57 * store.each(function(rec) {
58 * total += rec.get('data1');
60 * this.setTitle(storeItem.get('name') + ': ' + Math.round(storeItem.get('data1') / total * 100) + '%');
77 * In this configuration we set `pie` as the type for the series, set an object with specific style properties for highlighting options
78 * (triggered when hovering elements). We also set true to `showInLegend` so all the pie slices can be represented by a legend item.
80 * We set `data1` as the value of the field to determine the angle span for each pie slice. We also set a label configuration object
81 * 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.
83 * 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
84 * and size through the `font` parameter.
88 Ext.define('Ext.chart.series.Pie', {
90 /* Begin Definitions */
92 alternateClassName: ['Ext.chart.PieSeries', 'Ext.chart.PieChart'],
94 extend: 'Ext.chart.series.Series',
98 type: "pie",
104 <span id='Ext-chart-series-Pie-cfg-highlightDuration'> /**
105 </span> * @cfg {Number} highlightDuration
106 * The duration for the pie slice highlight effect.
108 highlightDuration: 150,
110 <span id='Ext-chart-series-Pie-cfg-angleField'> /**
111 </span> * @cfg {String} angleField (required)
112 * The store record field name to be used for the pie angles.
113 * The values bound to this field name must be positive real numbers.
117 <span id='Ext-chart-series-Pie-cfg-lengthField'> /**
118 </span> * @cfg {String} lengthField
119 * The store record field name to be used for the pie slice lengths.
120 * The values bound to this field name must be positive real numbers.
124 <span id='Ext-chart-series-Pie-cfg-donut'> /**
125 </span> * @cfg {Boolean/Number} donut
126 * Whether to set the pie chart as donut chart.
127 * Default's false. Can be set to a particular percentage to set the radius
128 * of the donut chart.
132 <span id='Ext-chart-series-Pie-cfg-showInLegend'> /**
133 </span> * @cfg {Boolean} showInLegend
134 * Whether to add the pie chart elements as legend items. Default's false.
138 <span id='Ext-chart-series-Pie-cfg-colorSet'> /**
139 </span> * @cfg {Array} colorSet
140 * An array of color values which will be used, in order, as the pie slice fill colors.
143 <span id='Ext-chart-series-Pie-cfg-style'> /**
144 </span> * @cfg {Object} style
145 * An object containing styles for overriding series styles from Theming.
149 constructor: function(config) {
150 this.callParent(arguments);
153 surface = chart.surface,
155 shadow = chart.shadow, i, l, cfg;
163 Ext.apply(me, config, {
165 "stroke-width": 6,
166 "stroke-opacity": 1,
167 stroke: 'rgb(200, 200, 200)',
174 "stroke-width": 4,
175 "stroke-opacity": 1,
176 stroke: 'rgb(150, 150, 150)',
183 "stroke-width": 2,
184 "stroke-opacity": 1,
185 stroke: 'rgb(100, 100, 100)',
192 me.group = surface.getGroup(me.seriesId);
194 for (i = 0, l = me.shadowAttributes.length; i < l; i++) {
195 me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i));
198 surface.customAttributes.segment = function(opt) {
199 return me.getSegment(opt);
201 me.__excludes = me.__excludes || [];
204 //@private updates some onbefore render parameters.
205 initialize: function() {
207 store = me.chart.getChartStore();
208 //Add yFields to be used in Legend.js
210 if (me.label.field) {
211 store.each(function(rec) {
212 me.yField.push(rec.get(me.label.field));
217 // @private returns an object with properties for a PieSlice.
218 getSegment: function(opt) {
225 x1 = 0, x2 = 0, x3 = 0, x4 = 0,
226 y1 = 0, y2 = 0, y3 = 0, y4 = 0,
227 x5 = 0, y5 = 0, x6 = 0, y6 = 0,
229 startAngle = opt.startAngle,
230 endAngle = opt.endAngle,
231 midAngle = (startAngle + endAngle) / 2 * rad,
232 margin = opt.margin || 0,
233 a1 = Math.min(startAngle, endAngle) * rad,
234 a2 = Math.max(startAngle, endAngle) * rad,
235 c1 = cos(a1), s1 = sin(a1),
236 c2 = cos(a2), s2 = sin(a2),
237 cm = cos(midAngle), sm = sin(midAngle),
238 flag = 0, hsqr2 = 0.7071067811865476; // sqrt(0.5)
240 if (a2 - a1 < delta) {
241 return {path: ""};
249 x2 = x + opt.endRho * c1;
250 y2 = y + opt.endRho * s1;
252 x4 = x + opt.endRho * c2;
253 y4 = y + opt.endRho * s2;
255 if (Math.abs(x2 - x4) + Math.abs(y2 - y4) < delta) {
261 x6 = x + opt.endRho * cm;
262 y6 = y + opt.endRho * sm;
264 // TODO(bei): It seems that the canvas engine cannot render half circle command correctly on IE.
265 // Better fix the VML engine for half circles.
267 if (opt.startRho !== 0) {
268 x1 = x + opt.startRho * c1;
269 y1 = y + opt.startRho * s1;
271 x3 = x + opt.startRho * c2;
272 y3 = y + opt.startRho * s2;
274 x5 = x + opt.startRho * cm;
275 y5 = y + opt.startRho * sm;
279 ["M", x2, y2],
280 ["A", opt.endRho, opt.endRho, 0, 0, 1, x6, y6], ["L", x6, y6],
281 ["A", opt.endRho, opt.endRho, 0, flag, 1, x4, y4], ["L", x4, y4],
282 ["L", x3, y3],
283 ["A", opt.startRho, opt.startRho, 0, flag, 0, x5, y5], ["L", x5, y5],
284 ["A", opt.startRho, opt.startRho, 0, 0, 0, x1, y1], ["L", x1, y1],
291 ["M", x, y],
292 ["L", x2, y2],
293 ["A", opt.endRho, opt.endRho, 0, 0, 1, x6, y6], ["L", x6, y6],
294 ["A", opt.endRho, opt.endRho, 0, flag, 1, x4, y4], ["L", x4, y4],
295 ["L", x, y],
302 // @private utility function to calculate the middle point of a pie slice.
303 calcMiddle: function(item) {
309 startAngle = slice.startAngle,
310 endAngle = slice.endAngle,
312 midAngle = -(startAngle + endAngle) * rad / 2,
313 r = (item.endRho + item.startRho) / 2,
314 xm = x + r * Math.cos(midAngle),
315 ym = y - r * Math.sin(midAngle);
323 <span id='Ext-chart-series-Pie-method-drawSeries'> /**
324 </span> * Draws the series for the current chart.
326 drawSeries: function() {
328 store = me.chart.getChartStore(),
330 animate = me.chart.animate,
331 field = me.angleField || me.field || me.xField,
332 lenField = [].concat(me.lengthField),
334 colors = me.colorSet,
336 surface = chart.surface,
337 chartBBox = chart.chartBBox,
338 enableShadows = chart.shadow,
339 shadowGroups = me.shadowGroups,
340 shadowAttributes = me.shadowAttributes,
341 lnsh = shadowGroups.length,
343 layers = lenField.length,
356 seriesStyle = me.seriesStyle,
357 seriesLabelStyle = me.seriesLabelStyle,
358 colorArrayStyle = me.colorArrayStyle,
359 colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0,
360 gutterX = chart.maxGutter[0],
361 gutterY = chart.maxGutter[1],
391 Ext.apply(seriesStyle, me.style || {});
396 //override theme colors
398 colorArrayStyle = me.colorSet;
399 colorArrayLength = colorArrayStyle.length;
402 //if not store or store is empty then there's nothing to draw
403 if (!store || !store.getCount()) {
407 me.unHighlightItem();
408 me.cleanHighlights();
410 centerX = me.centerX = chartBBox.x + (chartBBox.width / 2);
411 centerY = me.centerY = chartBBox.y + (chartBBox.height / 2);
412 me.radius = Math.min(centerX - chartBBox.x, centerY - chartBBox.y);
413 me.slices = slices = [];
414 me.items = items = [];
416 store.each(function(record, i) {
417 if (this.__excludes && this.__excludes[i]) {
421 totalField += +record.get(field);
423 for (j = 0, totalLenField = 0; j < layers; j++) {
424 totalLenField += +record.get(lenField[j]);
426 layerTotals[i] = totalLenField;
427 maxLenField = Math.max(maxLenField, totalLenField);
431 totalField = totalField || 1;
432 store.each(function(record, i) {
433 if (this.__excludes && this.__excludes[i]) {
436 value = record.get(field);
445 me.firstAngle = angle = 360 * value / totalField / 2;
446 for (j = 0; j < i; j++) {
447 slices[j].startAngle = slices[j].endAngle = me.firstAngle;
451 endAngle = angle - 360 * value / totalField;
460 lenValue = layerTotals[i];
461 slice.rho = me.radius * (lenValue / maxLenField);
463 slice.rho = me.radius;
468 //do all shadows first.
470 for (i = 0, ln = slices.length; i < ln; i++) {
472 slice.shadowAttrs = [];
473 for (j = 0, rhoAcum = 0, shadows = []; j < layers; j++) {
474 sprite = group.getAt(i * layers + j);
475 deltaRho = lenField[j] ? store.getAt(i).get(lenField[j]) / layerTotals[i] * slice.rho: slice.rho;
476 //set pie slice properties
477 rendererAttributes = {
479 startAngle: slice.startAngle,
480 endAngle: slice.endAngle,
483 startRho: rhoAcum + (deltaRho * donut / 100),
484 endRho: rhoAcum + deltaRho
486 hidden: !slice.value && (slice.startAngle % 360) == (slice.endAngle % 360)
489 for (shindex = 0, shadows = []; shindex < lnsh; shindex++) {
490 shadowAttr = shadowAttributes[shindex];
491 shadow = shadowGroups[shindex].getAt(i);
493 shadow = chart.surface.add(Ext.apply({}, {
495 group: shadowGroups[shindex],
496 strokeLinejoin: "round"
497 }, rendererAttributes, shadowAttr));
500 shadowAttr = me.renderer(shadow, store.getAt(i), Ext.apply({}, rendererAttributes, shadowAttr), i, store);
501 me.onAnimate(shadow, {
505 shadowAttr = me.renderer(shadow, store.getAt(i), shadowAttr, i, store);
506 shadow.setAttributes(shadowAttr, true);
508 shadows.push(shadow);
510 slice.shadowAttrs[j] = shadows;
514 //do pie slices after.
515 for (i = 0, ln = slices.length; i < ln; i++) {
517 for (j = 0, rhoAcum = 0; j < layers; j++) {
518 sprite = group.getAt(i * layers + j);
519 deltaRho = lenField[j] ? store.getAt(i).get(lenField[j]) / layerTotals[i] * slice.rho: slice.rho;
520 //set pie slice properties
521 rendererAttributes = Ext.apply({
523 startAngle: slice.startAngle,
524 endAngle: slice.endAngle,
527 startRho: rhoAcum + (deltaRho * donut / 100),
528 endRho: rhoAcum + deltaRho
530 hidden: (!slice.value && (slice.startAngle % 360) == (slice.endAngle % 360))
531 }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[(layers > 1? j : i) % colorArrayLength] } || {}));
533 rendererAttributes.segment, {
536 storeItem: slice.storeItem,
541 item.shadows = slice.shadowAttrs[j];
544 // Create a new sprite if needed (no height)
546 spriteOptions = Ext.apply({
547 type: "path",
550 }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[(layers > 1? j : i) % colorArrayLength] } || {}));
551 sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes));
553 slice.sprite = slice.sprite || [];
554 item.sprite = sprite;
555 slice.sprite.push(sprite);
556 slice.point = [item.middle.x, item.middle.y];
558 rendererAttributes = me.renderer(sprite, store.getAt(i), rendererAttributes, i, store);
559 sprite._to = rendererAttributes;
560 sprite._animating = true;
561 me.onAnimate(sprite, {
562 to: rendererAttributes,
566 this._animating = false;
573 rendererAttributes = me.renderer(sprite, store.getAt(i), Ext.apply(rendererAttributes, {
576 sprite.setAttributes(rendererAttributes, true);
583 ln = group.getCount();
584 for (i = 0; i < ln; i++) {
585 if (!slices[(i / layers) >> 0] && group.getAt(i)) {
586 group.getAt(i).hide(true);
590 lnsh = shadowGroups.length;
591 for (shindex = 0; shindex < ln; shindex++) {
592 if (!slices[(shindex / layers) >> 0]) {
593 for (j = 0; j < lnsh; j++) {
594 if (shadowGroups[j].getAt(shindex)) {
595 shadowGroups[j].getAt(shindex).hide(true);
605 // @private callback for when creating a label sprite.
606 onCreateLabel: function(storeItem, item, i, display) {
608 group = me.labelsGroup,
610 centerX = me.centerX,
611 centerY = me.centerY,
612 middle = item.middle,
613 endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config || {});
615 return me.chart.surface.add(Ext.apply({
617 'text-anchor': 'middle',
624 // @private callback for when placing a label sprite.
625 onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {
628 resizing = chart.resizing,
630 format = config.renderer,
631 field = [].concat(config.field),
632 centerX = me.centerX,
633 centerY = me.centerY,
634 middle = item.middle,
639 x = middle.x - centerX,
640 y = middle.y - centerY,
643 theta = Math.atan2(y, x || 1),
644 dg = theta * 180 / Math.PI,
646 if (this.__excludes && this.__excludes[i]) {
649 function fixAngle(a) {
656 label.setAttributes({
657 text: format(storeItem.get(field[index]))
662 rho = Math.sqrt(x * x + y * y) * 2;
664 opt.x = rho * Math.cos(theta) + centerX;
665 opt.y = rho * Math.sin(theta) + centerY;
670 dg = (dg > 90 && dg < 270) ? dg + 180: dg;
672 prevDg = label.attr.rotation.degrees;
673 if (prevDg != null && Math.abs(prevDg - dg) > 180) {
674 if (dg > prevDg) {
683 //update rotation angle
694 //ensure the object has zero translation
698 if (animate && !resizing && (display != 'rotate' || prevDg != null)) {
699 me.onAnimate(label, {
703 label.setAttributes(opt, true);
708 // @private callback for when placing a callout sprite.
709 onPlaceCallout: function(callout, storeItem, item, i, display, animate, index) {
712 resizing = chart.resizing,
713 config = me.callouts,
714 centerX = me.centerX,
715 centerY = me.centerY,
716 middle = item.middle,
721 x = middle.x - centerX,
722 y = middle.y - centerY,
725 theta = Math.atan2(y, x || 1),
726 bbox = callout.label.getBBox(),
732 //should be able to config this.
733 rho = item.endRho + offsetFromViz;
734 rhoCenter = (item.endRho + item.startRho) / 2 + (item.endRho - item.startRho) / 3;
736 opt.x = rho * Math.cos(theta) + centerX;
737 opt.y = rho * Math.sin(theta) + centerY;
739 x = rhoCenter * Math.cos(theta);
740 y = rhoCenter * Math.sin(theta);
743 //set the line from the middle of the pie to the box.
744 me.onAnimate(callout.lines, {
746 path: ["M", x + centerX, y + centerY, "L", opt.x, opt.y, "Z", "M", opt.x, opt.y, "l", x > 0 ? offsetToSide: -offsetToSide, 0, "z"]
750 me.onAnimate(callout.box, {
752 x: opt.x + (x > 0 ? offsetToSide: -(offsetToSide + bbox.width + 2 * offsetBox)),
753 y: opt.y + (y > 0 ? ( - bbox.height - offsetBox / 2) : ( - bbox.height - offsetBox / 2)),
754 width: bbox.width + 2 * offsetBox,
755 height: bbox.height + 2 * offsetBox
759 me.onAnimate(callout.label, {
761 x: opt.x + (x > 0 ? (offsetToSide + offsetBox) : -(offsetToSide + bbox.width + offsetBox)),
762 y: opt.y + (y > 0 ? -bbox.height / 4: -bbox.height / 4)
766 //set the line from the middle of the pie to the box.
767 callout.lines.setAttributes({
768 path: ["M", x + centerX, y + centerY, "L", opt.x, opt.y, "Z", "M", opt.x, opt.y, "l", x > 0 ? offsetToSide: -offsetToSide, 0, "z"]
772 callout.box.setAttributes({
773 x: opt.x + (x > 0 ? offsetToSide: -(offsetToSide + bbox.width + 2 * offsetBox)),
774 y: opt.y + (y > 0 ? ( - bbox.height - offsetBox / 2) : ( - bbox.height - offsetBox / 2)),
775 width: bbox.width + 2 * offsetBox,
776 height: bbox.height + 2 * offsetBox
780 callout.label.setAttributes({
781 x: opt.x + (x > 0 ? (offsetToSide + offsetBox) : -(offsetToSide + bbox.width + offsetBox)),
782 y: opt.y + (y > 0 ? -bbox.height / 4: -bbox.height / 4)
787 callout[p].show(true);
791 // @private handles sprite animation for the series.
792 onAnimate: function(sprite, attr) {
794 return this.callParent(arguments);
797 isItemInPoint: function(x, y, item, i) {
804 startAngle = item.startAngle,
805 endAngle = item.endAngle,
806 rho = Math.sqrt(dx * dx + dy * dy),
807 angle = Math.atan2(y - cy, x - cx) / me.rad;
809 // normalize to the same range of angles created by drawSeries
810 if (angle > me.firstAngle) {
813 return (angle <= startAngle && angle > endAngle
814 && rho >= item.startRho && rho <= item.endRho);
817 // @private hides all elements in the series.
818 hideAll: function() {
819 var i, l, shadow, shadows, sh, lsh, sprite;
820 if (!isNaN(this._index)) {
821 this.__excludes = this.__excludes || [];
822 this.__excludes[this._index] = true;
823 sprite = this.slices[this._index].sprite;
824 for (sh = 0, lsh = sprite.length; sh < lsh; sh++) {
825 sprite[sh].setAttributes({
829 if (this.slices[this._index].shadowAttrs) {
830 for (i = 0, shadows = this.slices[this._index].shadowAttrs, l = shadows.length; i < l; i++) {
832 for (sh = 0, lsh = shadow.length; sh < lsh; sh++) {
833 shadow[sh].setAttributes({
843 // @private shows all elements in the series.
844 showAll: function() {
845 if (!isNaN(this._index)) {
846 this.__excludes[this._index] = false;
851 <span id='Ext-chart-series-Pie-method-highlightItem'> /**
852 </span> * Highlight the specified item. If no item is provided the whole series will be highlighted.
853 * @param item {Object} Info about the item; same format as returned by #getItemForPoint
855 highlightItem: function(item) {
858 item = item || this.items[this._index];
860 //TODO(nico): sometimes in IE itemmouseover is triggered
861 //twice without triggering itemmouseout in between. This
862 //fixes the highlighting bug. Eventually, events should be
863 //changed to trigger one itemmouseout between two itemmouseovers.
864 this.unHighlightItem();
866 if (!item || item.sprite && item.sprite._animating) {
869 me.callParent([item]);
873 if ('segment' in me.highlightCfg) {
874 var highlightSegment = me.highlightCfg.segment,
875 animate = me.chart.animate,
876 attrs, i, shadows, shadow, ln, to, itemHighlightSegment, prop;
878 if (me.labelsGroup) {
879 var group = me.labelsGroup,
880 display = me.label.display,
881 label = group.getAt(item.index),
882 middle = (item.startAngle + item.endAngle) / 2 * rad,
883 r = highlightSegment.margin || 0,
884 x = r * Math.cos(middle),
885 y = r * Math.sin(middle);
887 //TODO(nico): rounding to 1e-10
888 //gives the right translation. Translation
889 //was buggy for very small numbers. In this
890 //case we're not looking to translate to very small
891 //numbers but not to translate at all.
892 if (Math.abs(x) < 1e-10) {
895 if (Math.abs(y) < 1e-10) {
900 label.stopAnimation();
908 duration: me.highlightDuration
912 label.setAttributes({
921 if (me.chart.shadow && item.shadows) {
923 shadows = item.shadows;
925 for (; i < ln; i++) {
928 itemHighlightSegment = item.sprite._from.segment;
929 for (prop in itemHighlightSegment) {
930 if (! (prop in highlightSegment)) {
931 to[prop] = itemHighlightSegment[prop];
935 segment: Ext.applyIf(to, me.highlightCfg.segment)
938 shadow.stopAnimation();
941 duration: me.highlightDuration
945 shadow.setAttributes(attrs, true);
952 <span id='Ext-chart-series-Pie-method-unHighlightItem'> /**
953 </span> * Un-highlights the specified item. If no item is provided it will un-highlight the entire series.
954 * @param item {Object} Info about the item; same format as returned by #getItemForPoint
956 unHighlightItem: function() {
962 if (('segment' in me.highlightCfg) && me.items) {
963 var items = me.items,
964 animate = me.chart.animate,
965 shadowsEnabled = !!me.chart.shadow,
966 group = me.labelsGroup,
970 display = me.label.display,
971 shadowLen, p, to, ihs, hs, sprite, shadows, shadow, item, label, attrs;
973 for (; i < len; i++) {
978 sprite = item.sprite;
979 if (sprite && sprite._highlighted) {
982 label = group.getAt(item.index);
989 display == 'rotate' ? {
993 degrees: label.attr.rotation.degrees
997 label.stopAnimation();
1000 duration: me.highlightDuration
1004 label.setAttributes(attrs, true);
1007 if (shadowsEnabled) {
1008 shadows = item.shadows;
1009 shadowLen = shadows.length;
1010 for (; j < shadowLen; j++) {
1012 ihs = item.sprite._to.segment;
1013 hs = item.sprite._from.segment;
1020 shadow = shadows[j];
1022 shadow.stopAnimation();
1027 duration: me.highlightDuration
1031 shadow.setAttributes({ segment: to }, true);
1038 me.callParent(arguments);
1041 <span id='Ext-chart-series-Pie-method-getLegendColor'> /**
1042 </span> * Returns the color of the series (to be displayed as color for the series legend item).
1043 * @param item {Object} Info about the item; same format as returned by #getItemForPoint
1045 getLegendColor: function(index) {
1047 return (me.colorSet && me.colorSet[index % me.colorSet.length]) || me.colorArrayStyle[index % me.colorArrayStyle.length];