## Posted By

mattneary on 11/13/11

# Canvas Grapher

/ Published in: JavaScript

1. <!DOCTYPE HTML>
2. <html>
4. <title>Grapher</title>
6. <body>
7. <canvas id="cvs" width="500" height="500"></canvas>
8. <form onsubmit="loadF(); return false;"><input type="text" id="f"><input type="submit"></form>
10. <script type="text/javascript">
11.
13. plotF( function(x) {
14. var e = Math.exp(1),
15. sin = Math.sin,
16. cos = Math.cos,
17. tan = Math.tan,
18. parse = \$('#f').val().replace(/([0-9])([a-zA-Z])/g, "\$1*\$2") //Change coeff to multiplication
19. .replace(/([a-zA-Z0-9])\^(\S*?)x(\s|\$)/g, "Math.pow(\$1, \$2"+x+")\$3") //Exponential Function
20. .replace(/x\^(\S*?)(\s|\$)/g, "Math.pow("+x+", \$1)\$2") //Polynomial Function
21. .replace(/x/g, x); //Insert x
22. console.log(parse);
23. return eval(parse);
24. }, document.getElementById('cvs'), {
25. xMin: -8,
26. xMax: 8,
27. yMin: -8,
28. yMax: 8
29. });
30. }
31.
32. function plotF( f, elem, scaleWindow ) {
33. elem.width = elem.width;
34. var scaleWindow = scaleWindow || {
35. xMin: -25,
36. xMax: 25,
37. yMin: -25,
38. yMax: 25
39. };
40. scaleWindow.yMax = [-scaleWindow.yMin, (scaleWindow.yMin = -scaleWindow.yMax)][0]; //Swap Max/Min to make more intuitive
41. var pdy = elem.height/(scaleWindow.yMax-scaleWindow.yMin),
42. pdx = elem.width/(scaleWindow.xMax-scaleWindow.xMin);
43.
44. axies = {
45. y: (elem.width*(0-scaleWindow.xMin)/(scaleWindow.xMax-scaleWindow.xMin)),
46. x: (elem.height*(0-scaleWindow.yMin)/(scaleWindow.yMax-scaleWindow.yMin))
47. };
48. // Always check for properties and methods, to make sure your code doesn't break
49. // in other browsers.
50. if (elem && elem.getContext) {
51. // Get the 2d context.
52. // Remember: you can only initialize one context per element.
53. var context = elem.getContext('2d');
54. if (context) {
55.
56. context.beginPath();
57.
58. //Axis Style
59. context.strokeStyle = '#000';
60. context.lineWidth = 1;
61.
62. //y-axis
63. context.moveTo( axies.y, 0 );
64. context.lineTo( axies.y, elem.height );
65.
66. //x-axis
67. context.moveTo( 0, axies.x );
68. context.lineTo( elem.width, axies.x );
69.
70. console.log("Function exists");
71. context.stroke();
72. context.closePath();
73.
74. context.beginPath();
75.
76. //Plot style
77. context.strokeStyle = '#f00';
78. context.lineWidth = 3;
79.
80. console.log("Start: ", axies.y/elem.width * -50 );
81. for( var i = axies.y/elem.width * -50; i < (elem.width-axies.y)/elem.width * 50; i++ ) {
82. var fraction = function(n) { return (n - axies.y/elem.width * -50)/50; },
83. xMin = scaleWindow.xMin,
84. xRange = scaleWindow.xMax - scaleWindow.xMin,
85. yRange = scaleWindow.yMax - scaleWindow.yMin;
86.
87. context.moveTo(fraction(i)*elem.width, axies.x-f(xMin+fraction(i)*xRange)/yRange*elem.height); // give the (x,y) coordinates
88. context.lineTo(fraction(i+1)*elem.width, axies.x-f(xMin+fraction(i+1)*xRange)/yRange*elem.height);
89. }
90.
91. context.stroke();
92. context.closePath();
93. }
94. }
95. }
96. </script>
97. </body>
98. </html>
99.
100. <!--<html>
103. <script type="text/javascript">
104. function process(str) {
105. return eval(str);
106. }
107. function sanitize_reg(str) {
108. return str.replace(/[\\\.\+\*\?\^\\$\[\]\(\)\{\}\/\'\#\:\!\=\|]/ig, "\\\$&");
109. }
110. function evaluate_parenthetic(str) {
111. arr = str.match(/[(][^)a-zA-Z]+[)]/g);
112. for( key in arr ) {
113. val = arr[key];
114. reg = RegExp( sanitize_reg(val), 'g' );
115. str = str.replace(reg, process(val));
116. }
117.
118. return str;
119. }
120. function main() {
121. var inputValue = \$('#expression').val();
122. inputValue = inputValue.replace(/(x)\^([0-9]+)/g, "1/(\$2+1) * \$1^(\$2+1)") //Power rule
123. .replace(/([0-9]*?)(x[^^])|x\$/g, '\$1/2 * x^2 ') //Plain x
124. .replace(/(\s|^)([0-9]+)(\s|\$)/g, '\$2x ') //Plain constant
125. .replace(/\s\//g, ' 1/'); //Fix lack of coeff with x
126. console.log(inputValue);
127. inputValue = evaluate_parenthetic(inputValue);
128.
129. \$('#resp').text(inputValue);
130. }
131. </script>