Prompts user for a function to graph. Includes sin, cos, tan, sqrt, PI, and exp amongst other math functions.
var y,z;var ƒ=function(b,d,e){c.style.width="400px";c.style.height="300px";y=b;z="x";var f=function(a,b){var c=a.replace(/([0-9])(\([^)]+\)|[a-zA-Z])/g,"$1*$2").replace(/(\([^)]+\)|\w+)\^(\([^)]+\)|\S+)(\s|$)/g,"pow($1, $2)$3");var e=new Function(z,"with(y) return ["+(b||z)+", "+c+"]");e.p=e.prototype=window.ƒ.p;for(d in e.p)e[d]=e.p[d];return e};f.p=f.prototype={constructor:f,init:function(a,b){f("0").graph(0,1),f(z,"0").graph(0,1)},graph:function(b,d){var g=thiz=this;var h=1e3,b=[-8,8,-8,8];b[3]=[-b[2],b[2]=-b[3]][0];e={y:c.width*(0-b[0])/(b[1]-b[0]),x:c.height*(0-b[2])/(b[3]-b[2])};if(a){!d&&f.init(c);a.beginPath();for(var i=e.y/c.width*-h;i<(c.width-e.y)/c.width*h;i++){var j=function(a){return a/h- -e.y/c.width},k=b[0],l=b[2],m=b[1]-b[0],n=b[3]-b[2],o;a.moveTo(e.y+g(o=k+j(i)*m)[0]/m*c.width,e.x-g(o)[1]/n*c.height);a.lineTo(e.y+g(o=k+j(i+1)*m)[0]/m*c.width,e.x-g(o)[1]/n*c.height)}a.stroke();a.closePath()}}};for(d in f.p)f[d]=f.p[d];return f}(Math);ƒ(prompt("f(x)?")).graph()dmFyIHksejt2YXIgxpI9ZnVuY3Rpb24oYixkLGUpe2Muc3R5bGUud2lkdGg9IjQwMHB4IjtjLnN0eWxlLmhlaWdodD0iMzAwcHgiO3k9Yjt6PSJ4Ijt2YXIgZj1mdW5jdGlvbihhLGIpe3ZhciBjPWEucmVwbGFjZSgvKFswLTldKShcKFteKV0rXCl8W2EtekEtWl0pL2csIiQxKiQyIikucmVwbGFjZSgvKFwoW14pXStcKXxcdyspXF4oXChbXildK1wpfFxTKykoXHN8JCkvZywicG93KCQxLCAkMikkMyIpO3ZhciBlPW5ldyBGdW5jdGlvbih6LCJ3aXRoKHkpIHJldHVybiBbIisoYnx8eikrIiwgIitjKyJdIik7ZS5wPWUucHJvdG90eXBlPXdpbmRvdy7Gki5wO2ZvcihkIGluIGUucCllW2RdPWUucFtkXTtyZXR1cm4gZX07Zi5wPWYucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpmLGluaXQ6ZnVuY3Rpb24oYSxiKXtmKCIwIikuZ3JhcGgoMCwxKSxmKHosIjAiKS5ncmFwaCgwLDEpfSxncmFwaDpmdW5jdGlvbihiLGQpe3ZhciBnPXRoaXo9dGhpczt2YXIgaD0xZTMsYj1bLTgsOCwtOCw4XTtiWzNdPVstYlsyXSxiWzJdPS1iWzNdXVswXTtlPXt5OmMud2lkdGgqKDAtYlswXSkvKGJbMV0tYlswXSkseDpjLmhlaWdodCooMC1iWzJdKS8oYlszXS1iWzJdKX07aWYoYSl7IWQmJmYuaW5pdChjKTthLmJlZ2luUGF0aCgpO2Zvcih2YXIgaT1lLnkvYy53aWR0aCotaDtpPChjLndpZHRoLWUueSkvYy53aWR0aCpoO2krKyl7dmFyIGo9ZnVuY3Rpb24oYSl7cmV0dXJuIGEvaC0gLWUueS9jLndpZHRofSxrPWJbMF0sbD1iWzJdLG09YlsxXS1iWzBdLG49YlszXS1iWzJdLG87YS5tb3ZlVG8oZS55K2cobz1rK2ooaSkqbSlbMF0vbSpjLndpZHRoLGUueC1nKG8pWzFdL24qYy5oZWlnaHQpO2EubGluZVRvKGUueStnKG89aytqKGkrMSkqbSlbMF0vbSpjLndpZHRoLGUueC1nKG8pWzFdL24qYy5oZWlnaHQpfWEuc3Ryb2tlKCk7YS5jbG9zZVBhdGgoKX19fTtmb3IoZCBpbiBmLnApZltkXT1mLnBbZF07cmV0dXJuIGZ9KE1hdGgpO8aSKHByb21wdCgiZih4KT8iKSkuZ3JhcGgoKQ==//Globals
var _g, _x;
//Main function
var ƒ = (function(el,globals,_x,key,axies) {			
	_g = globals;_x="x";
	//Local version of ƒ
	var ƒ = function(str, xstr) {				
		var parse = str.replace(/([0-9])(\([^)]+\)|[a-zA-Z])/g, "$1*$2")										
		//Change coeff to multiplication
				   .replace(/(\([^)]+\)|\w+)\^(\([^)]+\)|\S+)(\s|$)/g, "pow($1, $2)$3");						
				   //Exponential Function			
			
		//Once ƒ is constructed with a string, ƒ becomes a function of a value -- with the same prototype
		var ƒ = new Function(_x, "with(_g) return ["+(xstr||_x)+", "+parse+"]");								
		//with and eval in one line!!
		ƒ.p = ƒ.prototype = window.ƒ.p;																			
		//it's like jQuery.fn
		//Apply prototype to constructor
		for( key in ƒ.p ) ƒ[key] = ƒ.p[key];										
		//Extend the object with the proto
		return ƒ;																	
		//Return a new ƒ - a function of x
	};
	ƒ.p = ƒ.prototype = {															
	//jQuery.fn again
		constructor: ƒ,																
		//Constructor makes this thing act like a function
		init: function(over, e) {													
		//Draw x-axis, y-axis
			ƒ('0').graph(0,1),ƒ(_x,'0').graph(0,1);	
		},
		graph: function( win, ax ) {												
		//Main event e.g., ƒ("2x").graph()
			var f = thiz = this;													
			//Cache function being called on 
			var prec = 1000,														
			//Steps in loop
			    win = [
					-8, //xMin
					8, 	//xMax
					-8, //yMin
					8 	//yMax
			    ];
			win[3] = [-win[2], (win[2] = -win[3])][0];								
			//Swap Max/Min to make more intuitive
			axies = {																
			//Pixels to axis
				y: (el.width*(0-win[0])/(win[1]-win[0])),														
				x: (el.height*(0-win[2])/(win[3]-win[2]))
			};
			if (context) {	
				!ax&&ƒ.init(el);													
				//Prevent infinite loop
				context.beginPath();	
				for( var i = axies.y/el.width * -prec; i < (el.width-axies.y)/el.width * prec; i++ ) {			
				//Loop through steps, with neg and pos matching axis
					var fraction = function(n) { return n/prec - -axies.y/el.width; },							
					//D.R.Y.
						xMin	 = win[0],																								
						yMin	 = win[2],
						xRange 	 = win[1] - win[0],
						yRange	 = win[3] - win[2], 															
						p; //Declare for use below
					
					//Make a miniature line segment
				    context.moveTo(
				    	axies.y + 																				
				    	f(
				    		p=xMin+fraction(i)*xRange								
				    		//Convert pixels > x, shift to start at min
				    	)[0]/xRange*el.width, 										
				    	//Convert x back to pixels for drawing
				    	axies.x - 
				    	f(p)[1]/yRange*el.height									
				    	//Take y-value from previous evaluation and scale
				    ); 
				    context.lineTo(
				    	axies.y + 
				    	f(
				    		p=xMin+fraction(i+1)*xRange								
				    		//Convert pixels > x, shift to start at min
				    	)[0]/xRange*el.width, 										
				    	//Convert x back to pixels for drawing
				    	axies.x - 
				    	f(p)[1]/yRange*el.height									
				    	//Take y-value from previous evaluation and scale
				    );	
				}		
				   		
				context.stroke();
				context.closePath();
			}
		}
	};
	for( key in ƒ.p ) ƒ[key] = ƒ.p[key];											
	//Extend object with prototype
	return ƒ;
})(cvs,Math);																		
//Pass canvas and Math Object for constants + functions
//Calling of ƒ
ƒ(prompt("f(x)?")).graph();															
//Graph user-inputted function