logo

📈 equation_painter

Open Source Flutter Package by junayedahamed

A powerful, interactive, and performant Flutter package for visualizing multiple mathematical equations simultaneously with beautiful animations and a fully customizable coordinate system.


Language Switch / āĻ­āĻžāώāĻž āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

English | āĻŦāĻžāĻ‚āϞāĻž


đŸ‡Ŧ🇧 English Documentation (Click to Expand/Collapse)
Preview

✨ Features

  • ✅ New: Interactive Panning & Zooming: Drag to pan and pinch to zoom around the coordinate system!
  • ✅ New: Polar Coordinate Support: Visualize equations in polar form r = f(theta).
  • ✅ New: Inequality Visualization: Shading for regions like y >= x or x^2 + y^2 <= 25.
  • ✅ New: Tap & Hover to Inspect: Tap or hover on any curve to see the exact (x, y) or (r, theta) coordinates.
  • ✅ Robust Equation Parsing: Type equations like x^2 + y^2 - 100, sin(2x) - y, pow(x,2) * atan2(y,x) directly. It supports implicit multiplication (2x), constants (pi, e), unit +/- and ~20 built-in math functions.
  • ✅ Coordinate Labels: Show dynamic numbers along the axis to measure your functions.
  • ✅ Customizable Unit Scale: By default, each grid square represents 100 units, but you can adjust this to your specific needs.
  • ✅ Configurable Units: Define how many units each grid square represents.
  • ✅ Dynamic Animations: Beautiful radial, sequential, linearX, or linearY draw mechanics.
  • ✅ High Performance: Highly optimized utilizing Float32List, drawRawPoints and Marching Squares evaluation to preserve silky smooth 60fps framerates.

📸 Screenshots

Multiple Curves with Custom Styles and Complex Functions

Sin wave with radial animation

Heart curve

Cos wave with value inspection

Inequality Visualization

🚀 Getting Started

Add the package to your pubspec.yaml:

dependencies:
  equation_painter: ^0.0.1+2

💡 Usage

EquationPainter(
  equations: [
    EquationConfig(
      function: (x, y) => x * x + y * y - 25,
      color: Colors.indigoAccent,
      strokeWidth: 4,
    ),
  ],
  unitsPerSquare: 10,
  interactive: true,
  showGrid: true,
  onPointTapped: (x, y, config) {
    print("Tapped at ($x, $y)");
  },
)

🧮 Enhanced Equation Parsing

You can parse string-based equations directly using EquationParser. It's highly tolerant!

Supported Syntax

  • Variables: x, y
  • Constants: pi ($\pi$), e ($e$)
  • Operators: +, -, *, /, ^ (power)
  • Implicit Multiplication: 2x, 3(x+y), x(y-1)
  • Functions:
    • Trigonometric: sin, cos, tan, asin, acos, atan, atan2(y, x)
    • Logarithmic & Exponential: log/ln (natural), log2, log10, exp
    • Rounding & Absolute: abs, ceil, floor, round, sign
    • Miscellaneous: sqrt, cbrt (cube root), hypot(a, b), pow(base, exp), min(a, b), max(a, b)
final userEquation = "tan(20x) - tan(15y) + sin(xy) - 10";
final mathFunction = EquationParser.parseOrNull(userEquation); // Returns null if invalid 

if (mathFunction != null) {
  EquationConfig(
    function: mathFunction,
    color: Colors.pinkAccent,
  )
}

â„ī¸ Advanced Features

  • Customizable Grid Styles: Support for logarithmic scales, dashed lines, and custom colors.
  • Export to Image/SVG: Easily save your visualized equations as high-quality images or SVGs.

🔭 Future Upgrade Ideas

  • 🚀 3D Equation Visualization: Support for plotting $z = f(x, y)$ in a 3D coordinate system.
  • 🚀 Parametric Equation Support: Plot curves defined by equations like $x = f(t), y = g(t)$.
  • 🚀 Live Equation Editor: A built-in UI component to type and preview equations in real-time.
  • 🚀 Data Series Plotting: Ability to plot discrete data points (scatter plots) alongside continuous equations.
  • 🚀 Legend & Tooltips: Add customizable legends and more detailed information tooltips for complex graphs.

