X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/src/chart/LegendItem.js diff --git a/src/chart/LegendItem.js b/src/chart/LegendItem.js new file mode 100644 index 00000000..9ce396a9 --- /dev/null +++ b/src/chart/LegendItem.js @@ -0,0 +1,211 @@ +/** + * @class Ext.chart.LegendItem + * @extends Ext.draw.CompositeSprite + * A single item of a legend (marker plus label) + * @constructor + */ +Ext.define('Ext.chart.LegendItem', { + + /* Begin Definitions */ + + extend: 'Ext.draw.CompositeSprite', + + requires: ['Ext.chart.Shape'], + + /* End Definitions */ + + // Position of the item, relative to the upper-left corner of the legend box + x: 0, + y: 0, + zIndex: 500, + + constructor: function(config) { + this.callParent(arguments); + this.createLegend(config); + }, + + /** + * Creates all the individual sprites for this legend item + */ + createLegend: function(config) { + var me = this, + index = config.yFieldIndex, + series = me.series, + seriesType = series.type, + idx = me.yFieldIndex, + legend = me.legend, + surface = me.surface, + refX = legend.x + me.x, + refY = legend.y + me.y, + bbox, z = me.zIndex, + markerConfig, label, mask, + radius, toggle = false, + seriesStyle = Ext.apply(series.seriesStyle, series.style); + + function getSeriesProp(name) { + var val = series[name]; + return (Ext.isArray(val) ? val[idx] : val); + } + + label = me.add('label', surface.add({ + type: 'text', + x: 20, + y: 0, + zIndex: z || 0, + font: legend.labelFont, + text: getSeriesProp('title') || getSeriesProp('yField') + })); + + // Line series - display as short line with optional marker in the middle + if (seriesType === 'line' || seriesType === 'scatter') { + if(seriesType === 'line') { + me.add('line', surface.add({ + type: 'path', + path: 'M0.5,0.5L16.5,0.5', + zIndex: z, + "stroke-width": series.lineWidth, + "stroke-linejoin": "round", + "stroke-dasharray": series.dash, + stroke: seriesStyle.stroke || '#000', + style: { + cursor: 'pointer' + } + })); + } + if (series.showMarkers || seriesType === 'scatter') { + markerConfig = Ext.apply(series.markerStyle, series.markerConfig || {}); + me.add('marker', Ext.chart.Shape[markerConfig.type](surface, { + fill: markerConfig.fill, + x: 8.5, + y: 0.5, + zIndex: z, + radius: markerConfig.radius || markerConfig.size, + style: { + cursor: 'pointer' + } + })); + } + } + // All other series types - display as filled box + else { + me.add('box', surface.add({ + type: 'rect', + zIndex: z, + x: 0, + y: 0, + width: 12, + height: 12, + fill: series.getLegendColor(index), + style: { + cursor: 'pointer' + } + })); + } + + me.setAttributes({ + hidden: false + }, true); + + bbox = me.getBBox(); + + mask = me.add('mask', surface.add({ + type: 'rect', + x: bbox.x, + y: bbox.y, + width: bbox.width || 20, + height: bbox.height || 20, + zIndex: (z || 0) + 1000, + fill: '#f00', + opacity: 0, + style: { + 'cursor': 'pointer' + } + })); + + //add toggle listener + me.on('mouseover', function() { + label.setStyle({ + 'font-weight': 'bold' + }); + mask.setStyle({ + 'cursor': 'pointer' + }); + series._index = index; + series.highlightItem(); + }, me); + + me.on('mouseout', function() { + label.setStyle({ + 'font-weight': 'normal' + }); + series._index = index; + series.unHighlightItem(); + }, me); + + if (!series.visibleInLegend(index)) { + toggle = true; + label.setAttributes({ + opacity: 0.5 + }, true); + } + + me.on('mousedown', function() { + if (!toggle) { + series.hideAll(); + label.setAttributes({ + opacity: 0.5 + }, true); + } else { + series.showAll(); + label.setAttributes({ + opacity: 1 + }, true); + } + toggle = !toggle; + }, me); + me.updatePosition({x:0, y:0}); //Relative to 0,0 at first so that the bbox is calculated correctly + }, + + /** + * Update the positions of all this item's sprites to match the root position + * of the legend box. + * @param {Object} relativeTo (optional) If specified, this object's 'x' and 'y' values will be used + * as the reference point for the relative positioning. Defaults to the Legend. + */ + updatePosition: function(relativeTo) { + var me = this, + items = me.items, + ln = items.length, + i = 0, + item; + if (!relativeTo) { + relativeTo = me.legend; + } + for (; i < ln; i++) { + item = items[i]; + switch (item.type) { + case 'text': + item.setAttributes({ + x: 20 + relativeTo.x + me.x, + y: relativeTo.y + me.y + }, true); + break; + case 'rect': + item.setAttributes({ + translate: { + x: relativeTo.x + me.x, + y: relativeTo.y + me.y - 6 + } + }, true); + break; + default: + item.setAttributes({ + translate: { + x: relativeTo.x + me.x, + y: relativeTo.y + me.y + } + }, true); + } + } + } +}); \ No newline at end of file