function drawSpline(plot, ctx, series) {
    // Not interested if spline is not requested
    if (series.splines.show !== true) {
      return;
    }

    var cp = [],
      // array of control points
      tension = series.splines.tension || 0.5,
      idx, x, y, points = series.datapoints.points,
      ps = series.datapoints.pointsize,
      plotOffset = plot.getPlotOffset(),
      len = points.length,
      pts = [];

    line = [];

    // Cannot display a linespline/areaspline if there are less than 3 points
    if (len / ps < 4) {
      $.extend(series.lines, series.splines);
      return;
    }

    for (idx = 0; idx < len; idx += ps) {
      x = points[idx];
      y = points[idx + 1];
      if (x == null || x < series.xaxis.min || x > series.xaxis.max || y < series.yaxis.min || y > series.yaxis.max) {
        continue;
      }

      pts.push(series.xaxis.p2c(x) + plotOffset.left, series.yaxis.p2c(y) + plotOffset.top);
    }

    len = pts.length;

    // Draw an open curve, not connected at the ends
    for (idx = 0; idx < len - 2; idx += 2) {
      cp = cp.concat(getControlPoints.apply(this, pts.slice(idx, idx + 6).concat([tension])));
    }

    ctx.save();
    ctx.strokeStyle = series.color;
    ctx.lineWidth = series.splines.lineWidth;

    queue(ctx, 'quadratic', pts.slice(0, 4), cp.slice(0, 2));

    for (idx = 2; idx < len - 3; idx += 2) {
      queue(ctx, 'bezier', pts.slice(idx, idx + 4), cp.slice(2 * idx - 2, 2 * idx + 2));
    }

    queue(ctx, 'quadratic', pts.slice(len - 2, len), [cp[2 * len - 10], cp[2 * len - 9], pts[len - 4], pts[len - 3]]);

    drawLine(line, ctx, plot.height() + 10, series.splines.fill, series.color);

    ctx.restore();
  }
@param {Object} plot
@param {Object} ctx: canvas context
@param {Object} series

@api private