Show:
                            /**
                             * The CartesianChart class creates a chart with horizontal and vertical axes.
                             *
                             * @class CartesianChart
                             * @extends ChartBase
                             * @constructor
                             * @submodule charts-base
                             */
                            Y.CartesianChart = Y.Base.create("cartesianChart", Y.Widget, [Y.ChartBase, Y.Renderer], {
                                /**
                                 * @method renderUI
                                 * @private
                                 */
                                renderUI: function()
                                {
                                    var bb = this.get("boundingBox"),
                                        cb = this.get("contentBox"),
                                        tt = this.get("tooltip"),
                                        overlayClass = _getClassName("overlay");
                                    //move the position = absolute logic to a class file
                                    bb.setStyle("position", "absolute");
                                    cb.setStyle("position", "absolute");
                                    this._addAxes();
                                    this._addGridlines();
                                    this._addSeries();
                                    if(tt && tt.show)
                                    {
                                        this._addTooltip();
                                    }
                                    if(this.get("interactionType") === "planar")
                                    {
                                        this._overlay = Y.Node.create("<div></div>");
                                        this._overlay.set("id", this.get("id") + "_overlay");
                                        this._overlay.setStyle("position", "absolute");
                                        this._overlay.setStyle("background", "#fff");
                                        this._overlay.setStyle("opacity", 0);
                                        this._overlay.addClass(overlayClass);
                                        this._overlay.setStyle("zIndex", 4);
                                        cb.append(this._overlay);
                                    }
                                    this._setAriaElements(bb, cb);
                                    this._redraw();
                                },
                            
                                /**
                                 * When `interactionType` is set to `planar`, listens for mouse move events and fires `planarEvent:mouseover` or `planarEvent:mouseout`
                                 * depending on the position of the mouse in relation to data points on the `Chart`.
                                 *
                                 * @method _planarEventDispatcher
                                 * @param {Object} e Event object.
                                 * @private
                                 */
                                _planarEventDispatcher: function(e)
                                {
                                    var graph = this.get("graph"),
                                        bb = this.get("boundingBox"),
                                        cb = graph.get("contentBox"),
                                        isTouch = e && e.hasOwnProperty("changedTouches"),
                                        pageX = isTouch ? e.changedTouches[0].pageX : e.pageX,
                                        pageY = isTouch ? e.changedTouches[0].pageY : e.pageY,
                                        posX = pageX - bb.getX(),
                                        posY = pageY - bb.getY(),
                                        offset = {
                                            x: pageX - cb.getX(),
                                            y: pageY - cb.getY()
                                        },
                                        sc = graph.get("seriesCollection"),
                                        series,
                                        i = 0,
                                        index,
                                        oldIndex = this._selectedIndex,
                                        item,
                                        items = [],
                                        categoryItems = [],
                                        valueItems = [],
                                        direction = this.get("direction"),
                                        hasMarkers,
                                        catAxis,
                                        valAxis,
                                        coord,
                                        //data columns and area data could be created on a graph level
                                        markerPlane,
                                        len,
                                        coords;
                                    e.halt(true);
                                    if(direction === "horizontal")
                                    {
                                        catAxis = "x";
                                        valAxis = "y";
                                    }
                                    else
                                    {
                                        valAxis = "x";
                                        catAxis = "y";
                                    }
                                    coord = offset[catAxis];
                                    if(sc)
                                    {
                                        len = sc.length;
                                        while(i < len && !markerPlane)
                                        {
                                            if(sc[i])
                                            {
                                                markerPlane = sc[i].get(catAxis + "MarkerPlane");
                                            }
                                            i++;
                                        }
                                    }
                                    if(markerPlane)
                                    {
                                        len = markerPlane.length;
                                        for(i = 0; i < len; ++i)
                                        {
                                            if(coord <= markerPlane[i].end && coord >= markerPlane[i].start)
                                            {
                                                index = i;
                                                break;
                                            }
                                        }
                                        len = sc.length;
                                        for(i = 0; i < len; ++i)
                                        {
                                            series = sc[i];
                                            coords = series.get(valAxis + "coords");
                                            hasMarkers = series.get("markers");
                                            if(hasMarkers && !isNaN(oldIndex) && oldIndex > -1)
                                            {
                                                series.updateMarkerState("mouseout", oldIndex);
                                            }
                                            if(coords && coords[index] > -1)
                                            {
                                                if(hasMarkers && !isNaN(index) && index > -1)
                                                {
                                                    series.updateMarkerState("mouseover", index);
                                                }
                                                item = this.getSeriesItems(series, index);
                                                categoryItems.push(item.category);
                                                valueItems.push(item.value);
                                                items.push(series);
                                            }
                            
                                        }
                                        this._selectedIndex = index;
                            
                                        /**
                                         * Broadcasts when `interactionType` is set to `planar` and a series' marker plane has received a mouseover event.
                                         *
                                         *
                                         * @event planarEvent:mouseover
                                         * @preventable false
                                         * @param {EventFacade} e Event facade with the following additional
                                         *   properties:
                                         *  <dl>
                                         *      <dt>categoryItem</dt><dd>An array of hashes, each containing information about the category `Axis` of each marker
                                         *      whose plane has been intersected.</dd>
                                         *      <dt>valueItem</dt><dd>An array of hashes, each containing information about the value `Axis` of each marker whose
                                         *      plane has been intersected.</dd>
                                         *      <dt>x</dt><dd>The x-coordinate of the mouse in relation to the Chart.</dd>
                                         *      <dt>y</dt><dd>The y-coordinate of the mouse in relation to the Chart.</dd>
                                         *      <dt>pageX</dt><dd>The x location of the event on the page (including scroll)</dd>
                                         *      <dt>pageY</dt><dd>The y location of the event on the page (including scroll)</dd>
                                         *      <dt>items</dt><dd>An array including all the series which contain a marker whose plane has been intersected.</dd>
                                         *      <dt>index</dt><dd>Index of the markers in their respective series.</dd>
                                         *      <dt>originEvent</dt><dd>Underlying dom event.</dd>
                                         *  </dl>
                                         */
                                        /**
                                         * Broadcasts when `interactionType` is set to `planar` and a series' marker plane has received a mouseout event.
                                         *
                                         * @event planarEvent:mouseout
                                         * @preventable false
                                         * @param {EventFacade} e
                                         */
                                        if(index > -1)
                                        {
                                            this.fire("planarEvent:mouseover", {
                                                categoryItem:categoryItems,
                                                valueItem:valueItems,
                                                x:posX,
                                                y:posY,
                                                pageX:pageX,
                                                pageY:pageY,
                                                items:items,
                                                index:index,
                                                originEvent:e
                                            });
                                        }
                                        else
                                        {
                                            this.fire("planarEvent:mouseout");
                                        }
                                    }
                                },
                            
                                /**
                                 * Indicates the default series type for the chart.
                                 *
                                 * @property _type
                                 * @type {String}
                                 * @private
                                 */
                                _type: "combo",
                            
                                /**
                                 * Queue of axes instances that will be updated. This method is used internally to determine when all axes have been updated.
                                 *
                                 * @property _itemRenderQueue
                                 * @type Array
                                 * @private
                                 */
                                _itemRenderQueue: null,
                            
                                /**
                                 * Adds an `Axis` instance to the `_itemRenderQueue`.
                                 *
                                 * @method _addToAxesRenderQueue
                                 * @param {Axis} axis An `Axis` instance.
                                 * @private
                                 */
                                _addToAxesRenderQueue: function(axis)
                                {
                                    if(!this._itemRenderQueue)
                                    {
                                        this._itemRenderQueue = [];
                                    }
                                    if(Y.Array.indexOf(this._itemRenderQueue, axis) < 0)
                                    {
                                        this._itemRenderQueue.push(axis);
                                    }
                                },
                            
                                /**
                                 * Adds axis instance to the appropriate array based on position
                                 *
                                 * @method _addToAxesCollection
                                 * @param {String} position The position of the axis
                                 * @param {Axis} axis The `Axis` instance
                                 */
                                _addToAxesCollection: function(position, axis)
                                {
                                    var axesCollection = this.get(position + "AxesCollection");
                                    if(!axesCollection)
                                    {
                                        axesCollection = [];
                                        this.set(position + "AxesCollection", axesCollection);
                                    }
                                    axesCollection.push(axis);
                                },
                            
                                /**
                                 * Returns the default value for the `seriesCollection` attribute.
                                 *
                                 * @method _getDefaultSeriesCollection
                                 * @param {Array} val Array containing either `CartesianSeries` instances or objects containing data to construct series instances.
                                 * @return Array
                                 * @private
                                 */
                                _getDefaultSeriesCollection: function()
                                {
                                    var seriesCollection,
                                        dataProvider = this.get("dataProvider");
                                    if(dataProvider)
                                    {
                                        seriesCollection = this._parseSeriesCollection();
                                    }
                                    return seriesCollection;
                                },
                            
                                /**
                                 * Parses and returns a series collection from an object and default properties.
                                 *
                                 * @method _parseSeriesCollection
                                 * @param {Object} val Object contain properties for series being set.
                                 * @return Object
                                 * @private
                                 */
                                _parseSeriesCollection: function(val)
                                {
                                    var dir = this.get("direction"),
                                        seriesStyles = this.get("styles").series,
                                        stylesAreArray = seriesStyles && Y_Lang.isArray(seriesStyles),
                                        stylesIndex,
                                        setStyles,
                                        globalStyles,
                                        sc = [],
                                        catAxis,
                                        valAxis,
                                        tempKeys = [],
                                        series,
                                        seriesKeys = this.get("seriesKeys").concat(),
                                        i,
                                        index,
                                        l,
                                        type = this.get("type"),
                                        key,
                                        catKey,
                                        seriesKey,
                                        graph,
                                        orphans = [],
                                        categoryKey = this.get("categoryKey"),
                                        showMarkers = this.get("showMarkers"),
                                        showAreaFill = this.get("showAreaFill"),
                                        showLines = this.get("showLines");
                                    val = val ? val.concat() : [];
                                    if(dir === "vertical")
                                    {
                                        catAxis = "yAxis";
                                        catKey = "yKey";
                                        valAxis = "xAxis";
                                        seriesKey = "xKey";
                                    }
                                    else
                                    {
                                        catAxis = "xAxis";
                                        catKey = "xKey";
                                        valAxis = "yAxis";
                                        seriesKey = "yKey";
                                    }
                                    l = val.length;
                                    while(val && val.length > 0)
                                    {
                                        series = val.shift();
                                        key = this._getBaseAttribute(series, seriesKey);
                                        if(key)
                                        {
                                            index = Y.Array.indexOf(seriesKeys, key);
                                            if(index > -1)
                                            {
                                                seriesKeys.splice(index, 1);
                                                tempKeys.push(key);
                                                sc.push(series);
                                            }
                                            else
                                            {
                                                orphans.push(series);
                                            }
                                        }
                                        else
                                        {
                                            orphans.push(series);
                                        }
                                    }
                                    while(orphans.length > 0)
                                    {
                                        series = orphans.shift();
                                        if(seriesKeys.length > 0)
                                        {
                                            key = seriesKeys.shift();
                                            this._setBaseAttribute(series, seriesKey, key);
                                            tempKeys.push(key);
                                            sc.push(series);
                                        }
                                        else if(series instanceof Y.CartesianSeries)
                                        {
                                            series.destroy(true);
                                        }
                                    }
                                    if(seriesKeys.length > 0)
                                    {
                                        tempKeys = tempKeys.concat(seriesKeys);
                                    }
                                    l = tempKeys.length;
                                    for(i = 0; i < l; ++i)
                                    {
                                        series = sc[i] || {type:type};
                                        if(series instanceof Y.CartesianSeries)
                                        {
                                            this._parseSeriesAxes(series);
                                        }
                                        else
                                        {
                                            series[catKey] = series[catKey] || categoryKey;
                                            series[seriesKey] = series[seriesKey] || seriesKeys.shift();
                                            series[catAxis] = this._getCategoryAxis();
                                            series[valAxis] = this._getSeriesAxis(series[seriesKey]);
                            
                                            series.type = series.type || type;
                                            series.direction = series.direction || dir;
                            
                                            if(series.type === "combo" ||
                                                series.type === "stackedcombo" ||
                                                series.type === "combospline" ||
                                                series.type === "stackedcombospline")
                                            {
                                                if(showAreaFill !== null)
                                                {
                                                    series.showAreaFill = (series.showAreaFill !== null && series.showAreaFill !== undefined) ?
                                                                           series.showAreaFill : showAreaFill;
                                                }
                                                if(showMarkers !== null)
                                                {
                                                    series.showMarkers = (series.showMarkers !== null && series.showMarkers !== undefined) ? series.showMarkers : showMarkers;
                                                }
                                                if(showLines !== null)
                                                {
                                                    series.showLines = (series.showLines !== null && series.showLines !== undefined) ? series.showLines : showLines;
                                                }
                                            }
                                            if(seriesStyles)
                                            {
                                                stylesIndex = stylesAreArray ? i : series[seriesKey];
                                                globalStyles = seriesStyles[stylesIndex];
                                                if(globalStyles)
                                                {
                                                    setStyles = series.styles;
                                                    if(setStyles)
                                                    {
                                                        series.styles = this._mergeStyles(setStyles, globalStyles);
                                                    }
                                                    else
                                                    {
                                                        series.styles = globalStyles;
                                                    }
                                                }
                                            }
                                            sc[i] = series;
                                        }
                                    }
                                    if(sc)
                                    {
                                        graph = this.get("graph");
                                        graph.set("seriesCollection", sc);
                                        sc = graph.get("seriesCollection");
                                    }
                                    return sc;
                                },
                            
                                /**
                                 * Parse and sets the axes for a series instance.
                                 *
                                 * @method _parseSeriesAxes
                                 * @param {CartesianSeries} series A `CartesianSeries` instance.
                                 * @private
                                 */
                                _parseSeriesAxes: function(series)
                                {
                                    var axes = this.get("axes"),
                                        xAxis = series.get("xAxis"),
                                        yAxis = series.get("yAxis"),
                                        YAxis = Y.Axis,
                                        axis;
                                    if(xAxis && !(xAxis instanceof YAxis) && Y_Lang.isString(xAxis) && axes.hasOwnProperty(xAxis))
                                    {
                                        axis = axes[xAxis];
                                        if(axis instanceof YAxis)
                                        {
                                            series.set("xAxis", axis);
                                        }
                                    }
                                    if(yAxis && !(yAxis instanceof YAxis) && Y_Lang.isString(yAxis) && axes.hasOwnProperty(yAxis))
                                    {
                                        axis = axes[yAxis];
                                        if(axis instanceof YAxis)
                                        {
                                            series.set("yAxis", axis);
                                        }
                                    }
                            
                                },
                            
                                /**
                                 * Returns the category axis instance for the chart.
                                 *
                                 * @method _getCategoryAxis
                                 * @return Axis
                                 * @private
                                 */
                                _getCategoryAxis: function()
                                {
                                    var axis,
                                        axes = this.get("axes"),
                                        categoryAxisName = this.get("categoryAxisName") || this.get("categoryKey");
                                    axis = axes[categoryAxisName];
                                    return axis;
                                },
                            
                                /**
                                 * Returns the value axis for a series.
                                 *
                                 * @method _getSeriesAxis
                                 * @param {String} key The key value used to determine the axis instance.
                                 * @return Axis
                                 * @private
                                 */
                                _getSeriesAxis:function(key, axisName)
                                {
                                    var axes = this.get("axes"),
                                        i,
                                        keys,
                                        axis;
                                    if(axes)
                                    {
                                        if(axisName && axes.hasOwnProperty(axisName))
                                        {
                                            axis = axes[axisName];
                                        }
                                        else
                                        {
                                            for(i in axes)
                                            {
                                                if(axes.hasOwnProperty(i))
                                                {
                                                    keys = axes[i].get("keys");
                                                    if(keys && keys.hasOwnProperty(key))
                                                    {
                                                        axis = axes[i];
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    return axis;
                                },
                            
                                /**
                                 * Gets an attribute from an object, using a getter for Base objects and a property for object
                                 * literals. Used for determining attributes from series/axis references which can be an actual class instance
                                 * or a hash of properties that will be used to create a class instance.
                                 *
                                 * @method _getBaseAttribute
                                 * @param {Object} item Object or instance in which the attribute resides.
                                 * @param {String} key Attribute whose value will be returned.
                                 * @return Object
                                 * @private
                                 */
                                _getBaseAttribute: function(item, key)
                                {
                                    if(item instanceof Y.Base)
                                    {
                                        return item.get(key);
                                    }
                                    if(item.hasOwnProperty(key))
                                    {
                                        return item[key];
                                    }
                                    return null;
                                },
                            
                                /**
                                 * Sets an attribute on an object, using a setter of Base objects and a property for object
                                 * literals. Used for setting attributes on a Base class, either directly or to be stored in an object literal
                                 * for use at instantiation.
                                 *
                                 * @method _setBaseAttribute
                                 * @param {Object} item Object or instance in which the attribute resides.
                                 * @param {String} key Attribute whose value will be assigned.
                                 * @param {Object} value Value to be assigned to the attribute.
                                 * @private
                                 */
                                _setBaseAttribute: function(item, key, value)
                                {
                                    if(item instanceof Y.Base)
                                    {
                                        item.set(key, value);
                                    }
                                    else
                                    {
                                        item[key] = value;
                                    }
                                },
                            
                                /**
                                 * Creates `Axis` instances.
                                 *
                                 * @method _setAxes
                                 * @param {Object} val Object containing `Axis` instances or objects in which to construct `Axis` instances.
                                 * @return Object
                                 * @private
                                 */
                                _setAxes: function(val)
                                {
                                    var hash = this._parseAxes(val),
                                        axes = {},
                                        axesAttrs = {
                                            edgeOffset: "edgeOffset",
                                            calculateEdgeOffset: "calculateEdgeOffset",
                                            position: "position",
                                            overlapGraph:"overlapGraph",
                                            labelValues: "labelValues",
                                            hideFirstMajorUnit: "hideFirstMajorUnit",
                                            hideLastMajorUnit: "hideLastMajorUnit",
                                            labelFunction:"labelFunction",
                                            labelFunctionScope:"labelFunctionScope",
                                            labelFormat:"labelFormat",
                                            appendLabelFunction: "appendLabelFunction",
                                            appendTitleFunction: "appendTitleFunction",
                                            maximum:"maximum",
                                            minimum:"minimum",
                                            roundingMethod:"roundingMethod",
                                            alwaysShowZero:"alwaysShowZero",
                                            scaleType: "scaleType",
                                            title:"title",
                                            width:"width",
                                            height:"height"
                                        },
                                        dp = this.get("dataProvider"),
                                        ai,
                                        i,
                                        pos,
                                        axis,
                                        axisPosition,
                                        dh,
                                        AxisClass,
                                        config,
                                        axesCollection;
                                    for(i in hash)
                                    {
                                        if(hash.hasOwnProperty(i))
                                        {
                                            dh = hash[i];
                                            if(dh instanceof Y.Axis)
                                            {
                                                axis = dh;
                                            }
                                            else
                                            {
                                                axis = null;
                                                config = {};
                                                config.dataProvider = dh.dataProvider || dp;
                                                config.keys = dh.keys;
                            
                                                if(dh.hasOwnProperty("roundingUnit"))
                                                {
                                                    config.roundingUnit = dh.roundingUnit;
                                                }
                                                pos = dh.position;
                                                if(dh.styles)
                                                {
                                                    config.styles = dh.styles;
                                                }
                                                config.position = dh.position;
                                                for(ai in axesAttrs)
                                                {
                                                    if(axesAttrs.hasOwnProperty(ai) && dh.hasOwnProperty(ai))
                                                    {
                                                        config[ai] = dh[ai];
                                                    }
                                                }
                            
                                                //only check for existing axis if we constructed the default axes already
                                                if(val)
                                                {
                                                    axis = this.getAxisByKey(i);
                                                }
                            
                                                if(axis && axis instanceof Y.Axis)
                                                {
                                                    axisPosition = axis.get("position");
                                                    if(pos !== axisPosition)
                                                    {
                                                        if(axisPosition !== "none")
                                                        {
                                                            axesCollection = this.get(axisPosition + "AxesCollection");
                                                            axesCollection.splice(Y.Array.indexOf(axesCollection, axis), 1);
                                                        }
                                                        if(pos !== "none")
                                                        {
                                                            this._addToAxesCollection(pos, axis);
                                                        }
                                                    }
                                                    axis.setAttrs(config);
                                                }
                                                else
                                                {
                                                    AxisClass = this._getAxisClass(dh.type);
                                                    axis = new AxisClass(config);
                                                    axis.after("axisRendered", Y.bind(this._itemRendered, this));
                                                }
                                            }
                            
                                            if(axis)
                                            {
                                                axesCollection = this.get(pos + "AxesCollection");
                                                if(axesCollection && Y.Array.indexOf(axesCollection, axis) > 0)
                                                {
                                                    axis.set("overlapGraph", false);
                                                }
                                                axes[i] = axis;
                                            }
                                        }
                                    }
                                    return axes;
                                },
                            
                                /**
                                 * Adds axes to the chart.
                                 *
                                 * @method _addAxes
                                 * @private
                                 */
                                _addAxes: function()
                                {
                                    var axes = this.get("axes"),
                                        i,
                                        axis,
                                        pos,
                                        w = this.get("width"),
                                        h = this.get("height"),
                                        node = Y.Node.one(this._parentNode);
                                    if(!this._axesCollection)
                                    {
                                        this._axesCollection = [];
                                    }
                                    for(i in axes)
                                    {
                                        if(axes.hasOwnProperty(i))
                                        {
                                            axis = axes[i];
                                            if(axis instanceof Y.Axis)
                                            {
                                                if(!w)
                                                {
                                                    this.set("width", node.get("offsetWidth"));
                                                    w = this.get("width");
                                                }
                                                if(!h)
                                                {
                                                    this.set("height", node.get("offsetHeight"));
                                                    h = this.get("height");
                                                }
                                                this._addToAxesRenderQueue(axis);
                                                pos = axis.get("position");
                                                if(!this.get(pos + "AxesCollection"))
                                                {
                                                    this.set(pos + "AxesCollection", [axis]);
                                                }
                                                else
                                                {
                                                    this.get(pos + "AxesCollection").push(axis);
                                                }
                                                this._axesCollection.push(axis);
                                                if(axis.get("keys").hasOwnProperty(this.get("categoryKey")))
                                                {
                                                    this.set("categoryAxis", axis);
                                                }
                                                axis.render(this.get("contentBox"));
                                            }
                                        }
                                    }
                                },
                            
                                /**
                                 * Renders the Graph.
                                 *
                                 * @method _addSeries
                                 * @private
                                 */
                                _addSeries: function()
                                {
                                    var graph = this.get("graph");
                                    graph.render(this.get("contentBox"));
                            
                                },
                            
                                /**
                                 * Adds gridlines to the chart.
                                 *
                                 * @method _addGridlines
                                 * @private
                                 */
                                _addGridlines: function()
                                {
                                    var graph = this.get("graph"),
                                        hgl = this.get("horizontalGridlines"),
                                        vgl = this.get("verticalGridlines"),
                                        direction = this.get("direction"),
                                        leftAxesCollection = this.get("leftAxesCollection"),
                                        rightAxesCollection = this.get("rightAxesCollection"),
                                        bottomAxesCollection = this.get("bottomAxesCollection"),
                                        topAxesCollection = this.get("topAxesCollection"),
                                        seriesAxesCollection,
                                        catAxis = this.get("categoryAxis"),
                                        hAxis,
                                        vAxis;
                                    if(this._axesCollection)
                                    {
                                        seriesAxesCollection = this._axesCollection.concat();
                                        seriesAxesCollection.splice(Y.Array.indexOf(seriesAxesCollection, catAxis), 1);
                                    }
                                    if(hgl)
                                    {
                                        if(leftAxesCollection && leftAxesCollection[0])
                                        {
                                            hAxis = leftAxesCollection[0];
                                        }
                                        else if(rightAxesCollection && rightAxesCollection[0])
                                        {
                                            hAxis = rightAxesCollection[0];
                                        }
                                        else
                                        {
                                            hAxis = direction === "horizontal" ? catAxis : seriesAxesCollection[0];
                                        }
                                        if(!this._getBaseAttribute(hgl, "axis") && hAxis)
                                        {
                                            this._setBaseAttribute(hgl, "axis", hAxis);
                                        }
                                        if(this._getBaseAttribute(hgl, "axis"))
                                        {
                                            graph.set("horizontalGridlines", hgl);
                                        }
                                    }
                                    if(vgl)
                                    {
                                        if(bottomAxesCollection && bottomAxesCollection[0])
                                        {
                                            vAxis = bottomAxesCollection[0];
                                        }
                                        else if (topAxesCollection && topAxesCollection[0])
                                        {
                                            vAxis = topAxesCollection[0];
                                        }
                                        else
                                        {
                                            vAxis = direction === "vertical" ? catAxis : seriesAxesCollection[0];
                                        }
                                        if(!this._getBaseAttribute(vgl, "axis") && vAxis)
                                        {
                                            this._setBaseAttribute(vgl, "axis", vAxis);
                                        }
                                        if(this._getBaseAttribute(vgl, "axis"))
                                        {
                                            graph.set("verticalGridlines", vgl);
                                        }
                                    }
                                },
                            
                                /**
                                 * Default Function for the axes attribute.
                                 *
                                 * @method _getDefaultAxes
                                 * @return Object
                                 * @private
                                 */
                                _getDefaultAxes: function()
                                {
                                    var axes;
                                    if(this.get("dataProvider"))
                                    {
                                        axes = this._parseAxes();
                                    }
                                    return axes;
                                },
                            
                                /**
                                 * Generates and returns a key-indexed object containing `Axis` instances or objects used to create `Axis` instances.
                                 *
                                 * @method _parseAxes
                                 * @param {Object} axes Object containing `Axis` instances or `Axis` attributes.
                                 * @return Object
                                 * @private
                                 */
                                _parseAxes: function(axes)
                                {
                                    var catKey = this.get("categoryKey"),
                                        axis,
                                        attr,
                                        keys,
                                        newAxes = {},
                                        claimedKeys = [],
                                        newKeys = [],
                                        categoryAxisName = this.get("categoryAxisName") || this.get("categoryKey"),
                                        valueAxisName = this.get("valueAxisName"),
                                        seriesKeys = this.get("seriesKeys").concat(),
                                        i,
                                        l,
                                        ii,
                                        ll,
                                        cIndex,
                                        direction = this.get("direction"),
                                        seriesPosition,
                                        categoryPosition,
                                        valueAxes = [],
                                        seriesAxis = this.get("stacked") ? "stacked" : "numeric";
                                    if(direction === "vertical")
                                    {
                                        seriesPosition = "bottom";
                                        categoryPosition = "left";
                                    }
                                    else
                                    {
                                        seriesPosition = "left";
                                        categoryPosition = "bottom";
                                    }
                                    if(axes)
                                    {
                                        for(i in axes)
                                        {
                                            if(axes.hasOwnProperty(i))
                                            {
                                                axis = axes[i];
                                                keys = this._getBaseAttribute(axis, "keys");
                                                attr = this._getBaseAttribute(axis, "type");
                                                if(attr === "time" || attr === "category")
                                                {
                                                    categoryAxisName = i;
                                                    this.set("categoryAxisName", i);
                                                    if(Y_Lang.isArray(keys) && keys.length > 0)
                                                    {
                                                        catKey = keys[0];
                                                        this.set("categoryKey", catKey);
                                                    }
                                                    newAxes[i] = axis;
                                                }
                                                else if(i === categoryAxisName)
                                                {
                                                    newAxes[i] = axis;
                                                }
                                                else
                                                {
                                                    newAxes[i] = axis;
                                                    if(i !== valueAxisName && keys && Y_Lang.isArray(keys))
                                                    {
                                                        ll = keys.length;
                                                        for(ii = 0; ii < ll; ++ii)
                                                        {
                                                            claimedKeys.push(keys[ii]);
                                                        }
                                                        valueAxes.push(newAxes[i]);
                                                    }
                                                    if(!(this._getBaseAttribute(newAxes[i], "type")))
                                                    {
                                                        this._setBaseAttribute(newAxes[i], "type", seriesAxis);
                                                    }
                                                    if(!(this._getBaseAttribute(newAxes[i], "position")))
                                                    {
                                                        this._setBaseAttribute(
                                                            newAxes[i],
                                                            "position",
                                                            this._getDefaultAxisPosition(newAxes[i], valueAxes, seriesPosition)
                                                        );
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    cIndex = Y.Array.indexOf(seriesKeys, catKey);
                                    if(cIndex > -1)
                                    {
                                        seriesKeys.splice(cIndex, 1);
                                    }
                                    l = seriesKeys.length;
                                    for(i = 0; i < l; ++i)
                                    {
                                        cIndex = Y.Array.indexOf(claimedKeys, seriesKeys[i]);
                                        if(cIndex > -1)
                                        {
                                            newKeys = newKeys.concat(claimedKeys.splice(cIndex, 1));
                                        }
                                    }
                                    claimedKeys = newKeys.concat(claimedKeys);
                                    l = claimedKeys.length;
                                    for(i = 0; i < l; i = i + 1)
                                    {
                                        cIndex = Y.Array.indexOf(seriesKeys, claimedKeys[i]);
                                        if(cIndex > -1)
                                        {
                                            seriesKeys.splice(cIndex, 1);
                                        }
                                    }
                                    if(!newAxes.hasOwnProperty(categoryAxisName))
                                    {
                                        newAxes[categoryAxisName] = {};
                                    }
                                    if(!(this._getBaseAttribute(newAxes[categoryAxisName], "keys")))
                                    {
                                        this._setBaseAttribute(newAxes[categoryAxisName], "keys", [catKey]);
                                    }
                            
                                    if(!(this._getBaseAttribute(newAxes[categoryAxisName], "position")))
                                    {
                                        this._setBaseAttribute(newAxes[categoryAxisName], "position", categoryPosition);
                                    }
                            
                                    if(!(this._getBaseAttribute(newAxes[categoryAxisName], "type")))
                                    {
                                        this._setBaseAttribute(newAxes[categoryAxisName], "type", this.get("categoryType"));
                                    }
                                    if(!newAxes.hasOwnProperty(valueAxisName) && seriesKeys && seriesKeys.length > 0)
                                    {
                                        newAxes[valueAxisName] = {keys:seriesKeys};
                                        valueAxes.push(newAxes[valueAxisName]);
                                    }
                                    if(claimedKeys.length > 0)
                                    {
                                        if(seriesKeys.length > 0)
                                        {
                                            seriesKeys = claimedKeys.concat(seriesKeys);
                                        }
                                        else
                                        {
                                            seriesKeys = claimedKeys;
                                        }
                                    }
                                    if(newAxes.hasOwnProperty(valueAxisName))
                                    {
                                        if(!(this._getBaseAttribute(newAxes[valueAxisName], "position")))
                                        {
                                            this._setBaseAttribute(
                                                newAxes[valueAxisName],
                                                "position",
                                                this._getDefaultAxisPosition(newAxes[valueAxisName], valueAxes, seriesPosition)
                                            );
                                        }
                                        this._setBaseAttribute(newAxes[valueAxisName], "type", seriesAxis);
                                        this._setBaseAttribute(newAxes[valueAxisName], "keys", seriesKeys);
                                    }
                                    if(!this._wereSeriesKeysExplicitlySet())
                                    {
                                        this.set("seriesKeys", seriesKeys, {src: "internal"});
                                    }
                                    return newAxes;
                                },
                            
                                /**
                                 * Determines the position of an axis when one is not specified.
                                 *
                                 * @method _getDefaultAxisPosition
                                 * @param {Axis} axis `Axis` instance.
                                 * @param {Array} valueAxes Array of `Axis` instances.
                                 * @param {String} position Default position depending on the direction of the chart and type of axis.
                                 * @return String
                                 * @private
                                 */
                                _getDefaultAxisPosition: function(axis, valueAxes, position)
                                {
                                    var direction = this.get("direction"),
                                        i = Y.Array.indexOf(valueAxes, axis);
                            
                                    if(valueAxes[i - 1] && valueAxes[i - 1].position)
                                    {
                                        if(direction === "horizontal")
                                        {
                                            if(valueAxes[i - 1].position === "left")
                                            {
                                                position = "right";
                                            }
                                            else if(valueAxes[i - 1].position === "right")
                                            {
                                                position = "left";
                                            }
                                        }
                                        else
                                        {
                                            if (valueAxes[i -1].position === "bottom")
                                            {
                                                position = "top";
                                            }
                                            else
                                            {
                                                position = "bottom";
                                            }
                                        }
                                    }
                                    return position;
                                },
                            
                            
                                /**
                                 * Returns an object literal containing a categoryItem and a valueItem for a given series index. Below is the structure of each:
                                 *
                                 * @method getSeriesItems
                                 * @param {CartesianSeries} series Reference to a series.
                                 * @param {Number} index Index of the specified item within a series.
                                 * @return Object An object literal containing the following:
                                 *
                                 *  <dl>
                                 *      <dt>categoryItem</dt><dd>Object containing the following data related to the category axis of the series.
                                 *  <dl>
                                 *      <dt>axis</dt><dd>Reference to the category axis of the series.</dd>
                                 *      <dt>key</dt><dd>Category key for the series.</dd>
                                 *      <dt>value</dt><dd>Value on the axis corresponding to the series index.</dd>
                                 *  </dl>
                                 *      </dd>
                                 *      <dt>valueItem</dt><dd>Object containing the following data related to the category axis of the series.
                                 *  <dl>
                                 *      <dt>axis</dt><dd>Reference to the value axis of the series.</dd>
                                 *      <dt>key</dt><dd>Value key for the series.</dd>
                                 *      <dt>value</dt><dd>Value on the axis corresponding to the series index.</dd>
                                 *  </dl>
                                 *      </dd>
                                 *  </dl>
                                 */
                                getSeriesItems: function(series, index)
                                {
                                    var xAxis = series.get("xAxis"),
                                        yAxis = series.get("yAxis"),
                                        xKey = series.get("xKey"),
                                        yKey = series.get("yKey"),
                                        categoryItem,
                                        valueItem;
                                    if(this.get("direction") === "vertical")
                                    {
                                        categoryItem = {
                                            axis:yAxis,
                                            key:yKey,
                                            value:yAxis.getKeyValueAt(yKey, index)
                                        };
                                        valueItem = {
                                            axis:xAxis,
                                            key:xKey,
                                            value: xAxis.getKeyValueAt(xKey, index)
                                        };
                                    }
                                    else
                                    {
                                        valueItem = {
                                            axis:yAxis,
                                            key:yKey,
                                            value:yAxis.getKeyValueAt(yKey, index)
                                        };
                                        categoryItem = {
                                            axis:xAxis,
                                            key:xKey,
                                            value: xAxis.getKeyValueAt(xKey, index)
                                        };
                                    }
                                    categoryItem.displayName = series.get("categoryDisplayName");
                                    valueItem.displayName = series.get("valueDisplayName");
                                    categoryItem.value = categoryItem.axis.getKeyValueAt(categoryItem.key, index);
                                    valueItem.value = valueItem.axis.getKeyValueAt(valueItem.key, index);
                                    return {category:categoryItem, value:valueItem};
                                },
                            
                                /**
                                 * Handler for sizeChanged event.
                                 *
                                 * @method _sizeChanged
                                 * @param {Object} e Event object.
                                 * @private
                                 */
                                _sizeChanged: function()
                                {
                                    if(this._axesCollection)
                                    {
                                        var ac = this._axesCollection,
                                            i = 0,
                                            l = ac.length;
                                        for(; i < l; ++i)
                                        {
                                            this._addToAxesRenderQueue(ac[i]);
                                        }
                                        this._redraw();
                                    }
                                },
                            
                                /**
                                 * Returns the maximum distance in pixels that the extends outside the top bounds of all vertical axes.
                                 *
                                 * @method _getTopOverflow
                                 * @param {Array} set1 Collection of axes to check.
                                 * @param {Array} set2 Seconf collection of axes to check.
                                 * @param {Number} width Width of the axes
                                 * @return Number
                                 * @private
                                 */
                                _getTopOverflow: function(set1, set2, height)
                                {
                                    var i = 0,
                                        len,
                                        overflow = 0,
                                        axis;
                                    if(set1)
                                    {
                                        len = set1.length;
                                        for(; i < len; ++i)
                                        {
                                            axis = set1[i];
                                            overflow = Math.max(
                                                overflow,
                                                Math.abs(axis.getMaxLabelBounds().top) - axis.getEdgeOffset(axis.get("styles").majorTicks.count, height)
                                            );
                                        }
                                    }
                                    if(set2)
                                    {
                                        i = 0;
                                        len = set2.length;
                                        for(; i < len; ++i)
                                        {
                                            axis = set2[i];
                                            overflow = Math.max(
                                                overflow,
                                                Math.abs(axis.getMaxLabelBounds().top) - axis.getEdgeOffset(axis.get("styles").majorTicks.count, height)
                                            );
                                        }
                                    }
                                    return overflow;
                                },
                            
                                /**
                                 * Returns the maximum distance in pixels that the extends outside the right bounds of all horizontal axes.
                                 *
                                 * @method _getRightOverflow
                                 * @param {Array} set1 Collection of axes to check.
                                 * @param {Array} set2 Seconf collection of axes to check.
                                 * @param {Number} width Width of the axes
                                 * @return Number
                                 * @private
                                 */
                                _getRightOverflow: function(set1, set2, width)
                                {
                                    var i = 0,
                                        len,
                                        overflow = 0,
                                        axis;
                                    if(set1)
                                    {
                                        len = set1.length;
                                        for(; i < len; ++i)
                                        {
                                            axis = set1[i];
                                            overflow = Math.max(
                                                overflow,
                                                axis.getMaxLabelBounds().right - axis.getEdgeOffset(axis.get("styles").majorTicks.count, width)
                                            );
                                        }
                                    }
                                    if(set2)
                                    {
                                        i = 0;
                                        len = set2.length;
                                        for(; i < len; ++i)
                                        {
                                            axis = set2[i];
                                            overflow = Math.max(
                                                overflow,
                                                axis.getMaxLabelBounds().right - axis.getEdgeOffset(axis.get("styles").majorTicks.count, width)
                                            );
                                        }
                                    }
                                    return overflow;
                                },
                            
                                /**
                                 * Returns the maximum distance in pixels that the extends outside the left bounds of all horizontal axes.
                                 *
                                 * @method _getLeftOverflow
                                 * @param {Array} set1 Collection of axes to check.
                                 * @param {Array} set2 Seconf collection of axes to check.
                                 * @param {Number} width Width of the axes
                                 * @return Number
                                 * @private
                                 */
                                _getLeftOverflow: function(set1, set2, width)
                                {
                                    var i = 0,
                                        len,
                                        overflow = 0,
                                        axis;
                                    if(set1)
                                    {
                                        len = set1.length;
                                        for(; i < len; ++i)
                                        {
                                            axis = set1[i];
                                            overflow = Math.max(
                                                overflow,
                                                Math.abs(axis.getMinLabelBounds().left) - axis.getEdgeOffset(axis.get("styles").majorTicks.count, width)
                                            );
                                        }
                                    }
                                    if(set2)
                                    {
                                        i = 0;
                                        len = set2.length;
                                        for(; i < len; ++i)
                                        {
                                            axis = set2[i];
                                            overflow = Math.max(
                                                overflow,
                                                Math.abs(axis.getMinLabelBounds().left) - axis.getEdgeOffset(axis.get("styles").majorTicks.count, width)
                                            );
                                        }
                                    }
                                    return overflow;
                                },
                            
                                /**
                                 * Returns the maximum distance in pixels that the extends outside the bottom bounds of all vertical axes.
                                 *
                                 * @method _getBottomOverflow
                                 * @param {Array} set1 Collection of axes to check.
                                 * @param {Array} set2 Seconf collection of axes to check.
                                 * @param {Number} height Height of the axes
                                 * @return Number
                                 * @private
                                 */
                                _getBottomOverflow: function(set1, set2, height)
                                {
                                    var i = 0,
                                        len,
                                        overflow = 0,
                                        axis;
                                    if(set1)
                                    {
                                        len = set1.length;
                                        for(; i < len; ++i)
                                        {
                                            axis = set1[i];
                                            overflow = Math.max(
                                                overflow,
                                                axis.getMinLabelBounds().bottom - axis.getEdgeOffset(axis.get("styles").majorTicks.count, height)
                                            );
                                        }
                                    }
                                    if(set2)
                                    {
                                        i = 0;
                                        len = set2.length;
                                        for(; i < len; ++i)
                                        {
                                            axis = set2[i];
                                            overflow = Math.max(
                                                overflow,
                                                axis.getMinLabelBounds().bottom - axis.getEdgeOffset(axis.get("styles").majorTicks.count, height)
                                            );
                                        }
                                    }
                                    return overflow;
                                },
                            
                                /**
                                 * 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"),
                                        leftPaneWidth = 0,
                                        rightPaneWidth = 0,
                                        topPaneHeight = 0,
                                        bottomPaneHeight = 0,
                                        leftAxesCollection = this.get("leftAxesCollection"),
                                        rightAxesCollection = this.get("rightAxesCollection"),
                                        topAxesCollection = this.get("topAxesCollection"),
                                        bottomAxesCollection = this.get("bottomAxesCollection"),
                                        i = 0,
                                        l,
                                        axis,
                                        graphOverflow = "visible",
                                        graph = this.get("graph"),
                                        topOverflow,
                                        bottomOverflow,
                                        leftOverflow,
                                        rightOverflow,
                                        graphWidth,
                                        graphHeight,
                                        graphX,
                                        graphY,
                                        allowContentOverflow = this.get("allowContentOverflow"),
                                        diff,
                                        rightAxesXCoords,
                                        leftAxesXCoords,
                                        topAxesYCoords,
                                        bottomAxesYCoords,
                                        graphRect = {};
                                    if(leftAxesCollection)
                                    {
                                        leftAxesXCoords = [];
                                        l = leftAxesCollection.length;
                                        for(i = l - 1; i > -1; --i)
                                        {
                                            leftAxesXCoords.unshift(leftPaneWidth);
                                            leftPaneWidth += leftAxesCollection[i].get("width");
                                        }
                                    }
                                    if(rightAxesCollection)
                                    {
                                        rightAxesXCoords = [];
                                        l = rightAxesCollection.length;
                                        i = 0;
                                        for(i = l - 1; i > -1; --i)
                                        {
                                            rightPaneWidth += rightAxesCollection[i].get("width");
                                            rightAxesXCoords.unshift(w - rightPaneWidth);
                                        }
                                    }
                                    if(topAxesCollection)
                                    {
                                        topAxesYCoords = [];
                                        l = topAxesCollection.length;
                                        for(i = l - 1; i > -1; --i)
                                        {
                                            topAxesYCoords.unshift(topPaneHeight);
                                            topPaneHeight += topAxesCollection[i].get("height");
                                        }
                                    }
                                    if(bottomAxesCollection)
                                    {
                                        bottomAxesYCoords = [];
                                        l = bottomAxesCollection.length;
                                        for(i = l - 1; i > -1; --i)
                                        {
                                            bottomPaneHeight += bottomAxesCollection[i].get("height");
                                            bottomAxesYCoords.unshift(h - bottomPaneHeight);
                                        }
                                    }
                            
                                    graphWidth = w - (leftPaneWidth + rightPaneWidth);
                                    graphHeight = h - (bottomPaneHeight + topPaneHeight);
                                    graphRect.left = leftPaneWidth;
                                    graphRect.top = topPaneHeight;
                                    graphRect.bottom = h - bottomPaneHeight;
                                    graphRect.right = w - rightPaneWidth;
                                    if(!allowContentOverflow)
                                    {
                                        topOverflow = this._getTopOverflow(leftAxesCollection, rightAxesCollection);
                                        bottomOverflow = this._getBottomOverflow(leftAxesCollection, rightAxesCollection);
                                        leftOverflow = this._getLeftOverflow(bottomAxesCollection, topAxesCollection);
                                        rightOverflow = this._getRightOverflow(bottomAxesCollection, topAxesCollection);
                            
                                        diff = topOverflow - topPaneHeight;
                                        if(diff > 0)
                                        {
                                            graphRect.top = topOverflow;
                                            if(topAxesYCoords)
                                            {
                                                i = 0;
                                                l = topAxesYCoords.length;
                                                for(; i < l; ++i)
                                                {
                                                    topAxesYCoords[i] += diff;
                                                }
                                            }
                                        }
                            
                                        diff = bottomOverflow - bottomPaneHeight;
                                        if(diff > 0)
                                        {
                                            graphRect.bottom = h - bottomOverflow;
                                            if(bottomAxesYCoords)
                                            {
                                                i = 0;
                                                l = bottomAxesYCoords.length;
                                                for(; i < l; ++i)
                                                {
                                                    bottomAxesYCoords[i] -= diff;
                                                }
                                            }
                                        }
                            
                                        diff = leftOverflow - leftPaneWidth;
                                        if(diff > 0)
                                        {
                                            graphRect.left = leftOverflow;
                                            if(leftAxesXCoords)
                                            {
                                                i = 0;
                                                l = leftAxesXCoords.length;
                                                for(; i < l; ++i)
                                                {
                                                    leftAxesXCoords[i] += diff;
                                                }
                                            }
                                        }
                            
                                        diff = rightOverflow - rightPaneWidth;
                                        if(diff > 0)
                                        {
                                            graphRect.right = w - rightOverflow;
                                            if(rightAxesXCoords)
                                            {
                                                i = 0;
                                                l = rightAxesXCoords.length;
                                                for(; i < l; ++i)
                                                {
                                                    rightAxesXCoords[i] -= diff;
                                                }
                                            }
                                        }
                                    }
                                    graphWidth = graphRect.right - graphRect.left;
                                    graphHeight = graphRect.bottom - graphRect.top;
                                    graphX = graphRect.left;
                                    graphY = graphRect.top;
                                    if(topAxesCollection)
                                    {
                                        l = topAxesCollection.length;
                                        i = 0;
                                        for(; i < l; i++)
                                        {
                                            axis = topAxesCollection[i];
                                            if(axis.get("width") !== graphWidth)
                                            {
                                                axis.set("width", graphWidth);
                                            }
                                            axis.get("boundingBox").setStyle("left", graphX + "px");
                                            axis.get("boundingBox").setStyle("top", topAxesYCoords[i] + "px");
                                        }
                                        if(axis._hasDataOverflow())
                                        {
                                            graphOverflow = "hidden";
                                        }
                                    }
                                    if(bottomAxesCollection)
                                    {
                                        l = bottomAxesCollection.length;
                                        i = 0;
                                        for(; i < l; i++)
                                        {
                                            axis = bottomAxesCollection[i];
                                            if(axis.get("width") !== graphWidth)
                                            {
                                                axis.set("width", graphWidth);
                                            }
                                            axis.get("boundingBox").setStyle("left", graphX + "px");
                                            axis.get("boundingBox").setStyle("top", bottomAxesYCoords[i] + "px");
                                        }
                                        if(axis._hasDataOverflow())
                                        {
                                            graphOverflow = "hidden";
                                        }
                                    }
                                    if(leftAxesCollection)
                                    {
                                        l = leftAxesCollection.length;
                                        i = 0;
                                        for(; i < l; ++i)
                                        {
                                            axis = leftAxesCollection[i];
                                            axis.get("boundingBox").setStyle("top", graphY + "px");
                                            axis.get("boundingBox").setStyle("left", leftAxesXCoords[i] + "px");
                                            if(axis.get("height") !== graphHeight)
                                            {
                                                axis.set("height", graphHeight);
                                            }
                                        }
                                        if(axis._hasDataOverflow())
                                        {
                                            graphOverflow = "hidden";
                                        }
                                    }
                                    if(rightAxesCollection)
                                    {
                                        l = rightAxesCollection.length;
                                        i = 0;
                                        for(; i < l; ++i)
                                        {
                                            axis = rightAxesCollection[i];
                                            axis.get("boundingBox").setStyle("top", graphY + "px");
                                            axis.get("boundingBox").setStyle("left", rightAxesXCoords[i] + "px");
                                            if(axis.get("height") !== graphHeight)
                                            {
                                                axis.set("height", graphHeight);
                                            }
                                        }
                                        if(axis._hasDataOverflow())
                                        {
                                            graphOverflow = "hidden";
                                        }
                                    }
                                    this._drawing = false;
                                    if(this._callLater)
                                    {
                                        this._redraw();
                                        return;
                                    }
                                    if(graph)
                                    {
                                        graph.get("boundingBox").setStyle("left", graphX + "px");
                                        graph.get("boundingBox").setStyle("top", graphY + "px");
                                        graph.set("width", graphWidth);
                                        graph.set("height", graphHeight);
                                        graph.get("boundingBox").setStyle("overflow", graphOverflow);
                                    }
                            
                                    if(this._overlay)
                                    {
                                        this._overlay.setStyle("left", graphX + "px");
                                        this._overlay.setStyle("top", graphY + "px");
                                        this._overlay.setStyle("width", graphWidth + "px");
                                        this._overlay.setStyle("height", graphHeight + "px");
                                    }
                                },
                            
                                /**
                                 * Destructor implementation for the CartesianChart class. Calls destroy on all axes, series and the Graph instance.
                                 * Removes the tooltip and overlay HTML elements.
                                 *
                                 * @method destructor
                                 * @protected
                                 */
                                destructor: function()
                                {
                                    var graph = this.get("graph"),
                                        i = 0,
                                        len,
                                        seriesCollection = this.get("seriesCollection"),
                                        axesCollection = this._axesCollection,
                                        tooltip = this.get("tooltip").node;
                                    if(this._description)
                                    {
                                        this._description.empty();
                                        this._description.remove(true);
                                    }
                                    if(this._liveRegion)
                                    {
                                        this._liveRegion.empty();
                                        this._liveRegion.remove(true);
                                    }
                                    len = seriesCollection ? seriesCollection.length : 0;
                                    for(; i < len; ++i)
                                    {
                                        if(seriesCollection[i] instanceof Y.CartesianSeries)
                                        {
                                            seriesCollection[i].destroy(true);
                                        }
                                    }
                                    len = axesCollection ? axesCollection.length : 0;
                                    for(i = 0; i < len; ++i)
                                    {
                                        if(axesCollection[i] instanceof Y.Axis)
                                        {
                                            axesCollection[i].destroy(true);
                                        }
                                    }
                                    if(graph)
                                    {
                                        graph.destroy(true);
                                    }
                                    if(tooltip)
                                    {
                                        tooltip.empty();
                                        tooltip.remove(true);
                                    }
                                    if(this._overlay)
                                    {
                                        this._overlay.empty();
                                        this._overlay.remove(true);
                                    }
                                },
                            
                                /**
                                 * Returns the appropriate message based on the key press.
                                 *
                                 * @method _getAriaMessage
                                 * @param {Number} key The keycode that was pressed.
                                 * @return String
                                 */
                                _getAriaMessage: function(key)
                                {
                                    var msg = "",
                                        series,
                                        items,
                                        categoryItem,
                                        valueItem,
                                        seriesIndex = this._seriesIndex,
                                        itemIndex = this._itemIndex,
                                        seriesCollection = this.get("seriesCollection"),
                                        len = seriesCollection.length,
                                        dataLength;
                                    if(key % 2 === 0)
                                    {
                                        if(len > 1)
                                        {
                                            if(key === 38)
                                            {
                                                seriesIndex = seriesIndex < 1 ? len - 1 : seriesIndex - 1;
                                            }
                                            else if(key === 40)
                                            {
                                                seriesIndex = seriesIndex >= len - 1 ? 0 : seriesIndex + 1;
                                            }
                                            this._itemIndex = -1;
                                        }
                                        else
                                        {
                                            seriesIndex = 0;
                                        }
                                        this._seriesIndex = seriesIndex;
                                        series = this.getSeries(parseInt(seriesIndex, 10));
                                        msg = series.get("valueDisplayName") + " series.";
                                    }
                                    else
                                    {
                                        if(seriesIndex > -1)
                                        {
                                            msg = "";
                                            series = this.getSeries(parseInt(seriesIndex, 10));
                                        }
                                        else
                                        {
                                            seriesIndex = 0;
                                            this._seriesIndex = seriesIndex;
                                            series = this.getSeries(parseInt(seriesIndex, 10));
                                            msg = series.get("valueDisplayName") + " series.";
                                        }
                                        dataLength = series._dataLength ? series._dataLength : 0;
                                        if(key === 37)
                                        {
                                            itemIndex = itemIndex > 0 ? itemIndex - 1 : dataLength - 1;
                                        }
                                        else if(key === 39)
                                        {
                                            itemIndex = itemIndex >= dataLength - 1 ? 0 : itemIndex + 1;
                                        }
                                        this._itemIndex = itemIndex;
                                        items = this.getSeriesItems(series, itemIndex);
                                        categoryItem = items.category;
                                        valueItem = items.value;
                                        if(categoryItem && valueItem && categoryItem.value && valueItem.value)
                                        {
                                            msg += categoryItem.displayName +
                                                ": " +
                                                categoryItem.axis.formatLabel.apply(this, [categoryItem.value, categoryItem.axis.get("labelFormat")]) +
                                                ", ";
                                            msg += valueItem.displayName +
                                                ": " +
                                                valueItem.axis.formatLabel.apply(this, [valueItem.value, valueItem.axis.get("labelFormat")]) +
                                                ", ";
                                        }
                                       else
                                        {
                                            msg += "No data available.";
                                        }
                                        msg += (itemIndex + 1) + " of " + dataLength + ". ";
                                    }
                                    return msg;
                                }
                            }, {
                                ATTRS: {
                                    /**
                                     * Indicates whether axis labels are allowed to overflow beyond the bounds of the chart's content box.
                                     *
                                     * @attribute allowContentOverflow
                                     * @type Boolean
                                     */
                                    allowContentOverflow: {
                                        value: false
                                    },
                            
                                    /**
                                     * Style object for the axes.
                                     *
                                     * @attribute axesStyles
                                     * @type Object
                                     * @private
                                     */
                                    axesStyles: {
                                        lazyAdd: false,
                            
                                        getter: function()
                                        {
                                            var axes = this.get("axes"),
                                                i,
                                                styles = this._axesStyles;
                                            if(axes)
                                            {
                                                for(i in axes)
                                                {
                                                    if(axes.hasOwnProperty(i) && axes[i] instanceof Y.Axis)
                                                    {
                                                        if(!styles)
                                                        {
                                                            styles = {};
                                                        }
                                                        styles[i] = axes[i].get("styles");
                                                    }
                                                }
                                            }
                                            return styles;
                                        },
                            
                                        setter: function(val)
                                        {
                                            var axes = this.get("axes"),
                                                i;
                                            for(i in val)
                                            {
                                                if(val.hasOwnProperty(i) && axes.hasOwnProperty(i))
                                                {
                                                    this._setBaseAttribute(axes[i], "styles", val[i]);
                                                }
                                            }
                                            return val;
                                        }
                                    },
                            
                                    /**
                                     * Style object for the series
                                     *
                                     * @attribute seriesStyles
                                     * @type Object
                                     * @private
                                     */
                                    seriesStyles: {
                                        lazyAdd: false,
                            
                                        getter: function()
                                        {
                                            var styles = this._seriesStyles,
                                                graph = this.get("graph"),
                                                dict,
                                                i;
                                            if(graph)
                                            {
                                                dict = graph.get("seriesDictionary");
                                                if(dict)
                                                {
                                                    styles = {};
                                                    for(i in dict)
                                                    {
                                                        if(dict.hasOwnProperty(i))
                                                        {
                                                            styles[i] = dict[i].get("styles");
                                                        }
                                                    }
                                                }
                                            }
                                            return styles;
                                        },
                            
                                        setter: function(val)
                                        {
                                            var i,
                                                l,
                                                s;
                            
                                            if(Y_Lang.isArray(val))
                                            {
                                                s = this.get("seriesCollection");
                                                i = 0;
                                                l = val.length;
                            
                                                for(; i < l; ++i)
                                                {
                                                    this._setBaseAttribute(s[i], "styles", val[i]);
                                                }
                                            }
                                            else
                                            {
                                                for(i in val)
                                                {
                                                    if(val.hasOwnProperty(i))
                                                    {
                                                        s = this.getSeries(i);
                                                        this._setBaseAttribute(s, "styles", val[i]);
                                                    }
                                                }
                                            }
                                            return val;
                                        }
                                    },
                            
                                    /**
                                     * Styles for the graph.
                                     *
                                     * @attribute graphStyles
                                     * @type Object
                                     * @private
                                     */
                                    graphStyles: {
                                        lazyAdd: false,
                            
                                        getter: function()
                                        {
                                            var graph = this.get("graph");
                                            if(graph)
                                            {
                                                return(graph.get("styles"));
                                            }
                                            return this._graphStyles;
                                        },
                            
                                        setter: function(val)
                                        {
                                            var graph = this.get("graph");
                                            this._setBaseAttribute(graph, "styles", val);
                                            return val;
                                        }
                            
                                    },
                            
                                    /**
                                     * Style properties for the chart. Contains a key indexed hash of the following:
                                     *  <dl>
                                     *      <dt>series</dt><dd>A key indexed hash containing references to the `styles` attribute for each series in the chart.
                                     *      Specific style attributes vary depending on the series:
                                     *      <ul>
                                     *          <li><a href="AreaSeries.html#attr_styles">AreaSeries</a></li>
                                     *          <li><a href="BarSeries.html#attr_styles">BarSeries</a></li>
                                     *          <li><a href="ColumnSeries.html#attr_styles">ColumnSeries</a></li>
                                     *          <li><a href="ComboSeries.html#attr_styles">ComboSeries</a></li>
                                     *          <li><a href="LineSeries.html#attr_styles">LineSeries</a></li>
                                     *          <li><a href="MarkerSeries.html#attr_styles">MarkerSeries</a></li>
                                     *          <li><a href="SplineSeries.html#attr_styles">SplineSeries</a></li>
                                     *      </ul>
                                     *      </dd>
                                     *      <dt>axes</dt><dd>A key indexed hash containing references to the `styles` attribute for each axes in the chart. Specific
                                     *      style attributes can be found in the <a href="Axis.html#attr_styles">Axis</a> class.</dd>
                                     *      <dt>graph</dt><dd>A reference to the `styles` attribute in the chart. Specific style attributes can be found in the
                                     *      <a href="Graph.html#attr_styles">Graph</a> class.</dd>
                                     *  </dl>
                                     *
                                     * @attribute styles
                                     * @type Object
                                     */
                                    styles: {
                                        lazyAdd: false,
                            
                                        getter: function()
                                        {
                                            var styles = {
                                                axes: this.get("axesStyles"),
                                                series: this.get("seriesStyles"),
                                                graph: this.get("graphStyles")
                                            };
                                            return styles;
                                        },
                                        setter: function(val)
                                        {
                                            if(val.hasOwnProperty("axes"))
                                            {
                                                if(this.get("axesStyles"))
                                                {
                                                    this.set("axesStyles", val.axes);
                                                }
                                                else
                                                {
                                                    this._axesStyles = val.axes;
                                                }
                                            }
                                            if(val.hasOwnProperty("series"))
                                            {
                                                if(this.get("seriesStyles"))
                                                {
                                                    this.set("seriesStyles", val.series);
                                                }
                                                else
                                                {
                                                    this._seriesStyles = val.series;
                                                }
                                            }
                                            if(val.hasOwnProperty("graph"))
                                            {
                                                this.set("graphStyles", val.graph);
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Axes to appear in the chart. This can be a key indexed hash of axis instances or object literals
                                     * used to construct the appropriate axes.
                                     *
                                     * @attribute axes
                                     * @type Object
                                     */
                                    axes: {
                                        lazyAdd: false,
                            
                                        valueFn: "_getDefaultAxes",
                            
                                        setter: function(val)
                                        {
                                            if(this.get("dataProvider"))
                                            {
                                                val = this._setAxes(val);
                                            }
                                            return val;
                                        }
                                    },
                            
                                    /**
                                     * Collection of series to appear on the chart. This can be an array of Series instances or object literals
                                     * used to construct the appropriate series.
                                     *
                                     * @attribute seriesCollection
                                     * @type Array
                                     */
                                    seriesCollection: {
                                        lazyAdd: false,
                            
                                        valueFn: "_getDefaultSeriesCollection",
                            
                                        setter: function(val)
                                        {
                                            if(this.get("dataProvider"))
                                            {
                                                return this._parseSeriesCollection(val);
                                            }
                                            return val;
                                        }
                                    },
                            
                                    /**
                                     * Reference to the left-aligned axes for the chart.
                                     *
                                     * @attribute leftAxesCollection
                                     * @type Array
                                     * @private
                                     */
                                    leftAxesCollection: {},
                            
                                    /**
                                     * Reference to the bottom-aligned axes for the chart.
                                     *
                                     * @attribute bottomAxesCollection
                                     * @type Array
                                     * @private
                                     */
                                    bottomAxesCollection: {},
                            
                                    /**
                                     * Reference to the right-aligned axes for the chart.
                                     *
                                     * @attribute rightAxesCollection
                                     * @type Array
                                     * @private
                                     */
                                    rightAxesCollection: {},
                            
                                    /**
                                     * Reference to the top-aligned axes for the chart.
                                     *
                                     * @attribute topAxesCollection
                                     * @type Array
                                     * @private
                                     */
                                    topAxesCollection: {},
                            
                                    /**
                                     * Indicates whether or not the chart is stacked.
                                     *
                                     * @attribute stacked
                                     * @type Boolean
                                     */
                                    stacked: {
                                        value: false
                                    },
                            
                                    /**
                                     * Direction of chart's category axis when there is no series collection specified. Charts can
                                     * be horizontal or vertical. When the chart type is column, the chart is horizontal.
                                     * When the chart type is bar, the chart is vertical.
                                     *
                                     * @attribute direction
                                     * @type String
                                     */
                                    direction: {
                                        getter: function()
                                        {
                                            var type = this.get("type");
                                            if(type === "bar")
                                            {
                                                return "vertical";
                                            }
                                            else if(type === "column")
                                            {
                                                return "horizontal";
                                            }
                                            return this._direction;
                                        },
                            
                                        setter: function(val)
                                        {
                                            this._direction = val;
                                            return this._direction;
                                        }
                                    },
                            
                                    /**
                                     * Indicates whether or not an area is filled in a combo chart.
                                     *
                                     * @attribute showAreaFill
                                     * @type Boolean
                                     */
                                    showAreaFill: {},
                            
                                    /**
                                     * Indicates whether to display markers in a combo chart.
                                     *
                                     * @attribute showMarkers
                                     * @type Boolean
                                     */
                                    showMarkers:{},
                            
                                    /**
                                     * Indicates whether to display lines in a combo chart.
                                     *
                                     * @attribute showLines
                                     * @type Boolean
                                     */
                                    showLines:{},
                            
                                    /**
                                     * Indicates the key value used to identify a category axis in the `axes` hash. If
                                     * not specified, the categoryKey attribute value will be used.
                                     *
                                     * @attribute categoryAxisName
                                     * @type String
                                     */
                                    categoryAxisName: {
                                    },
                            
                                    /**
                                     * Indicates the key value used to identify a the series axis when an axis not generated.
                                     *
                                     * @attribute valueAxisName
                                     * @type String
                                     */
                                    valueAxisName: {
                                        value: "values"
                                    },
                            
                                    /**
                                     * Reference to the horizontalGridlines for the chart.
                                     *
                                     * @attribute horizontalGridlines
                                     * @type Gridlines
                                     */
                                    horizontalGridlines: {
                                        getter: function()
                                        {
                                            var graph = this.get("graph");
                                            if(graph)
                                            {
                                                return graph.get("horizontalGridlines");
                                            }
                                            return this._horizontalGridlines;
                                        },
                                        setter: function(val)
                                        {
                                            var graph = this.get("graph");
                                            if(val && !Y_Lang.isObject(val))
                                            {
                                                val = {};
                                            }
                                            if(graph)
                                            {
                                                graph.set("horizontalGridlines", val);
                                            }
                                            else
                                            {
                                                this._horizontalGridlines = val;
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Reference to the verticalGridlines for the chart.
                                     *
                                     * @attribute verticalGridlines
                                     * @type Gridlines
                                     */
                                    verticalGridlines: {
                                        getter: function()
                                        {
                                            var graph = this.get("graph");
                                            if(graph)
                                            {
                                                return graph.get("verticalGridlines");
                                            }
                                            return this._verticalGridlines;
                                        },
                                        setter: function(val)
                                        {
                                            var graph = this.get("graph");
                                            if(val && !Y_Lang.isObject(val))
                                            {
                                                val = {};
                                            }
                                            if(graph)
                                            {
                                                graph.set("verticalGridlines", val);
                                            }
                                            else
                                            {
                                                this._verticalGridlines = val;
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Type of chart when there is no series collection specified.
                                     *
                                     * @attribute type
                                     * @type String
                                     */
                                    type: {
                                        getter: function()
                                        {
                                            if(this.get("stacked"))
                                            {
                                                return "stacked" + this._type;
                                            }
                                            return this._type;
                                        },
                            
                                        setter: function(val)
                                        {
                                            if(this._type === "bar")
                                            {
                                                if(val !== "bar")
                                                {
                                                    this.set("direction", "horizontal");
                                                }
                                            }
                                            else
                                            {
                                                if(val === "bar")
                                                {
                                                    this.set("direction", "vertical");
                                                }
                                            }
                                            this._type = val;
                                            return this._type;
                                        }
                                    },
                            
                                    /**
                                     * Reference to the category axis used by the chart.
                                     *
                                     * @attribute categoryAxis
                                     * @type Axis
                                     */
                                    categoryAxis:{}
                                }
                            });