4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../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-Legend'>/**
19 </span> * @class Ext.chart.Legend
21 * Defines a legend for a chart's series.
22 * The 'chart' member must be set prior to rendering.
23 * The legend class displays a list of legend items each of them related with a
24 * series being rendered. In order to render the legend item of the proper series
25 * the series configuration object must have `showInSeries` set to true.
27 * The legend configuration object accepts a `position` as parameter.
28 * The `position` parameter can be `left`, `right`
29 * `top` or `bottom`. For example:
36 <pre><code>
37 var store = Ext.create('Ext.data.JsonStore', {
38 fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
40 {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
41 {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
42 {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
43 {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
44 {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
48 Ext.create('Ext.chart.Chart', {
49 renderTo: Ext.getBody(),
63 fields: ['data1', 'data2', 'data3', 'data4', 'data5'],
64 title: 'Sample Values',
74 adjustMinimumByMajorUnit: 0
79 title: 'Sample Metrics',
92 yField: ['data1', 'data2', 'data3', 'data4', 'data5'],
98 </code></pre>
101 Ext.define('Ext.chart.Legend', {
103 /* Begin Definitions */
105 requires: ['Ext.chart.LegendItem'],
107 /* End Definitions */
109 <span id='Ext-chart-Legend-cfg-visible'> /**
110 </span> * @cfg {Boolean} visible
111 * Whether or not the legend should be displayed.
115 <span id='Ext-chart-Legend-cfg-position'> /**
116 </span> * @cfg {String} position
117 * The position of the legend in relation to the chart. One of: "top",
118 * "bottom", "left", "right", or "float". If set to "float", then the legend
119 * box will be positioned at the point denoted by the x and y parameters.
123 <span id='Ext-chart-Legend-cfg-x'> /**
124 </span> * @cfg {Number} x
125 * X-position of the legend box. Used directly if position is set to "float", otherwise
126 * it will be calculated dynamically.
130 <span id='Ext-chart-Legend-cfg-y'> /**
131 </span> * @cfg {Number} y
132 * Y-position of the legend box. Used directly if position is set to "float", otherwise
133 * it will be calculated dynamically.
137 <span id='Ext-chart-Legend-cfg-labelFont'> /**
138 </span> * @cfg {String} labelFont
139 * Font to be used for the legend labels, eg '12px Helvetica'
141 labelFont: '12px Helvetica, sans-serif',
143 <span id='Ext-chart-Legend-cfg-boxStroke'> /**
144 </span> * @cfg {String} boxStroke
145 * Style of the stroke for the legend box
149 <span id='Ext-chart-Legend-cfg-boxStrokeWidth'> /**
150 </span> * @cfg {String} boxStrokeWidth
151 * Width of the stroke for the legend box
155 <span id='Ext-chart-Legend-cfg-boxFill'> /**
156 </span> * @cfg {String} boxFill
157 * Fill style for the legend box
161 <span id='Ext-chart-Legend-cfg-itemSpacing'> /**
162 </span> * @cfg {Number} itemSpacing
163 * Amount of space between legend items
167 <span id='Ext-chart-Legend-cfg-padding'> /**
168 </span> * @cfg {Number} padding
169 * Amount of padding between the legend box's border and its items
178 <span id='Ext-chart-Legend-cfg-boxZIndex'> /**
179 </span> * @cfg {Number} boxZIndex
180 * Sets the z-index for the legend. Defaults to 100.
184 <span id='Ext-chart-Legend-method-constructor'> /**
185 </span> * Creates new Legend.
186 * @param {Object} config (optional) Config object.
188 constructor: function(config) {
191 Ext.apply(me, config);
194 <span id='Ext-chart-Legend-property-isVertical'> /**
195 </span> * Whether the legend box is oriented vertically, i.e. if it is on the left or right side or floating.
198 me.isVertical = ("left|right|float".indexOf(me.position) !== -1);
200 // cache these here since they may get modified later on
205 <span id='Ext-chart-Legend-method-create'> /**
206 </span> * @private Create all the sprites for the legend
211 if (!me.created && me.isDisplayed()) {
215 // Listen for changes to series titles to trigger regeneration of the legend
216 me.chart.series.each(function(series) {
217 series.on('titlechange', function() {
225 <span id='Ext-chart-Legend-method-isDisplayed'> /**
226 </span> * @private Determine whether the legend should be displayed. Looks at the legend's 'visible' config,
227 * and also the 'showInLegend' config for each of the series.
229 isDisplayed: function() {
230 return this.visible && this.chart.series.findIndex('showInLegend', true) !== -1;
233 <span id='Ext-chart-Legend-method-createItems'> /**
234 </span> * @private Create the series markers and labels
236 createItems: function() {
239 surface = chart.surface,
241 padding = me.padding,
242 itemSpacing = me.itemSpacing,
248 vertical = me.isVertical,
254 len = items ? items.length : 0,
255 x, y, spacing, item, bbox, height, width;
257 //remove all legend items
259 for (; i < len; i++) {
265 // Create all the item labels, collecting their dimensions and positioning each one
266 // properly in relation to the previous item
267 chart.series.each(function(series, i) {
268 if (series.showInLegend) {
269 Ext.each([].concat(series.yField), function(field, j) {
270 item = Ext.create('Ext.chart.LegendItem', {
273 surface: chart.surface,
276 bbox = item.getBBox();
278 //always measure from x=0, since not all markers go all the way to the left
280 height = bbox.height;
283 spacing = vertical ? padding + height / 2 : padding;
286 spacing = itemSpacing / (vertical ? 2 : 1);
288 // Set the item's position relative to the legend box
289 item.x = mfloor(vertical ? padding : totalWidth + spacing);
290 item.y = mfloor(vertical ? totalHeight + spacing : padding + height / 2);
292 // Collect cumulative dimensions
293 totalWidth += width + spacing;
294 totalHeight += height + spacing;
295 maxWidth = mmax(maxWidth, width);
296 maxHeight = mmax(maxHeight, height);
303 // Store the collected dimensions for later
304 me.width = mfloor((vertical ? maxWidth : totalWidth) + padding * 2);
305 if (vertical && items.length === 1) {
308 me.height = mfloor((vertical ? totalHeight - spacingOffset * spacing : maxHeight) + (padding * 2));
309 me.itemHeight = maxHeight;
312 <span id='Ext-chart-Legend-method-getBBox'> /**
313 </span> * @private Get the bounds for the legend's outer box
315 getBBox: function() {
318 x: Math.round(me.x) - me.boxStrokeWidth / 2,
319 y: Math.round(me.y) - me.boxStrokeWidth / 2,
325 <span id='Ext-chart-Legend-method-createBox'> /**
326 </span> * @private Create the box around the legend items
328 createBox: function() {
330 box = me.boxSprite = me.chart.surface.add(Ext.apply({
332 stroke: me.boxStroke,
333 "stroke-width": me.boxStrokeWidth,
340 <span id='Ext-chart-Legend-method-updatePosition'> /**
341 </span> * @private Update the position of all the legend's sprites to match its current x/y values
343 updatePosition: function() {
346 legendWidth = me.width,
347 legendHeight = me.height,
348 padding = me.padding,
350 chartBBox = chart.chartBBox,
351 insets = chart.insetPadding,
352 chartWidth = chartBBox.width - (insets * 2),
353 chartHeight = chartBBox.height - (insets * 2),
354 chartX = chartBBox.x + insets,
355 chartY = chartBBox.y + insets,
356 surface = chart.surface,
359 if (me.isDisplayed()) {
360 // Find the position based on the dimensions
361 switch(me.position) {
362 case "left":
364 y = mfloor(chartY + chartHeight / 2 - legendHeight / 2);
366 case "right":
367 x = mfloor(surface.width - legendWidth) - insets;
368 y = mfloor(chartY + chartHeight / 2 - legendHeight / 2);
370 case "top":
371 x = mfloor(chartX + chartWidth / 2 - legendWidth / 2);
374 case "bottom":
375 x = mfloor(chartX + chartWidth / 2 - legendWidth / 2);
376 y = mfloor(surface.height - legendHeight) - insets;
379 x = mfloor(me.origX) + insets;
380 y = mfloor(me.origY) + insets;
385 // Update the position of each item
386 Ext.each(me.items, function(item) {
387 item.updatePosition();
389 // Update the position of the outer box
390 me.boxSprite.setAttributes(me.getBBox(), true);