Fundographics

;Status
:Stable
;Change(s)
:Providing scaling
;To do
:none
== Code ==
function Graph(a, b, c) {
	// values
	this.v = {
		a: a,
		b: b,
		c: c
	};
	// function graph - f(x)
	this.f = function(x) {
		return a * Math.pow(x, 2) + b * x + c;
	}
	// prime function - f'(x)
	this.fP = function(x) {
		return 2 * a * x + b;
	}
	// calculate control points
	this.calcCtrl = function(x1, x2) {
		var y1 = this.f(x1),
			y2 = this.f(x2),
			m1 = this.fP(x1),
			m2 = this.fP(x2),
			ctrl = {};
		ctrl.x = (x1 * m1 - x2 * m2 - y1 + y2) / (m1 - m2); // essentially compare g(x) and h(x), only constructed in a way that a result will be returned
		ctrl.y = m1 * (ctrl.x - x1) + y1; // pass value to g(x)
		console.log("Control points: ", ctrl);
		return [ctrl.x, ctrl.y];
	}
	// to path
	this.toPath = function(x1, x2, originX, originY, scaleX, scaleY) { // origin[XY] are the point in an svg object which will be used as the path's origin
		var path = document.createElementNS("http://www.w3.org/2000/svg", "path"),
			y1 = this.f(x1),
			y2 = this.f(x2),
			scaleX = arguments[4] || 1,
			scaleY = arguments[5] || 1,
			m, // moveto command
			q; // quadric bezier command
		m = [originX + scaleX * x1, originY - scaleY * y1];
		q = this.calcCtrl(x1, x2);
		q.push(scaleX * (x2 - x1), scaleY * (y1 - y2));
		q[0] = scaleX * (q[0] - x1); // xval control point
		q[1] = (y1 - q[1]) * scaleY; // yval control point
		path.setAttributeNS(
			null,
			"d",
			"M " + m.join(" ") + " q " + q.join(" ")
		);
		return path;
	}
}
== Example ==
var graph = new Graph(1, 3, 2), // f(x) = x ^ 2 + 3x + 2
	svg = document.querySelector("svg"), // the svg element
	path = graph.toPath(0, 12, 0, 200, 20); // svg path node - start path at (0, 200) in the svg axis-system, and scale the x values by 20
path.setAttributeNS(null, "fill", "none"); // remove fill
path.setAttributeNS(null, "stroke", "purple"); // add stroke
svg.appendChild(path); // insert path