Show:
                            /**
                             * The ChartBase class is an abstract class used to create charts.
                             *
                             * @class ChartBase
                             * @constructor
                             * @submodule charts-base
                             */
                            function ChartBase() {}
                            
                            ChartBase.ATTRS = {
                                /**
                                 * Data used to generate the chart.
                                 *
                                 * @attribute dataProvider
                                 * @type Array
                                 */
                                dataProvider: {
                                    lazyAdd: false,
                            
                                    valueFn: function()
                                    {
                                        var defDataProvider = [];
                                        if(!this._wereSeriesKeysExplicitlySet())
                                        {
                                            this.set("seriesKeys", this._buildSeriesKeys(defDataProvider), {src: "internal"});
                                        }
                                        return defDataProvider;
                                    },
                            
                                    setter: function(val)
                                    {
                                        var dataProvider = this._setDataValues(val);
                                        if(!this._wereSeriesKeysExplicitlySet())
                                        {
                                            this.set("seriesKeys", this._buildSeriesKeys(dataProvider), {src: "internal"});
                                        }
                                        return dataProvider;
                                    }
                                },
                            
                                /**
                                 * A collection of keys that map to the series axes. If no keys are set,
                                 * they will be generated automatically depending on the data structure passed into
                                 * the chart.
                                 *
                                 * @attribute seriesKeys
                                 * @type Array
                                 */
                                seriesKeys: {
                                    lazyAdd: false,
                            
                                    setter: function(val)
                                    {
                                        var opts = arguments[2];
                                        if(!val || (opts && opts.src && opts.src === "internal"))
                                        {
                                            this._seriesKeysExplicitlySet = false;
                                        }
                                        else
                                        {
                                            this._seriesKeysExplicitlySet = true;
                                        }
                                        return val;
                                    }
                                },
                            
                                /**
                                 * Sets the `aria-label` for the chart.
                                 *
                                 * @attribute ariaLabel
                                 * @type String
                                 */
                                ariaLabel: {
                                    value: "Chart Application",
                            
                                    setter: function(val)
                                    {
                                        var cb = this.get("contentBox");
                                        if(cb)
                                        {
                                            cb.setAttribute("aria-label", val);
                                        }
                                        return val;
                                    }
                                },
                            
                                /**
                                 * Sets the aria description for the chart.
                                 *
                                 * @attribute ariaDescription
                                 * @type String
                                 */
                                ariaDescription: {
                                    value: "Use the up and down keys to navigate between series. Use the left and right keys to navigate through items in a series.",
                            
                                    setter: function(val)
                                    {
                                        if(this._description)
                                        {
                                            this._description.set("text", val);
                                        }
                                        return val;
                                    }
                                },
                            
                                /**
                                 * Reference to the default tooltip available for the chart.
                                 * <p>Contains the following properties:</p>
                                 *  <dl>
                                 *      <dt>node</dt><dd>Reference to the actual dom node</dd>
                                 *      <dt>showEvent</dt><dd>Event that should trigger the tooltip</dd>
                                 *      <dt>hideEvent</dt><dd>Event that should trigger the removal of a tooltip (can be an event or an array of events)</dd>
                                 *      <dt>styles</dt><dd>A hash of style properties that will be applied to the tooltip node</dd>
                                 *      <dt>show</dt><dd>Indicates whether or not to show the tooltip</dd>
                                 *      <dt>markerEventHandler</dt><dd>Displays and hides tooltip based on marker events</dd>
                                 *      <dt>planarEventHandler</dt><dd>Displays and hides tooltip based on planar events</dd>
                                 *      <dt>markerLabelFunction</dt><dd>Reference to the function used to format a marker event triggered tooltip's text.
                                 *      The method contains the following arguments:
                                 *  <dl>
                                 *      <dt>categoryItem</dt><dd>An object containing the following:
                                 *  <dl>
                                 *      <dt>axis</dt><dd>The axis to which the category is bound.</dd>
                                 *      <dt>displayName</dt><dd>The display name set to the category (defaults to key if not provided).</dd>
                                 *      <dt>key</dt><dd>The key of the category.</dd>
                                 *      <dt>value</dt><dd>The value of the category.</dd>
                                 *  </dl>
                                 *  </dd>
                                 *  <dt>valueItem</dt><dd>An object containing the following:
                                 *      <dl>
                                 *          <dt>axis</dt><dd>The axis to which the item's series is bound.</dd>
                                 *          <dt>displayName</dt><dd>The display name of the series. (defaults to key if not provided)</dd>
                                 *          <dt>key</dt><dd>The key for the series.</dd>
                                 *          <dt>value</dt><dd>The value for the series item.</dd>
                                 *      </dl>
                                 *  </dd>
                                 *  <dt>itemIndex</dt><dd>The index of the item within the series.</dd>
                                 *  <dt>series</dt><dd> The `CartesianSeries` instance of the item.</dd>
                                 *  <dt>seriesIndex</dt><dd>The index of the series in the `seriesCollection`.</dd>
                                 *  </dl>
                                 *  The method returns an `HTMLElement` which is written into the DOM using `appendChild`. If you override this method and choose
                                 *  to return an html string, you will also need to override the tooltip's `setTextFunction` method to accept an html string.
                                 *  </dd>
                                 *  <dt>planarLabelFunction</dt><dd>Reference to the function used to format a planar event triggered tooltip's text
                                 *  <dl>
                                 *      <dt>categoryAxis</dt><dd> `CategoryAxis` Reference to the categoryAxis of the chart.
                                 *      <dt>valueItems</dt><dd>Array of objects for each series that has a data point in the coordinate plane of the event. Each
                                 *      object contains the following data:
                                 *  <dl>
                                 *      <dt>axis</dt><dd>The value axis of the series.</dd>
                                 *      <dt>key</dt><dd>The key for the series.</dd>
                                 *      <dt>value</dt><dd>The value for the series item.</dd>
                                 *      <dt>displayName</dt><dd>The display name of the series. (defaults to key if not provided)</dd>
                                 *  </dl>
                                 *  </dd>
                                 *      <dt>index</dt><dd>The index of the item within its series.</dd>
                                 *      <dt>seriesArray</dt><dd>Array of series instances for each value item.</dd>
                                 *      <dt>seriesIndex</dt><dd>The index of the series in the `seriesCollection`.</dd>
                                 *  </dl>
                                 *  </dd>
                                 *  </dl>
                                 *  The method returns an `HTMLElement` which is written into the DOM using `appendChild`. If you override this method and choose
                                 *  to return an html string, you will also need to override the tooltip's `setTextFunction` method to accept an html string.
                                 *  </dd>
                                 *  <dt>setTextFunction</dt><dd>Method that writes content returned from `planarLabelFunction` or `markerLabelFunction` into the
                                 *  the tooltip node. Has the following signature:
                                 *  <dl>
                                 *      <dt>label</dt><dd>The `HTMLElement` that the content is to be added.</dd>
                                 *      <dt>val</dt><dd>The content to be rendered into tooltip. This can be a `String` or `HTMLElement`. If an HTML string is used,
                                 *      it will be rendered as a string.</dd>
                                 *  </dl>
                                 *  </dd>
                                 *  </dl>
                                 * @attribute tooltip
                                 * @type Object
                                 */
                                tooltip: {
                                    valueFn: "_getTooltip",
                            
                                    setter: function(val)
                                    {
                                        return this._updateTooltip(val);
                                    }
                                },
                            
                                /**
                                 * The key value used for the chart's category axis.
                                 *
                                 * @attribute categoryKey
                                 * @type String
                                 * @default category
                                 */
                                categoryKey: {
                                    value: "category"
                                },
                            
                                /**
                                 * Indicates the type of axis to use for the category axis.
                                 *
                                 *  <dl>
                                 *      <dt>category</dt><dd>Specifies a `CategoryAxis`.</dd>
                                 *      <dt>time</dt><dd>Specifies a `TimeAxis</dd>
                                 *  </dl>
                                 *
                                 * @attribute categoryType
                                 * @type String
                                 * @default category
                                 */
                                categoryType:{
                                    value:"category"
                                },
                            
                                /**
                                 * Indicates the the type of interactions that will fire events.
                                 *
                                 *  <dl>
                                 *      <dt>marker</dt><dd>Events will be broadcasted when the mouse interacts with individual markers.</dd>
                                 *      <dt>planar</dt><dd>Events will be broadcasted when the mouse intersects the plane of any markers on the chart.</dd>
                                 *      <dt>none</dt><dd>No events will be broadcasted.</dd>
                                 *  </dl>
                                 *
                                 * @attribute interactionType
                                 * @type String
                                 * @default marker
                                 */
                                interactionType: {
                                    value: "marker"
                                },
                            
                                /**
                                 * Reference to all the axes in the chart.
                                 *
                                 * @attribute axesCollection
                                 * @type Array
                                 */
                                axesCollection: {},
                            
                                /**
                                 * Reference to graph instance.
                                 *
                                 * @attribute graph
                                 * @type Graph
                                 */
                                graph: {
                                    valueFn: "_getGraph"
                                },
                            
                                /**
                                 * Indicates whether or not markers for a series will be grouped and rendered in a single complex shape instance.
                                 *
                                 * @attribute groupMarkers
                                 * @type Boolean
                                 */
                                groupMarkers: {
                                    value: false
                                }
                            };
                            
                            ChartBase.prototype = {
                            
                                /**
                                 * Utility method to determine if `seriesKeys` was explicitly provided
                                 * (for example during construction, or set by the user), as opposed to
                                 * being derived from the dataProvider for example.
                                 *
                                 * @method _wereSeriesKeysExplicitlySet
                                 * @private
                                 * @return boolean true if the `seriesKeys` attribute was explicitly set.
                                 */
                                _wereSeriesKeysExplicitlySet : function()
                                {
                                    var seriesKeys = this.get("seriesKeys");
                                    return seriesKeys && this._seriesKeysExplicitlySet;
                                },
                            
                                /**
                                 * Handles groupMarkers change event.
                                 *
                                 * @method _groupMarkersChangeHandler
                                 * @param {Object} e Event object.
                                 * @private
                                 */
                                _groupMarkersChangeHandler: function(e)
                                {
                                    var graph = this.get("graph"),
                                        useGroupMarkers = e.newVal;
                                    if(graph)
                                    {
                                        graph.set("groupMarkers", useGroupMarkers);
                                    }
                                },
                            
                                /**
                                 * Handler for itemRendered event.
                                 *
                                 * @method _itemRendered
                                 * @param {Object} e Event object.
                                 * @private
                                 */
                                _itemRendered: function(e)
                                {
                                    this._itemRenderQueue = this._itemRenderQueue.splice(1 + Y.Array.indexOf(this._itemRenderQueue, e.currentTarget), 1);
                                    if(this._itemRenderQueue.length < 1)
                                    {
                                        this._redraw();
                                    }
                                },
                            
                                /**
                                 * Default value function for the `Graph` attribute.
                                 *
                                 * @method _getGraph
                                 * @return Graph
                                 * @private
                                 */
                                _getGraph: function()
                                {
                                    var graph = new Y.Graph({
                                        chart:this,
                                        groupMarkers: this.get("groupMarkers")
                                    });
                                    graph.after("chartRendered", Y.bind(function() {
                                        this.fire("chartRendered");
                                    }, this));
                                    return graph;
                                },
                            
                                /**
                                 * Returns a series instance by index or key value.
                                 *
                                 * @method getSeries
                                 * @param val
                                 * @return CartesianSeries
                                 */
                                getSeries: function(val)
                                {
                                    var series = null,
                                        graph = this.get("graph");
                                    if(graph)
                                    {
                                        if(Y_Lang.isNumber(val))
                                        {
                                            series = graph.getSeriesByIndex(val);
                                        }
                                        else
                                        {
                                            series = graph.getSeriesByKey(val);
                                        }
                                    }
                                    return series;
                                },
                            
                                /**
                                 * Returns an `Axis` instance by key reference. If the axis was explicitly set through the `axes` attribute,
                                 * the key will be the same as the key used in the `axes` object. For default axes, the key for
                                 * the category axis is the value of the `categoryKey` (`category`). For the value axis, the default
                                 * key is `values`.
                                 *
                                 * @method getAxisByKey
                                 * @param {String} val Key reference used to look up the axis.
                                 * @return Axis
                                 */
                                getAxisByKey: function(val)
                                {
                                    var axis,
                                        axes = this.get("axes");
                                    if(axes && axes.hasOwnProperty(val))
                                    {
                                        axis = axes[val];
                                    }
                                    return axis;
                                },
                            
                                /**
                                 * Returns the category axis for the chart.
                                 *
                                 * @method getCategoryAxis
                                 * @return Axis
                                 */
                                getCategoryAxis: function()
                                {
                                    var axis,
                                        key = this.get("categoryKey"),
                                        axes = this.get("axes");
                                    if(axes.hasOwnProperty(key))
                                    {
                                        axis = axes[key];
                                    }
                                    return axis;
                                },
                            
                                /**
                                 * Default direction of the chart.
                                 *
                                 * @property _direction
                                 * @type String
                                 * @default horizontal
                                 * @private
                                 */
                                _direction: "horizontal",
                            
                                /**
                                 * Storage for the `dataProvider` attribute.
                                 *
                                 * @property _dataProvider
                                 * @type Array
                                 * @private
                                 */
                                _dataProvider: null,
                            
                                /**
                                 * Setter method for `dataProvider` attribute.
                                 *
                                 * @method _setDataValues
                                 * @param {Array} val Array to be set as `dataProvider`.
                                 * @return Array
                                 * @private
                                 */
                                _setDataValues: function(val)
                                {
                                    if(Y_Lang.isArray(val[0]))
                                    {
                                        var hash,
                                            dp = [],
                                            cats = val[0],
                                            i = 0,
                                            l = cats.length,
                                            n,
                                            sl = val.length;
                                        for(; i < l; ++i)
                                        {
                                            hash = {category:cats[i]};
                                            for(n = 1; n < sl; ++n)
                                            {
                                                hash["series" + n] = val[n][i];
                                            }
                                            dp[i] = hash;
                                        }
                                        return dp;
                                    }
                                    return val;
                                },
                            
                                /**
                                 * Storage for `seriesCollection` attribute.
                                 *
                                 * @property _seriesCollection
                                 * @type Array
                                 * @private
                                 */
                                _seriesCollection: null,
                            
                                /**
                                 * Setter method for `seriesCollection` attribute.
                                 *
                                 * @property _setSeriesCollection
                                 * @param {Array} val Array of either `CartesianSeries` instances or objects containing series attribute key value pairs.
                                 * @private
                                 */
                                _setSeriesCollection: function(val)
                                {
                                    this._seriesCollection = val;
                                },
                                /**
                                 * Helper method that returns the axis class that a key references.
                                 *
                                 * @method _getAxisClass
                                 * @param {String} t The type of axis.
                                 * @return Axis
                                 * @private
                                 */
                                _getAxisClass: function(t)
                                {
                                    return this._axisClass[t];
                                },
                            
                                /**
                                 * Key value pairs of axis types.
                                 *
                                 * @property _axisClass
                                 * @type Object
                                 * @private
                                 */
                                _axisClass: {
                                    stacked: Y.StackedAxis,
                                    numeric: Y.NumericAxis,
                                    category: Y.CategoryAxis,
                                    time: Y.TimeAxis
                                },
                            
                                /**
                                 * Collection of axes.
                                 *
                                 * @property _axes
                                 * @type Array
                                 * @private
                                 */
                                _axes: null,
                            
                                /**
                                 * @method initializer
                                 * @private
                                 */
                                initializer: function()
                                {
                                    this._itemRenderQueue = [];
                                    this._seriesIndex = -1;
                                    this._itemIndex = -1;
                                    this.after("dataProviderChange", this._dataProviderChangeHandler);
                                },
                            
                                /**
                                 * @method renderUI
                                 * @private
                                 */
                                renderUI: function()
                                {
                                    var tt = this.get("tooltip"),
                                        bb = this.get("boundingBox"),
                                        cb = this.get("contentBox");
                                    //move the position = absolute logic to a class file
                                    bb.setStyle("position", "absolute");
                                    cb.setStyle("position", "absolute");
                                    this._addAxes();
                                    this._addSeries();
                                    if(tt && tt.show)
                                    {
                                        this._addTooltip();
                                    }
                                    this._setAriaElements(bb, cb);
                                },
                            
                                /**
                                 * Creates an aria `live-region`, `aria-label` and `aria-describedby` for the Chart.
                                 *
                                 * @method _setAriaElements
                                 * @param {Node} cb Reference to the Chart's `contentBox` attribute.
                                 * @private
                                 */
                                _setAriaElements: function(bb, cb)
                                {
                                    var description = this._getAriaOffscreenNode(),
                                        id = this.get("id") + "_description",
                                        liveRegion = this._getAriaOffscreenNode();
                                    cb.set("tabIndex", 0);
                                    cb.set("role", "img");
                                    cb.setAttribute("aria-label", this.get("ariaLabel"));
                                    cb.setAttribute("aria-describedby", id);
                                    description.set("id", id);
                                    description.set("tabIndex", -1);
                                    description.set("text", this.get("ariaDescription"));
                                    liveRegion.set("id", "live-region");
                                    liveRegion.set("aria-live", "polite");
                                    liveRegion.set("aria-atomic", "true");
                                    liveRegion.set("role", "status");
                                    bb.setAttribute("role", "application");
                                    bb.appendChild(description);
                                    bb.appendChild(liveRegion);
                                    this._description = description;
                                    this._liveRegion = liveRegion;
                                },
                            
                                /**
                                 * Sets a node offscreen for use as aria-description or aria-live-regin.
                                 *
                                 * @method _setOffscreen
                                 * @return Node
                                 * @private
                                 */
                                _getAriaOffscreenNode: function()
                                {
                                    var node = Y.Node.create("<div></div>"),
                                        ie = Y.UA.ie,
                                        clipRect = (ie && ie < 8) ? "rect(1px 1px 1px 1px)" : "rect(1px, 1px, 1px, 1px)";
                                    node.setStyle("position", "absolute");
                                    node.setStyle("height", "1px");
                                    node.setStyle("width", "1px");
                                    node.setStyle("overflow", "hidden");
                                    node.setStyle("clip", clipRect);
                                    return node;
                                },
                            
                                /**
                                 * @method syncUI
                                 * @private
                                 */
                                syncUI: function()
                                {
                                    this._redraw();
                                },
                            
                                /**
                                 * @method bindUI
                                 * @private
                                 */
                                bindUI: function()
                                {
                                    this.after("tooltipChange", Y.bind(this._tooltipChangeHandler, this));
                                    this.after("widthChange", this._sizeChanged);
                                    this.after("heightChange", this._sizeChanged);
                                    this.after("groupMarkersChange", this._groupMarkersChangeHandler);
                                    var tt = this.get("tooltip"),
                                        hideEvent = "mouseout",
                                        showEvent = "mouseover",
                                        cb = this.get("contentBox"),
                                        interactionType = this.get("interactionType"),
                                        i = 0,
                                        len,
                                        markerClassName = "." + SERIES_MARKER,
                                        isTouch = ((WINDOW && ("ontouchstart" in WINDOW)) && !(Y.UA.chrome && Y.UA.chrome < 6));
                                    Y.on("keydown", Y.bind(function(e) {
                                        var key = e.keyCode,
                                            numKey = parseFloat(key),
                                            msg;
                                        if(numKey > 36 && numKey < 41)
                                        {
                                            e.halt();
                                            msg = this._getAriaMessage(numKey);
                                            this._liveRegion.set("text", msg);
                                        }
                                    }, this), this.get("contentBox"));
                                    if(interactionType === "marker")
                                    {
                                        //if touch capabilities, toggle tooltip on touchend. otherwise, the tooltip attribute's hideEvent/showEvent types.
                                        hideEvent = tt.hideEvent;
                                        showEvent = tt.showEvent;
                                        if(isTouch)
                                        {
                                            Y.delegate("touchend", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
                                            //hide active tooltip if the chart is touched
                                            Y.on("touchend", Y.bind(function(e) {
                                                //only halt the event if it originated from the chart
                                                if(cb.contains(e.target))
                                                {
                                                    e.halt(true);
                                                }
                                                if(this._activeMarker)
                                                {
                                                    this._activeMarker = null;
                                                    this.hideTooltip(e);
                                                }
                                            }, this));
                                        }
                            
                                        Y.delegate("mouseenter", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
                                        Y.delegate("mousedown", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
                                        Y.delegate("mouseup", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
                                        Y.delegate("mouseleave", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
                                        Y.delegate("click", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
                                        Y.delegate("mousemove", Y.bind(this._positionTooltip, this), cb, markerClassName);
                                    }
                                    else if(interactionType === "planar")
                                    {
                                        if(isTouch)
                                        {
                                            this._overlay.on("touchend", Y.bind(this._planarEventDispatcher, this));
                                        }
                                        else
                                        {
                                            this._overlay.on("mousemove", Y.bind(this._planarEventDispatcher, this));
                                            this.on("mouseout", this.hideTooltip);
                                        }
                                    }
                                    if(tt)
                                    {
                                        this.on("markerEvent:touchend", Y.bind(function(e) {
                                            var marker = e.series.get("markers")[e.index];
                                            if(this._activeMarker && marker === this._activeMarker)
                                            {
                                                this._activeMarker = null;
                                                this.hideTooltip(e);
                                            }
                                            else
                                            {
                            
                                                this._activeMarker = marker;
                                                tt.markerEventHandler.apply(this, [e]);
                                            }
                                        }, this));
                                        if(hideEvent && showEvent && hideEvent === showEvent)
                                        {
                                            this.on(interactionType + "Event:" + hideEvent, this.toggleTooltip);
                                        }
                                        else
                                        {
                                            if(showEvent)
                                            {
                                                this.on(interactionType + "Event:" + showEvent, tt[interactionType + "EventHandler"]);
                                            }
                                            if(hideEvent)
                                            {
                                                if(Y_Lang.isArray(hideEvent))
                                                {
                                                    len = hideEvent.length;
                                                    for(; i < len; ++i)
                                                    {
                                                        this.on(interactionType + "Event:" + hideEvent[i], this.hideTooltip);
                                                    }
                                                }
                                                this.on(interactionType + "Event:" + hideEvent, this.hideTooltip);
                                            }
                                        }
                                    }
                                },
                            
                                /**
                                 * Event handler for marker events.
                                 *
                                 * @method _markerEventDispatcher
                                 * @param {Object} e Event object.
                                 * @private
                                 */
                                _markerEventDispatcher: function(e)
                                {
                                    var type = e.type,
                                        cb = this.get("contentBox"),
                                        markerNode = e.currentTarget,
                                        strArr = markerNode.getAttribute("id").split("_"),
                                        index = strArr.pop(),
                                        seriesIndex = strArr.pop(),
                                        series = this.getSeries(parseInt(seriesIndex, 10)),
                                        items = this.getSeriesItems(series, index),
                                        isTouch = e && e.hasOwnProperty("changedTouches"),
                                        pageX = isTouch ? e.changedTouches[0].pageX : e.pageX,
                                        pageY = isTouch ? e.changedTouches[0].pageY : e.pageY,
                                        x = pageX - cb.getX(),
                                        y = pageY - cb.getY();
                                    if(type === "mouseenter")
                                    {
                                        type = "mouseover";
                                    }
                                    else if(type === "mouseleave")
                                    {
                                        type = "mouseout";
                                    }
                                    series.updateMarkerState(type, index);
                                    e.halt();
                                    /**
                                     * Broadcasts when `interactionType` is set to `marker` and a series marker has received a mouseover event.
                                     *
                                     *
                                     * @event markerEvent:mouseover
                                     * @preventable false
                                     * @param {EventFacade} e Event facade with the following additional
                                     *   properties:
                                     *  <dl>
                                     *      <dt>categoryItem</dt><dd>Hash containing information about the category `Axis`.</dd>
                                     *      <dt>valueItem</dt><dd>Hash containing information about the value `Axis`.</dd>
                                     *      <dt>node</dt><dd>The dom node of the marker.</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>series</dt><dd>Reference to the series of the marker.</dd>
                                     *      <dt>index</dt><dd>Index of the marker in the series.</dd>
                                     *      <dt>seriesIndex</dt><dd>The `order` of the marker's series.</dd>
                                     *  </dl>
                                     */
                                    /**
                                     * Broadcasts when `interactionType` is set to `marker` and a series marker has received a mouseout event.
                                     *
                                     * @event markerEvent:mouseout
                                     * @preventable false
                                     * @param {EventFacade} e Event facade with the following additional
                                     *   properties:
                                     *  <dl>
                                     *      <dt>categoryItem</dt><dd>Hash containing information about the category `Axis`.</dd>
                                     *      <dt>valueItem</dt><dd>Hash containing information about the value `Axis`.</dd>
                                     *      <dt>node</dt><dd>The dom node of the marker.</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>series</dt><dd>Reference to the series of the marker.</dd>
                                     *      <dt>index</dt><dd>Index of the marker in the series.</dd>
                                     *      <dt>seriesIndex</dt><dd>The `order` of the marker's series.</dd>
                                     *  </dl>
                                     */
                                    /**
                                     * Broadcasts when `interactionType` is set to `marker` and a series marker has received a mousedown event.
                                     *
                                     * @event markerEvent:mousedown
                                     * @preventable false
                                     * @param {EventFacade} e Event facade with the following additional
                                     *   properties:
                                     *  <dl>
                                     *      <dt>categoryItem</dt><dd>Hash containing information about the category `Axis`.</dd>
                                     *      <dt>valueItem</dt><dd>Hash containing information about the value `Axis`.</dd>
                                     *      <dt>node</dt><dd>The dom node of the marker.</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>series</dt><dd>Reference to the series of the marker.</dd>
                                     *      <dt>index</dt><dd>Index of the marker in the series.</dd>
                                     *      <dt>seriesIndex</dt><dd>The `order` of the marker's series.</dd>
                                     *  </dl>
                                     */
                                    /**
                                     * Broadcasts when `interactionType` is set to `marker` and a series marker has received a mouseup event.
                                     *
                                     * @event markerEvent:mouseup
                                     * @preventable false
                                     * @param {EventFacade} e Event facade with the following additional
                                     *   properties:
                                     *  <dl>
                                     *      <dt>categoryItem</dt><dd>Hash containing information about the category `Axis`.</dd>
                                     *      <dt>valueItem</dt><dd>Hash containing information about the value `Axis`.</dd>
                                     *      <dt>node</dt><dd>The dom node of the marker.</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>series</dt><dd>Reference to the series of the marker.</dd>
                                     *      <dt>index</dt><dd>Index of the marker in the series.</dd>
                                     *      <dt>seriesIndex</dt><dd>The `order` of the marker's series.</dd>
                                     *  </dl>
                                     */
                                    /**
                                     * Broadcasts when `interactionType` is set to `marker` and a series marker has received a click event.
                                     *
                                     * @event markerEvent:click
                                     * @preventable false
                                     * @param {EventFacade} e Event facade with the following additional
                                     *   properties:
                                     *  <dl>
                                     *      <dt>categoryItem</dt><dd>Hash containing information about the category `Axis`.</dd>
                                     *      <dt>valueItem</dt><dd>Hash containing information about the value `Axis`.</dd>
                                     *      <dt>node</dt><dd>The dom node of the marker.</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>series</dt><dd>Reference to the series of the marker.</dd>
                                     *      <dt>index</dt><dd>Index of the marker in the series.</dd>
                                     *      <dt>seriesIndex</dt><dd>The `order` of the marker's series.</dd>
                                     *      <dt>originEvent</dt><dd>Underlying dom event.</dd>
                                     *  </dl>
                                     */
                                    this.fire("markerEvent:" + type, {
                                        originEvent: e,
                                        pageX:pageX,
                                        pageY:pageY,
                                        categoryItem:items.category,
                                        valueItem:items.value,
                                        node:markerNode,
                                        x:x,
                                        y:y,
                                        series:series,
                                        index:index,
                                        seriesIndex:seriesIndex
                                    });
                                },
                            
                                /**
                                 * Event handler for dataProviderChange.
                                 *
                                 * @method _dataProviderChangeHandler
                                 * @param {Object} e Event object.
                                 * @private
                                 */
                                _dataProviderChangeHandler: function(e)
                                {
                                    var dataProvider = e.newVal,
                                        axes,
                                        i,
                                        axis;
                                    this._seriesIndex = -1;
                                    this._itemIndex = -1;
                                    if(this instanceof Y.CartesianChart)
                                    {
                                        this.set("axes", this.get("axes"));
                                        this.set("seriesCollection", this.get("seriesCollection"));
                                    }
                                    axes = this.get("axes");
                                    if(axes)
                                    {
                                        for(i in axes)
                                        {
                                            if(axes.hasOwnProperty(i))
                                            {
                                                axis = axes[i];
                                                if(axis instanceof Y.Axis)
                                                {
                                                    if(axis.get("position") !== "none")
                                                    {
                                                        this._addToAxesRenderQueue(axis);
                                                    }
                                                    axis.set("dataProvider", dataProvider);
                                                }
                                            }
                                        }
                                    }
                                },
                            
                                /**
                                 * Event listener for toggling the tooltip. If a tooltip is visible, hide it. If not, it
                                 * will create and show a tooltip based on the event object.
                                 *
                                 * @method toggleTooltip
                                 * @param {Object} e Event object.
                                 */
                                toggleTooltip: function(e)
                                {
                                    var tt = this.get("tooltip");
                                    if(tt.visible)
                                    {
                                        this.hideTooltip();
                                    }
                                    else
                                    {
                                        tt.markerEventHandler.apply(this, [e]);
                                    }
                                },
                            
                                /**
                                 * Shows a tooltip
                                 *
                                 * @method _showTooltip
                                 * @param {String} msg Message to dispaly in the tooltip.
                                 * @param {Number} x x-coordinate
                                 * @param {Number} y y-coordinate
                                 * @private
                                 */
                                _showTooltip: function(msg, x, y)
                                {
                                    var tt = this.get("tooltip"),
                                        node = tt.node;
                                    if(msg)
                                    {
                                        tt.visible = true;
                                        tt.setTextFunction(node, msg);
                                        node.setStyle("top", y + "px");
                                        node.setStyle("left", x + "px");
                                        node.setStyle("visibility", "visible");
                                    }
                                },
                            
                                /**
                                 * Positions the tooltip
                                 *
                                 * @method _positionTooltip
                                 * @param {Object} e Event object.
                                 * @private
                                 */
                                _positionTooltip: function(e)
                                {
                                    var tt = this.get("tooltip"),
                                        node = tt.node,
                                        cb = this.get("contentBox"),
                                        x = (e.pageX + 10) - cb.getX(),
                                        y = (e.pageY + 10) - cb.getY();
                                    if(node)
                                    {
                                        node.setStyle("left", x + "px");
                                        node.setStyle("top", y + "px");
                                    }
                                },
                            
                                /**
                                 * Hides the default tooltip
                                 *
                                 * @method hideTooltip
                                 */
                                hideTooltip: function()
                                {
                                    var tt = this.get("tooltip"),
                                        node = tt.node;
                                    tt.visible = false;
                                    node.set("innerHTML", "");
                                    node.setStyle("left", -10000);
                                    node.setStyle("top", -10000);
                                    node.setStyle("visibility", "hidden");
                                },
                            
                                /**
                                 * Adds a tooltip to the dom.
                                 *
                                 * @method _addTooltip
                                 * @private
                                 */
                                _addTooltip: function()
                                {
                                    var tt = this.get("tooltip"),
                                        id = this.get("id") + "_tooltip",
                                        cb = this.get("contentBox"),
                                        oldNode = DOCUMENT.getElementById(id);
                                    if(oldNode)
                                    {
                                        cb.removeChild(oldNode);
                                    }
                                    tt.node.set("id", id);
                                    tt.node.setStyle("visibility", "hidden");
                                    cb.appendChild(tt.node);
                                },
                            
                                /**
                                 * Updates the tooltip attribute.
                                 *
                                 * @method _updateTooltip
                                 * @param {Object} val Object containing properties for the tooltip.
                                 * @return Object
                                 * @private
                                 */
                                _updateTooltip: function(val)
                                {
                                    var tt = this.get("tooltip") || this._getTooltip(),
                                        i,
                                        styles,
                                        node,
                                        props = {
                                            markerLabelFunction:"markerLabelFunction",
                                            planarLabelFunction:"planarLabelFunction",
                                            setTextFunction:"setTextFunction",
                                            showEvent:"showEvent",
                                            hideEvent:"hideEvent",
                                            markerEventHandler:"markerEventHandler",
                                            planarEventHandler:"planarEventHandler",
                                            show:"show"
                                        };
                                    if(Y_Lang.isObject(val))
                                    {
                                        styles = val.styles;
                                        if(val.node && tt.node)
                                        {
                                            tt.node.destroy(true);
                                            node = Y.one(val.node);
                                        }
                                        else
                                        {
                                            node = tt.node;
                                        }
                                        if(styles)
                                        {
                                            for(i in styles)
                                            {
                                                if(styles.hasOwnProperty(i))
                                                {
                                                    node.setStyle(i, styles[i]);
                                                }
                                            }
                                        }
                                        for(i in props)
                                        {
                                            if(val.hasOwnProperty(i))
                                            {
                                                tt[i] = val[i];
                                            }
                                        }
                                        tt.node = node;
                                    }
                                    return tt;
                                },
                            
                                /**
                                 * Default getter for `tooltip` attribute.
                                 *
                                 * @method _getTooltip
                                 * @return Object
                                 * @private
                                 */
                                _getTooltip: function()
                                {
                                    var node = DOCUMENT.createElement("div"),
                                        tooltipClass = _getClassName("chart-tooltip"),
                                        tt = {
                                            setTextFunction: this._setText,
                                            markerLabelFunction: this._tooltipLabelFunction,
                                            planarLabelFunction: this._planarLabelFunction,
                                            show: true,
                                            hideEvent: "mouseout",
                                            showEvent: "mouseover",
                                            markerEventHandler: function(e)
                                            {
                                                var tt = this.get("tooltip"),
                                                msg = tt.markerLabelFunction.apply(this, [e.categoryItem, e.valueItem, e.index, e.series, e.seriesIndex]);
                                                this._showTooltip(msg, e.x + 10, e.y + 10);
                                            },
                                            planarEventHandler: function(e)
                                            {
                                                var tt = this.get("tooltip"),
                                                    msg ,
                                                    categoryAxis = this.get("categoryAxis");
                                                msg = tt.planarLabelFunction.apply(this, [categoryAxis, e.valueItem, e.index, e.items, e.seriesIndex]);
                                                this._showTooltip(msg, e.x + 10, e.y + 10);
                                            }
                                        };
                                    node = Y.one(node);
                                    node.set("id", this.get("id") + "_tooltip");
                                    node.setStyle("fontSize", "85%");
                                    node.setStyle("opacity", "0.83");
                                    node.setStyle("position", "absolute");
                                    node.setStyle("paddingTop", "2px");
                                    node.setStyle("paddingRight", "5px");
                                    node.setStyle("paddingBottom", "4px");
                                    node.setStyle("paddingLeft", "2px");
                                    node.setStyle("backgroundColor", "#fff");
                                    node.setStyle("border", "1px solid #dbdccc");
                                    node.setStyle("pointerEvents", "none");
                                    node.setStyle("zIndex", 3);
                                    node.setStyle("whiteSpace", "noWrap");
                                    node.setStyle("visibility", "hidden");
                                    node.addClass(tooltipClass);
                                    tt.node = Y.one(node);
                                    return tt;
                                },
                            
                                /**
                                 * Formats tooltip text when `interactionType` is `planar`.
                                 *
                                 * @method _planarLabelFunction
                                 * @param {Axis} categoryAxis Reference to the categoryAxis of the chart.
                                 * @param {Array} valueItems Array of objects for each series that has a data point in the coordinate plane of the event.
                                 * Each object contains the following data:
                                 *  <dl>
                                 *      <dt>axis</dt><dd>The value axis of the series.</dd>
                                 *      <dt>key</dt><dd>The key for the series.</dd>
                                 *      <dt>value</dt><dd>The value for the series item.</dd>
                                 *      <dt>displayName</dt><dd>The display name of the series. (defaults to key if not provided)</dd>
                                 *  </dl>
                                 *  @param {Number} index The index of the item within its series.
                                 *  @param {Array} seriesArray Array of series instances for each value item.
                                 *  @param {Number} seriesIndex The index of the series in the `seriesCollection`.
                                 *  @return {HTMLElement}
                                 * @private
                                 */
                                _planarLabelFunction: function(categoryAxis, valueItems, index, seriesArray)
                                {
                                    var msg = DOCUMENT.createElement("div"),
                                        valueItem,
                                        i = 0,
                                        len = seriesArray.length,
                                        axis,
                                        categoryValue,
                                        seriesValue,
                                        series;
                                    if(categoryAxis)
                                    {
                                        categoryValue = categoryAxis.get("labelFunction").apply(
                                            this,
                                            [categoryAxis.getKeyValueAt(this.get("categoryKey"), index), categoryAxis.get("labelFormat")]
                                        );
                                        if(!Y_Lang.isObject(categoryValue))
                                        {
                                            categoryValue = DOCUMENT.createTextNode(categoryValue);
                                        }
                                        msg.appendChild(categoryValue);
                                    }
                            
                                    for(; i < len; ++i)
                                    {
                                        series = seriesArray[i];
                                        if(series.get("visible"))
                                        {
                                            valueItem = valueItems[i];
                                            axis = valueItem.axis;
                                            seriesValue =  axis.get("labelFunction").apply(
                                                this,
                                                [axis.getKeyValueAt(valueItem.key, index), axis.get("labelFormat")]
                                            );
                                            msg.appendChild(DOCUMENT.createElement("br"));
                                            msg.appendChild(DOCUMENT.createTextNode(valueItem.displayName));
                                            msg.appendChild(DOCUMENT.createTextNode(": "));
                                            if(!Y_Lang.isObject(seriesValue))
                                            {
                                                seriesValue = DOCUMENT.createTextNode(seriesValue);
                                            }
                                            msg.appendChild(seriesValue);
                                        }
                                    }
                                    return msg;
                                },
                            
                                /**
                                 * Formats tooltip text when `interactionType` is `marker`.
                                 *
                                 * @method _tooltipLabelFunction
                                 * @param {Object} categoryItem An object containing the following:
                                 *  <dl>
                                 *      <dt>axis</dt><dd>The axis to which the category is bound.</dd>
                                 *      <dt>displayName</dt><dd>The display name set to the category (defaults to key if not provided)</dd>
                                 *      <dt>key</dt><dd>The key of the category.</dd>
                                 *      <dt>value</dt><dd>The value of the category</dd>
                                 *  </dl>
                                 * @param {Object} valueItem An object containing the following:
                                 *  <dl>
                                 *      <dt>axis</dt><dd>The axis to which the item's series is bound.</dd>
                                 *      <dt>displayName</dt><dd>The display name of the series. (defaults to key if not provided)</dd>
                                 *      <dt>key</dt><dd>The key for the series.</dd>
                                 *      <dt>value</dt><dd>The value for the series item.</dd>
                                 *  </dl>
                                 * @return {HTMLElement}
                                 * @private
                                 */
                                _tooltipLabelFunction: function(categoryItem, valueItem)
                                {
                                    var msg = DOCUMENT.createElement("div"),
                                        categoryValue = categoryItem.axis.get("labelFunction").apply(
                                            this,
                                            [categoryItem.value, categoryItem.axis.get("labelFormat")]
                                        ),
                                        seriesValue = valueItem.axis.get("labelFunction").apply(
                                            this,
                                            [valueItem.value, valueItem.axis.get("labelFormat")]
                                        );
                                    msg.appendChild(DOCUMENT.createTextNode(categoryItem.displayName));
                                    msg.appendChild(DOCUMENT.createTextNode(": "));
                                    if(!Y_Lang.isObject(categoryValue))
                                    {
                                        categoryValue = DOCUMENT.createTextNode(categoryValue);
                                    }
                                    msg.appendChild(categoryValue);
                                    msg.appendChild(DOCUMENT.createElement("br"));
                                    msg.appendChild(DOCUMENT.createTextNode(valueItem.displayName));
                                    msg.appendChild(DOCUMENT.createTextNode(": "));
                                    if(!Y_Lang.isObject(seriesValue))
                                    {
                                        seriesValue = DOCUMENT.createTextNode(seriesValue);
                                    }
                                    msg.appendChild(seriesValue);
                                    return msg;
                                },
                            
                                /**
                                 * Event handler for the tooltipChange.
                                 *
                                 * @method _tooltipChangeHandler
                                 * @param {Object} e Event object.
                                 * @private
                                 */
                                _tooltipChangeHandler: function()
                                {
                                    if(this.get("tooltip"))
                                    {
                                        var tt = this.get("tooltip"),
                                            node = tt.node,
                                            show = tt.show,
                                            cb = this.get("contentBox");
                                        if(node && show)
                                        {
                                            if(!cb.contains(node))
                                            {
                                                this._addTooltip();
                                            }
                                        }
                                    }
                                },
                            
                                /**
                                 * Updates the content of text field. This method writes a value into a text field using
                                 * `appendChild`. If the value is a `String`, it is converted to a `TextNode` first.
                                 *
                                 * @method _setText
                                 * @param label {HTMLElement} label to be updated
                                 * @param val {String} value with which to update the label
                                 * @private
                                 */
                                _setText: function(textField, val)
                                {
                                    textField.empty();
                                    if(Y_Lang.isNumber(val))
                                    {
                                        val = val + "";
                                    }
                                    else if(!val)
                                    {
                                        val = "";
                                    }
                                    if(IS_STRING(val))
                                    {
                                        val = DOCUMENT.createTextNode(val);
                                    }
                                    textField.appendChild(val);
                                },
                            
                                /**
                                 * Returns all the keys contained in a  `dataProvider`.
                                 *
                                 * @method _getAllKeys
                                 * @param {Array} dp Collection of objects to be parsed.
                                 * @return Object
                                 */
                                _getAllKeys: function(dp)
                                {
                                    var i = 0,
                                        len = dp.length,
                                        item,
                                        key,
                                        keys = {};
                                    for(; i < len; ++i)
                                    {
                                        item = dp[i];
                                        for(key in item)
                                        {
                                            if(item.hasOwnProperty(key))
                                            {
                                                keys[key] = true;
                                            }
                                        }
                                    }
                                    return keys;
                                },
                            
                                /**
                                 * Constructs seriesKeys if not explicitly specified.
                                 *
                                 * @method _buildSeriesKeys
                                 * @param {Array} dataProvider The dataProvider for the chart.
                                 * @return Array
                                 * @private
                                 */
                                _buildSeriesKeys: function(dataProvider)
                                {
                                    var allKeys,
                                        catKey = this.get("categoryKey"),
                                        keys = [],
                                        i;
                                    if(this._seriesKeysExplicitlySet)
                                    {
                                        return this._seriesKeys;
                                    }
                                    allKeys = this._getAllKeys(dataProvider);
                                    for(i in allKeys)
                                    {
                                        if(allKeys.hasOwnProperty(i) && i !== catKey)
                                        {
                                            keys.push(i);
                                        }
                                    }
                                    return keys;
                                }
                            };
                            Y.ChartBase = ChartBase;