Enter a function and click "Graph Function" to see its plot.
Understanding Function Graphing
A function graph is a visual representation of a mathematical function. It plots the relationship between the input values (typically 'x') and their corresponding output values (typically 'y' or f(x)) on a Cartesian coordinate system. Each point on the graph represents an ordered pair (x, y) where y = f(x).
Graphing calculators and tools allow us to visualize complex functions, understand their behavior, identify key features such as intercepts, maximum and minimum points, asymptotes, and periodicity, and compare different functions.
How This Calculator Works
This calculator takes a function expression as input, along with a range for the independent variable 'x' (minimum and maximum values) and the number of points to calculate and plot.
Function Input: You can enter various mathematical functions using standard notation. Common operators include +, -, *, /, and the exponentiation operator ^ (or **). Built-in mathematical functions like sin(x), cos(x), tan(x), log(x), exp(x), sqrt(x), and abs(x) are supported. For log(x), this typically refers to the natural logarithm (ln(x)).
X Range: The Minimum X Value and Maximum X Value define the horizontal bounds of the graph. The calculator will plot points for 'x' values within this range.
Number of Points: A higher number of points generally results in a smoother, more accurate graph, especially for curves. The calculator divides the x-range into this many intervals to calculate y-values.
Mathematical Concepts Involved
Cartesian Coordinates: The graph is plotted on a 2D plane with a horizontal x-axis and a vertical y-axis.
Function Evaluation: For each 'x' value within the specified range, the calculator evaluates the provided function expression to determine the corresponding 'y' value.
Interpolation: The calculator generates a series of points (x, f(x)) and connects them to form the visual graph.
Common Functions:
Linear: f(x) = mx + b (e.g., 2*x + 1)
Quadratic: f(x) = ax^2 + bx + c (e.g., x^2 - 4)
Trigonometric: f(x) = sin(x), f(x) = cos(x)
Exponential: f(x) = exp(x) (e^x)
Logarithmic: f(x) = log(x) (ln(x))
Use Cases
Function graphing is fundamental in many fields:
Mathematics Education: Helping students understand abstract concepts visually.
Physics: Visualizing motion, forces, and wave phenomena.
Engineering: Analyzing signal processing, control systems, and structural behavior.
Economics: Modeling supply and demand curves, cost functions.
Computer Science: Understanding algorithm complexity and data distribution.
// JavaScript for the Function Graphing Calculator
function evaluateFunction(funcString, x) {
// Basic security measure: prevent arbitrary code execution
// Allowable characters: letters, numbers, common math symbols, 'x', '.', '(', ')', ',', whitespace
var sanitizedString = funcString.replace(/[^a-zA-Z0-9\.\+\-\*\/\^\(\)\s,]/g, ");
// Replace common math functions and operators
sanitizedString = sanitizedString.replace(/sin/g, 'Math.sin');
sanitizedString = sanitizedString.replace(/cos/g, 'Math.cos');
sanitizedString = sanitizedString.replace(/tan/g, 'Math.tan');
sanitizedString = sanitizedString.replace(/log/g, 'Math.log'); // Natural log
sanitizedString = sanitizedString.replace(/ln/g, 'Math.log'); // Alias for natural log
sanitizedString = sanitizedString.replace(/exp/g, 'Math.exp');
sanitizedString = sanitizedString.replace(/sqrt/g, 'Math.sqrt');
sanitizedString = sanitizedString.replace(/abs/g, 'Math.abs');
sanitizedString = sanitizedString.replace(/\^/g, '**'); // Use JS exponentiation operator
// Replace 'x' with the actual value
// Use a regex to ensure we only replace 'x' as a whole word or part of a function call,
// and avoid replacing it within variable names if we were to extend this.
// For simplicity here, direct replacement is often sufficient if inputs are controlled.
// A more robust solution would involve parsing.
var expression = sanitizedString.replace(/x/g, '(' + x + ')');
try {
// Use eval carefully, after sanitization and replacing math functions.
// This is still a security risk if sanitization is not perfect.
return Function('"use strict";return (' + expression + ')')();
} catch (e) {
console.error("Error evaluating function: " + e.message);
return NaN; // Return NaN on error
}
}
function plotFunction() {
var functionInput = document.getElementById("functionInput").value;
var minX = parseFloat(document.getElementById("minX").value);
var maxX = parseFloat(document.getElementById("maxX").value);
var numPoints = parseInt(document.getElementById("numPoints").value);
var canvas = document.getElementById("graphCanvas");
var ctx = canvas.getContext("2d");
var graphContainer = document.getElementById("graphContainer");
var plottingInfo = document.getElementById("plottingInfo");
// Clear previous graph
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Input validation
if (functionInput.trim() === "") {
plottingInfo.textContent = "Error: Please enter a function.";
return;
}
if (isNaN(minX) || isNaN(maxX) || minX >= maxX) {
plottingInfo.textContent = "Error: Invalid X range. Ensure Min X < Max X.";
return;
}
if (isNaN(numPoints) || numPoints <= 1) {
plottingInfo.textContent = "Error: Number of points must be greater than 1.";
return;
}
// Set canvas dimensions based on container
canvas.width = graphContainer.clientWidth;
canvas.height = graphContainer.clientHeight;
var dataPoints = [];
var step = (maxX – minX) / (numPoints – 1);
var maxY = -Infinity;
var minY = Infinity;
for (var i = 0; i maxY) maxY = y;
if (y < minY) minY = y;
} else {
// Handle cases where function is undefined (e.g., division by zero, sqrt of negative)
// We can choose to skip these points or mark them
console.warn("Function returned NaN at x =", x);
}
}
if (dataPoints.length === 0) {
plottingInfo.textContent = "Error: Could not plot function. Check function syntax or domain.";
return;
}
// Determine graph scaling and translation
var graphWidth = canvas.width;
var graphHeight = canvas.height;
var padding = 40; // Padding around the graph for axes
var effectiveWidth = graphWidth – 2 * padding;
var effectiveHeight = graphHeight – 2 * padding;
var xRange = maxX – minX;
var yRange = maxY – minY;
// Handle cases where yRange is zero (horizontal line)
if (yRange === 0) {
yRange = 1; // Arbitrary range to avoid division by zero
maxY += 0.5;
minY -= 0.5;
}
var xScale = effectiveWidth / xRange;
var yScale = effectiveHeight / yRange;
// Center the graph if the range is small
var xOffset = padding;
if (xRange = padding && xAxisY = padding && yAxisX <= graphWidth – padding) {
ctx.beginPath();
ctx.moveTo(yAxisX, padding);
ctx.lineTo(yAxisX, graphHeight – padding);
ctx.stroke();
// Y-axis arrow
ctx.lineTo(yAxisX – 5, padding + 10);
ctx.moveTo(yAxisX, padding);
ctx.lineTo(yAxisX + 5, padding + 10);
ctx.stroke();
ctx.fillText('Y', yAxisX + 15, padding + 10);
}
// Draw plot points and lines
ctx.strokeStyle = '#28a745'; // Success Green for the plot line
ctx.lineWidth = 2;
ctx.beginPath();
for (var i = 0; i < dataPoints.length; i++) {
var point = dataPoints[i];
var canvasX = xOffset + (point.x – minX) * xScale;
var canvasY = yOffset – (point.y – minY) * yScale; // Invert Y for canvas
if (i === 0) {
ctx.moveTo(canvasX, canvasY);
} else {
// Check if the previous point was valid to avoid connecting across NaNs
var prevPoint = dataPoints[i-1];
if (prevPoint && !isNaN(prevPoint.y)) {
ctx.lineTo(canvasX, canvasY);
} else {
ctx.moveTo(canvasX, canvasY); // Start a new line segment if there was a gap
}
}
}
ctx.stroke();
// Update plotting info
plottingInfo.textContent = "Graph plotted for function: '" + functionInput + "' from x=" + minX + " to x=" + maxX + ".";
}
function clearGraph() {
var canvas = document.getElementById("graphCanvas");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
document.getElementById("plottingInfo").textContent = "Graph cleared. Enter a function and click 'Graph Function'.";
// Optionally reset inputs
// document.getElementById("functionInput").value = "";
// document.getElementById("minX").value = "-10";
// document.getElementById("maxX").value = "10";
// document.getElementById("numPoints").value = "200";
}
// Initial setup: adjust canvas size on load
window.addEventListener('load', function() {
var canvas = document.getElementById("graphCanvas");
var graphContainer = document.getElementById("graphContainer");
canvas.width = graphContainer.clientWidth;
canvas.height = graphContainer.clientHeight;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#ccc";
ctx.fillRect(0, 0, canvas.width, canvas.height);
document.getElementById("plottingInfo").textContent = "Enter a function and click 'Graph Function' to see its plot.";
});
// Adjust canvas size on window resize
window.addEventListener('resize', function() {
var canvas = document.getElementById("graphCanvas");
var graphContainer = document.getElementById("graphContainer");
canvas.width = graphContainer.clientWidth;
canvas.height = graphContainer.clientHeight;
// Optionally redraw the last plotted graph if data is stored
// For simplicity, we'll just clear it or show a message
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#ccc";
ctx.fillRect(0, 0, canvas.width, canvas.height);
document.getElementById("plottingInfo").textContent = "Window resized. Please re-plot your function.";
});