⭐

If you Like this project, please give it a ⭐ on GitHub and share it with your friends! It really helps me out and motivates me to keep improving it. Thank you for your support! 🙏

🔭 Licensing

This project is licensed under the MIT License.

đŸ‡Ŧ🇧 Bangla Documentation (Click to Expand/Collapse)

āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝāϏāĻŽā§‚āĻš

  • ✅ āύāϤ⧁āύ: āχāĻ¨ā§āϟāĻžāϰ⧇āĻ•ā§āϟāĻŋāĻ­ āĻĒā§āϝāĻžāύāĻŋāĻ‚ āĻ“ āϜ⧁āĻŽāĻŋāĻ‚: āφāĻĒāύāĻŋ āĻāĻ–āύ āĻ—ā§āϰāĻžāĻĢ⧇ āĻĄā§āĻ°ā§āϝāĻžāĻ— āĻ•āϰ⧇ āĻĒā§āϝāĻžāύ āĻāĻŦāĻ‚ āĻĒāĻŋāĻžā§āϚ-āϟ⧁-āϜ⧁āĻŽ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ!
  • ✅ āύāϤ⧁āύ: āĻĒā§‹āϞāĻžāϰ āϕ⧋āĻ…āĻ°ā§āĻĄāĻŋāύ⧇āϟ āϏāĻžāĻĒā§‹āĻ°ā§āϟ: $r = f(theta)$ āĻĢāĻ°ā§āĻŽā§‡ āϏāĻŽā§€āĻ•āϰāĻŖ āĻ•āĻ˛ā§āĻĒāύāĻž āĻ•āϰāĻžāϰ āϏ⧁āĻŦāĻŋāϧāĻžāĨ¤
  • ✅ āύāϤ⧁āύ: āχāύāχāϕ⧁āϝāĻŧāĻžāϞāĻŋāϟāĻŋ āĻ­āĻŋāĻœā§āϝ⧁āϝāĻŧāĻžāϞāĻžāχāĻœā§‡āĻļāύ: $y \ge x$ āĻŦāĻž $x^2 + y^2 \le 25$ āĻāϰ āĻŽāϤ⧋ āĻ…āϏāĻŽāϤāĻž āĻļ⧇āĻĄāĻŋāĻ‚ā§Ÿā§‡āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āĻĒā§āϰāĻĻāĻ°ā§āĻļāύāĨ¤
  • ✅ āύāϤ⧁āύ: āĻŸā§āϝāĻžāĻĒ āĻ“ āĻšā§‹āĻ­āĻžāϰ āχāĻ¨ā§āϏāĻĒ⧇āĻ•āĻļāύ: āĻ•āĻžāĻ°ā§āϭ⧇āϰ āϝ⧇āϕ⧋āύ⧋ āĻ¸ā§āĻĨāĻžāύ⧇ āĻŸā§āϝāĻžāĻĒ āĻŦāĻž āĻšā§‹āĻ­āĻžāϰ āĻ•āϰ⧇ āϤāĻžā§ŽāĻ•ā§āώāĻŖāĻŋāĻ•āĻ­āĻžāĻŦ⧇ $(x, y)$ āĻŦāĻž $(r, theta)$ āĻ¸ā§āĻĨāĻžāύāĻžāĻ™ā§āĻ• āĻĻ⧇āĻ–āĻžāĨ¤
  • ✅ āĻļāĻ•ā§āϤāĻŋāĻļāĻžāϞ⧀ āχāϕ⧁āϝāĻŧ⧇āĻļāύ āĻĒāĻžāĻ°ā§āϏāĻžāϰ: āφāĻĒāύāĻŋ āĻāĻ–āύ āϏāϰāĻžāϏāϰāĻŋ x^2 + y^2 - 100, sin(2x) - y āĻāϰ āĻŽāϤ⧋ āϏāĻŽā§€āĻ•āϰāĻŖ āϟāĻžāχāĻĒ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻāϟāĻŋ ➇āĻŽāĻĒā§āϞāĻŋāϏāĻŋāϟ āϗ⧁āĻŖ (2x), āĻ§ā§āϰ⧁āĻŦāĻ• (pi, e), āĻāĻŦāĻ‚ ⧍ā§ĻāϟāĻŋāϰāĻ“ āĻŦ⧇āĻļāĻŋ āĻŦāĻŋāĻ˛ā§āϟ-āχāύ āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻĢāĻžāĻ‚āĻļāύ āϏāĻžāĻĒā§‹āĻ°ā§āϟ āĻ•āϰ⧇āĨ¤
  • ✅ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāχāϜāϝ⧋āĻ—ā§āϝ āχāωāύāĻŋāϟ āĻ¸ā§āϕ⧇āϞ: āĻĄāĻŋāĻĢāĻ˛ā§āϟāĻ­āĻžāĻŦ⧇ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻ—ā§āϰāĻŋāĻĄ āĻ¸ā§āĻ•āϝāĻŧāĻžāϰ ā§§ā§Ļā§Ļ āχāωāύāĻŋāϟ āĻĒā§āϰāϤāĻŋāύāĻŋāϧāĻŋāĻ¤ā§āĻŦ āĻ•āϰ⧇, āϤāĻŦ⧇ āφāĻĒāύāĻŋ āφāĻĒāύāĻžāϰ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻ…āύ⧁āϝāĻžāϝāĻŧā§€ āĻāϟāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύāĨ¤
  • ✅ āĻ¸ā§āĻĨāĻžāύāĻžāĻ™ā§āĻ• āϞ⧇āĻŦ⧇āϞ: āĻĢāĻžāĻ‚āĻļāύ āĻĒāϰāĻŋāĻŽāĻžāĻĒ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻĄāĻžāχāύāĻžāĻŽāĻŋāĻ• āĻ…āĻ•ā§āώ⧇āĻĒ⧇ āϏāĻ‚āĻ–ā§āϝāĻž āĻĒā§āϰāĻĻāĻ°ā§āĻļāύāĨ¤
  • ✅ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāχāϜāϝ⧋āĻ—ā§āϝ āĻ—ā§āϰāĻŋāĻĄ: āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻ—ā§āϰāĻŋāĻĄ āĻ¸ā§āĻ•āϝāĻŧāĻžāϰ āĻ•āϤāϟ⧁āϕ⧁ āχāωāύāĻŋāĻŸā§‡āϰ āĻĒā§āϰāϤāĻŋāύāĻŋāϧāĻŋāĻ¤ā§āĻŦ āĻ•āϰāĻŦ⧇ āϤāĻž āφāĻĒāύāĻŋ āύāĻŋāĻœā§‡āχ āĻ āĻŋāĻ• āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύāĨ¤
  • ✅ āĻĄāĻžā§ŸāύāĻžāĻŽāĻŋāĻ• āĻ…ā§āϝāĻžāύāĻŋāĻŽā§‡āĻļāύ: radial, sequential, linearX, āĻ…āĻĨāĻŦāĻž linearY āĻ¸ā§āϟāĻžāχāϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻ•āĻžāĻ°ā§āĻ­ āφāρāĻ•āĻžāϰ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻ…ā§āϝāĻžāύāĻŋāĻŽā§‡āϟ āĻ•āϰāĻžāĨ¤
  • ✅ āωāĻšā§āϚ āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāĻ¨ā§āϏ: āĻŽāϏ⧃āĻŖ ā§Ŧā§Ļ FPS āĻĢā§āϰ⧇āĻŽ āϰ⧇āĻŸā§‡āϰ āϜāĻ¨ā§āϝ Float32List, drawRawPoints āĻāĻŦāĻ‚ Marching Squares āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻ…āĻĒā§āϟāĻŋāĻŽāĻžāχāϜ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇āĨ¤

