#

API Docs for: 3.10.3
Show: Inherited Protected Private Deprecated

# File: charts/js/CurveUtil.js

    /**
     * Provides functionality for drawing curves in a series.
     *
     * @module charts
     * @submodule series-curve-util
     */
    /**
     * Utility class used for calculating curve points.
     *
     * @class CurveUtil
     * @constructor
     * @submodule series-curve-util
     */
    function CurveUtil()
    {
    }

    CurveUtil.prototype = {
        /**
         * Creates an array of start, end and control points for splines.
         *
         * @method getCurveControlPoints
         * @param {Array} xcoords Collection of x-coordinates used for calculate the curves
         * @param {Array} ycoords Collection of y-coordinates used for calculate the curves
         * @return Object
         * @protected
         */
        getCurveControlPoints: function(xcoords, ycoords)
        {
    		var outpoints = [],
                i = 1,
                l = xcoords.length - 1,
                xvals = [],
                yvals = [];

    		// Too few points, need at least two
    		if (l < 1)
            {
    			return null;
    		}

            outpoints[0] = {
                startx: xcoords[0],
                starty: ycoords[0],
                endx: xcoords[1],
                endy: ycoords[1]
            };

    		// Special case, the Bezier should be a straight line
            if (l === 1)
            {
    			outpoints[0].ctrlx1 = (2.0*xcoords[0] + xcoords[1])/3.0;
    			outpoints[0].ctrly2 = (2.0*ycoords[0] + ycoords[1])/3.0;
    			outpoints[0].ctrlx2 = 2.0*outpoints[0].ctrlx1 - xcoords[0];
                outpoints[0].ctrly2 = 2.0*outpoints[0].ctrly1 - ycoords[0];
                return outpoints;
    		}

    		for (; i < l; ++i)
            {
    			outpoints.push({
                    startx: Math.round(xcoords[i]),
                    starty: Math.round(ycoords[i]),
                    endx: Math.round(xcoords[i+1]),
                    endy: Math.round(ycoords[i+1])
                });
    			xvals[i] = 4.0 * xcoords[i] + 2*xcoords[i+1];
    			yvals[i] = 4.0*ycoords[i] + 2*ycoords[i+1];
    		}

    		xvals[0] = xcoords[0] + (2.0 * xcoords[1]);
    		xvals[l-1] = (8.0 * xcoords[l-1] + xcoords[l]) / 2.0;
    		xvals = this.getControlPoints(xvals.concat());
            yvals[0] = ycoords[0] + (2.0 * ycoords[1]);
    		yvals[l-1] = (8.0 * ycoords[l-1] + ycoords[l]) / 2.0;
    		yvals = this.getControlPoints(yvals.concat());

            for (i = 0; i < l; ++i)
            {
    			outpoints[i].ctrlx1 = Math.round(xvals[i]);
                outpoints[i].ctrly1 = Math.round(yvals[i]);

    			if (i < l-1)
                {
    				outpoints[i].ctrlx2 = Math.round(2*xcoords[i+1] - xvals[i+1]);
                    outpoints[i].ctrly2 = Math.round(2*ycoords[i+1] - yvals[i+1]);
    			}
    			else
                {
    				outpoints[i].ctrlx2 = Math.round((xcoords[l] + xvals[l-1])/2);
                    outpoints[i].ctrly2 = Math.round((ycoords[l] + yvals[l-1])/2);
    			}
    		}

    		return outpoints;
    	},

        /**
         * Gets the control points for the curve.
         *
         * @method getControlPoints
         * @param {Array} vals Collection of values coords used to generate control points.
         * @return Array
         * @private
         */
    	getControlPoints: function(vals)
        {
    		var l = vals.length,
                x = [],
                tmp = [],
                b = 2.0,
                i = 1;
    		x[0] = vals[0] / b;
    		for (; i < l; ++i)
            {
    			tmp[i] = 1/b;
    			b = (i < l-1 ? 4.0 : 3.5) - tmp[i];
    			x[i] = (vals[i] - x[i-1]) / b;
    		}

    		for (i = 1; i < l; ++i)
            {
    			x[l-i-1] -= tmp[l-i] * x[l-i];
    		}

    		return x;
    	}
    };
    Y.CurveUtil = CurveUtil;