#

API Docs for: 3.10.3
Show: Inherited Protected Private Deprecated

# File: charts/js/Lines.js

    /**
     * Provides functionality for drawing lines in a series.
     *
     * @module charts
     * @submodule series-line-util
     */
    /**
     * Utility class used for drawing lines.
     *
     * @class Lines
     * @constructor
     * @submodule series-line-util
     */
    var Y_Lang = Y.Lang;
    function Lines(){}

    Lines.prototype = {
        /**
         * @property _lineDefaults
         * @type Object
         * @private
         */
        _lineDefaults: null,

        /**
         * Creates a graphic in which to draw a series.
         *
         * @method _getGraphic
         * @return Graphic
         * @private
         */
        _getGraphic: function()
        {
            var graphic = this.get("graphic") || this.get("graph").get("graphic");
            if(!this._lineGraphic)
            {
                this._lineGraphic = graphic.addShape({type: "path"});
            }
            this._lineGraphic.clear();
            return this._lineGraphic;
        },

        /**
         * Toggles visibility
         *
         * @method _toggleVisible
         * @param {Boolean} visible indicates visibilitye
         * @private
         */
        _toggleVisible: function(visible)
        {
            if(this._lineGraphic)
            {
                this._lineGraphic.set("visible", visible);
            }
        },

        /**
         * Draws lines for the series.
         *
         * @method drawLines
         * @protected
         */
        drawLines: function()
        {
            if(this.get("xcoords").length < 1)
            {
                return;
            }
            var isNumber = Y_Lang.isNumber,
                xcoords,
                ycoords,
                direction = this.get("direction"),
                len,
                lastPointValid,
                pointValid,
                noPointsRendered = true,
                lastValidX,
                lastValidY,
                nextX,
                nextY,
                i,
                styles = this.get("styles").line,
                lineType = styles.lineType,
                lc = styles.color || this._getDefaultColor(this.get("graphOrder"), "line"),
                lineAlpha = styles.alpha,
                dashLength = styles.dashLength,
                gapSpace = styles.gapSpace,
                connectDiscontinuousPoints = styles.connectDiscontinuousPoints,
                discontinuousType = styles.discontinuousType,
                discontinuousDashLength = styles.discontinuousDashLength,
                discontinuousGapSpace = styles.discontinuousGapSpace,
                path = this._getGraphic();
            if(this._stacked)
            {
                xcoords = this.get("stackedXCoords");
                ycoords = this.get("stackedYCoords");
            }
            else
            {
                xcoords = this.get("xcoords");
                ycoords = this.get("ycoords");
            }
            len = direction === "vertical" ? ycoords.length : xcoords.length;
            path.set("stroke", {
                weight: styles.weight,
                color: lc,
                opacity: lineAlpha
            });
            for(i = 0; i < len; i = ++i)
            {
                nextX = xcoords[i];
                nextY = ycoords[i];
                pointValid = isNumber(nextX) && isNumber(nextY);
                if(!pointValid)
                {
                    lastPointValid = pointValid;
                    continue;
                }
                if(noPointsRendered)
                {
                    noPointsRendered = false;
                    path.moveTo(nextX, nextY);
                }
                else if(lastPointValid)
                {
                    if(lineType !== "dashed")
                    {
                        path.lineTo(nextX, nextY);
                    }
                    else
                    {
                        this.drawDashedLine(path, lastValidX, lastValidY, nextX, nextY,
                                                    dashLength,
                                                    gapSpace);
                    }
                }
                else if(!connectDiscontinuousPoints)
                {
                    path.moveTo(nextX, nextY);
                }
                else
                {
                    if(discontinuousType !== "solid")
                    {
                        this.drawDashedLine(path, lastValidX, lastValidY, nextX, nextY,
                                                    discontinuousDashLength,
                                                    discontinuousGapSpace);
                    }
                    else
                    {
                        path.lineTo(nextX, nextY);
                    }
                }
                lastValidX = nextX;
                lastValidY = nextY;
                lastPointValid = true;
            }
            path.end();
        },

        /**
         * Connects data points with a consistent curve for a series.
         *
         * @method drawSpline
         * @protected
         */
        drawSpline: function()
        {
            if(this.get("xcoords").length < 1)
            {
                return;
            }
            var xcoords = this.get("xcoords"),
                ycoords = this.get("ycoords"),
                curvecoords = this.getCurveControlPoints(xcoords, ycoords),
                len = curvecoords.length,
                cx1,
                cx2,
                cy1,
                cy2,
                x,
                y,
                i = 0,
                styles = this.get("styles").line,
                path = this._getGraphic(),
                lineAlpha = styles.alpha,
                color = styles.color || this._getDefaultColor(this.get("graphOrder"), "line");
            path.set("stroke", {
                weight: styles.weight,
                color: color,
                opacity: lineAlpha
            });
            path.moveTo(xcoords[0], ycoords[0]);
            for(; i < len; i = ++i)
            {
                x = curvecoords[i].endx;
                y = curvecoords[i].endy;
                cx1 = curvecoords[i].ctrlx1;
                cx2 = curvecoords[i].ctrlx2;
                cy1 = curvecoords[i].ctrly1;
                cy2 = curvecoords[i].ctrly2;
                path.curveTo(cx1, cy1, cx2, cy2, x, y);
            }
            path.end();
        },

        /**
         * Draws a dashed line between two points.
         *
         * @method drawDashedLine
         * @param {Number} xStart	The x position of the start of the line
         * @param {Number} yStart	The y position of the start of the line
         * @param {Number} xEnd		The x position of the end of the line
         * @param {Number} yEnd		The y position of the end of the line
         * @param {Number} dashSize	the size of dashes, in pixels
         * @param {Number} gapSize	the size of gaps between dashes, in pixels
         * @private
         */
        drawDashedLine: function(path, xStart, yStart, xEnd, yEnd, dashSize, gapSize)
        {
            dashSize = dashSize || 10;
            gapSize = gapSize || 10;
            var segmentLength = dashSize + gapSize,
                xDelta = xEnd - xStart,
                yDelta = yEnd - yStart,
                delta = Math.sqrt(Math.pow(xDelta, 2) + Math.pow(yDelta, 2)),
                segmentCount = Math.floor(Math.abs(delta / segmentLength)),
                radians = Math.atan2(yDelta, xDelta),
                xCurrent = xStart,
                yCurrent = yStart,
                i;
            xDelta = Math.cos(radians) * segmentLength;
            yDelta = Math.sin(radians) * segmentLength;

            for(i = 0; i < segmentCount; ++i)
            {
                path.moveTo(xCurrent, yCurrent);
                path.lineTo(xCurrent + Math.cos(radians) * dashSize, yCurrent + Math.sin(radians) * dashSize);
                xCurrent += xDelta;
                yCurrent += yDelta;
            }

            path.moveTo(xCurrent, yCurrent);
            delta = Math.sqrt((xEnd - xCurrent) * (xEnd - xCurrent) + (yEnd - yCurrent) * (yEnd - yCurrent));

            if(delta > dashSize)
            {
                path.lineTo(xCurrent + Math.cos(radians) * dashSize, yCurrent + Math.sin(radians) * dashSize);
            }
            else if(delta > 0)
            {
                path.lineTo(xCurrent + Math.cos(radians) * delta, yCurrent + Math.sin(radians) * delta);
            }

            path.moveTo(xEnd, yEnd);
        },

        /**
         * Default values for `styles` attribute.
         *
         * @method _getLineDefaults
         * @return Object
         * @protected
         */
        _getLineDefaults: function()
        {
            return {
                alpha: 1,
                weight: 6,
                lineType:"solid",
                dashLength:10,
                gapSpace:10,
                connectDiscontinuousPoints:true,
                discontinuousType:"solid",
                discontinuousDashLength:10,
                discontinuousGapSpace:10
            };
        }
    };
    Y.augment(Lines, Y.Attribute);
    Y.Lines = Lines;