3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.chart.Label
18 * Labels is a mixin whose methods are appended onto the Series class. Labels is an interface with methods implemented
19 * in each of the Series (Pie, Bar, etc) for label creation and label placement.
21 * The methods implemented by the Series are:
23 * - **`onCreateLabel(storeItem, item, i, display)`** Called each time a new label is created.
24 * The arguments of the method are:
25 * - *`storeItem`* The element of the store that is related to the label sprite.
26 * - *`item`* The item related to the label sprite. An item is an object containing the position of the shape
27 * used to describe the visualization and also pointing to the actual shape (circle, rectangle, path, etc).
28 * - *`i`* The index of the element created (i.e the first created label, second created label, etc)
29 * - *`display`* The display type. May be <b>false</b> if the label is hidden
31 * - **`onPlaceLabel(label, storeItem, item, i, display, animate)`** Called for updating the position of the label.
32 * The arguments of the method are:
33 * - *`label`* The sprite label.</li>
34 * - *`storeItem`* The element of the store that is related to the label sprite</li>
35 * - *`item`* The item related to the label sprite. An item is an object containing the position of the shape
36 * used to describe the visualization and also pointing to the actual shape (circle, rectangle, path, etc).
37 * - *`i`* The index of the element to be updated (i.e. whether it is the first, second, third from the labelGroup)
38 * - *`display`* The display type. May be <b>false</b> if the label is hidden.
39 * - *`animate`* A boolean value to set or unset animations for the labels.
41 Ext.define('Ext.chart.Label', {
43 /* Begin Definitions */
45 requires: ['Ext.draw.Color'],
50 * @cfg {String} display
51 * Specifies the presence and position of labels for each pie slice. Either "rotate", "middle", "insideStart",
52 * "insideEnd", "outside", "over", "under", or "none" to prevent label rendering.
53 * Default value: 'none'.
58 * The color of the label text.
59 * Default value: '#000' (black).
64 * The name of the field to be displayed in the label.
65 * Default value: 'name'.
69 * @cfg {Number} minMargin
70 * Specifies the minimum distance from a label to the origin of the visualization.
71 * This parameter is useful when using PieSeries width variable pie slice lengths.
77 * The font used for the labels.
78 * Defautl value: "11px Helvetica, sans-serif".
82 * @cfg {String} orientation
83 * Either "horizontal" or "vertical".
84 * Dafault value: "horizontal".
88 * @cfg {Function} renderer
89 * Optional function for formatting the label into a displayable value.
90 * Default value: function(v) { return v; }
94 //@private a regex to parse url type colors.
95 colorStringRe: /url\s*\(\s*#([^\/)]+)\s*\)/,
97 //@private the mixin constructor. Used internally by Series.
98 constructor: function(config) {
100 me.label = Ext.applyIf(me.label || {},
106 font: "11px Helvetica, sans-serif",
107 orientation: "horizontal",
108 renderer: function(v) {
113 if (me.label.display !== 'none') {
114 me.labelsGroup = me.chart.surface.getGroup(me.seriesId + '-labels');
118 //@private a method to render all labels in the labelGroup
119 renderLabels: function() {
122 gradients = chart.gradients,
124 animate = chart.animate,
126 display = config.display,
127 color = config.color,
128 field = [].concat(config.field),
129 group = me.labelsGroup,
130 store = me.chart.store,
131 len = store.getCount(),
132 itemLength = (items || 0) && items.length,
133 ratio = itemLength / len,
134 gradientsCount = (gradients || 0) && gradients.length,
135 Color = Ext.draw.Color,
136 gradient, i, count, index, j, k, colorStopTotal, colorStopIndex, colorStop, item, label,
137 storeItem, sprite, spriteColor, spriteBrightness, labelColor, colorString;
139 if (display == 'none') {
143 for (i = 0, count = 0; i < len; i++) {
145 for (j = 0; j < ratio; j++) {
147 label = group.getAt(count);
148 storeItem = store.getAt(i);
151 while(this.__excludes && this.__excludes[index]) {
155 if (!item && label) {
159 if (item && field[j]) {
161 label = me.onCreateLabel(storeItem, item, i, display, j, index);
163 me.onPlaceLabel(label, storeItem, item, i, display, animate, j, index);
166 if (config.contrast && item.sprite) {
167 sprite = item.sprite;
168 //set the color string to the color to be set.
169 if (sprite._endStyle) {
170 colorString = sprite._endStyle.fill;
172 else if (sprite._to) {
173 colorString = sprite._to.fill;
176 colorString = sprite.attr.fill;
178 colorString = colorString || sprite.attr.fill;
180 spriteColor = Color.fromString(colorString);
181 //color wasn't parsed property maybe because it's a gradient id
182 if (colorString && !spriteColor) {
183 colorString = colorString.match(me.colorStringRe)[1];
184 for (k = 0; k < gradientsCount; k++) {
185 gradient = gradients[k];
186 if (gradient.id == colorString) {
188 colorStop = 0; colorStopTotal = 0;
189 for (colorStopIndex in gradient.stops) {
191 colorStopTotal += Color.fromString(gradient.stops[colorStopIndex].color).getGrayscale();
193 spriteBrightness = (colorStopTotal / colorStop) / 255;
199 spriteBrightness = spriteColor.getGrayscale() / 255;
201 if (label.isOutside) {
202 spriteBrightness = 1;
204 labelColor = Color.fromString(label.attr.color || label.attr.fill).getHSL();
205 labelColor[2] = spriteBrightness > 0.5 ? 0.2 : 0.8;
206 label.setAttributes({
207 fill: String(Color.fromHSL.apply({}, labelColor))
215 me.hideLabels(count);
218 //@private a method to hide labels.
219 hideLabels: function(index) {
220 var labelsGroup = this.labelsGroup, len;
222 len = labelsGroup.getCount();
223 while (len-->index) {
224 labelsGroup.getAt(len).hide(true);