/**
* Adds legend functionality to charts.
*
* @module charts
* @submodule charts-legend
*/
TOP = "top",
RIGHT = "right",
BOTTOM = "bottom",
LEFT = "left",
EXTERNAL = "external",
HORIZONTAL = "horizontal",
VERTICAL = "vertical",
WIDTH = "width",
HEIGHT = "height",
POSITION = "position",
_X = "x",
_Y = "y",
PX = "px",
LEGEND = {
{
if(legend)
{
}
if(val instanceof Y.ChartLegend)
{
}
else
{
{
val.includeInChartLayout = true;
}
}
return legend;
}
},
/**
* Contains methods for displaying items horizontally in a legend.
*
* @module charts
* @submodule charts-legend
* @class HorizontalLegendLayout
*/
/**
* Displays items horizontally in a legend.
*
* @method _positionLegendItems
* @param {Array} items Array of items to display in the legend.
* @param {Number} maxWidth The width of the largest item in the legend.
* @param {Number} maxHeight The height of the largest item in the legend.
* @param {Number} totalWidth The total width of all items in a legend.
* @param {Number} totalHeight The total height of all items in a legend.
* @param {Number} padding The left, top, right and bottom padding properties for the legend.
* @param {Number} horizontalGap The horizontal distance between items in a legend.
* @param {Number} verticalGap The vertical distance between items in a legend.
* @param {String} hAlign The horizontal alignment of the legend.
* @param {String} vAlign The vertical alignment of the legend.
* @protected
*/
_positionLegendItems: function(items, maxWidth, maxHeight, totalWidth, totalHeight, padding, horizontalGap, verticalGap, hAlign, vAlign)
{
var i = 0,
rowIterator = 0,
item,
node,
len,
rows,
row,
left,
top,
{
topHeight += verticalGap;
legendWidth = HorizontalLegendLayout.getStartPoint(width, totalWidthArray[rowIterator], hAlign, padding);
for(i = 0; i < len; ++i)
{
item.x = legendWidth;
item.y = 0;
}
}
this._contentRect = {
};
if(this.get("includeInChartLayout"))
{
}
},
/**
* Creates row and total width arrays used for displaying multiple rows of
* legend items based on the items, available width and horizontalGap for the legend.
*
* @method _setRowArrays
* @param {Array} items Array of legend items to display in a legend.
* @param {Number} limit Total available width for displaying items in a legend.
* @param {Number} horizontalGap Horizontal distance between items in a legend.
* @protected
*/
{
i = 1,
rowIterator = 0,
totalWidthArray = [[totalWidth]];
for(; i < len; ++i)
{
{
}
else
{
if(rowArray[rowIterator])
{
rowIterator += 1;
}
}
}
},
/**
* Returns the starting x-coordinate for a row of legend items.
*
* @method getStartPoint
* @param {Number} w Width of the legend.
* @param {Number} totalWidth Total width of all labels in the row.
* @param {String} align Horizontal alignment of items for the legend.
* @param {Object} padding Object contain left, top, right and bottom padding properties.
* @return Number
* @protected
*/
{
var startPoint;
switch(align)
{
case LEFT :
break;
case "center" :
break;
case RIGHT :
break;
}
return startPoint;
}
},
/**
* Contains methods for displaying items vertically in a legend.
*
* @module charts
* @submodule charts-legend
* @class VerticalLegendLayout
*/
/**
* Displays items vertically in a legend.
*
* @method _positionLegendItems
* @param {Array} items Array of items to display in the legend.
* @param {Number} maxWidth The width of the largest item in the legend.
* @param {Number} maxHeight The height of the largest item in the legend.
* @param {Number} totalWidth The total width of all items in a legend.
* @param {Number} totalHeight The total height of all items in a legend.
* @param {Number} padding The left, top, right and bottom padding properties for the legend.
* @param {Number} horizontalGap The horizontal distance between items in a legend.
* @param {Number} verticalGap The vertical distance between items in a legend.
* @param {String} hAlign The horizontal alignment of the legend.
* @param {String} vAlign The vertical alignment of the legend.
* @protected
*/
_positionLegendItems: function(items, maxWidth, maxHeight, totalWidth, totalHeight, padding, horizontalGap, verticalGap, hAlign, vAlign)
{
var i = 0,
columnIterator = 0,
item,
node,
len,
left,
top,
{
legendHeight = VerticalLegendLayout.getStartPoint(height, totalHeightArray[columnIterator], vAlign, padding);
legendWidth = 0;
for(i = 0; i < len; ++i)
{
item.y = legendHeight;
}
leftWidth += legendWidth;
}
this._contentRect = {
};
if(this.get("includeInChartLayout"))
{
}
},
/**
* Creates column and total height arrays used for displaying multiple columns of
* legend items based on the items, available height and verticalGap for the legend.
*
* @method _setColumnArrays
* @param {Array} items Array of legend items to display in a legend.
* @param {Number} limit Total available height for displaying items in a legend.
* @param {Number} verticalGap Vertical distance between items in a legend.
* @protected
*/
{
columnArray = [[item]],
i = 1,
columnIterator = 0,
totalHeightArray = [[totalHeight]];
for(; i < len; ++i)
{
{
}
else
{
{
columnIterator += 1;
}
}
}
},
/**
* Returns the starting y-coordinate for a column of legend items.
*
* @method getStartPoint
* @param {Number} h Height of the legend.
* @param {Number} totalHeight Total height of all labels in the column.
* @param {String} align Vertical alignment of items for the legend.
* @param {Object} padding Object contain left, top, right and bottom padding properties.
* @return Number
* @protected
*/
{
var startPoint;
switch(align)
{
case TOP :
break;
case "middle" :
break;
case BOTTOM :
break;
}
return startPoint;
}
},
/**
* Redraws and position all the components of the chart instance.
*
* @method _redraw
* @private
*/
_redraw: function()
{
if(this._drawing)
{
this._callLater = true;
return;
}
this._drawing = true;
this._callLater = false;
var w = this.get("width"),
h = this.get("height"),
layoutBoxDimensions = this._getLayoutBoxDimensions(),
i = 0,
l,
axis,
graphOverflow = "visible",
diff,
graphRect = {};
{
leftAxesXCoords = [];
l = leftAxesCollection.length;
for(i = l - 1; i > -1; --i)
{
}
}
{
rightAxesXCoords = [];
i = 0;
for(i = l - 1; i > -1; --i)
{
}
}
{
topAxesYCoords = [];
l = topAxesCollection.length;
for(i = l - 1; i > -1; --i)
{
}
}
{
bottomAxesYCoords = [];
for(i = l - 1; i > -1; --i)
{
}
}
if(!allowContentOverflow)
{
if(diff > 0)
{
if(topAxesYCoords)
{
i = 0;
l = topAxesYCoords.length;
for(; i < l; ++i)
{
topAxesYCoords[i] += diff;
}
}
}
if(diff > 0)
{
{
i = 0;
l = bottomAxesYCoords.length;
for(; i < l; ++i)
{
bottomAxesYCoords[i] -= diff;
}
}
}
if(diff > 0)
{
if(leftAxesXCoords)
{
i = 0;
l = leftAxesXCoords.length;
for(; i < l; ++i)
{
leftAxesXCoords[i] += diff;
}
}
}
if(diff > 0)
{
if(rightAxesXCoords)
{
i = 0;
l = rightAxesXCoords.length;
for(; i < l; ++i)
{
rightAxesXCoords[i] -= diff;
}
}
}
}
if(legend)
{
{
{
case "left" :
break;
case "top" :
break;
case "bottom" :
break;
case "right" :
break;
}
}
}
{
l = topAxesCollection.length;
i = 0;
for(; i < l; i++)
{
axis = topAxesCollection[i];
{
}
}
if(axis._hasDataOverflow())
{
graphOverflow = "hidden";
}
}
{
i = 0;
for(; i < l; i++)
{
axis = bottomAxesCollection[i];
{
}
}
if(axis._hasDataOverflow())
{
graphOverflow = "hidden";
}
}
{
l = leftAxesCollection.length;
i = 0;
for(; i < l; ++i)
{
axis = leftAxesCollection[i];
{
}
}
if(axis._hasDataOverflow())
{
graphOverflow = "hidden";
}
}
{
i = 0;
for(; i < l; ++i)
{
axis = rightAxesCollection[i];
{
}
}
if(axis._hasDataOverflow())
{
graphOverflow = "hidden";
}
}
this._drawing = false;
if(this._callLater)
{
this._redraw();
return;
}
if(graph)
{
}
if(this._overlay)
{
}
},
/**
* Positions the legend in a chart and returns the properties of the legend to be used in the
* chart's layout algorithm.
*
* @method _getLayoutDimensions
* @return {Object} The left, top, right and bottom values for the legend.
* @protected
*/
_getLayoutBoxDimensions: function()
{
var box = {
top: 0,
right: 0,
bottom: 0,
left: 0
},
size,
gap;
{
{
switch(position)
{
case TOP :
break;
case BOTTOM :
break;
case RIGHT :
break;
case LEFT:
break;
}
}
}
return box;
},
/**
* Destructor implementation for the CartesianChart class. Calls destroy on all axes, series, legend (if available) and the Graph instance.
* Removes the tooltip and overlay HTML elements.
*
* @method destructor
* @protected
*/
destructor: function()
{
if(legend)
{
}
}
}, {
ATTRS: {
}
});
/**
* Redraws the chart instance.
*
* @method _redraw
* @private
*/
_redraw: function()
{
if(this._drawing)
{
this._callLater = true;
return;
}
this._drawing = true;
this._callLater = false;
w = this.get("width"),
h = this.get("height"),
x = 0,
y = 0,
legendX = 0,
legendY = 0,
gap,
if(graph)
{
if(legend)
{
if((direction == "vertical" && (graphWidth + legendWidth + gap !== w)) || (direction == "horizontal" && (graphHeight + legendHeight + gap !== h)))
{
{
case LEFT :
legendHeight = h;
x = legendWidth + gap;
break;
case TOP :
legendWidth = w;
y = legendHeight + gap;
break;
case RIGHT :
legendHeight = h;
break;
case BOTTOM :
legendWidth = w;
break;
}
}
else
{
{
case LEFT :
x = legendWidth + gap;
break;
case TOP :
y = legendHeight + gap;
break;
case RIGHT :
break;
case BOTTOM :
break;
}
}
}
else
{
}
}
this._drawing = false;
if(this._callLater)
{
this._redraw();
return;
}
if(graph)
{
}
if(legend)
{
}
}
}, {
ATTRS: {
/**
* The legend for the chart.
*
* @attribute
* @type Legend
*/
}
});
Y.PieChart = PieChartLegend;
/**
* ChartLegend provides a legend for a chart.
*
* @class ChartLegend
* @module charts
* @submodule charts-legend
* @extends Widget
*/
/**
* Initializes the chart.
*
* @method initializer
* @private
*/
initializer: function()
{
this._items = [];
},
/**
* @method renderUI
* @private
*/
renderUI: function()
{
background = new Y.Rect({
});
},
/**
* @method bindUI
* @private
*/
bindUI: function()
{
},
/**
* @method syncUI
* @private
*/
syncUI: function()
{
var w = this.get("width"),
h = this.get("height");
{
this._drawLegend();
}
},
/**
* Handles changes to legend.
*
* @method _updateHandler
* @param {Object} e Event object
* @private
*/
_updateHandler: function(e)
{
if(this.get("rendered"))
{
this._drawLegend();
}
},
/**
* Handles position changes.
*
* @method _positionChangeHandler
* @parma {Object} e Event object
* @private
*/
_positionChangeHandler: function(e)
{
parentNode = this._parentNode;
{
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)
{
{
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"))
{
}
i,
len,
item,
fill,
items = [],
maxWidth = 0,
maxHeight = 0,
{
}
this._destroyLegendItems();
{
i = 0;
for(; i < len; ++i)
{
fill = {
color: fillColors[i]
};
border = {
colors: borderColors[i],
};
item = this._getLegendItem(node, this._getShapeClass(shape), fill, border, labelStyles, markerWidth, markerHeight, displayName);
}
}
else
{
i = 0;
for(; i < len; ++i)
{
series = seriesCollection[i];
if(!shape)
{
if(!shape)
{
}
}
item = this._getLegendItem(node, this._getShapeClass(shape), seriesStyles.fill, seriesStyles.border, labelStyles, markerWidth, markerHeight, series.get("valueDisplayName"));
}
}
this._drawing = false;
if(this._callLater)
{
this._drawLegend();
}
else
{
layout._positionLegendItems.apply(this, [items, maxWidth, maxHeight, totalWidth, totalHeight, padding, hSpacing, vSpacing, hAlign, vAlign]);
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)
{
contentRect = this._contentRect,
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)
{
{
return {
border: {
weight: 1,
},
fill: {
}
};
}
{
return {
border: {
weight: 1,
},
fill: {
}
};
}
else
{
return {
border: {
},
};
}
},
/**
* 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} text 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 {HTML | String} text Text for the legendItem
* @return Object
* @private
*/
{
left,
item;
shape = new shapeClass({
width: w,
height: h,
x: padding * 0.5,
y: padding * 0.5,
w: w,
h: h,
});
item = {
};
return item;
},
/**
* Evaluates and returns correct class for drawing a shape.
*
* @method _getShapeClass
* @return Shape
* @private
*/
_getShapeClass: function()
{
},
/**
* 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%"
}
},
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)
{
{
item = null;
}
}
this._items = [];
},
/**
* Maps layout classes.
*
* @property _layout
* @private
*/
_layout: {
},
/**
* Destructor implementation ChartLegend class. Removes all items and the Graphic instance from the widget.
*
* @method destructor
* @protected
*/
destructor: function()
{
this._destroyLegendItems();
if(graphic)
{
}
}
}, {
ATTRS: {
/**
* Indicates whether the chart's contentBox is the parentNode for the legend.
*
* @attribute includeInChartLayout
* @type Boolean
* @private
*/
value: false
},
/**
* Reference to the `Chart` instance.
*
* @attribute chart
* @type Chart
*/
chart: {
{
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",
{
{
}
{
}
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()
{
parentNode = this._parentNode;
if(parentNode)
{
{
if(!this._width)
{
this._width = 0;
}
return this._width;
}
else
{
}
}
return "";
},
{
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()
{
parentNode = this._parentNode;
if(parentNode)
{
{
if(!this._height)
{
this._height = 0;
}
return this._height;
}
else
{
}
}
return "";
},
{
return val;
}
},
/**
* Indicates the x position of legend.
*
* @attribute x
* @type Number
* @readOnly
*/
x: {
lazyAdd: false,
value: 0,
{
if(node)
{
}
return val;
}
},
/**
* Indicates the y position of legend.
*
* @attribute y
* @type Number
* @readOnly
*/
y: {
lazyAdd: false,
value: 0,
{
if(node)
{
}
return val;
}
},
/**
* 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
*/
}
});
/**
* The Chart class is the basic application used to create a chart.
*
* @module charts
* @class Chart
* @constructor
*/
{
{
return new Y.CartesianChart(cfg);
}
else
{
}
}