Skip to main content

infinite_math_plot 0.1.1 copy "infinite_math_plot: ^0.1.1" to clipboard
infinite_math_plot: ^0.1.1 copied to clipboard

A Flutter package that renders interactive mathematical graphs on a simulated infinite coordinate plane.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:infinite_math_plot/infinite_math_plot.dart';

void main() => runApp(const DemoApp());

class DemoApp extends StatelessWidget {
  const DemoApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'InfiniteMathPlot Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
        useMaterial3: true,
      ),
      home: const DemoHome(),
    );
  }
}

// ---------------------------------------------------------------------------
// Preset definitions
// ---------------------------------------------------------------------------

class _Preset {
  final String label;
  final List<EquationConfig> equations;

  const _Preset({required this.label, required this.equations});
}

final _presets = [
  _Preset(
    label: 'Sine & Cosine',
    equations: [
      const EquationConfig(equation: 'y = sin(x)', color: Colors.blue, strokeWidth: 2),
      const EquationConfig(equation: 'y = cos(x)', color: Colors.orange, strokeWidth: 2),
    ],
  ),
  _Preset(
    label: 'Parabola',
    equations: [
      const EquationConfig(equation: 'y = x^2', color: Colors.green, strokeWidth: 2.5),
    ],
  ),
  _Preset(
    label: 'Tangent (discontinuous)',
    equations: [
      const EquationConfig(equation: 'y = tan(x)', color: Colors.red, strokeWidth: 2),
    ],
  ),
  _Preset(
    label: '1/x (asymptote)',
    equations: [
      const EquationConfig(equation: 'y = 1/x', color: Colors.purple, strokeWidth: 2),
    ],
  ),
  _Preset(
    label: 'Circle (implicit)',
    equations: [
      const EquationConfig(equation: 'x^2 + y^2 = 25', color: Colors.teal, strokeWidth: 2),
    ],
  ),
  _Preset(
    label: 'Lissajous (parametric)',
    equations: [
      const EquationConfig(
        equation: 'x = sin(3*t), y = sin(2*t)',
        color: Colors.deepOrange,
        strokeWidth: 2,
      ),
    ],
  ),
  _Preset(
    label: 'Rose (polar)',
    equations: [
      const EquationConfig(equation: 'r = cos(3*theta)', color: Colors.pink, strokeWidth: 2),
    ],
  ),
  _Preset(
    label: 'Multi-curve',
    equations: [
      const EquationConfig(equation: 'y = x', color: Colors.blue, strokeWidth: 1.5),
      const EquationConfig(equation: 'y = x^2', color: Colors.green, strokeWidth: 1.5),
      const EquationConfig(equation: 'y = x^3', color: Colors.red, strokeWidth: 1.5),
      const EquationConfig(equation: 'y = sin(x)', color: Colors.orange, strokeWidth: 1.5),
      const EquationConfig(equation: 'y = cos(x)', color: Colors.purple, strokeWidth: 1.5),
    ],
  ),
];

// ---------------------------------------------------------------------------
// Home screen
// ---------------------------------------------------------------------------

class DemoHome extends StatefulWidget {
  const DemoHome({super.key});

  @override
  State<DemoHome> createState() => _DemoHomeState();
}

class _DemoHomeState extends State<DemoHome> {
  int _presetIndex = 0;
  bool _showGrid = true;
  bool _showAxes = true;
  bool _enableZoom = true;
  bool _enablePan = true;

  // Custom equation input
  final _controller = TextEditingController(text: 'y = sin(x)');
  String? _customEquation;
  String? _parseError;

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _applyCustom() {
    final input = _controller.text.trim();
    if (input.isEmpty) return;
    try {
      // Validate by parsing
      EquationParser().parse(input);
      setState(() {
        _customEquation = input;
        _parseError = null;
        _presetIndex = -1; // custom mode
      });
    } on ParseException catch (e) {
      setState(() => _parseError = e.message);
    }
  }

  List<EquationConfig> get _activeEquations {
    if (_presetIndex >= 0) return _presets[_presetIndex].equations;
    return [
      EquationConfig(
        equation: _customEquation!,
        color: Colors.indigo,
        strokeWidth: 2.5,
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('InfiniteMathPlot Demo'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: Column(
        children: [
          // ---- Graph ----
          Expanded(
            child: InfiniteMathPlot(
              equations: _activeEquations,
              showGrid: _showGrid,
              showAxes: _showAxes,
              enableZoom: _enableZoom,
              enablePan: _enablePan,
            ),
          ),

          // ---- Controls ----
          Container(
            color: Theme.of(context).colorScheme.surfaceContainerHighest,
            padding: const EdgeInsets.fromLTRB(12, 8, 12, 12),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                // Preset chips
                SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  child: Row(
                    children: [
                      for (var i = 0; i < _presets.length; i++)
                        Padding(
                          padding: const EdgeInsets.only(right: 6),
                          child: ChoiceChip(
                            label: Text(_presets[i].label),
                            selected: _presetIndex == i,
                            onSelected: (_) =>
                                setState(() {
                                  _presetIndex = i;
                                  _customEquation = null;
                                  _parseError = null;
                                }),
                          ),
                        ),
                    ],
                  ),
                ),

                const SizedBox(height: 8),

                // Custom equation input
                Row(
                  children: [
                    Expanded(
                      child: TextField(
                        controller: _controller,
                        decoration: InputDecoration(
                          labelText: 'Custom equation',
                          hintText: 'e.g. y = sin(x) + cos(2*x)',
                          errorText: _parseError,
                          isDense: true,
                          border: const OutlineInputBorder(),
                        ),
                        onSubmitted: (_) => _applyCustom(),
                      ),
                    ),
                    const SizedBox(width: 8),
                    FilledButton(
                      onPressed: _applyCustom,
                      child: const Text('Plot'),
                    ),
                  ],
                ),

                const SizedBox(height: 8),

                // Toggle row
                Wrap(
                  spacing: 4,
                  children: [
                    FilterChip(
                      label: const Text('Grid'),
                      selected: _showGrid,
                      onSelected: (v) => setState(() => _showGrid = v),
                    ),
                    FilterChip(
                      label: const Text('Axes'),
                      selected: _showAxes,
                      onSelected: (v) => setState(() => _showAxes = v),
                    ),
                    FilterChip(
                      label: const Text('Zoom'),
                      selected: _enableZoom,
                      onSelected: (v) => setState(() => _enableZoom = v),
                    ),
                    FilterChip(
                      label: const Text('Pan'),
                      selected: _enablePan,
                      onSelected: (v) => setState(() => _enablePan = v),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
1
likes
130
points
12
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter package that renders interactive mathematical graphs on a simulated infinite coordinate plane.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, math_expressions

More

Packages that depend on infinite_math_plot