Version 3.18.1

APIs

  • Begin typing in the search box above to see results.
Show:

File: charts/js/ChartLegend.js

 /**
 * ChartLegend provides a legend for a chart.
 *
 * @class ChartLegend
 * @module charts
 * @submodule charts-legend
 * @extends Widget
 */
 Y.ChartLegend = Y.Base.create("chartlegend", Y.Widget, [Y.Renderer], {
 /**
 * Initializes the chart.
 *
 * @method initializer
 * @private
 */
 initializer: function()
 {
 this._items = [];
 },
 
 /**
 * @method renderUI
 * @private
 */
 renderUI: function()
 {
 var bb = this.get("boundingBox"),
 cb = this.get("contentBox"),
 styles = this.get("styles").background,
 background = new Y.Rect({
 graphic: cb,
 fill: styles.fill,
 stroke: styles.border
 });
 bb.setStyle("display", "block");
 bb.setStyle("position", "absolute");
 this.set("background", background);
 },
 
 /**
 * @method bindUI
 * @private
 */
 bindUI: function()
 {
 this.get("chart").after("seriesCollectionChange", Y.bind(this._updateHandler, this));
 this.get("chart").after("stylesChange", Y.bind(this._updateHandler, this));
 this.after("stylesChange", this._updateHandler);
 this.after("positionChange", this._positionChangeHandler);
 this.after("widthChange", this._handleSizeChange);
 this.after("heightChange", this._handleSizeChange);
 },
 
 /**
 * @method syncUI
 * @private
 */
 syncUI: function()
 {
 var w = this.get("width"),
 h = this.get("height");
 if(isFinite(w) && isFinite(h) && w > 0 && h > 0)
 {
 this._drawLegend();
 }
 },
 
 /**
 * Handles changes to legend.
 *
 * @method _updateHandler
 * @param {Object} e Event object
 * @private
 */
 _updateHandler: function()
 {
 if(this.get("rendered"))
 {
 this._drawLegend();
 }
 },
 
 /**
 * Handles position changes.
 *
 * @method _positionChangeHandler
 * @param {Object} e Event object
 * @private
 */
 _positionChangeHandler: function()
 {
 var chart = this.get("chart"),
 parentNode = this._parentNode;
 if(parentNode && ((chart && this.get("includeInChartLayout"))))
 {
 this.fire("legendRendered");
 }
 else if(this.get("rendered"))
 {
 this._drawLegend();
 }
 },
 
 /**
 * Updates the legend when the size changes.
 *
 * @method _handleSizeChange
 * @param {Object} e Event object.
 * @private
 */
 _handleSizeChange: function(e)
 {
 var attrName = e.attrName,
 pos = this.get(POSITION),
 vert = pos === LEFT || pos === RIGHT,
 hor = pos === BOTTOM || pos === TOP;
 if((hor && attrName === WIDTH) || (vert && attrName === HEIGHT))
 {
 this._drawLegend();
 }
 },
 
 /**
 * Draws the legend
 *
 * @method _drawLegend
 * @private
 */
 _drawLegend: function()
 {
 if(this._drawing)
 {
 this._callLater = true;
 return;
 }
 this._drawing = true;
 this._callLater = false;
 if(this.get("includeInChartLayout"))
 {
 this.get("chart")._itemRenderQueue.unshift(this);
 }
 var chart = this.get("chart"),
 node = this.get("contentBox"),
 seriesCollection = chart.get("seriesCollection"),
 series,
 styles = this.get("styles"),
 padding = styles.padding,
 itemStyles = styles.item,
 seriesStyles,
 hSpacing = itemStyles.hSpacing,
 vSpacing = itemStyles.vSpacing,
 direction = this.get("direction"),
 align = direction === "vertical" ? styles.vAlign : styles.hAlign,
 marker = styles.marker,
 labelStyles = itemStyles.label,
 displayName,
 layout = this._layout[direction],
 i,
 len,
 isArray,
 legendShape,
 shape,
 shapeClass,
 item,
 fill,
 border,
 fillColors,
 borderColors,
 borderWeight,
 items = [],
 markerWidth = marker.width,
 markerHeight = marker.height,
 totalWidth = 0 - hSpacing,
 totalHeight = 0 - vSpacing,
 maxWidth = 0,
 maxHeight = 0,
 itemWidth,
 itemHeight;
 if(marker && marker.shape)
 {
 legendShape = marker.shape;
 }
 this._destroyLegendItems();
 if(chart instanceof Y.PieChart)
 {
 series = seriesCollection[0];
 displayName = series.get("categoryAxis").getDataByKey(series.get("categoryKey"));
 seriesStyles = series.get("styles").marker;
 fillColors = seriesStyles.fill.colors;
 borderColors = seriesStyles.border.colors;
 borderWeight = seriesStyles.border.weight;
 i = 0;
 len = displayName.length;
 shape = legendShape || Y.Circle;
 isArray = Y.Lang.isArray(shape);
 for(; i < len; ++i)
 {
 shape = isArray ? shape[i] : shape;
 fill = {
 color: fillColors[i]
 };
 border = {
 colors: borderColors[i],
 weight: borderWeight
 };
 displayName = chart.getSeriesItems(series, i).category.value;
 item = this._getLegendItem(node, this._getShapeClass(shape), fill, border, labelStyles, markerWidth, markerHeight, displayName);
 itemWidth = item.width;
 itemHeight = item.height;
 maxWidth = Math.max(maxWidth, itemWidth);
 maxHeight = Math.max(maxHeight, itemHeight);
 totalWidth += itemWidth + hSpacing;
 totalHeight += itemHeight + vSpacing;
 items.push(item);
 }
 }
 else
 {
 i = 0;
 len = seriesCollection.length;
 for(; i < len; ++i)
 {
 series = seriesCollection[i];
 seriesStyles = this._getStylesBySeriesType(series, shape);
 if(!legendShape)
 {
 shape = seriesStyles.shape;
 if(!shape)
 {
 shape = Y.Circle;
 }
 }
 shapeClass = Y.Lang.isArray(shape) ? shape[i] : shape;
 item = this._getLegendItem(
 node,
 this._getShapeClass(shape),
 seriesStyles.fill,
 seriesStyles.border,
 labelStyles,
 markerWidth,
 markerHeight,
 series.get("valueDisplayName")
 );
 itemWidth = item.width;
 itemHeight = item.height;
 maxWidth = Math.max(maxWidth, itemWidth);
 maxHeight = Math.max(maxHeight, itemHeight);
 totalWidth += itemWidth + hSpacing;
 totalHeight += itemHeight + vSpacing;
 items.push(item);
 }
 }
 this._drawing = false;
 if(this._callLater)
 {
 this._drawLegend();
 }
 else
 {
 layout._positionLegendItems.apply(
 this,
 [items, maxWidth, maxHeight, totalWidth, totalHeight, padding, hSpacing, vSpacing, align]
 );
 this._updateBackground(styles);
 this.fire("legendRendered");
 }
 },
 
 /**
 * Updates the background for the legend.
 *
 * @method _updateBackground
 * @param {Object} styles Reference to the legend's styles attribute
 * @private
 */
 _updateBackground: function(styles)
 {
 var backgroundStyles = styles.background,
 contentRect = this._contentRect,
 padding = styles.padding,
 x = contentRect.left - padding.left,
 y = contentRect.top - padding.top,
 w = contentRect.right - x + padding.right,
 h = contentRect.bottom - y + padding.bottom;
 this.get("background").set({
 fill: backgroundStyles.fill,
 stroke: backgroundStyles.border,
 width: w,
 height: h,
 x: x,
 y: y
 });
 },
 
 /**
 * Retrieves the marker styles based on the type of series. For series that contain a marker, the marker styles are returned.
 *
 * @method _getStylesBySeriesType
 * @param {CartesianSeries | PieSeries} The series in which the style properties will be received.
 * @return Object An object containing fill, border and shape information.
 * @private
 */
 _getStylesBySeriesType: function(series)
 {
 var styles = series.get("styles"),
 color;
 if(series instanceof Y.LineSeries || series instanceof Y.StackedLineSeries)
 {
 styles = series.get("styles").line;
 color = styles.color || series._getDefaultColor(series.get("graphOrder"), "line");
 return {
 border: {
 weight: 1,
 color: color
 },
 fill: {
 color: color
 }
 };
 }
 else if(series instanceof Y.AreaSeries || series instanceof Y.StackedAreaSeries)
 {
 styles = series.get("styles").area;
 color = styles.color || series._getDefaultColor(series.get("graphOrder"), "slice");
 return {
 border: {
 weight: 1,
 color: color
 },
 fill: {
 color: color
 }
 };
 }
 else
 {
 styles = series.get("styles").marker;
 return {
 fill: styles.fill,
 
 border: {
 weight: styles.border.weight,
 
 color: styles.border.color,
 
 shape: styles.shape
 },
 shape: styles.shape
 };
 }
 },
 
 /**
 * Returns a legend item consisting of the following properties:
 * <dl>
 * <dt>node</dt><dd>The `Node` containing the legend item elements.</dd>
 * <dt>shape</dt><dd>The `Shape` element for the legend item.</dd>
 * <dt>textNode</dt><dd>The `Node` containing the text></dd>
 * <dt>text</dt><dd></dd>
 * </dl>
 *
 * @method _getLegendItem
 * @param {Node} shapeProps Reference to the `node` attribute.
 * @param {String | Class} shapeClass The type of shape
 * @param {Object} fill Properties for the shape's fill
 * @param {Object} border Properties for the shape's border
 * @param {String} labelStyles String to be rendered as the legend's text
 * @param {Number} width Total width of the legend item
 * @param {Number} height Total height of the legend item
 * @param {String} text Text for the legendItem
 * @return Object
 * @private
 */
 _getLegendItem: function(node, shapeClass, fill, border, labelStyles, w, h, text)
 {
 var containerNode = Y.Node.create("<div>"),
 textField = Y.Node.create("<span>"),
 shape,
 dimension,
 padding,
 left,
 item,
 ShapeClass = shapeClass;
 containerNode.setStyle(POSITION, "absolute");
 textField.setStyle(POSITION, "absolute");
 textField.setStyles(labelStyles);
 textField.set("text", text);
 containerNode.appendChild(textField);
 node.append(containerNode);
 dimension = textField.get("offsetHeight");
 padding = dimension - h;
 left = w + padding + 2;
 textField.setStyle("left", left + PX);
 containerNode.setStyle("height", dimension + PX);
 containerNode.setStyle("width", (left + textField.get("offsetWidth")) + PX);
 shape = new ShapeClass({
 fill: fill,
 stroke: border,
 width: w,
 height: h,
 x: padding * 0.5,
 y: padding * 0.5,
 w: w,
 h: h,
 graphic: containerNode
 });
 textField.setStyle("left", dimension + PX);
 item = {
 node: containerNode,
 width: containerNode.get("offsetWidth"),
 height: containerNode.get("offsetHeight"),
 shape: shape,
 textNode: textField,
 text: text
 };
 this._items.push(item);
 return item;
 },
 
 /**
 * Evaluates and returns correct class for drawing a shape.
 *
 * @method _getShapeClass
 * @return Shape
 * @private
 */
 _getShapeClass: function()
 {
 var graphic = this.get("background").get("graphic");
 return graphic._getShapeClass.apply(graphic, arguments);
 },
 
 /**
 * Returns the default hash for the `styles` attribute.
 *
 * @method _getDefaultStyles
 * @return Object
 * @protected
 */
 _getDefaultStyles: function()
 {
 var styles = {
 padding: {
 top: 8,
 right: 8,
 bottom: 8,
 left: 9
 },
 gap: 10,
 hAlign: "center",
 vAlign: "top",
 marker: this._getPlotDefaults(),
 item: {
 hSpacing: 10,
 vSpacing: 5,
 label: {
 color:"#808080",
 fontSize:"85%",
 whiteSpace: "nowrap"
 }
 },
 background: {
 shape: "rect",
 fill:{
 color:"#faf9f2"
 },
 border: {
 color:"#dad8c9",
 weight: 1
 }
 }
 };
 return styles;
 },
 
 /**
 * Gets the default values for series that use the utility. This method is used by
 * the class' `styles` attribute's getter to get build default values.
 *
 * @method _getPlotDefaults
 * @return Object
 * @protected
 */
 _getPlotDefaults: function()
 {
 var defs = {
 width: 10,
 height: 10
 };
 return defs;
 },
 
 /**
 * Destroys legend items.
 *
 * @method _destroyLegendItems
 * @private
 */
 _destroyLegendItems: function()
 {
 var item;
 if(this._items)
 {
 while(this._items.length > 0)
 {
 item = this._items.shift();
 item.shape.get("graphic").destroy();
 item.node.empty();
 item.node.destroy(true);
 item.node = null;
 item = null;
 }
 }
 this._items = [];
 },
 
 /**
 * Maps layout classes.
 *
 * @property _layout
 * @private
 */
 _layout: {
 vertical: VerticalLegendLayout,
 horizontal: HorizontalLegendLayout
 },
 
 /**
 * Destructor implementation ChartLegend class. Removes all items and the Graphic instance from the widget.
 *
 * @method destructor
 * @protected
 */
 destructor: function()
 {
 var background = this.get("background"),
 backgroundGraphic;
 this._destroyLegendItems();
 if(background)
 {
 backgroundGraphic = background.get("graphic");
 if(backgroundGraphic)
 {
 backgroundGraphic.destroy();
 }
 else
 {
 background.destroy();
 }
 }
 
 }
 }, {
 ATTRS: {
 /**
 * Indicates whether the chart's contentBox is the parentNode for the legend.
 *
 * @attribute includeInChartLayout
 * @type Boolean
 * @private
 */
 includeInChartLayout: {
 value: false
 },
 
 /**
 * Reference to the `Chart` instance.
 *
 * @attribute chart
 * @type Chart
 */
 chart: {
 setter: function(val)
 {
 this.after("legendRendered", Y.bind(val._itemRendered, val));
 return val;
 }
 },
 
 /**
 * Indicates the direction in relation of the legend's layout. The `direction` of the legend is determined by its
 * `position` value.
 *
 * @attribute direction
 * @type String
 */
 direction: {
 value: "vertical"
 },
 
 /**
 * Indicates the position and direction of the legend. Possible values are `left`, `top`, `right` and `bottom`.
 * Values of `left` and `right` values have a `direction` of `vertical`. Values of `top` and `bottom` values have
 * a `direction` of `horizontal`.
 *
 * @attribute position
 * @type String
 */
 position: {
 lazyAdd: false,
 
 value: "right",
 
 setter: function(val)
 {
 if(val === TOP || val === BOTTOM)
 {
 this.set("direction", HORIZONTAL);
 }
 else if(val === LEFT || val === RIGHT)
 {
 this.set("direction", VERTICAL);
 }
 return val;
 }
 },
 
 /**
 * The width of the legend. Depending on the implementation of the ChartLegend, this value is `readOnly`.
 * By default, the legend is included in the layout of the `Chart` that it references. Under this circumstance,
 * `width` is always `readOnly`. When the legend is rendered in its own dom element, the `readOnly` status is
 * determined by the direction of the legend. If the `position` is `left` or `right` or the `direction` is
 * `vertical`, width is `readOnly`. If the position is `top` or `bottom` or the `direction` is `horizontal`,
 * width can be explicitly set. If width is not explicitly set, the width will be determined by the width of the
 * legend's parent element.
 *
 * @attribute width
 * @type Number
 */
 width: {
 getter: function()
 {
 var chart = this.get("chart"),
 parentNode = this._parentNode;
 if(parentNode)
 {
 if((chart && this.get("includeInChartLayout")) || this._width)
 {
 if(!this._width)
 {
 this._width = 0;
 }
 return this._width;
 }
 else
 {
 return parentNode.get("offsetWidth");
 }
 }
 return "";
 },
 
 setter: function(val)
 {
 this._width = val;
 return val;
 }
 },
 
 /**
 * The height of the legend. Depending on the implementation of the ChartLegend, this value is `readOnly`.
 * By default, the legend is included in the layout of the `Chart` that it references. Under this circumstance,
 * `height` is always `readOnly`. When the legend is rendered in its own dom element, the `readOnly` status is
 * determined by the direction of the legend. If the `position` is `top` or `bottom` or the `direction` is
 * `horizontal`, height is `readOnly`. If the position is `left` or `right` or the `direction` is `vertical`,
 * height can be explicitly set. If height is not explicitly set, the height will be determined by the width of the
 * legend's parent element.
 *
 * @attribute height
 * @type Number
 */
 height: {
 valueFn: "_heightGetter",
 
 getter: function()
 {
 var chart = this.get("chart"),
 parentNode = this._parentNode;
 if(parentNode)
 {
 if((chart && this.get("includeInChartLayout")) || this._height)
 {
 if(!this._height)
 {
 this._height = 0;
 }
 return this._height;
 }
 else
 {
 return parentNode.get("offsetHeight");
 }
 }
 return "";
 },
 
 setter: function(val)
 {
 this._height = val;
 return val;
 }
 },
 
 /**
 * Indicates the x position of legend.
 *
 * @attribute x
 * @type Number
 * @readOnly
 */
 x: {
 lazyAdd: false,
 
 value: 0,
 
 setter: function(val)
 {
 var node = this.get("boundingBox");
 if(node)
 {
 node.setStyle(LEFT, val + PX);
 }
 return val;
 }
 },
 
 /**
 * Indicates the y position of legend.
 *
 * @attribute y
 * @type Number
 * @readOnly
 */
 y: {
 lazyAdd: false,
 
 value: 0,
 
 setter: function(val)
 {
 var node = this.get("boundingBox");
 if(node)
 {
 node.setStyle(TOP, val + PX);
 }
 return val;
 }
 },
 
 /**
 * Array of items contained in the legend. Each item is an object containing the following properties:
 *
 * <dl>
 * <dt>node</dt><dd>Node containing text for the legend item.</dd>
 * <dt>marker</dt><dd>Shape for the legend item.</dd>
 * </dl>
 *
 * @attribute items
 * @type Array
 * @readOnly
 */
 items: {
 getter: function()
 {
 return this._items;
 }
 },
 
 /**
 * Background for the legend.
 *
 * @attribute background
 * @type Rect
 */
 background: {}
 
 /**
 * Properties used to display and style the ChartLegend. This attribute is inherited from `Renderer`.
 * Below are the default values:
 *
 * <dl>
 * <dt>gap</dt><dd>Distance, in pixels, between the `ChartLegend` instance and the chart's content. When `ChartLegend`
 * is rendered within a `Chart` instance this value is applied.</dd>
 * <dt>hAlign</dt><dd>Defines the horizontal alignment of the `items` in a `ChartLegend` rendered in a horizontal direction.
 * This value is applied when the instance's `position` is set to top or bottom. This attribute can be set to left, center
 * or right. The default value is center.</dd>
 * <dt>vAlign</dt><dd>Defines the vertical alignment of the `items` in a `ChartLegend` rendered in vertical direction. This
 * value is applied when the instance's `position` is set to left or right. The attribute can be set to top, middle or
 * bottom. The default value is middle.</dd>
 * <dt>item</dt><dd>Set of style properties applied to the `items` of the `ChartLegend`.
 * <dl>
 * <dt>hSpacing</dt><dd>Horizontal distance, in pixels, between legend `items`.</dd>
 * <dt>vSpacing</dt><dd>Vertical distance, in pixels, between legend `items`.</dd>
 * <dt>label</dt><dd>Properties for the text of an `item`.
 * <dl>
 * <dt>color</dt><dd>Color of the text. The default values is "#808080".</dd>
 * <dt>fontSize</dt><dd>Font size for the text. The default value is "85%".</dd>
 * </dl>
 * </dd>
 * <dt>marker</dt><dd>Properties for the `item` markers.
 * <dl>
 * <dt>width</dt><dd>Specifies the width of the markers.</dd>
 * <dt>height</dt><dd>Specifies the height of the markers.</dd>
 * </dl>
 * </dd>
 * </dl>
 * </dd>
 * <dt>background</dt><dd>Properties for the `ChartLegend` background.
 * <dl>
 * <dt>fill</dt><dd>Properties for the background fill.
 * <dl>
 * <dt>color</dt><dd>Color for the fill. The default value is "#faf9f2".</dd>
 * </dl>
 * </dd>
 * <dt>border</dt><dd>Properties for the background border.
 * <dl>
 * <dt>color</dt><dd>Color for the border. The default value is "#dad8c9".</dd>
 * <dt>weight</dt><dd>Weight of the border. The default values is 1.</dd>
 * </dl>
 * </dd>
 * </dl>
 * </dd>
 * </dl>
 *
 * @attribute styles
 * @type Object
 */
 }
 });
 
 

AltStyle によって変換されたページ (->オリジナル) /