Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / docs / source / Legend.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.Legend-method-constructor'><span id='Ext-chart.Legend'>/**
2 </span></span> * @class Ext.chart.Legend
3  *
4  * Defines a legend for a chart's series.
5  * The 'chart' member must be set prior to rendering.
6  * The legend class displays a list of legend items each of them related with a
7  * series being rendered. In order to render the legend item of the proper series
8  * the series configuration object must have `showInSeries` set to true.
9  *
10  * The legend configuration object accepts a `position` as parameter.
11  * The `position` parameter can be `left`, `right`
12  * `top` or `bottom`. For example:
13  *
14  *     legend: {
15  *         position: 'right'
16  *     },
17  * 
18  * Full example:
19     &lt;pre&gt;&lt;code&gt;
20     var store = Ext.create('Ext.data.JsonStore', {
21         fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
22         data: [
23             {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
24             {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
25             {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
26             {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
27             {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}                                                
28         ]
29     });
30     
31     Ext.create('Ext.chart.Chart', {
32         renderTo: Ext.getBody(),
33         width: 500,
34         height: 300,
35         animate: true,
36         store: store,
37         shadow: true,
38         theme: 'Category1',
39         legend: {
40             position: 'top'
41         },
42          axes: [{
43                 type: 'Numeric',
44                 grid: true,
45                 position: 'left',
46                 fields: ['data1', 'data2', 'data3', 'data4', 'data5'],
47                 title: 'Sample Values',
48                 grid: {
49                     odd: {
50                         opacity: 1,
51                         fill: '#ddd',
52                         stroke: '#bbb',
53                         'stroke-width': 1
54                     }
55                 },
56                 minimum: 0,
57                 adjustMinimumByMajorUnit: 0
58             }, {
59                 type: 'Category',
60                 position: 'bottom',
61                 fields: ['name'],
62                 title: 'Sample Metrics',
63                 grid: true,
64                 label: {
65                     rotate: {
66                         degrees: 315
67                     }
68                 }
69         }],
70         series: [{
71             type: 'area',
72             highlight: false,
73             axis: 'left',
74             xField: 'name',
75             yField: ['data1', 'data2', 'data3', 'data4', 'data5'],
76             style: {
77                 opacity: 0.93
78             }
79         }]
80     });    
81     &lt;/code&gt;&lt;/pre&gt;    
82  *
83  * @constructor
84  */
85 Ext.define('Ext.chart.Legend', {
86
87     /* Begin Definitions */
88
89     requires: ['Ext.chart.LegendItem'],
90
91     /* End Definitions */
92
93 <span id='Ext-chart.Legend-cfg-visible'>    /**
94 </span>     * @cfg {Boolean} visible
95      * Whether or not the legend should be displayed.
96      */
97     visible: true,
98
99 <span id='Ext-chart.Legend-cfg-position'>    /**
100 </span>     * @cfg {String} position
101      * The position of the legend in relation to the chart. One of: &quot;top&quot;,
102      * &quot;bottom&quot;, &quot;left&quot;, &quot;right&quot;, or &quot;float&quot;. If set to &quot;float&quot;, then the legend
103      * box will be positioned at the point denoted by the x and y parameters.
104      */
105     position: 'bottom',
106
107 <span id='Ext-chart.Legend-cfg-x'>    /**
108 </span>     * @cfg {Number} x
109      * X-position of the legend box. Used directly if position is set to &quot;float&quot;, otherwise 
110      * it will be calculated dynamically.
111      */
112     x: 0,
113
114 <span id='Ext-chart.Legend-cfg-y'>    /**
115 </span>     * @cfg {Number} y
116      * Y-position of the legend box. Used directly if position is set to &quot;float&quot;, otherwise
117      * it will be calculated dynamically.
118      */
119     y: 0,
120
121 <span id='Ext-chart.Legend-cfg-labelFont'>    /**
122 </span>     * @cfg {String} labelFont
123      * Font to be used for the legend labels, eg '12px Helvetica'
124      */
125     labelFont: '12px Helvetica, sans-serif',
126
127 <span id='Ext-chart.Legend-cfg-boxStroke'>    /**
128 </span>     * @cfg {String} boxStroke
129      * Style of the stroke for the legend box
130      */
131     boxStroke: '#000',
132
133 <span id='Ext-chart.Legend-cfg-boxStrokeWidth'>    /**
134 </span>     * @cfg {String} boxStrokeWidth
135      * Width of the stroke for the legend box
136      */
137     boxStrokeWidth: 1,
138
139 <span id='Ext-chart.Legend-cfg-boxFill'>    /**
140 </span>     * @cfg {String} boxFill
141      * Fill style for the legend box
142      */
143     boxFill: '#FFF',
144
145 <span id='Ext-chart.Legend-cfg-itemSpacing'>    /**
146 </span>     * @cfg {Number} itemSpacing
147      * Amount of space between legend items
148      */
149     itemSpacing: 10,
150
151 <span id='Ext-chart.Legend-cfg-padding'>    /**
152 </span>     * @cfg {Number} padding
153      * Amount of padding between the legend box's border and its items
154      */
155     padding: 5,
156
157     // @private
158     width: 0,
159     // @private
160     height: 0,
161
162 <span id='Ext-chart.Legend-cfg-boxZIndex'>    /**
163 </span>     * @cfg {Number} boxZIndex
164      * Sets the z-index for the legend. Defaults to 100.
165      */
166     boxZIndex: 100,
167
168     constructor: function(config) {
169         var me = this;
170         if (config) {
171             Ext.apply(me, config);
172         }
173         me.items = [];
174 <span id='Ext-chart.Legend-property-isVertical'>        /**
175 </span>         * Whether the legend box is oriented vertically, i.e. if it is on the left or right side or floating.
176          * @type {Boolean}
177          */
178         me.isVertical = (&quot;left|right|float&quot;.indexOf(me.position) !== -1);
179         
180         // cache these here since they may get modified later on
181         me.origX = me.x;
182         me.origY = me.y;
183     },
184
185 <span id='Ext-chart.Legend-method-create'>    /**
186 </span>     * @private Create all the sprites for the legend
187      */
188     create: function() {
189         var me = this;
190         me.createItems();
191         if (!me.created &amp;&amp; me.isDisplayed()) {
192             me.createBox();
193             me.created = true;
194
195             // Listen for changes to series titles to trigger regeneration of the legend
196             me.chart.series.each(function(series) {
197                 series.on('titlechange', function() {
198                     me.create();
199                     me.updatePosition();
200                 });
201             });
202         }
203     },
204
205 <span id='Ext-chart.Legend-method-isDisplayed'>    /**
206 </span>     * @private Determine whether the legend should be displayed. Looks at the legend's 'visible' config,
207      * and also the 'showInLegend' config for each of the series.
208      */
209     isDisplayed: function() {
210         return this.visible &amp;&amp; this.chart.series.findIndex('showInLegend', true) !== -1;
211     },
212
213 <span id='Ext-chart.Legend-method-createItems'>    /**
214 </span>     * @private Create the series markers and labels
215      */
216     createItems: function() {
217         var me = this,
218             chart = me.chart,
219             surface = chart.surface,
220             items = me.items,
221             padding = me.padding,
222             itemSpacing = me.itemSpacing,
223             spacingOffset = 2,
224             maxWidth = 0,
225             maxHeight = 0,
226             totalWidth = 0,
227             totalHeight = 0,
228             vertical = me.isVertical,
229             math = Math,
230             mfloor = math.floor,
231             mmax = math.max,
232             index = 0, 
233             i = 0, 
234             len = items ? items.length : 0,
235             x, y, spacing, item, bbox, height, width;
236
237         //remove all legend items
238         if (len) {
239             for (; i &lt; len; i++) {
240                 items[i].destroy();
241             }
242         }
243         //empty array
244         items.length = [];
245         // Create all the item labels, collecting their dimensions and positioning each one
246         // properly in relation to the previous item
247         chart.series.each(function(series, i) {
248             if (series.showInLegend) {
249                 Ext.each([].concat(series.yField), function(field, j) {
250                     item = Ext.create('Ext.chart.LegendItem', {
251                         legend: this,
252                         series: series,
253                         surface: chart.surface,
254                         yFieldIndex: j
255                     });
256                     bbox = item.getBBox();
257
258                     //always measure from x=0, since not all markers go all the way to the left
259                     width = bbox.width; 
260                     height = bbox.height;
261
262                     if (i + j === 0) {
263                         spacing = vertical ? padding + height / 2 : padding;
264                     }
265                     else {
266                         spacing = itemSpacing / (vertical ? 2 : 1);
267                     }
268                     // Set the item's position relative to the legend box
269                     item.x = mfloor(vertical ? padding : totalWidth + spacing);
270                     item.y = mfloor(vertical ? totalHeight + spacing : padding + height / 2);
271
272                     // Collect cumulative dimensions
273                     totalWidth += width + spacing;
274                     totalHeight += height + spacing;
275                     maxWidth = mmax(maxWidth, width);
276                     maxHeight = mmax(maxHeight, height);
277
278                     items.push(item);
279                 }, this);
280             }
281         }, me);
282
283         // Store the collected dimensions for later
284         me.width = mfloor((vertical ? maxWidth : totalWidth) + padding * 2);
285         if (vertical &amp;&amp; items.length === 1) {
286             spacingOffset = 1;
287         }
288         me.height = mfloor((vertical ? totalHeight - spacingOffset * spacing : maxHeight) + (padding * 2));
289         me.itemHeight = maxHeight;
290     },
291
292 <span id='Ext-chart.Legend-method-getBBox'>    /**
293 </span>     * @private Get the bounds for the legend's outer box
294      */
295     getBBox: function() {
296         var me = this;
297         return {
298             x: Math.round(me.x) - me.boxStrokeWidth / 2,
299             y: Math.round(me.y) - me.boxStrokeWidth / 2,
300             width: me.width,
301             height: me.height
302         };
303     },
304
305 <span id='Ext-chart.Legend-method-createBox'>    /**
306 </span>     * @private Create the box around the legend items
307      */
308     createBox: function() {
309         var me = this,
310             box = me.boxSprite = me.chart.surface.add(Ext.apply({
311                 type: 'rect',
312                 stroke: me.boxStroke,
313                 &quot;stroke-width&quot;: me.boxStrokeWidth,
314                 fill: me.boxFill,
315                 zIndex: me.boxZIndex
316             }, me.getBBox()));
317         box.redraw();
318     },
319
320 <span id='Ext-chart.Legend-method-updatePosition'>    /**
321 </span>     * @private Update the position of all the legend's sprites to match its current x/y values
322      */
323     updatePosition: function() {
324         var me = this,
325             x, y,
326             legendWidth = me.width,
327             legendHeight = me.height,
328             padding = me.padding,
329             chart = me.chart,
330             chartBBox = chart.chartBBox,
331             insets = chart.insetPadding,
332             chartWidth = chartBBox.width - (insets * 2),
333             chartHeight = chartBBox.height - (insets * 2),
334             chartX = chartBBox.x + insets,
335             chartY = chartBBox.y + insets,
336             surface = chart.surface,
337             mfloor = Math.floor;
338         
339         if (me.isDisplayed()) {
340             // Find the position based on the dimensions
341             switch(me.position) {
342                 case &quot;left&quot;:
343                     x = insets;
344                     y = mfloor(chartY + chartHeight / 2 - legendHeight / 2);
345                     break;
346                 case &quot;right&quot;:
347                     x = mfloor(surface.width - legendWidth) - insets;
348                     y = mfloor(chartY + chartHeight / 2 - legendHeight / 2);
349                     break;
350                 case &quot;top&quot;:
351                     x = mfloor(chartX + chartWidth / 2 - legendWidth / 2);
352                     y = insets;
353                     break;
354                 case &quot;bottom&quot;:
355                     x = mfloor(chartX + chartWidth / 2 - legendWidth / 2);
356                     y = mfloor(surface.height - legendHeight) - insets;
357                     break;
358                 default:
359                     x = mfloor(me.origX) + insets;
360                     y = mfloor(me.origY) + insets;
361             }
362             me.x = x;
363             me.y = y;
364
365             // Update the position of each item
366             Ext.each(me.items, function(item) {
367                 item.updatePosition();
368             });
369             // Update the position of the outer box
370             me.boxSprite.setAttributes(me.getBBox(), true);
371         }
372     }
373 });</pre></pre></body></html>