🚀 āĻļ⧁āϰ⧁ āĻ•āϰāĻž āϝāĻžāĻ•

āφāĻĒāύāĻžāϰ pubspec.yaml-āĻ āĻĒā§āϝāĻžāϕ⧇āϜāϟāĻŋ āϝ⧋āĻ— āĻ•āϰ⧁āύ:

dependencies:
  equation_painter: ^0.0.1+2

💡 āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻĒāĻĻā§āϧāϤāĻŋ

import 'package:equation_painter/equation_painter.dart';

// ... āφāĻĒāύāĻžāϰ āωāχāĻœā§‡āϟ āĻŸā§āϰāĻŋāϰ āϭ⧇āϤāϰ⧇
EquationPainterWidget(
  width: double.infinity,
  height: 400,
  interactive: true, // āχāĻ¨ā§āϟāĻžāϰ⧇āĻ•ā§āϟāĻŋāĻ­ āĻĒā§āϝāĻžāύāĻŋāĻ‚ āϚāĻžāϞ⧁
  unitsPerSquare: 50.0,
  alignment: Alignment.center,
  equations: [
    EquationConfig(
      function: EquationParser.parse('x^2 + y^2 - 2500'),
      color: Colors.cyanAccent,
      strokeWidth: 3,
      animationType: AnimationType.radial,
    ),
  ],
)

