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-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:
38 * var store = Ext.create('Ext.data.JsonStore', {
39 * fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
41 * { 'name': 'metric one', 'data1': 10, 'data2': 12, 'data3': 14, 'data4': 8, 'data5': 13 },
42 * { 'name': 'metric two', 'data1': 7, 'data2': 8, 'data3': 16, 'data4': 10, 'data5': 3 },
43 * { 'name': 'metric three', 'data1': 5, 'data2': 2, 'data3': 14, 'data4': 12, 'data5': 7 },
44 * { 'name': 'metric four', 'data1': 2, 'data2': 14, 'data3': 6, 'data4': 1, 'data5': 23 },
45 * { 'name': 'metric five', 'data1': 27, 'data2': 38, 'data3': 36, 'data4': 13, 'data5': 33 }
49 * Ext.create('Ext.chart.Chart', {
50 * renderTo: Ext.getBody(),
65 * fields: ['data1', 'data2', 'data3', 'data4', 'data5'],
66 * title: 'Sample Values',
76 * adjustMinimumByMajorUnit: 0
82 * title: 'Sample Metrics',
96 * yField: ['data1', 'data2', 'data3', 'data4', 'data5'],
103 Ext.define('Ext.chart.Legend', {
105 /* Begin Definitions */
107 requires: ['Ext.chart.LegendItem'],
109 /* End Definitions */
111 <span id='Ext-chart-Legend-cfg-visible'> /**
112 </span> * @cfg {Boolean} visible
113 * Whether or not the legend should be displayed.
117 <span id='Ext-chart-Legend-cfg-position'> /**
118 </span> * @cfg {String} position
119 * The position of the legend in relation to the chart. One of: "top",
120 * "bottom", "left", "right", or "float". If set to "float", then the legend
121 * box will be positioned at the point denoted by the x and y parameters.
125 <span id='Ext-chart-Legend-cfg-x'> /**
126 </span> * @cfg {Number} x
127 * X-position of the legend box. Used directly if position is set to "float", otherwise
128 * it will be calculated dynamically.
132 <span id='Ext-chart-Legend-cfg-y'> /**
133 </span> * @cfg {Number} y
134 * Y-position of the legend box. Used directly if position is set to "float", otherwise
135 * it will be calculated dynamically.
139 <span id='Ext-chart-Legend-cfg-labelFont'> /**
140 </span> * @cfg {String} labelFont
141 * Font to be used for the legend labels, eg '12px Helvetica'
143 labelFont: '12px Helvetica, sans-serif',
145 <span id='Ext-chart-Legend-cfg-boxStroke'> /**
146 </span> * @cfg {String} boxStroke
147 * Style of the stroke for the legend box
151 <span id='Ext-chart-Legend-cfg-boxStrokeWidth'> /**
152 </span> * @cfg {String} boxStrokeWidth
153 * Width of the stroke for the legend box
157 <span id='Ext-chart-Legend-cfg-boxFill'> /**
158 </span> * @cfg {String} boxFill
159 * Fill style for the legend box
163 <span id='Ext-chart-Legend-cfg-itemSpacing'> /**
164 </span> * @cfg {Number} itemSpacing
165 * Amount of space between legend items
169 <span id='Ext-chart-Legend-cfg-padding'> /**
170 </span> * @cfg {Number} padding
171 * Amount of padding between the legend box's border and its items
180 <span id='Ext-chart-Legend-cfg-boxZIndex'> /**
181 </span> * @cfg {Number} boxZIndex
182 * Sets the z-index for the legend. Defaults to 100.
186 <span id='Ext-chart-Legend-method-constructor'> /**
187 </span> * Creates new Legend.
188 * @param {Object} config (optional) Config object.
190 constructor: function(config) {
193 Ext.apply(me, config);
196 <span id='Ext-chart-Legend-property-isVertical'> /**
197 </span> * Whether the legend box is oriented vertically, i.e. if it is on the left or right side or floating.
200 me.isVertical = ("left|right|float".indexOf(me.position) !== -1);
202 // cache these here since they may get modified later on
207 <span id='Ext-chart-Legend-method-create'> /**
208 </span> * @private Create all the sprites for the legend
214 if (!me.created && me.isDisplayed()) {
217 // Listen for changes to series titles to trigger regeneration of the legend
218 me.chart.series.each(function(series) {
219 series.on('titlechange', function() {
227 <span id='Ext-chart-Legend-method-isDisplayed'> /**
228 </span> * @private Determine whether the legend should be displayed. Looks at the legend's 'visible' config,
229 * and also the 'showInLegend' config for each of the series.
231 isDisplayed: function() {
232 return this.visible && this.chart.series.findIndex('showInLegend', true) !== -1;
235 <span id='Ext-chart-Legend-method-createItems'> /**
236 </span> * @private Create the series markers and labels
238 createItems: function() {
241 surface = chart.surface,
243 padding = me.padding,
244 itemSpacing = me.itemSpacing,
250 vertical = me.isVertical,
256 len = items ? items.length : 0,
257 x, y, spacing, item, bbox, height, width;
259 //remove all legend items
261 for (; i < len; i++) {
267 // Create all the item labels, collecting their dimensions and positioning each one
268 // properly in relation to the previous item
269 chart.series.each(function(series, i) {
270 if (series.showInLegend) {
271 Ext.each([].concat(series.yField), function(field, j) {
272 item = Ext.create('Ext.chart.LegendItem', {
275 surface: chart.surface,
278 bbox = item.getBBox();
280 //always measure from x=0, since not all markers go all the way to the left
282 height = bbox.height;
285 spacing = vertical ? padding + height / 2 : padding;
288 spacing = itemSpacing / (vertical ? 2 : 1);
290 // Set the item's position relative to the legend box
291 item.x = mfloor(vertical ? padding : totalWidth + spacing);
292 item.y = mfloor(vertical ? totalHeight + spacing : padding + height / 2);
294 // Collect cumulative dimensions
295 totalWidth += width + spacing;
296 totalHeight += height + spacing;
297 maxWidth = mmax(maxWidth, width);
298 maxHeight = mmax(maxHeight, height);
305 // Store the collected dimensions for later
306 me.width = mfloor((vertical ? maxWidth : totalWidth) + padding * 2);
307 if (vertical && items.length === 1) {
310 me.height = mfloor((vertical ? totalHeight - spacingOffset * spacing : maxHeight) + (padding * 2));
311 me.itemHeight = maxHeight;
314 <span id='Ext-chart-Legend-method-getBBox'> /**
315 </span> * @private Get the bounds for the legend's outer box
317 getBBox: function() {
320 x: Math.round(me.x) - me.boxStrokeWidth / 2,
321 y: Math.round(me.y) - me.boxStrokeWidth / 2,
327 <span id='Ext-chart-Legend-method-createBox'> /**
328 </span> * @private Create the box around the legend items
330 createBox: function() {
335 me.boxSprite.destroy();
338 box = me.boxSprite = me.chart.surface.add(Ext.apply({
340 stroke: me.boxStroke,
341 "stroke-width": me.boxStrokeWidth,
349 <span id='Ext-chart-Legend-method-updatePosition'> /**
350 </span> * @private Update the position of all the legend's sprites to match its current x/y values
352 updatePosition: function() {
355 legendWidth = me.width,
356 legendHeight = me.height,
357 padding = me.padding,
359 chartBBox = chart.chartBBox,
360 insets = chart.insetPadding,
361 chartWidth = chartBBox.width - (insets * 2),
362 chartHeight = chartBBox.height - (insets * 2),
363 chartX = chartBBox.x + insets,
364 chartY = chartBBox.y + insets,
365 surface = chart.surface,
368 if (me.isDisplayed()) {
369 // Find the position based on the dimensions
370 switch(me.position) {
371 case "left":
373 y = mfloor(chartY + chartHeight / 2 - legendHeight / 2);
375 case "right":
376 x = mfloor(surface.width - legendWidth) - insets;
377 y = mfloor(chartY + chartHeight / 2 - legendHeight / 2);
379 case "top":
380 x = mfloor(chartX + chartWidth / 2 - legendWidth / 2);
383 case "bottom":
384 x = mfloor(chartX + chartWidth / 2 - legendWidth / 2);
385 y = mfloor(surface.height - legendHeight) - insets;
388 x = mfloor(me.origX) + insets;
389 y = mfloor(me.origY) + insets;
394 // Update the position of each item
395 Ext.each(me.items, function(item) {
396 item.updatePosition();
398 // Update the position of the outer box
399 me.boxSprite.setAttributes(me.getBBox(), true);