diff --git a/src/AdvancedCalculator.js b/src/AdvancedCalculator.js
index a13914f..8e8c4ec 100644
--- a/src/AdvancedCalculator.js
+++ b/src/AdvancedCalculator.js
@@ -1,22 +1,37 @@
-import React, { useState, useEffect } from 'react';
-import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, ScatterChart, Scatter } from 'recharts';
-import * as math from 'mathjs';
-import _ from 'lodash';
-import './AdvancedCalculatorStyles.css';
+import React, { useState, useEffect } from "react";
+import {
+ LineChart,
+ Line,
+ XAxis,
+ YAxis,
+ CartesianGrid,
+ Tooltip,
+ Legend,
+ ResponsiveContainer,
+ ScatterChart,
+ Scatter,
+} from "recharts";
+import * as math from "mathjs";
+import _ from "lodash";
+import "./AdvancedCalculatorStyles.css";
// Main Calculator Component
const AdvancedCalculator = () => {
// State management
- const [activeTab, setActiveTab] = useState('basic');
+ const [activeTab, setActiveTab] = useState("basic");
const [darkMode, setDarkMode] = useState(false);
- const [display, setDisplay] = useState('0');
+ const [display, setDisplay] = useState("0");
const [memory, setMemory] = useState(0);
const [history, setHistory] = useState([]);
- const [graphFunction, setGraphFunction] = useState('x^2');
+ const [graphFunction, setGraphFunction] = useState("x^2");
const [graphRange, setGraphRange] = useState([-10, 10]);
const [graphData, setGraphData] = useState([]);
- const [secondGraph, setSecondGraph] = useState({ enabled: false, function: 'x', color: '#82ca9d' });
- const [physicsType, setPhysicsType] = useState('projectile');
+ const [secondGraph, setSecondGraph] = useState({
+ enabled: false,
+ function: "x",
+ color: "#82ca9d",
+ });
+ const [physicsType, setPhysicsType] = useState("projectile");
const [physicsParams, setPhysicsParams] = useState({
velocity: 20,
angle: 45,
@@ -30,76 +45,68 @@ const AdvancedCalculator = () => {
magneticField: 1.0,
resistance: 10,
voltage: 12,
- current: 1.2
+ current: 1.2,
});
const [simulationData, setSimulationData] = useState([]);
const [simulationRunning, setSimulationRunning] = useState(false);
const [simulationInterval, setSimulationInterval] = useState(null);
const [unitConversion, setUnitConversion] = useState({
fromValue: 1,
- fromUnit: 'm',
- toUnit: 'ft',
- category: 'length'
+ fromUnit: "m",
+ toUnit: "ft",
+ category: "length",
});
const [matrixA, setMatrixA] = useState([
[1, 2],
- [3, 4]
+ [3, 4],
]);
const [matrixB, setMatrixB] = useState([
[5, 6],
- [7, 8]
+ [7, 8],
]);
const [matrixResult, setMatrixResult] = useState(null);
- const [matrixOperation, setMatrixOperation] = useState('add');
- const [statisticsData, setStatisticsData] = useState('1, 2, 3, 4, 5');
+ const [matrixOperation, setMatrixOperation] = useState("add");
+ const [statisticsData, setStatisticsData] = useState("1, 2, 3, 4, 5");
const [statisticsResults, setStatisticsResults] = useState({});
- const [saveName, setSaveName] = useState('');
+ const [saveName, setSaveName] = useState("");
const [savedStates, setSavedStates] = useState({});
const [showSettings, setShowSettings] = useState(false);
const [settings, setSettings] = useState({
precision: 4,
- angleUnit: 'deg',
- notationFormat: 'auto',
- graphTheme: 'default'
+ angleUnit: "deg",
+ notationFormat: "auto",
+ graphTheme: "default",
});
-
- // Adding state for spreadsheet
- const [spreadsheetTemplate, setSpreadsheetTemplate] = useState('budget');
- const [spreadsheetData, setSpreadsheetData] = useState([]);
- const [spreadsheetHeaders, setSpreadsheetHeaders] = useState([]);
- const [activeCell, setActiveCell] = useState({ row: 0, col: 0 });
- const [cellValues, setCellValues] = useState({});
- const [cellFormulas, setCellFormulas] = useState({});
- // Get graph colors based on theme
+ // Get graph colors based on theme
const getGraphColors = () => {
const themes = {
default: {
line1: "#8884d8",
line2: "#82ca9d",
grid: "#ccc",
- background: darkMode ? "#1f2937" : "#fff"
+ background: darkMode ? "#1f2937" : "#fff",
},
dark: {
line1: "#ff7300",
line2: "#00bcd4",
grid: "#555",
- background: "#111"
+ background: "#111",
},
pastel: {
line1: "#ffb6c1",
line2: "#add8e6",
grid: "#d3d3d3",
- background: darkMode ? "#1f2937" : "#f0f8ff"
+ background: darkMode ? "#1f2937" : "#f0f8ff",
},
neon: {
line1: "#39ff14",
line2: "#ff00ff",
grid: "#0066ff",
- background: "#000"
- }
+ background: "#000",
+ },
};
-
+
return themes[settings.graphTheme];
};
@@ -109,7 +116,7 @@ const AdvancedCalculator = () => {
const data = [];
const step = (graphRange[1] - graphRange[0]) / 200;
const expr = math.compile(graphFunction);
-
+
for (let x = graphRange[0]; x <= graphRange[1]; x += step) {
try {
const y = expr.evaluate({ x });
@@ -125,12 +132,12 @@ const AdvancedCalculator = () => {
console.error("Error generating graph data:", error);
}
}, [graphFunction, graphRange]);
-
+
// Generate second graph data
useEffect(() => {
if (secondGraph.enabled) {
try {
- const data = graphData.map(point => {
+ const data = graphData.map((point) => {
try {
const expr = math.compile(secondGraph.function);
const y2 = expr.evaluate({ x: point.x });
@@ -145,14 +152,17 @@ const AdvancedCalculator = () => {
}
}
}, [secondGraph.function, secondGraph.enabled, graphRange, graphData]);
-
+
// Statistical calculations
useEffect(() => {
try {
- const data = statisticsData.split(',').map(n => parseFloat(n.trim())).filter(n => !isNaN(n));
-
+ const data = statisticsData
+ .split(",")
+ .map((n) => parseFloat(n.trim()))
+ .filter((n) => !isNaN(n));
+
if (data.length === 0) return;
-
+
const mean = math.mean(data);
const median = math.median(data);
const mode = calculateMode(data);
@@ -163,26 +173,34 @@ const AdvancedCalculator = () => {
const range = max - min;
const sum = math.sum(data);
const count = data.length;
-
+
setStatisticsResults({
- mean, median, mode, standardDeviation, variance,
- min, max, range, sum, count
+ mean,
+ median,
+ mode,
+ standardDeviation,
+ variance,
+ min,
+ max,
+ range,
+ sum,
+ count,
});
} catch (error) {
console.error("Error calculating statistics:", error);
}
}, [statisticsData]);
-
+
// Calculate mode
const calculateMode = (arr) => {
const frequency = {};
- arr.forEach(val => {
+ arr.forEach((val) => {
frequency[val] = (frequency[val] || 0) + 1;
});
-
+
let maxFreq = 0;
let modes = [];
-
+
for (const key in frequency) {
if (frequency[key] > maxFreq) {
maxFreq = frequency[key];
@@ -191,103 +209,107 @@ const AdvancedCalculator = () => {
modes.push(parseFloat(key));
}
}
-
- return modes.join(', ');
+
+ return modes.join(", ");
};
-
+
// Handle basic calculator button clicks
const handleButtonClick = (value) => {
- if (display === '0' || display === 'Error') {
+ if (display === "0" || display === "Error") {
setDisplay(value);
} else {
setDisplay(display + value);
}
};
-
+
// Handle calculation
const calculateResult = () => {
try {
// Replace π with pi and adjust for angle units
- let formula = display.replace(/π/g, 'pi');
-
- if (settings.angleUnit === 'deg') {
+ let formula = display.replace(/π/g, "pi");
+
+ if (settings.angleUnit === "deg") {
// Convert degrees to radians for trig functions
- formula = formula.replace(/sin\(([^)]+)\)/g, 'sin($1 * pi/180)');
- formula = formula.replace(/cos\(([^)]+)\)/g, 'cos($1 * pi/180)');
- formula = formula.replace(/tan\(([^)]+)\)/g, 'tan($1 * pi/180)');
+ formula = formula.replace(/sin\(([^)]+)\)/g, "sin($1 * pi/180)");
+ formula = formula.replace(/cos\(([^)]+)\)/g, "cos($1 * pi/180)");
+ formula = formula.replace(/tan\(([^)]+)\)/g, "tan($1 * pi/180)");
}
-
+
const result = math.evaluate(formula);
let formattedResult;
-
+
// Format result according to settings
- if (settings.notationFormat === 'scientific') {
+ if (settings.notationFormat === "scientific") {
formattedResult = result.toExponential(settings.precision);
- } else if (settings.notationFormat === 'fixed') {
+ } else if (settings.notationFormat === "fixed") {
formattedResult = result.toFixed(settings.precision);
} else {
- formattedResult = typeof result === 'number'
- ? math.format(result, { precision: settings.precision })
- : result.toString();
+ formattedResult =
+ typeof result === "number"
+ ? math.format(result, { precision: settings.precision })
+ : result.toString();
}
-
- setHistory([...history, { expression: display, result: formattedResult }]);
+
+ setHistory([
+ ...history,
+ { expression: display, result: formattedResult },
+ ]);
setDisplay(formattedResult.toString());
} catch (error) {
- setDisplay('Error');
+ setDisplay("Error");
}
};
-
+
// Clear display
const clearDisplay = () => {
- setDisplay('0');
+ setDisplay("0");
};
-
+
// Memory functions
const memoryAdd = () => {
try {
const value = math.evaluate(display);
setMemory(memory + value);
} catch (error) {
- setDisplay('Error');
+ setDisplay("Error");
}
};
-
+
const memorySubtract = () => {
try {
const value = math.evaluate(display);
setMemory(memory - value);
} catch (error) {
- setDisplay('Error');
+ setDisplay("Error");
}
};
-
+
const memoryRecall = () => {
setDisplay(memory.toString());
};
-
+
const memoryClear = () => {
setMemory(0);
};
-
+
// Handle physics simulations
const startSimulation = () => {
if (simulationRunning) return;
-
+
setSimulationData([]);
- setPhysicsParams({...physicsParams, time: 0});
+ setPhysicsParams({ ...physicsParams, time: 0 });
setSimulationRunning(true);
-
+
const interval = setInterval(() => {
- setPhysicsParams(prevParams => ({
+ setPhysicsParams((prevParams) => ({
...prevParams,
- time: prevParams.time + 0.1
+ time: prevParams.time + 0.1,
}));
}, 100);
-
+
setSimulationInterval(interval);
};
-
+
// eslint-disable-next-line react-hooks/exhaustive-deps
const stopSimulation = () => {
if (simulationInterval) {
@@ -295,216 +317,253 @@ const AdvancedCalculator = () => {
}
setSimulationRunning(false);
};
-
+
// Unit conversion
const convertUnit = () => {
try {
- const result = math.evaluate(`${unitConversion.fromValue} ${unitConversion.fromUnit} to ${unitConversion.toUnit}`);
+ const result = math.evaluate(
+ `${unitConversion.fromValue} ${unitConversion.fromUnit} to ${unitConversion.toUnit}`
+ );
// Return just the numeric value, without units
- return result.toString().replace(unitConversion.toUnit, '').trim();
+ return result.toString().replace(unitConversion.toUnit, "").trim();
} catch (error) {
- return 'Error: Invalid conversion';
+ return "Error: Invalid conversion";
}
};
-
+
// Matrix operations
const performMatrixOperation = () => {
try {
const A = math.matrix(matrixA);
const B = math.matrix(matrixB);
let result;
-
+
switch (matrixOperation) {
- case 'add':
+ case "add":
result = math.add(A, B);
break;
- case 'subtract':
+ case "subtract":
result = math.subtract(A, B);
break;
- case 'multiply':
+ case "multiply":
result = math.multiply(A, B);
break;
- case 'determinantA':
+ case "determinantA":
result = math.det(A);
break;
- case 'determinantB':
+ case "determinantB":
result = math.det(B);
break;
- case 'inverseA':
+ case "inverseA":
result = math.inv(A);
break;
- case 'inverseB':
+ case "inverseB":
result = math.inv(B);
break;
- case 'transposeA':
+ case "transposeA":
result = math.transpose(A);
break;
- case 'transposeB':
+ case "transposeB":
result = math.transpose(B);
break;
default:
result = null;
}
-
- if (['determinantA', 'determinantB'].includes(matrixOperation)) {
+
+ if (["determinantA", "determinantB"].includes(matrixOperation)) {
setMatrixResult(result);
} else {
setMatrixResult(result.toArray());
}
} catch (error) {
- setMatrixResult('Error: ' + error.message);
+ setMatrixResult("Error: " + error.message);
}
};
-
+
// Calculate physics simulation data
useEffect(() => {
if (!simulationRunning) return;
-
+
let newData = [];
-
- if (physicsType === 'projectile') {
+
+ if (physicsType === "projectile") {
const { velocity, angle, height, gravity, time } = physicsParams;
- const radians = angle * Math.PI / 180;
+ const radians = (angle * Math.PI) / 180;
const vx = velocity * Math.cos(radians);
const vy = velocity * Math.sin(radians);
-
+
// Calculate the theoretical range
- const theoreticalRange = calculatePhysics('range');
-
+ const theoreticalRange = calculatePhysics("range");
+
// Calculate current position
const x = vx * time;
const y = height + vy * time - 0.5 * gravity * time * time;
-
+
// If we've reached or passed the ground, add final points and stop
if (y < 0) {
// Calculate the exact time when y=0 (impact time)
// Using the quadratic formula for: height + vy*t - 0.5*g*t² = 0
const a = -0.5 * gravity;
- const b = vy;
+ const b = vy;
const c = height;
-
- const discriminant = b*b - 4*a*c;
+
+ const discriminant = b * b - 4 * a * c;
let impactTime;
-
+
if (discriminant >= 0) {
// Get both solutions
- const t1 = (-b + Math.sqrt(discriminant)) / (2*a);
- const t2 = (-b - Math.sqrt(discriminant)) / (2*a);
-
+ const t1 = (-b + Math.sqrt(discriminant)) / (2 * a);
+ const t2 = (-b - Math.sqrt(discriminant)) / (2 * a);
+
// Choose the positive solution that makes sense in context
if (t1 > 0 && t2 > 0) {
impactTime = Math.min(t1, t2);
} else {
impactTime = Math.max(t1, t2);
}
-
+
// Make sure we have the right data array to work with
newData = simulationData.slice(0, -1); // Remove the last point (which is below ground)
-
+
// Add a point just before landing for a smooth curve
if (impactTime > 0.1) {
const preImpactTime = impactTime - 0.05;
const preImpactX = vx * preImpactTime;
- const preImpactY = height + vy * preImpactTime - 0.5 * gravity * preImpactTime * preImpactTime;
-
+ const preImpactY =
+ height +
+ vy * preImpactTime -
+ 0.5 * gravity * preImpactTime * preImpactTime;
+
if (preImpactY > 0) {
newData.push({ x: preImpactX, y: preImpactY });
}
}
-
- // Add the exact landing point (y = 0)
+
+ // Calculate the exact landing point (y = 0)
const impactX = vx * impactTime;
newData.push({ x: impactX, y: 0 });
+
+ // Add additional points to show the full theoretical range
+ // Only do this if we haven't reached the theoretical range yet
+ if (impactX < theoreticalRange) {
+ // Add points at regular intervals to extend to the theoretical range
+ const intervalCount = 5; // Number of additional points to add
+ const xInterval = (theoreticalRange - impactX) / intervalCount;
+
+ for (let i = 1; i <= intervalCount; i++) {
+ const extendedX = impactX + xInterval * i;
+ newData.push({ x: extendedX, y: 0 });
+ }
+ }
} else {
newData = [...simulationData];
}
-
+
+ // Set the final data and stop the simulation
+ setSimulationData(newData);
stopSimulation();
return;
}
-
+
newData = [...simulationData, { x, y }];
- }
-
- else if (physicsType === 'pendulum') {
+ } else if (physicsType === "pendulum") {
const { pendulumLength, gravity, time } = physicsParams;
const omega = Math.sqrt(gravity / pendulumLength);
- const angle = 30 * Math.PI / 180; // Starting angle (30 degrees)
-
+ const angle = (30 * Math.PI) / 180; // Starting angle (30 degrees)
+
const x = pendulumLength * Math.sin(angle * Math.cos(omega * time));
const y = -pendulumLength * Math.cos(angle * Math.cos(omega * time));
-
+
newData = [...simulationData, { x, y }];
- }
- else if (physicsType === 'spring') {
+ } else if (physicsType === "spring") {
const { mass, springConstant, time } = physicsParams;
const omega = Math.sqrt(springConstant / mass);
const amplitude = 5;
-
+
const x = amplitude * Math.cos(omega * time);
const y = 0;
-
+
newData = [...simulationData, { x, y }];
- }
- else if (physicsType === 'circuit') {
+ } else if (physicsType === "circuit") {
const { voltage, resistance, time } = physicsParams;
const current = voltage / resistance;
-
+
newData = [...simulationData, { x: time, y: current }];
- }
- else if (physicsType === 'wave') {
+ } else if (physicsType === "wave") {
const { time } = physicsParams;
const amplitude = 3;
const wavelength = 2;
const frequency = 1;
-
+
for (let x = 0; x <= 20; x += 0.5) {
- const y = amplitude * Math.sin(2 * Math.PI * (x / wavelength - frequency * time));
+ const y =
+ amplitude *
+ Math.sin(2 * Math.PI * (x / wavelength - frequency * time));
newData.push({ x, y, time });
}
-
+
// Filter to keep only the latest time values
- newData = _.uniqBy(newData, 'x');
- newData = _.sortBy(newData, 'x');
+ newData = _.uniqBy(newData, "x");
+ newData = _.sortBy(newData, "x");
}
-
+
setSimulationData(newData);
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [physicsParams.time, simulationRunning, physicsParams, physicsType, simulationData]);
-
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [
+ physicsParams.time,
+ simulationRunning,
+ physicsParams,
+ physicsType,
+ simulationData,
+ ]);
+
// Calculate physics values
const calculatePhysics = (type) => {
- const { velocity, angle, height, mass, gravity,
- current, voltage,
- electricCharge, magneticField } = physicsParams;
- const radians = angle * Math.PI / 180;
-
+ const {
+ velocity,
+ angle,
+ height,
+ mass,
+ gravity,
+ current,
+ voltage,
+ electricCharge,
+ magneticField,
+ } = physicsParams;
+ const radians = (angle * Math.PI) / 180;
+
switch (type) {
- case 'range':
+ case "range":
return (velocity * velocity * Math.sin(2 * radians)) / gravity;
- case 'maxHeight':
+ case "maxHeight":
return height + (velocity * Math.sin(radians)) ** 2 / (2 * gravity);
- case 'flightTime':
- return (velocity * Math.sin(radians) + Math.sqrt((velocity * Math.sin(radians)) ** 2 + 2 * gravity * height)) / gravity;
- case 'kineticEnergy':
+ case "flightTime":
+ return (
+ (velocity * Math.sin(radians) +
+ Math.sqrt(
+ (velocity * Math.sin(radians)) ** 2 + 2 * gravity * height
+ )) /
+ gravity
+ );
+ case "kineticEnergy":
return 0.5 * mass * velocity * velocity;
- case 'potentialEnergy':
+ case "potentialEnergy":
return mass * gravity * height;
- case 'power':
+ case "power":
return voltage * current;
- case 'resistance':
+ case "resistance":
return voltage / current;
- case 'lorentzForce':
+ case "lorentzForce":
return electricCharge * velocity * magneticField;
default:
return 0;
}
};
-
+
// Save current state
const saveCurrentState = () => {
if (!saveName) return;
-
+
const currentState = {
display,
memory,
@@ -515,22 +574,22 @@ const AdvancedCalculator = () => {
physicsParams,
statisticsData,
matrixA,
- matrixB
+ matrixB,
};
-
+
setSavedStates({
...savedStates,
- [saveName]: currentState
+ [saveName]: currentState,
});
-
- setSaveName('');
+
+ setSaveName("");
};
-
+
// Load saved state
const loadState = (stateName) => {
const state = savedStates[stateName];
if (!state) return;
-
+
setDisplay(state.display);
setMemory(state.memory);
setHistory(state.history);
@@ -542,19 +601,33 @@ const AdvancedCalculator = () => {
setMatrixA(state.matrixA);
setMatrixB(state.matrixB);
};
-
+
// Render theme-aware button
const Button = ({ children, onClick, className = "", color = "default" }) => {
const colorClasses = {
- default: darkMode ? "bg-gray-700 hover:bg-gray-600" : "bg-gray-200 hover:bg-gray-300",
- blue: darkMode ? "bg-blue-700 hover:bg-blue-600" : "bg-blue-500 hover:bg-blue-400",
- green: darkMode ? "bg-green-700 hover:bg-green-600" : "bg-green-500 hover:bg-green-400",
- red: darkMode ? "bg-red-700 hover:bg-red-600" : "bg-red-500 hover:bg-red-400",
- yellow: darkMode ? "bg-yellow-700 hover:bg-yellow-600" : "bg-yellow-100 hover:bg-yellow-200",
+ default: darkMode
+ ? "bg-gray-700 hover:bg-gray-600"
+ : "bg-gray-200 hover:bg-gray-300",
+ blue: darkMode
+ ? "bg-blue-700 hover:bg-blue-600"
+ : "bg-blue-500 hover:bg-blue-400",
+ green: darkMode
+ ? "bg-green-700 hover:bg-green-600"
+ : "bg-green-500 hover:bg-green-400",
+ red: darkMode
+ ? "bg-red-700 hover:bg-red-600"
+ : "bg-red-500 hover:bg-red-400",
+ yellow: darkMode
+ ? "bg-yellow-700 hover:bg-yellow-600"
+ : "bg-yellow-100 hover:bg-yellow-200",
};
-
- const textColor = darkMode ? "text-gray-100" : (color === "default" ? "text-gray-800" : "text-white");
-
+
+ const textColor = darkMode
+ ? "text-gray-100"
+ : color === "default"
+ ? "text-gray-800"
+ : "text-white";
+
return (
{
);
};
-
- // Evaluate cell formula - Helper function
- const evaluateFormula = (formula, cellValues) => {
- try {
- // Replace cell references (e.g., A1, B2) with their values
- let expression = formula.substring(1); // Remove the '='
-
- // Replace SUM function
- expression = expression.replace(/SUM\(([A-Z][0-9]+):([A-Z][0-9]+)\)/g, (match, start, end) => {
- const startCol = start.charAt(0).charCodeAt(0) - 65;
- const startRow = parseInt(start.substring(1)) - 1;
- const endCol = end.charAt(0).charCodeAt(0) - 65;
- const endRow = parseInt(end.substring(1)) - 1;
-
- let sum = 0;
- for (let row = startRow; row <= endRow; row++) {
- for (let col = startCol; col <= endCol; col++) {
- const cellKey = `${row}-${col}`;
- const value = parseFloat(cellValues[cellKey] || '0');
- if (!isNaN(value)) {
- sum += value;
- }
- }
- }
- return sum;
- });
-
- // Replace PMT function (simplified)
- expression = expression.replace(/PMT\(([^,]+),\s*([^,]+),\s*([^)]+)\)/g, (match, rate, nper, pv) => {
- // Parse values instead of using eval
- const rateVal = parseFloat(rate);
- const nperVal = parseFloat(nper);
- const pvVal = parseFloat(pv);
- return (pvVal * rateVal) / (1 - Math.pow(1 + rateVal, -nperVal));
- });
-
- // Replace FV function (simplified)
- expression = expression.replace(/FV\(([^,]+),\s*([^,]+),\s*([^,]+),\s*([^)]+)\)/g, (match, rate, nper, pmt, pv) => {
- // Parse values instead of using eval
- const rateVal = parseFloat(rate);
- const nperVal = parseFloat(nper);
- const pmtVal = parseFloat(pmt);
- const pvVal = parseFloat(pv);
- return -1 * (pvVal * Math.pow(1 + rateVal, nperVal) + pmtVal * (Math.pow(1 + rateVal, nperVal) - 1) / rateVal);
- });
-
- // Replace cell references
- expression = expression.replace(/([A-Z])([0-9]+)/g, (match, col, row) => {
- const colIndex = col.charCodeAt(0) - 65;
- const rowIndex = parseInt(row) - 1;
- const cellKey = `${rowIndex}-${colIndex}`;
-
- // First check if there's a direct value in cellValues
- if (cellValues[cellKey] !== undefined) {
- return isNaN(parseFloat(cellValues[cellKey])) ? '0' : cellValues[cellKey];
- }
-
- // Otherwise, check the spreadsheetData
- if (spreadsheetData[rowIndex] && spreadsheetData[rowIndex][colIndex] !== undefined) {
- const value = spreadsheetData[rowIndex][colIndex];
- // If it's a formula, we need to recursively evaluate it
- if (typeof value === 'string' && value.startsWith('=')) {
- return evaluateFormula(value, cellValues);
- }
- return isNaN(parseFloat(value)) ? '0' : value;
- }
-
- return '0';
- });
-
- // Use math.js to evaluate the expression instead of eval
- const result = math.evaluate(expression);
- return isNaN(result) ? 'Error' : parseFloat(result).toFixed(2);
- } catch (error) {
- console.error("Formula evaluation error:", error);
- return 'Error';
- }
- };
-
- // Initialize spreadsheet data for blank template
- useEffect(() => {
- if (spreadsheetTemplate === 'blank' && (!spreadsheetData.length || spreadsheetData.length === 0)) {
- setSpreadsheetHeaders(['A', 'B', 'C', 'D', 'E']);
- setSpreadsheetData([
- ['', '', '', '', ''],
- ['', '', '', '', ''],
- ['', '', '', '', ''],
- ['', '', '', '', ''],
- ['', '', '', '', '']
- ]);
- }
- }, [spreadsheetTemplate, spreadsheetData]);
-
- // Handle cell input change
- const handleCellChange = (rowIndex, colIndex, value) => {
- const cellKey = `${rowIndex}-${colIndex}`;
-
- // Update the cell value
- setCellValues(prev => ({
- ...prev,
- [cellKey]: value
- }));
-
- // If it's a formula, store it in cellFormulas
- if (value.startsWith('=')) {
- setCellFormulas(prev => ({
- ...prev,
- [cellKey]: value
- }));
- } else if (cellFormulas[cellKey]) {
- // Remove from formulas if it's no longer a formula
- const newFormulas = {...cellFormulas};
- delete newFormulas[cellKey];
- setCellFormulas(newFormulas);
- }
-
- // Update the spreadsheet data for proper rendering
- const newData = [...spreadsheetData];
- if (newData[rowIndex] && colIndex < newData[rowIndex].length) {
- const newRow = [...newData[rowIndex]];
- newRow[colIndex] = value;
- newData[rowIndex] = newRow;
- setSpreadsheetData(newData);
- }
- };
-
- // Render spreadsheet
- const renderSpreadsheet = () => (
-
-
- Template:
- setSpreadsheetTemplate(e.target.value)}
- className="spreadsheet-template-select"
- >
- Monthly Budget
- Loan Calculator
- Rent Comparison
- Mortgage Calculator
- Investment Growth
- Retirement Planner
- Expense Tracker
- Blank Spreadsheet
-
-
-
-
-
-
- Formula:
- handleCellChange(activeCell.row, activeCell.col, e.target.value)}
- placeholder="Enter formula (e.g., =A1+B2)"
- className="formula-input"
- />
-
-
-
-
Formulas:
-
- Basic math: =A1+B1, =C1-D1, =A2*B2, =C2/D2
- Sum range: =SUM(A1:A5)
- Loan payment: =PMT(rate, nper, pv)
- Future value: =FV(rate, nper, pmt, pv)
-
-
-
- );
-
+
// Render basic calculator
const renderBasicCalculator = () => (
-
- {display}
-
-
+
{display}
+
- MC
- MR
- M+
- M-
-
- handleButtonClick('7')}>7
- handleButtonClick('8')}>8
- handleButtonClick('9')}>9
- handleButtonClick('/')}>/
-
- handleButtonClick('4')}>4
- handleButtonClick('5')}>5
- handleButtonClick('6')}>6
- handleButtonClick('*')}>×
-
- handleButtonClick('1')}>1
- handleButtonClick('2')}>2
- handleButtonClick('3')}>3
- handleButtonClick('-')}>-
-
- handleButtonClick('0')}>0
- handleButtonClick('.')}>.
- =
- handleButtonClick('+')}>+
-
- C
- handleButtonClick('(')}>(
- handleButtonClick(')')}>)
- handleButtonClick('^')}>^
-
- handleButtonClick('sqrt(')}>√
- handleButtonClick('sin(')}>sin
- handleButtonClick('cos(')}>cos
- handleButtonClick('tan(')}>tan
-
- handleButtonClick('log(')}>log
- handleButtonClick('ln(')}>ln
- handleButtonClick('π')}>π
- handleButtonClick('e')}>e
+
+ MC
+
+
+ MR
+
+
+ M+
+
+
+ M-
+
+
+ handleButtonClick("7")}>
+ 7
+
+ handleButtonClick("8")}>
+ 8
+
+ handleButtonClick("9")}>
+ 9
+
+ handleButtonClick("/")}>
+ /
+
+
+ handleButtonClick("4")}>
+ 4
+
+ handleButtonClick("5")}>
+ 5
+
+ handleButtonClick("6")}>
+ 6
+
+ handleButtonClick("*")}>
+ ×
+
+
+ handleButtonClick("1")}>
+ 1
+
+ handleButtonClick("2")}>
+ 2
+
+ handleButtonClick("3")}>
+ 3
+
+ handleButtonClick("-")}>
+ -
+
+
+ handleButtonClick("0")}>
+ 0
+
+ handleButtonClick(".")}>
+ .
+
+
+ =
+
+ handleButtonClick("+")}>
+ +
+
+
+
+ C
+
+ handleButtonClick("(")}>
+ (
+
+ handleButtonClick(")")}>
+ )
+
+ handleButtonClick("^")}>
+ ^
+
+
+ handleButtonClick("sqrt(")}>
+ √
+
+ handleButtonClick("sin(")}>
+ sin
+
+ handleButtonClick("cos(")}>
+ cos
+
+ handleButtonClick("tan(")}>
+ tan
+
+
+ handleButtonClick("log(")}>
+ log
+
+ handleButtonClick("ln(")}>
+ ln
+
+ handleButtonClick("π")}>
+ π
+
+ handleButtonClick("e")}>
+ e
+
-
+
History:
@@ -832,13 +757,15 @@ const AdvancedCalculator = () => {
) : (
history.map((item, index) => (
-
{item.expression} = {item.result}
+
+ {item.expression} = {item.result}
+
))
)}
-
+
Save Current State:
@@ -850,10 +777,12 @@ const AdvancedCalculator = () => {
placeholder="Name this state..."
className="flex-1"
/>
-
Save
+
+ Save
+
-
+
Load Saved State:
@@ -863,7 +792,12 @@ const AdvancedCalculator = () => {
Object.keys(savedStates).map((name) => (
{name}
- loadState(name)}>Load
+ loadState(name)}
+ >
+ Load
+
))
)}
@@ -872,11 +806,11 @@ const AdvancedCalculator = () => {
);
-
+
// Render graphing calculator
const renderGraphingCalculator = () => {
const colors = getGraphColors();
-
+
return (
@@ -891,33 +825,42 @@ const AdvancedCalculator = () => {
placeholder="e.g., x^2, sin(x), etc."
/>
-
+
-
+
-
+
-
@@ -945,16 +891,22 @@ const AdvancedCalculator = () => {
dataKey="x"
domain={[graphRange[0], graphRange[1]]}
type="number"
- label={{ value: 'x', position: 'insideBottomRight', offset: -5 }}
+ label={{
+ value: "x",
+ position: "insideBottomRight",
+ offset: -5,
+ }}
stroke={darkMode ? "#fff" : "#333"}
/>
value.toFixed(settings.precision)}
- labelFormatter={(value) => `x = ${parseFloat(value).toFixed(settings.precision)}`}
+ labelFormatter={(value) =>
+ `x = ${parseFloat(value).toFixed(settings.precision)}`
+ }
contentStyle={{ backgroundColor: darkMode ? "#333" : "#fff" }}
/>
@@ -979,41 +931,131 @@ const AdvancedCalculator = () => {
-
+
Common Functions:
- setGraphFunction('x^2')}>x²
- setGraphFunction('x^3')}>x³
- setGraphFunction('sin(x)')}>sin(x)
- setGraphFunction('cos(x)')}>cos(x)
- setGraphFunction('tan(x)')}>tan(x)
- setGraphFunction('log(x)')}>log(x)
- setGraphFunction('sqrt(x)')}>√x
- setGraphFunction('1/x')}>1/x
- setGraphFunction('exp(x)')}>e^x
- setGraphFunction('abs(x)')}>|x|
- setGraphFunction('x^2-4')}>x²-4
- setGraphFunction('sin(x)*cos(x)')}>sin(x)cos(x)
+ setGraphFunction("x^2")}
+ >
+ x²
+
+ setGraphFunction("x^3")}
+ >
+ x³
+
+ setGraphFunction("sin(x)")}
+ >
+ sin(x)
+
+ setGraphFunction("cos(x)")}
+ >
+ cos(x)
+
+ setGraphFunction("tan(x)")}
+ >
+ tan(x)
+
+ setGraphFunction("log(x)")}
+ >
+ log(x)
+
+ setGraphFunction("sqrt(x)")}
+ >
+ √x
+
+ setGraphFunction("1/x")}
+ >
+ 1/x
+
+ setGraphFunction("exp(x)")}
+ >
+ e^x
+
+ setGraphFunction("abs(x)")}
+ >
+ |x|
+
+ setGraphFunction("x^2-4")}
+ >
+ x²-4
+
+ setGraphFunction("sin(x)*cos(x)")}
+ >
+ sin(x)cos(x)
+
View Presets:
- setGraphRange([-10, 10])}>Standard
- setGraphRange([-2 * Math.PI, 2 * Math.PI])}>Trig
- setGraphRange([-100, 100])}>Wide
- setGraphRange([-1, 1])}>Zoom In
- setGraphRange([0, 10])}>Positive
- setGraphRange([-10, 0])}>Negative
+ setGraphRange([-10, 10])}
+ >
+ Standard
+
+ setGraphRange([-2 * Math.PI, 2 * Math.PI])}
+ >
+ Trig
+
+ setGraphRange([-100, 100])}
+ >
+ Wide
+
+ setGraphRange([-1, 1])}
+ >
+ Zoom In
+
+ setGraphRange([0, 10])}
+ >
+ Positive
+
+ setGraphRange([-10, 0])}
+ >
+ Negative
+
);
};
-
+
// Render unit conversion
const renderUnitConversion = () => (
@@ -1022,7 +1064,9 @@ const AdvancedCalculator = () => {
Category:
setUnitConversion({...unitConversion, category: e.target.value})}
+ onChange={(e) =>
+ setUnitConversion({ ...unitConversion, category: e.target.value })
+ }
>
Length
Mass
@@ -1038,25 +1082,32 @@ const AdvancedCalculator = () => {
Digital Storage
-
+
Value:
setUnitConversion({...unitConversion, fromValue: parseFloat(e.target.value)})}
+ onChange={(e) =>
+ setUnitConversion({
+ ...unitConversion,
+ fromValue: parseFloat(e.target.value),
+ })
+ }
/>
-
+
From Unit:
setUnitConversion({...unitConversion, fromUnit: e.target.value})}
+ onChange={(e) =>
+ setUnitConversion({ ...unitConversion, fromUnit: e.target.value })
+ }
>
- {unitConversion.category === 'length' && (
+ {unitConversion.category === "length" && (
<>
Meters (m)
Centimeters (cm)
@@ -1069,7 +1120,7 @@ const AdvancedCalculator = () => {
Nautical Miles (nmi)
>
)}
- {unitConversion.category === 'volume' && (
+ {unitConversion.category === "volume" && (
<>
Cubic Meters (m³)
Liters (L)
@@ -1088,7 +1139,7 @@ const AdvancedCalculator = () => {
Imperial Gallons (imp gal)
>
)}
- {unitConversion.category === 'temperature' && (
+ {unitConversion.category === "temperature" && (
<>
Celsius (°C)
Fahrenheit (°F)
@@ -1096,7 +1147,7 @@ const AdvancedCalculator = () => {
Rankine (°R)
>
)}
- {unitConversion.category === 'area' && (
+ {unitConversion.category === "area" && (
<>
Square Meters (m²)
Square Kilometers (km²)
@@ -1110,7 +1161,7 @@ const AdvancedCalculator = () => {
Square Miles (mi²)
>
)}
- {unitConversion.category === 'time' && (
+ {unitConversion.category === "time" && (
<>
Seconds (s)
Milliseconds (ms)
@@ -1126,7 +1177,7 @@ const AdvancedCalculator = () => {
Centuries
>
)}
- {unitConversion.category === 'speed' && (
+ {unitConversion.category === "speed" && (
<>
Meters per Second (m/s)
Kilometers per Hour (km/h)
@@ -1138,7 +1189,7 @@ const AdvancedCalculator = () => {
Speed of Light (c)
>
)}
- {unitConversion.category === 'pressure' && (
+ {unitConversion.category === "pressure" && (
<>
Pascal (Pa)
Hectopascal (hPa)
@@ -1154,7 +1205,7 @@ const AdvancedCalculator = () => {
Torr
>
)}
- {unitConversion.category === 'energy' && (
+ {unitConversion.category === "energy" && (
<>
Joules (J)
Kilojoules (kJ)
@@ -1170,7 +1221,7 @@ const AdvancedCalculator = () => {
Foot-pounds (ft-lb)
>
)}
- {unitConversion.category === 'power' && (
+ {unitConversion.category === "power" && (
<>
Watts (W)
Milliwatts (mW)
@@ -1179,10 +1230,12 @@ const AdvancedCalculator = () => {
Gigawatts (GW)
Horsepower (hp)
BTU per Hour (BTU/h)
- Foot-pounds per second (ft-lb/s)
+
+ Foot-pounds per second (ft-lb/s)
+
>
)}
- {unitConversion.category === 'angle' && (
+ {unitConversion.category === "angle" && (
<>
Radians (rad)
Degrees (°)
@@ -1195,7 +1248,7 @@ const AdvancedCalculator = () => {
Steradians (sr)
>
)}
- {unitConversion.category === 'digital' && (
+ {unitConversion.category === "digital" && (
<>
Bits (b)
Bytes (B)
@@ -1215,14 +1268,16 @@ const AdvancedCalculator = () => {
)}
-
+
To Unit:
setUnitConversion({...unitConversion, toUnit: e.target.value})}
+ onChange={(e) =>
+ setUnitConversion({ ...unitConversion, toUnit: e.target.value })
+ }
>
- {unitConversion.category === 'length' && (
+ {unitConversion.category === "length" && (
<>
Meters (m)
Centimeters (cm)
@@ -1237,7 +1292,7 @@ const AdvancedCalculator = () => {
)}
{/* Other categories as in your original code */}
{/* I've truncated these for brevity but you should include all original options */}
- {unitConversion.category === 'volume' && (
+ {unitConversion.category === "volume" && (
<>
Cubic Meters (m³)
Liters (L)
@@ -1256,7 +1311,7 @@ const AdvancedCalculator = () => {
Imperial Gallons (imp gal)
>
)}
- {unitConversion.category === 'temperature' && (
+ {unitConversion.category === "temperature" && (
<>
Celsius (°C)
Fahrenheit (°F)
@@ -1264,7 +1319,7 @@ const AdvancedCalculator = () => {
Rankine (°R)
>
)}
- {unitConversion.category === 'area' && (
+ {unitConversion.category === "area" && (
<>
Square Meters (m²)
Square Kilometers (km²)
@@ -1278,7 +1333,7 @@ const AdvancedCalculator = () => {
Square Miles (mi²)
>
)}
- {unitConversion.category === 'time' && (
+ {unitConversion.category === "time" && (
<>
Seconds (s)
Milliseconds (ms)
@@ -1294,7 +1349,7 @@ const AdvancedCalculator = () => {
Centuries
>
)}
- {unitConversion.category === 'speed' && (
+ {unitConversion.category === "speed" && (
<>
Meters per Second (m/s)
Kilometers per Hour (km/h)
@@ -1306,7 +1361,7 @@ const AdvancedCalculator = () => {
Speed of Light (c)
>
)}
- {unitConversion.category === 'pressure' && (
+ {unitConversion.category === "pressure" && (
<>
Pascal (Pa)
Hectopascal (hPa)
@@ -1322,7 +1377,7 @@ const AdvancedCalculator = () => {
Torr
>
)}
- {unitConversion.category === 'energy' && (
+ {unitConversion.category === "energy" && (
<>
Joules (J)
Kilojoules (kJ)
@@ -1338,7 +1393,7 @@ const AdvancedCalculator = () => {
Foot-pounds (ft-lb)
>
)}
- {unitConversion.category === 'power' && (
+ {unitConversion.category === "power" && (
<>
Watts (W)
Milliwatts (mW)
@@ -1347,10 +1402,12 @@ const AdvancedCalculator = () => {
Gigawatts (GW)
Horsepower (hp)
BTU per Hour (BTU/h)
- Foot-pounds per second (ft-lb/s)
+
+ Foot-pounds per second (ft-lb/s)
+
>
)}
- {unitConversion.category === 'angle' && (
+ {unitConversion.category === "angle" && (
<>
Radians (rad)
Degrees (°)
@@ -1363,7 +1420,7 @@ const AdvancedCalculator = () => {
Steradians (sr)
>
)}
- {unitConversion.category === 'digital' && (
+ {unitConversion.category === "digital" && (
<>
Bits (b)
Bytes (B)
@@ -1384,15 +1441,16 @@ const AdvancedCalculator = () => {
-
+
Convert
-
+
- {unitConversion.fromValue} {unitConversion.fromUnit} = {convertUnit()} {unitConversion.toUnit}
+ {unitConversion.fromValue} {unitConversion.fromUnit} = {convertUnit()}{" "}
+ {unitConversion.toUnit}
-
+
Common Conversions:
@@ -1420,14 +1478,22 @@ const AdvancedCalculator = () => {
);
-
+
// Render matrix calculator
const renderMatrixCalculator = () => (
-
+
Matrix A:
-
+
{matrixA.map((row, rowIndex) => (
{row.map((cell, cellIndex) => (
@@ -1437,40 +1503,68 @@ const AdvancedCalculator = () => {
value={cell}
onChange={(e) => {
const newMatrix = [...matrixA];
- newMatrix[rowIndex][cellIndex] = parseFloat(e.target.value);
+ newMatrix[rowIndex][cellIndex] = parseFloat(
+ e.target.value
+ );
setMatrixA(newMatrix);
}}
- className={`w-16 p-2 mr-2 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
+ className={`w-16 p-2 mr-2 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
/>
))}
- {
- const newMatrix = [...matrixA];
- newMatrix[rowIndex].push(0);
- setMatrixA(newMatrix);
- }}>+
+ {
+ const newMatrix = [...matrixA];
+ newMatrix[rowIndex].push(0);
+ setMatrixA(newMatrix);
+ }}
+ >
+ +
+
))}
- {
- setMatrixA([...matrixA, Array(matrixA[0].length).fill(0)]);
- }}>Add Row
- {
- if (matrixA[0].length > 1) {
- setMatrixA(matrixA.map(row => row.slice(0, -1)));
- }
- }}>Remove Column
- {
- if (matrixA.length > 1) {
- setMatrixA(matrixA.slice(0, -1));
- }
- }}>Remove Row
+ {
+ setMatrixA([...matrixA, Array(matrixA[0].length).fill(0)]);
+ }}
+ >
+ Add Row
+
+ {
+ if (matrixA[0].length > 1) {
+ setMatrixA(matrixA.map((row) => row.slice(0, -1)));
+ }
+ }}
+ >
+ Remove Column
+
+ {
+ if (matrixA.length > 1) {
+ setMatrixA(matrixA.slice(0, -1));
+ }
+ }}
+ >
+ Remove Row
+
-
+
Matrix B:
-
+
{matrixB.map((row, rowIndex) => (
{row.map((cell, cellIndex) => (
@@ -1480,85 +1574,158 @@ const AdvancedCalculator = () => {
value={cell}
onChange={(e) => {
const newMatrix = [...matrixB];
- newMatrix[rowIndex][cellIndex] = parseFloat(e.target.value);
+ newMatrix[rowIndex][cellIndex] = parseFloat(
+ e.target.value
+ );
setMatrixB(newMatrix);
}}
- className={`w-16 p-2 mr-2 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
+ className={`w-16 p-2 mr-2 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
/>
))}
- {
- const newMatrix = [...matrixB];
- newMatrix[rowIndex].push(0);
- setMatrixB(newMatrix);
- }}>+
+ {
+ const newMatrix = [...matrixB];
+ newMatrix[rowIndex].push(0);
+ setMatrixB(newMatrix);
+ }}
+ >
+ +
+
))}
- {
- setMatrixB([...matrixB, Array(matrixB[0].length).fill(0)]);
- }}>Add Row
- {
- if (matrixB[0].length > 1) {
- setMatrixB(matrixB.map(row => row.slice(0, -1)));
- }
- }}>Remove Column
- {
- if (matrixB.length > 1) {
- setMatrixB(matrixB.slice(0, -1));
- }
- }}>Remove Row
+ {
+ setMatrixB([...matrixB, Array(matrixB[0].length).fill(0)]);
+ }}
+ >
+ Add Row
+
+ {
+ if (matrixB[0].length > 1) {
+ setMatrixB(matrixB.map((row) => row.slice(0, -1)));
+ }
+ }}
+ >
+ Remove Column
+
+ {
+ if (matrixB.length > 1) {
+ setMatrixB(matrixB.slice(0, -1));
+ }
+ }}
+ >
+ Remove Row
+
-
+
- {
- setMatrixOperation('add');
- performMatrixOperation();
- }}>A + B
- {
- setMatrixOperation('subtract');
- performMatrixOperation();
- }}>A - B
- {
- setMatrixOperation('multiply');
- performMatrixOperation();
- }}>A × B
- {
- setMatrixOperation('determinantA');
- performMatrixOperation();
- }}>det(A)
- {
- setMatrixOperation('determinantB');
- performMatrixOperation();
- }}>det(B)
- {
- setMatrixOperation('transposeA');
- performMatrixOperation();
- }}>Transpose A
- {
- setMatrixOperation('transposeB');
- performMatrixOperation();
- }}>Transpose B
- {
- setMatrixOperation('inverseA');
- performMatrixOperation();
- }}>Inverse A
- {
- setMatrixOperation('inverseB');
- performMatrixOperation();
- }}>Inverse B
+ {
+ setMatrixOperation("add");
+ performMatrixOperation();
+ }}
+ >
+ A + B
+
+ {
+ setMatrixOperation("subtract");
+ performMatrixOperation();
+ }}
+ >
+ A - B
+
+ {
+ setMatrixOperation("multiply");
+ performMatrixOperation();
+ }}
+ >
+ A × B
+
+ {
+ setMatrixOperation("determinantA");
+ performMatrixOperation();
+ }}
+ >
+ det(A)
+
+ {
+ setMatrixOperation("determinantB");
+ performMatrixOperation();
+ }}
+ >
+ det(B)
+
+ {
+ setMatrixOperation("transposeA");
+ performMatrixOperation();
+ }}
+ >
+ Transpose A
+
+ {
+ setMatrixOperation("transposeB");
+ performMatrixOperation();
+ }}
+ >
+ Transpose B
+
+ {
+ setMatrixOperation("inverseA");
+ performMatrixOperation();
+ }}
+ >
+ Inverse A
+
+ {
+ setMatrixOperation("inverseB");
+ performMatrixOperation();
+ }}
+ >
+ Inverse B
+
-
+
Result:
-
+
{matrixResult === null ? (
-
Perform an operation to see results
- ) : typeof matrixResult === 'string' ? (
+
+ Perform an operation to see results
+
+ ) : typeof matrixResult === "string" ? (
{matrixResult}
- ) : typeof matrixResult === 'number' ? (
+ ) : typeof matrixResult === "number" ? (
{matrixResult}
) : (
@@ -1567,9 +1734,13 @@ const AdvancedCalculator = () => {
{row.map((cell, cellIndex) => (
- {typeof cell === 'number' ? cell.toFixed(settings.precision) : cell}
+ {typeof cell === "number"
+ ? cell.toFixed(settings.precision)
+ : cell}
))}
@@ -1580,71 +1751,113 @@ const AdvancedCalculator = () => {
);
-
+
// Render statistics calculator
const renderStatisticsCalculator = () => (
-
+
Enter data (comma separated):
-
+
Basic Statistics:
-
+
Mean:
-
{statisticsResults.mean?.toFixed(settings.precision) || 'N/A'}
-
+
+ {statisticsResults.mean?.toFixed(settings.precision) || "N/A"}
+
+
Median:
-
{statisticsResults.median?.toFixed(settings.precision) || 'N/A'}
-
+
+ {statisticsResults.median?.toFixed(settings.precision) || "N/A"}
+
+
Mode:
-
{statisticsResults.mode || 'N/A'}
-
+
{statisticsResults.mode || "N/A"}
+
Range:
-
{statisticsResults.range?.toFixed(settings.precision) || 'N/A'}
-
+
+ {statisticsResults.range?.toFixed(settings.precision) || "N/A"}
+
+
Min:
-
{statisticsResults.min?.toFixed(settings.precision) || 'N/A'}
-
+
+ {statisticsResults.min?.toFixed(settings.precision) || "N/A"}
+
+
Max:
-
{statisticsResults.max?.toFixed(settings.precision) || 'N/A'}
+
+ {statisticsResults.max?.toFixed(settings.precision) || "N/A"}
+
-
+
Advanced Statistics:
-
+
Count:
-
{statisticsResults.count || 'N/A'}
-
+
{statisticsResults.count || "N/A"}
+
Sum:
-
{statisticsResults.sum?.toFixed(settings.precision) || 'N/A'}
-
+
+ {statisticsResults.sum?.toFixed(settings.precision) || "N/A"}
+
+
Variance:
-
{statisticsResults.variance?.toFixed(settings.precision) || 'N/A'}
-
+
+ {statisticsResults.variance?.toFixed(settings.precision) ||
+ "N/A"}
+
+
Std Deviation:
-
{statisticsResults.standardDeviation?.toFixed(settings.precision) || 'N/A'}
+
+ {statisticsResults.standardDeviation?.toFixed(
+ settings.precision
+ ) || "N/A"}
+
-
+
Data Visualization:
-
- {statisticsData.split(',').map(n => parseFloat(n.trim())).filter(n => !isNaN(n)).length > 0 ? (
+
+ {statisticsData
+ .split(",")
+ .map((n) => parseFloat(n.trim()))
+ .filter((n) => !isNaN(n)).length > 0 ? (
{
name="value"
stroke={darkMode ? "#fff" : "#333"}
/>
-
+
parseFloat(n.trim())).filter(n => !isNaN(n)).map((value, index) => ({ x: index + 1, y: value }))}
+ data={statisticsData
+ .split(",")
+ .map((n) => parseFloat(n.trim()))
+ .filter((n) => !isNaN(n))
+ .map((value, index) => ({ x: index + 1, y: value }))}
fill={getGraphColors().line1}
/>
@@ -1680,159 +1897,313 @@ const AdvancedCalculator = () => {
);
-
+
// Render physics calculator
const renderPhysicsCalculator = () => (
-
+
Kinematics & Dynamics
-
+
Velocity:
setPhysicsParams({...physicsParams, velocity: parseFloat(e.target.value)})}
- className={`w-24 p-1 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
- /> m/s
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ velocity: parseFloat(e.target.value),
+ })
+ }
+ className={`w-24 p-1 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
+ />{" "}
+ m/s
Angle:
setPhysicsParams({...physicsParams, angle: parseFloat(e.target.value)})}
- className={`w-24 p-1 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
- /> °
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ angle: parseFloat(e.target.value),
+ })
+ }
+ className={`w-24 p-1 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
+ />{" "}
+ °
Height:
setPhysicsParams({...physicsParams, height: parseFloat(e.target.value)})}
- className={`w-24 p-1 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
- /> m
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ height: parseFloat(e.target.value),
+ })
+ }
+ className={`w-24 p-1 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
+ />{" "}
+ m
Mass:
setPhysicsParams({...physicsParams, mass: parseFloat(e.target.value)})}
- className={`w-24 p-1 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
- /> kg
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ mass: parseFloat(e.target.value),
+ })
+ }
+ className={`w-24 p-1 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
+ />{" "}
+ kg
Gravity:
setPhysicsParams({...physicsParams, gravity: parseFloat(e.target.value)})}
- className={`w-24 p-1 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
- /> m/s²
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ gravity: parseFloat(e.target.value),
+ })
+ }
+ className={`w-24 p-1 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
+ />{" "}
+ m/s²
-
+
Electromagnetism
-
+
Voltage:
setPhysicsParams({...physicsParams, voltage: parseFloat(e.target.value)})}
- className={`w-24 p-1 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
- /> V
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ voltage: parseFloat(e.target.value),
+ })
+ }
+ className={`w-24 p-1 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
+ />{" "}
+ V
Current:
setPhysicsParams({...physicsParams, current: parseFloat(e.target.value)})}
- className={`w-24 p-1 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
- /> A
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ current: parseFloat(e.target.value),
+ })
+ }
+ className={`w-24 p-1 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
+ />{" "}
+ A
Resistance:
setPhysicsParams({...physicsParams, resistance: parseFloat(e.target.value)})}
- className={`w-24 p-1 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
- /> Ω
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ resistance: parseFloat(e.target.value),
+ })
+ }
+ className={`w-24 p-1 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
+ />{" "}
+ Ω
Magnetic Field:
setPhysicsParams({...physicsParams, magneticField: parseFloat(e.target.value)})}
- className={`w-24 p-1 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
- /> T
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ magneticField: parseFloat(e.target.value),
+ })
+ }
+ className={`w-24 p-1 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
+ />{" "}
+ T
Electric Charge:
setPhysicsParams({...physicsParams, electricCharge: parseFloat(e.target.value)})}
- className={`w-24 p-1 border rounded ${darkMode ? "bg-gray-800 border-gray-600 text-white" : "bg-white border-gray-300"}`}
- /> C
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ electricCharge: parseFloat(e.target.value),
+ })
+ }
+ className={`w-24 p-1 border rounded ${
+ darkMode
+ ? "bg-gray-800 border-gray-600 text-white"
+ : "bg-white border-gray-300"
+ }`}
+ />{" "}
+ C
-
+
Calculated Values
-
+
Projectile Range:
- {calculatePhysics('range').toFixed(settings.precision)} m
+
+ {calculatePhysics("range").toFixed(settings.precision)} m
+
Maximum Height:
- {calculatePhysics('maxHeight').toFixed(settings.precision)} m
+
+ {calculatePhysics("maxHeight").toFixed(settings.precision)} m
+
Flight Time:
- {calculatePhysics('flightTime').toFixed(settings.precision)} s
+
+ {calculatePhysics("flightTime").toFixed(settings.precision)} s
+
Kinetic Energy:
- {calculatePhysics('kineticEnergy').toFixed(settings.precision)} J
+
+ {calculatePhysics("kineticEnergy").toFixed(settings.precision)}{" "}
+ J
+
Potential Energy:
- {calculatePhysics('potentialEnergy').toFixed(settings.precision)} J
+
+ {calculatePhysics("potentialEnergy").toFixed(
+ settings.precision
+ )}{" "}
+ J
+
Total Energy:
- {(calculatePhysics('kineticEnergy') + calculatePhysics('potentialEnergy')).toFixed(settings.precision)} J
+
+ {(
+ calculatePhysics("kineticEnergy") +
+ calculatePhysics("potentialEnergy")
+ ).toFixed(settings.precision)}{" "}
+ J
+
Momentum:
- {(physicsParams.mass * physicsParams.velocity).toFixed(settings.precision)} kg·m/s
+
+ {(physicsParams.mass * physicsParams.velocity).toFixed(
+ settings.precision
+ )}{" "}
+ kg·m/s
+
Electric Power:
- {calculatePhysics('power').toFixed(settings.precision)} W
+
+ {calculatePhysics("power").toFixed(settings.precision)} W
+
Calculated Resistance:
- {calculatePhysics('resistance').toFixed(settings.precision)} Ω
+
+ {calculatePhysics("resistance").toFixed(settings.precision)} Ω
+
Lorentz Force:
- {calculatePhysics('lorentzForce').toExponential(settings.precision)} N
+
+ {calculatePhysics("lorentzForce").toExponential(
+ settings.precision
+ )}{" "}
+ N
+
-
+
Physics Constants
-
+
Gravitational Constant (G):
@@ -1854,31 +2225,103 @@ const AdvancedCalculator = () => {
-
+
Physics Formulas
-
v = v₀ + at
-
s = s₀ + v₀t + ½at²
-
v² = v₀² + 2a(s-s₀)
-
F = ma
-
Ek = ½mv²
-
Ep = mgh
-
p = mv
-
W = F·d
-
P = VI
-
V = IR
-
F = qvB sin θ
-
E = mc²
+
+ v = v₀ + at
+
+
+ s = s₀ + v₀t + ½at²
+
+
+ v² = v₀² + 2a(s-s₀)
+
+
+ F = ma
+
+
+ Ek = ½mv²
+
+
+ Ep = mgh
+
+
+ p = mv
+
+
+ W = F·d
+
+
+ P = VI
+
+
+ V = IR
+
+
+ F = qvB sin θ
+
+
+ E = mc²
+
);
-
+
// Render physics simulation
const renderPhysicsSimulation = () => {
const colors = getGraphColors();
-
+
return (
@@ -1896,15 +2339,20 @@ const AdvancedCalculator = () => {
Wave Propagation
-
- {physicsType === 'projectile' && (
+
+ {physicsType === "projectile" && (
@@ -1922,7 +2375,12 @@ const AdvancedCalculator = () => {
setPhysicsParams({...physicsParams, height: parseFloat(e.target.value)})}
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ height: parseFloat(e.target.value),
+ })
+ }
className="w-20"
/>
@@ -1931,21 +2389,31 @@ const AdvancedCalculator = () => {
setPhysicsParams({...physicsParams, gravity: parseFloat(e.target.value)})}
+ onChange={(e) =>
+ setPhysicsParams({
+ ...physicsParams,
+ gravity: parseFloat(e.target.value),
+ })
+ }
className="w-20"
/>
)}
-
- {physicsType === 'pendulum' && (
+
+ {physicsType === "pendulum" && (
)}
-
- {physicsType === 'spring' && (
+
+ {physicsType === "spring" && (
)}
-
- {physicsType === 'circuit' && (
+
+ {physicsType === "circuit" && (
)}
-
+
{
Stop Simulation
-
+
{
{
contentStyle={{ backgroundColor: darkMode ? "#333" : "#fff" }}
/>
{
/>
-
- {simulationData.length > 0 && physicsType === 'projectile' && (
+
+ {simulationData.length > 0 && physicsType === "projectile" && (
)}
-
+
Simulation Info:
- {physicsType === 'projectile' && (
+ {physicsType === "projectile" && (
<>
-
A projectile is launched at {physicsParams.velocity} m/s at an angle of {physicsParams.angle}°.
-
It will travel {calculatePhysics('range').toFixed(settings.precision)} meters horizontally and reach a maximum height of {calculatePhysics('maxHeight').toFixed(settings.precision)} meters.
-
Time of flight: {calculatePhysics('flightTime').toFixed(settings.precision)} seconds.
+
+ A projectile is launched at {physicsParams.velocity} m/s at an
+ angle of {physicsParams.angle}°.
+
+
+ It will travel{" "}
+ {calculatePhysics("range").toFixed(settings.precision)} meters
+ horizontally and reach a maximum height of{" "}
+ {calculatePhysics("maxHeight").toFixed(settings.precision)}{" "}
+ meters.
+
+
+ Time of flight:{" "}
+ {calculatePhysics("flightTime").toFixed(settings.precision)}{" "}
+ seconds.
+
>
)}
- {physicsType === 'pendulum' && (
+ {physicsType === "pendulum" && (
<>
-
A pendulum of length {physicsParams.pendulumLength} m oscillates under the influence of gravity ({physicsParams.gravity} m/s²).
-
Period of oscillation: {(2 * Math.PI * Math.sqrt(physicsParams.pendulumLength / physicsParams.gravity)).toFixed(settings.precision)} seconds.
+
+ A pendulum of length {physicsParams.pendulumLength} m
+ oscillates under the influence of gravity (
+ {physicsParams.gravity} m/s²).
+
+
+ Period of oscillation:{" "}
+ {(
+ 2 *
+ Math.PI *
+ Math.sqrt(
+ physicsParams.pendulumLength / physicsParams.gravity
+ )
+ ).toFixed(settings.precision)}{" "}
+ seconds.
+
>
)}
- {physicsType === 'spring' && (
+ {physicsType === "spring" && (
<>
-
A mass of {physicsParams.mass} kg oscillates on a spring with spring constant k = {physicsParams.springConstant} N/m.
-
Period of oscillation: {(2 * Math.PI * Math.sqrt(physicsParams.mass / physicsParams.springConstant)).toFixed(settings.precision)} seconds.
+
+ A mass of {physicsParams.mass} kg oscillates on a spring with
+ spring constant k = {physicsParams.springConstant} N/m.
+
+
+ Period of oscillation:{" "}
+ {(
+ 2 *
+ Math.PI *
+ Math.sqrt(physicsParams.mass / physicsParams.springConstant)
+ ).toFixed(settings.precision)}{" "}
+ seconds.
+
>
)}
- {physicsType === 'circuit' && (
+ {physicsType === "circuit" && (
<>
-
A simple DC circuit with voltage {physicsParams.voltage} V and resistance {physicsParams.resistance} Ω.
-
Current: {(physicsParams.voltage / physicsParams.resistance).toFixed(settings.precision)} A
-
Power dissipated: {(physicsParams.voltage * physicsParams.voltage / physicsParams.resistance).toFixed(settings.precision)} W
+
+ A simple DC circuit with voltage {physicsParams.voltage} V and
+ resistance {physicsParams.resistance} Ω.
+
+
+ Current:{" "}
+ {(physicsParams.voltage / physicsParams.resistance).toFixed(
+ settings.precision
+ )}{" "}
+ A
+
+
+ Power dissipated:{" "}
+ {(
+ (physicsParams.voltage * physicsParams.voltage) /
+ physicsParams.resistance
+ ).toFixed(settings.precision)}{" "}
+ W
+
>
)}
- {physicsType === 'wave' && (
+ {physicsType === "wave" && (
Wave propagation with amplitude modulation over time.
)}
@@ -2100,16 +2665,19 @@ const AdvancedCalculator = () => {
);
};
-
+
// Add CSS variables for dark mode
useEffect(() => {
// Apply dark mode to document body or root element
- document.documentElement.setAttribute('data-theme', darkMode ? 'dark' : 'light');
+ document.documentElement.setAttribute(
+ "data-theme",
+ darkMode ? "dark" : "light"
+ );
}, [darkMode]);
// Return the calculator UI
return (
-
+
Advanced Calculator
@@ -2127,11 +2695,11 @@ const AdvancedCalculator = () => {
-
+
{showSettings ? (
Settings
-
+
Dark Mode
@@ -2145,7 +2713,7 @@ const AdvancedCalculator = () => {
{darkMode ? "On" : "Off"}
-
+
Decimal Precision
{
min="0"
max="10"
value={settings.precision}
- onChange={(e) => setSettings({...settings, precision: parseInt(e.target.value)})}
+ onChange={(e) =>
+ setSettings({
+ ...settings,
+ precision: parseInt(e.target.value),
+ })
+ }
/>
-
+
Angle Unit
setSettings({...settings, angleUnit: e.target.value})}
+ onChange={(e) =>
+ setSettings({ ...settings, angleUnit: e.target.value })
+ }
>
Degrees
Radians
-
+
Number Format
setSettings({...settings, notationFormat: e.target.value})}
+ onChange={(e) =>
+ setSettings({ ...settings, notationFormat: e.target.value })
+ }
>
Auto
Scientific
Fixed Decimal
-
+
Graph Theme
setSettings({...settings, graphTheme: e.target.value})}
+ onChange={(e) =>
+ setSettings({ ...settings, graphTheme: e.target.value })
+ }
>
Default
Dark
@@ -2193,7 +2772,7 @@ const AdvancedCalculator = () => {
-
+
setShowSettings(false)}
@@ -2205,63 +2784,56 @@ const AdvancedCalculator = () => {
<>
setActiveTab('basic')}
+ className={`tab ${activeTab === "basic" ? "active" : ""}`}
+ onClick={() => setActiveTab("basic")}
>
Basic
setActiveTab('graphing')}
+ className={`tab ${activeTab === "graphing" ? "active" : ""}`}
+ onClick={() => setActiveTab("graphing")}
>
Graphing
setActiveTab('units')}
+ className={`tab ${activeTab === "units" ? "active" : ""}`}
+ onClick={() => setActiveTab("units")}
>
Unit Converter
setActiveTab('matrix')}
+ className={`tab ${activeTab === "matrix" ? "active" : ""}`}
+ onClick={() => setActiveTab("matrix")}
>
Matrix
setActiveTab('statistics')}
+ className={`tab ${activeTab === "statistics" ? "active" : ""}`}
+ onClick={() => setActiveTab("statistics")}
>
Statistics
setActiveTab('physics')}
+ className={`tab ${activeTab === "physics" ? "active" : ""}`}
+ onClick={() => setActiveTab("physics")}
>
Physics
setActiveTab('simulation')}
+ className={`tab ${activeTab === "simulation" ? "active" : ""}`}
+ onClick={() => setActiveTab("simulation")}
>
Simulations
- setActiveTab('spreadsheet')}
- >
- Spreadsheet
-
-
- {activeTab === 'basic' && renderBasicCalculator()}
- {activeTab === 'graphing' && renderGraphingCalculator()}
- {activeTab === 'units' && renderUnitConversion()}
- {activeTab === 'matrix' && renderMatrixCalculator()}
- {activeTab === 'statistics' && renderStatisticsCalculator()}
- {activeTab === 'physics' && renderPhysicsCalculator()}
- {activeTab === 'simulation' && renderPhysicsSimulation()}
- {activeTab === 'spreadsheet' && renderSpreadsheet()}
+
+ {activeTab === "basic" && renderBasicCalculator()}
+ {activeTab === "graphing" && renderGraphingCalculator()}
+ {activeTab === "units" && renderUnitConversion()}
+ {activeTab === "matrix" && renderMatrixCalculator()}
+ {activeTab === "statistics" && renderStatisticsCalculator()}
+ {activeTab === "physics" && renderPhysicsCalculator()}
+ {activeTab === "simulation" && renderPhysicsSimulation()}
>
)}