trend

trend

by manecocomph

HTML

<canvas id="trendCanvas"></canvas>
<h5>About author: <a target='_blank' href='https://blog.tianxiaohui.com'>Tian Xiaohui</a></h5>

JavaScript

function logPoints(msg, points) {
	console.log(msg);
  var pointCount = points.length;
  var pointStr = "";
  for (var i = 0; i < pointCount; i++) {
  	pointStr += "(" + points[i].x + ", " + points[i].y + ") "
  }
  console.log(pointStr);
}
//get next N points: start + 1, start + 2, ..., start + N
function getNextNPoints(points, cur, n) {
	var halfN = Math.ceil(n / 2);
	var start = cur - halfN;
  if (start < 0) {
  	start = 0;
  }
	var end = cur + halfN;
  var pointCount = points.length;
	if (pointCount < end) {
  	end = pointCount;
  }
  
  return points.slice(start, end);
}

//calc average value point
function calcAveragePoint(points) {
	var pointCount = points.length;
  var xSum = 0, ySum = 0;
  for (var i = 0; i < pointCount; i++) {
  	xSum += points[i].x;
    ySum += points[i].y;
  }
  
  return {'x': xSum / pointCount, 'y': ySum / pointCount};
}

function calcBezierEndPoint(points) {
	var bezierPoints = [points[0]];
  var pointCount = points.length;
  var curIndex = 1;
  while (pointCount > curIndex + 3) {
  	bezierPoints.push(points[curIndex], points[curIndex + 1], {'x': (points[curIndex + 1].x + points[curIndex + 2].x) / 2, 'y': (points[curIndex + 1].y + points[curIndex + 2].y) / 2});
    curIndex += 2;
  }
  
  if (3 == (pointCount - curIndex)) {
  	bezierPoints.push(points[curIndex], points[curIndex + 1], points[curIndex + 2]);
  }
  if (2 == (pointCount - curIndex)) {
  	bezierPoints.push(points[curIndex], {'x': (points[curIndex].x + points[curIndex + 1].x) / 2, 'y': (points[curIndex].y + points[curIndex + 1].y) / 2}, points[curIndex + 1],);
  }
  if (1 == (pointCount - curIndex)) {
  	bezierPoints.push(points[curIndex], points[curIndex], points[curIndex]);
  }
  
  return bezierPoints;
}

function convertToBezierPoint(sourcePoints, m) {
	if (typeof m == 'undefined') {
  	m = 2; //default as 2
  };
  
  var pointCount = sourcePoints.length;
  if (m > pointCount) {
  	m = Math.floor(pointCount / 2);
    if (m > 2) {
    	m = 2;
    }
  }
  
  var...