🧮 āωāĻ¨ā§āύāϤ āϏāĻŽā§€āĻ•āϰāĻŖ āĻĒāĻžāĻ°ā§āϏāĻžāϰ

āφāĻĒāύāĻŋ āϏāϰāĻžāϏāϰāĻŋ EquationParser āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚-āĻ­āĻŋāĻ¤ā§āϤāĻŋāĻ• āϏāĻŽā§€āĻ•āϰāĻŖ āĻĒāĻžāĻ°ā§āϏ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻāϟāĻŋ āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āύāĻŽāύ⧀āϝāĻŧ!

āϏāĻŽāĻ°ā§āĻĨāĻŋāϤ āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ

  • āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ/āϚāϞāĻ•: x, y
  • āĻ§ā§āϰ⧁āĻŦāĻ•: pi ($\pi$), e ($e$)
  • āĻ…āĻĒāĻžāϰ⧇āϟāϰ: +, -, *, /, ^ (power)
  • āωāĻšā§āϝ āϗ⧁āĻŖ (Implicit Multiplication): 2x, 3(x+y), x(y-1)
  • āĻĢāĻžāĻ‚āĻļāύāϏāĻŽā§‚āĻš:
    • āĻ¤ā§āϰāĻŋāϕ⧋āĻŖāĻŽāĻŋāϤāĻŋāĻ•: sin, cos, tan, asin, acos, atan, atan2(y, x)
    • āϞāĻ—āĻžāϰāĻŋāĻĻāĻŽāĻŋāĻ• āĻāĻŦāĻ‚ āĻāĻ•ā§āϏāĻĒā§‹āύ⧇āύāĻļāĻŋāϝāĻŧāĻžāϞ: log/ln (natural), log2, log10, exp
    • āϰāĻžāωāĻ¨ā§āĻĄāĻŋāĻ‚ āĻāĻŦāĻ‚ āĻāĻŦāϏāϞāĻŋāωāϟ: abs, ceil, floor, round, sign
    • āĻŦāĻŋāĻŦāĻŋāϧ: sqrt, cbrt (cube root), hypot(a, b), pow(base, exp), min(a, b), max(a, b)

