#

API Docs for: 3.10.3
Show: Inherited Protected Private Deprecated

# File: charts/js/StackedBarSeries.js

    /**
     * Provides functionality for creating a stacked bar series.
     *
     * @module charts
     * @submodule series-bar-stacked
     */
    var Y_Lang = Y.Lang;

    /**
     * The StackedBarSeries renders bar chart in which series are stacked horizontally to show
     * their contribution to the cumulative total.
     *
     * @class StackedBarSeries
     * @extends BarSeries
     * @uses StackingUtil
     * @constructor
     * @param {Object} config (optional) Configuration parameters.
     * @submodule series-bar-stacked
     */
    Y.StackedBarSeries = Y.Base.create("stackedBarSeries", Y.BarSeries, [Y.StackingUtil], {
        /**
         * @protected
         *
         * Draws the series.
         *
         * @method drawSeries
         */
        drawSeries: function()
    	{
            if(this.get("xcoords").length < 1)
            {
                return;
            }

            var isNumber = Y_Lang.isNumber,
                style = Y.clone(this.get("styles").marker),
                w = style.width,
                h = style.height,
                xcoords = this.get("xcoords"),
                ycoords = this.get("ycoords"),
                i = 0,
                len = xcoords.length,
                top = ycoords[0],
                seriesCollection = this.get("seriesTypeCollection"),
                ratio,
                order = this.get("order"),
                graphOrder = this.get("graphOrder"),
                left,
                marker,
                lastCollection,
                negativeBaseValues,
                positiveBaseValues,
                fillColors,
                borderColors,
                useOrigin = order === 0,
                totalHeight = len * h,
                dimensions = {
                    width: [],
                    height: []
                },
                xvalues = [],
                yvalues = [],
                groupMarkers = this.get("groupMarkers");
            if(Y_Lang.isArray(style.fill.color))
            {
                fillColors = style.fill.color.concat();
            }
            if(Y_Lang.isArray(style.border.color))
            {
                borderColors = style.border.color.concat();
            }
            this._createMarkerCache();
            if(totalHeight > this.get("height"))
            {
                ratio = this.get("height")/totalHeight;
                h *= ratio;
                h = Math.max(h, 1);
            }
            if(!useOrigin)
            {
                lastCollection = seriesCollection[order - 1];
                negativeBaseValues = lastCollection.get("negativeBaseValues");
                positiveBaseValues = lastCollection.get("positiveBaseValues");
                if(!negativeBaseValues || !positiveBaseValues)
                {
                    useOrigin = true;
                    positiveBaseValues = [];
                    negativeBaseValues = [];
                }
            }
            else
            {
                negativeBaseValues = [];
                positiveBaseValues = [];
            }
            this.set("negativeBaseValues", negativeBaseValues);
            this.set("positiveBaseValues", positiveBaseValues);
            for(i = 0; i < len; ++i)
            {
                top = ycoords[i];
                left = xcoords[i];
                if(!isNumber(top) || !isNumber(left))
                {
                    if(useOrigin)
                    {
                        positiveBaseValues[i] = this._leftOrigin;
                        negativeBaseValues[i] = this._leftOrigin;
                    }
                    this._markers.push(null);
                    continue;
                }
                if(useOrigin)
                {
                    w = Math.abs(left - this._leftOrigin);
                    if(left > this._leftOrigin)
                    {
                        positiveBaseValues[i] = left;
                        negativeBaseValues[i] = this._leftOrigin;
                        left -= w;
                    }
                    else if(left < this._leftOrigin)
                    {
                        positiveBaseValues[i] = this._leftOrigin;
                        negativeBaseValues[i] = left;
                    }
                    else
                    {
                        positiveBaseValues[i] = left;
                        negativeBaseValues[i] = this._leftOrigin;
                    }
                }
                else
                {
                    if(left < this._leftOrigin)
                    {
                        left = negativeBaseValues[i] - (this._leftOrigin - xcoords[i]);
                        w = negativeBaseValues[i] - left;
                        negativeBaseValues[i] = left;
                    }
                    else if(left >= this._leftOrigin)
                    {
                        left += (positiveBaseValues[i] - this._leftOrigin);
                        w = left - positiveBaseValues[i];
                        positiveBaseValues[i] = left;
                        left -= w;
                    }
                }
                if(!isNaN(w) && w > 0)
                {
                    top -= h/2;
                    if(groupMarkers)
                    {
                        dimensions.width[i] = w;
                        dimensions.height[i] = h;
                        xvalues.push(left);
                        yvalues.push(top);
                    }
                    else
                    {
                        style.width = w;
                        style.height = h;
                        style.x = left;
                        style.y = top;
                        if(fillColors)
                        {
                            style.fill.color = fillColors[i % fillColors.length];
                        }
                        if(borderColors)
                        {
                            style.border.color = borderColors[i % borderColors.length];
                        }
                        marker = this.getMarker(style, graphOrder, i);
                    }
                }
                else if(!groupMarkers)
                {
                    this._markers.push(null);
                }
            }
            if(groupMarkers)
            {
                this._createGroupMarker({
                    fill: style.fill,
                    border: style.border,
                    dimensions: dimensions,
                    xvalues: xvalues,
                    yvalues: yvalues,
                    shape: style.shape
                });
            }
            else
            {
                this._clearMarkerCache();
            }
        },

        /**
         * @protected
         *
         * Resizes and positions markers based on a mouse interaction.
         *
         * @method updateMarkerState
         * @param {String} type state of the marker
         * @param {Number} i index of the marker
         */
        updateMarkerState: function(type, i)
        {
            if(this._markers[i])
            {
                var state = this._getState(type),
                    ycoords = this.get("ycoords"),
                    marker = this._markers[i],
                    styles = this.get("styles").marker,
                    h = styles.height,
                    markerStyles = state === "off" || !styles[state] ? Y.clone(styles) : Y.clone(styles[state]),
                    fillColor,
                    borderColor;
                markerStyles.y = (ycoords[i] - h/2);
                markerStyles.x = marker.get("x");
                markerStyles.width = marker.get("width");
                markerStyles.id = marker.get("id");
                fillColor = markerStyles.fill.color;
                borderColor = markerStyles.border.color;
                if(Y_Lang.isArray(fillColor))
                {
                    markerStyles.fill.color = fillColor[i % fillColor.length];
                }
                else
                {
                    markerStyles.fill.color = this._getItemColor(markerStyles.fill.color, i);
                }
                if(Y_Lang.isArray(borderColor))
                {
                    markerStyles.border.color = borderColor[i % borderColor.length];
                }
                else
                {
                    markerStyles.border.color = this._getItemColor(markerStyles.border.color, i);
                }
                marker.set(markerStyles);
            }
        },

        /**
         * @protected
         *
         * Returns default values for the `styles` attribute.
         *
         * @method _getPlotDefaults
         * @return Object
         */
        _getPlotDefaults: function()
        {
            var defs = {
                fill:{
                    type: "solid",
                    alpha: 1,
                    colors:null,
                    alphas: null,
                    ratios: null
                },
                border:{
                    weight: 0,
                    alpha: 1
                },
                width: 24,
                height: 24,
                shape: "rect",

                padding:{
                    top: 0,
                    left: 0,
                    right: 0,
                    bottom: 0
                }
            };
            defs.fill.color = this._getDefaultColor(this.get("graphOrder"), "fill");
            defs.border.color = this._getDefaultColor(this.get("graphOrder"), "border");
            return defs;
        }
    }, {
        ATTRS: {
            /**
             * Read-only attribute indicating the type of series.
             *
             * @attribute type
             * @type String
             * @default stackedBar
             */
            type: {
                value: "stackedBar"
            },

            /**
             * Direction of the series
             *
             * @attribute direction
             * @type String
             * @default vertical
             */
            direction: {
                value: "vertical"
            },

            /**
             * @private
             *
             * @attribute negativeBaseValues
             * @type Array
             * @default null
             */
            negativeBaseValues: {
                value: null
            },

            /**
             * @private
             *
             * @attribute positiveBaseValues
             * @type Array
             * @default null
             */
            positiveBaseValues: {
                value: null
            }

            /**
             * Style properties used for drawing markers. This attribute is inherited from `BarSeries`. Below are the default values:
             *  <dl>
             *      <dt>fill</dt><dd>A hash containing the following values:
             *          <dl>
             *              <dt>color</dt><dd>Color of the fill. The default value is determined by the order of the series on the graph. The color
             *              will be retrieved from the below array:<br/>
             *              `["#66007f", "#a86f41", "#295454", "#996ab2", "#e8cdb7", "#90bdbd","#000000","#c3b8ca", "#968373", "#678585"]`
             *              </dd>
             *              <dt>alpha</dt><dd>Number from 0 to 1 indicating the opacity of the marker fill. The default value is 1.</dd>
             *          </dl>
             *      </dd>
             *      <dt>border</dt><dd>A hash containing the following values:
             *          <dl>
             *              <dt>color</dt><dd>Color of the border. The default value is determined by the order of the series on the graph. The color
             *              will be retrieved from the below array:<br/>
             *              `["#205096", "#b38206", "#000000", "#94001e", "#9d6fa0", "#e55b00", "#5e85c9", "#adab9e", "#6ac291", "#006457"]`
             *              <dt>alpha</dt><dd>Number from 0 to 1 indicating the opacity of the marker border. The default value is 1.</dd>
             *              <dt>weight</dt><dd>Number indicating the width of the border. The default value is 1.</dd>
             *          </dl>
             *      </dd>
             *      <dt>height</dt><dd>indicates the width of the marker. The default value is 24.</dd>
             *      <dt>over</dt><dd>hash containing styles for markers when highlighted by a `mouseover` event. The default
             *      values for each style is null. When an over style is not set, the non-over value will be used. For example,
             *      the default value for `marker.over.fill.color` is equivalent to `marker.fill.color`.</dd>
             *  </dl>
             *
             * @attribute styles
             * @type Object
             */
        }
    });