Enter a mathematical function (e.g., y = 2x + 1, y = x^2 – 3x + 2, y = sin(x)) to see its graph.
Enter a function and click "Graph Function".
Understanding the Online Graphing Calculator
A graphing calculator is a powerful mathematical tool that plots graphs of functions. Unlike standard calculators that focus on numerical computation, graphing calculators visualize mathematical relationships, making complex concepts more intuitive and easier to understand. Our free online graphing calculator allows you to input mathematical expressions and instantly see their graphical representation on a Cartesian coordinate system.
How it Works: The Math Behind the Graph
At its core, a graphing calculator works by evaluating a given function for a range of input values (typically for the variable 'x') and then plotting the resulting output values (typically for 'y' or 'f(x)') as points on a coordinate plane. The calculator connects these points to form the curve or line representing the function.
Key Components:
Function Input: You provide a mathematical expression, often in the form of y = f(x). This expression defines the relationship between the x and y variables. Our calculator supports common mathematical operations like addition, subtraction, multiplication, division, exponentiation (e.g., x^2), and standard mathematical functions (e.g., sin(x), cos(x), log(x), sqrt(x), abs(x)).
Domain (X-axis Range): This is the set of all possible x-values for which the function is defined and that you want to plot. Our calculator allows you to set the minimum (xMin) and maximum (xMax) values for the x-axis.
Range (Y-axis Range): This is the set of all possible y-values (or f(x) values) that the function produces over its domain. You can specify the minimum (yMin) and maximum (yMax) values for the y-axis to control the viewing window of the graph.
Calculation Steps (X-Steps): To draw a smooth curve, the calculator needs to calculate many points. The xSteps parameter determines how many x-values are evaluated within the specified xMin and xMax range. A higher number of steps generally results in a smoother, more accurate graph but may take slightly longer to compute.
The Calculation Process:
For each step between xMin and xMax (determined by xSteps), the calculator does the following:
Takes an x-value.
Substitutes this x-value into the entered function.
Calculates the corresponding y-value.
Stores the coordinate pair (x, y).
Once all points are calculated, the calculator scales these points to fit within the specified xMin, xMax, yMin, and yMax viewport and draws lines connecting adjacent points on the canvas element.
Common Use Cases:
Algebra: Visualizing linear equations (lines), quadratic equations (parabolas), polynomial functions, and rational functions to understand their behavior, roots (x-intercepts), and y-intercepts.
Trigonometry: Graphing trigonometric functions like sine, cosine, and tangent to understand their periodic nature, amplitude, and phase shifts.
Calculus: Visualizing derivatives and integrals, finding maxima and minima, and understanding limits.
Pre-Calculus: Exploring exponential and logarithmic functions, transformations of functions, and inverse functions.
Education: A vital tool for students learning mathematics, helping them connect abstract equations to concrete visual representations.
Problem Solving: Quickly testing hypotheses about mathematical relationships and finding approximate solutions to equations by observing where the graph intersects the x-axis or other lines.
Our free online graphing calculator aims to provide an accessible and intuitive platform for exploring the visual aspects of mathematics.
function drawGraph() {
var functionInput = document.getElementById("functionInput").value.toLowerCase();
var xMin = parseFloat(document.getElementById("xMin").value);
var xMax = parseFloat(document.getElementById("xMax").value);
var yMin = parseFloat(document.getElementById("yMin").value);
var yMax = parseFloat(document.getElementById("yMax").value);
var xSteps = parseInt(document.getElementById("xSteps").value);
var resultDiv = document.getElementById("result");
var canvas = document.getElementById("graphCanvas");
var ctx = canvas.getContext("2d");
// Clear previous graph and result
ctx.clearRect(0, 0, canvas.width, canvas.height);
resultDiv.innerHTML = ""; // Clear any previous message
// — Input Validation —
if (isNaN(xMin) || isNaN(xMax) || isNaN(yMin) || isNaN(yMax) || isNaN(xSteps)) {
resultDiv.innerHTML = "Error: Please enter valid numbers for all axis limits and steps.";
return;
}
if (xMin >= xMax || yMin >= yMax) {
resultDiv.innerHTML = "Error: Minimum values must be less than maximum values for axes.";
return;
}
if (xSteps 1000) {
resultDiv.innerHTML = "Error: X-Axis Steps must be between 10 and 1000.";
return;
}
if (functionInput.trim() === "" || !(functionInput.includes('y=') || functionInput.includes('f(x)='))) {
resultDiv.innerHTML = "Error: Please enter a valid function (e.g., 'y = 2*x + 1' or 'f(x) = x^2').";
return;
}
// Remove 'y=' or 'f(x)=' prefix and replace 'x' with the variable 'x'
var expression = functionInput.replace(/^(y=|f\(x\)=)\s*/, ").trim();
// — Canvas Setup —
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var padding = 40; // Padding around the graph area
ctx.lineWidth = 2;
ctx.font = "12px Arial";
ctx.textAlign = "center";
// — Coordinate System Transformation —
// Map function coordinates to canvas coordinates
var scaleX = (canvasWidth – 2 * padding) / (xMax – xMin);
var scaleY = (canvasHeight – 2 * padding) / (yMax – yMin);
var canvasX = function(x) {
return padding + (x – xMin) * scaleX;
};
var canvasY = function(y) {
// Invert Y axis because canvas Y=0 is at the top
return canvasHeight – padding – (y – yMin) * scaleY;
};
// — Draw Axes —
ctx.strokeStyle = "#666"; // Color for axes
ctx.beginPath();
// Y-axis
var originXCanvas = canvasX(0);
if (originXCanvas >= padding && originXCanvas = padding && originYCanvas <= canvasHeight – padding) {
ctx.moveTo(padding, originYCanvas);
ctx.lineTo(canvasWidth – padding, originYCanvas);
} else {
ctx.moveTo(padding, canvasHeight – padding);
ctx.lineTo(canvasWidth – padding, canvasHeight – padding);
}
ctx.stroke();
// Draw Axis Labels and Ticks (simplified)
ctx.fillStyle = "#333";
// X-axis label
ctx.fillText("X", canvasWidth – padding / 2, originYCanvas + 15);
// Y-axis label
ctx.fillText("Y", originXCanvas – 15, padding / 2 + 5);
// Draw Ticks on X-axis (simplified)
var tickIntervalX = (xMax – xMin) / 10; // Approximately 10 ticks
for (var i = 1; i padding && cx < canvasWidth – padding) {
ctx.fillText(tickX.toFixed(1), cx, originYCanvas + 15);
ctx.beginPath();
ctx.moveTo(cx, originYCanvas – 5);
ctx.lineTo(cx, originYCanvas + 5);
ctx.stroke();
}
}
// Draw Ticks on Y-axis (simplified)
var tickIntervalY = (yMax – yMin) / 10; // Approximately 10 ticks
for (var i = 1; i padding && cy < canvasHeight – padding) {
ctx.fillText(tickY.toFixed(1), originXCanvas – 15, cy + 4);
ctx.beginPath();
ctx.moveTo(originXCanvas – 5, cy);
ctx.lineTo(originXCanvas + 5, cy);
ctx.stroke();
}
}
// — Function Evaluation and Plotting —
var points = [];
var step = (xMax – xMin) / xSteps;
var mathEvalError = false;
// Use a safe evaluation function to prevent abuse
function safeEval(expr, xVal) {
try {
// Replace common math functions and constants
expr = expr.replace(/sin/g, 'Math.sin');
expr = expr.replace(/cos/g, 'Math.cos');
expr = expr.replace(/tan/g, 'Math.tan');
expr = expr.replace(/sqrt/g, 'Math.sqrt');
expr = expr.replace(/log/g, 'Math.log'); // Natural log
expr = expr.replace(/log10/g, 'Math.log10');
expr = expr.replace(/abs/g, 'Math.abs');
expr = expr.replace(/pi/g, 'Math.PI');
expr = expr.replace(/\^/g, '**'); // Exponentiation
// Basic security check: disallow dangerous characters
if (/[^a-z0-9\.\+\-\*\/\(\)\s\_\%]/.test(expr)) {
throw new Error("Invalid characters in expression.");
}
// Ensure only 'x' is the variable
if (expr.includes('y') || expr.includes('f') || expr.includes('t') || expr.includes('z')) {
throw new Error("Only 'x' is allowed as a variable.");
}
// Evaluate using the Function constructor (safer than eval directly)
var func = new Function('x', 'return ' + expr);
var result = func(xVal);
// Check for results outside reasonable bounds or invalid types
if (typeof result !== 'number' || !isFinite(result)) {
return NaN; // Treat as undefined
}
return result;
} catch (e) {
console.error("Evaluation error:", e.message);
mathEvalError = true;
return NaN; // Return NaN on any error
}
}
var lastY = NaN; // Keep track of the previous y value to avoid jumps
for (var x = xMin; x Math.max(Math.abs(yMin), Math.abs(yMax)) * 2 && !isNaN(lastY)) {
// If the new y is extremely far from the last one, treat it as a break in the line
lastY = NaN;
continue;
}
points.push({ x: x, y: y });
lastY = y;
} else {
// If y is NaN, it means there's a break in the function (e.g., division by zero)
// Reset lastY to NaN to ensure the next valid point starts a new line segment
lastY = NaN;
}
}
if (mathEvalError) {
resultDiv.innerHTML = "Error evaluating function. Check syntax or function domain.";
return;
}
// — Draw the Function Curve —
ctx.strokeStyle = "#28a745"; // Success Green for the function graph
ctx.beginPath();
var firstPoint = true;
for (var i = 0; i = padding && cx = padding && cy 0) {
resultDiv.innerHTML = "Graph plotted successfully!";
}
}
// Initial drawing on load
document.addEventListener('DOMContentLoaded', function() {
var canvas = document.getElementById("graphCanvas");
canvas.width = canvas.parentElement.clientWidth; // Make canvas fill container width
canvas.height = canvas.parentElement.clientHeight; // Make canvas fill container height
drawGraph(); // Draw a default or empty graph
});
// Adjust canvas size on window resize
window.addEventListener('resize', function() {
var canvas = document.getElementById("graphCanvas");
var container = canvas.parentElement;
canvas.width = container.clientWidth;
canvas.height = container.clientHeight;
drawGraph(); // Redraw the graph with new dimensions
});