🔭 āĻ­āĻŦāĻŋāĻˇā§āϝāϤ⧇āϰ āφāĻĒāĻ—ā§āϰ⧇āĻĄ āφāχāĻĄāĻŋāϝāĻŧāĻž

  • 🚀 āĻĨā§āϰāĻŋ-āĻĄāĻŋ (3D) āχāϕ⧁āϝāĻŧ⧇āĻļāύ āĻ­āĻŋāωāϝāĻŧāĻžāϞāĻžāχāĻœā§‡āĻļāύ: $z = f(x, y)$ āĻāϰ āĻŽāϤ⧋ āĻ¤ā§āϰāĻŋāĻŽāĻžāĻ¤ā§āϰāĻŋāĻ• āϏāĻŽā§€āĻ•āϰāĻŖ āĻ—ā§āϰāĻžāĻĢ⧇ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰāĨ¤
  • 🚀 āĻĒā§āϝāĻžāϰāĻžāĻŽā§‡āĻŸā§āϰāĻŋāĻ• āχāϕ⧁āϝāĻŧ⧇āĻļāύ āϏāĻžāĻĒā§‹āĻ°ā§āϟ: $x = f(t), y = g(t)$ āϟāĻžāχāĻĒ⧇āϰ āĻ•āĻžāĻ°ā§āĻ­ āĻŦāĻž āĻŦāĻ•ā§āϰāϰ⧇āĻ–āĻž āφāρāĻ•āĻžāϰ āϏ⧁āĻŦāĻŋāϧāĻžāĨ¤
  • 🚀 āϞāĻžāχāĻ­ āχāϕ⧁āϝāĻŧ⧇āĻļāύ āĻāĻĄāĻŋāϟāϰ: āϏāϰāĻžāϏāϰāĻŋ āχāωāϜāĻžāϰ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ⧇ āϟāĻžāχāĻĒ āĻ•āϰāĻžāϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ āĻ—ā§āϰāĻžāĻĢ āĻĒā§āϰāĻŋāĻ­āĻŋāω āĻ•āϰāĻžāϰ āϏ⧁āĻŦāĻŋāϧāĻžāĨ¤
  • 🚀 āĻĄā§‡āϟāĻž āϏāĻŋāϰāĻŋāϜ āĻĒā§āϞāϟāĻŋāĻ‚: āύāĻŋāϰāĻŦāĻšā§āĻ›āĻŋāĻ¨ā§āύ āϏāĻŽā§€āĻ•āϰāϪ⧇āϰ āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āĻĄāĻŋāϏāĻ•ā§āϰāĻŋāϟ āĻĄā§‡āϟāĻž āĻĒāϝāĻŧ⧇āĻ¨ā§āϟ āĻŦāĻž āĻ¸ā§āĻ•ā§āϝāĻžāϟāĻžāϰ āĻĒā§āϞāϟ āĻ•āϰāĻžāϰ āĻ•ā§āώāĻŽāϤāĻžāĨ¤
  • 🚀 āϞ⧇āĻœā§‡āĻ¨ā§āĻĄ āĻāĻŦāĻ‚ āϟ⧁āϞāϟāĻŋāĻĒāϏ: āϜāϟāĻŋāϞ āĻ—ā§āϰāĻžāĻĢ⧇āϰ āϜāĻ¨ā§āϝ āĻ•āĻžāĻ¸ā§āϟāĻŽ āϞ⧇āĻœā§‡āĻ¨ā§āĻĄ āĻāĻŦāĻ‚ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āϤāĻĨā§āϝ⧇āϰ āϟ⧁āϞāϟāĻŋāĻĒ āϝ⧋āĻ— āĻ•āϰāĻžāĨ¤

⭐

āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻāχ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒāϟāĻŋ āĻĒāĻ›āĻ¨ā§āĻĻ āĻ•āϰ⧇āύ, āϤāĻžāĻšāϞ⧇ āĻĻāϝāĻŧāĻž āĻ•āϰ⧇ GitHub-āĻ āĻāĻ•āϟāĻŋ ⭐ āĻĻāĻŋāύ āĻāĻŦāĻ‚ āφāĻĒāύāĻžāϰ āĻŦāĻ¨ā§āϧ⧁āĻĻ⧇āϰ āϏāĻžāĻĨ⧇ āĻļ⧇āϝāĻŧāĻžāϰ āĻ•āϰ⧁āύ! āĻāϟāĻŋ āφāĻŽāĻžāϕ⧇ āϏāĻ¤ā§āϝāĻŋāχ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰ⧇ āĻāĻŦāĻ‚ āφāĻŽāĻžāϕ⧇ āωāĻ¨ā§āύāϤ āĻ•āϰāϤ⧇ āĻ‰ā§ŽāϏāĻžāĻšāĻŋāϤ āĻ•āϰ⧇āĨ¤ āφāĻĒāύāĻžāϰ āϏāĻŽāĻ°ā§āĻĨāύ⧇āϰ āϜāĻ¨ā§āϝ āϧāĻ¨ā§āϝāĻŦāĻžāĻĻ! 🙏

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🤝 Contributing

Contributions are welcome! Feel free to open issues or submit pull requests.


Crafted with â¤ī¸ for Mathematicians and Developers.

Libraries

equation_painter