jyotish 1.0.1 copy "jyotish: ^1.0.1" to clipboard
jyotish: ^1.0.1 copied to clipboard

A production-ready Flutter library for Vedic astrology (Jyotish) calculations using Swiss Ephemeris. Provides high-precision sidereal planetary positions with Lahiri ayanamsa, nakshatras, and complete [...]

example/lib/main.dart

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

void main() {
  runApp(const MyApp());
}

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

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

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

  @override
  State<PlanetaryPositionsScreen> createState() =>
      _PlanetaryPositionsScreenState();
}

class _PlanetaryPositionsScreenState extends State<PlanetaryPositionsScreen> {
  final Jyotish _jyotish = Jyotish();
  Map<Planet, PlanetPosition>? _positions;
  bool _isLoading = false;
  String? _error;
  bool _useSidereal = false;

  // Default location: Kathmandu, Nepal
  GeographicLocation _location = GeographicLocation(
    latitude: 27.7172,
    longitude: 85.3240,
    altitude: 1400,
  );

  DateTime _selectedDateTime = DateTime.now();

  @override
  void initState() {
    super.initState();
    _initializeAndCalculate();
  }

  Future<void> _initializeAndCalculate() async {
    setState(() {
      _isLoading = true;
      _error = null;
    });

    try {
      await _jyotish.initialize();
      await _calculatePositions();
    } catch (e) {
      setState(() {
        _error = e.toString();
      });
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  Future<void> _calculatePositions() async {
    try {
      final flags = _useSidereal
          ? CalculationFlags.siderealLahiri()
          : CalculationFlags.defaultFlags();

      final positions = await _jyotish.getAllPlanetPositions(
        dateTime: _selectedDateTime,
        location: _location,
        flags: flags,
      );

      setState(() {
        _positions = positions;
        _error = null;
      });
    } catch (e) {
      setState(() {
        _error = e.toString();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Jyotish - Planetary Positions'),
      ),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : _error != null
              ? Center(
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Text(
                      'Error: $_error',
                      style: const TextStyle(color: Colors.red),
                    ),
                  ),
                )
              : SingleChildScrollView(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      _buildControlPanel(),
                      const SizedBox(height: 24),
                      _buildLocationInfo(),
                      const SizedBox(height: 24),
                      _buildPlanetList(),
                    ],
                  ),
                ),
      floatingActionButton: FloatingActionButton(
        onPressed: _isLoading ? null : _calculatePositions,
        tooltip: 'Recalculate',
        child: const Icon(Icons.refresh),
      ),
    );
  }

  Widget _buildControlPanel() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Settings',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 16),
            SwitchListTile(
              title: const Text('Use Sidereal (Lahiri)'),
              subtitle: const Text('Toggle between Tropical and Sidereal'),
              value: _useSidereal,
              onChanged: (value) {
                setState(() {
                  _useSidereal = value;
                });
                _calculatePositions();
              },
            ),
            ListTile(
              title: const Text('Date & Time'),
              subtitle: Text(_selectedDateTime.toString().substring(0, 19)),
              trailing: const Icon(Icons.calendar_today),
              onTap: () async {
                final date = await showDatePicker(
                  context: context,
                  initialDate: _selectedDateTime,
                  firstDate: DateTime(1900),
                  lastDate: DateTime(2100),
                );
                if (date != null) {
                  final time = await showTimePicker(
                    context: context,
                    initialTime: TimeOfDay.fromDateTime(_selectedDateTime),
                  );
                  if (time != null) {
                    setState(() {
                      _selectedDateTime = DateTime(
                        date.year,
                        date.month,
                        date.day,
                        time.hour,
                        time.minute,
                      );
                    });
                    _calculatePositions();
                  }
                }
              },
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildLocationInfo() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Location',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 8),
            Text(_location.toString()),
          ],
        ),
      ),
    );
  }

  Widget _buildPlanetList() {
    if (_positions == null) {
      return const SizedBox.shrink();
    }

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Planetary Positions',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const SizedBox(height: 16),
            ..._positions!.entries.map((entry) {
              return _buildPlanetCard(entry.value);
            }).toList(),
          ],
        ),
      ),
    );
  }

  Widget _buildPlanetCard(PlanetPosition position) {
    return Card(
      elevation: 2,
      margin: const EdgeInsets.only(bottom: 12),
      child: Padding(
        padding: const EdgeInsets.all(12.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  position.planet.displayName,
                  style: const TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                if (position.isRetrograde)
                  Chip(
                    label: const Text('R'),
                    backgroundColor: Colors.orange[100],
                    labelStyle: const TextStyle(
                      fontWeight: FontWeight.bold,
                      color: Colors.orange,
                    ),
                  ),
              ],
            ),
            const SizedBox(height: 8),
            _buildInfoRow('Position', position.formattedPositionDMS),
            _buildInfoRow(
                'Longitude', '${position.longitude.toStringAsFixed(6)}°'),
            _buildInfoRow(
                'Latitude', '${position.latitude.toStringAsFixed(6)}°'),
            _buildInfoRow(
                'Distance', '${position.distance.toStringAsFixed(6)} AU'),
            _buildInfoRow('Nakshatra',
                '${position.nakshatra} (Pada ${position.nakshatraPada})'),
            _buildInfoRow(
                'Speed', '${position.longitudeSpeed.toStringAsFixed(4)}°/day'),
          ],
        ),
      ),
    );
  }

  Widget _buildInfoRow(String label, String value) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(
            label,
            style: const TextStyle(
              fontWeight: FontWeight.w500,
              color: Colors.grey,
            ),
          ),
          Text(
            value,
            style: const TextStyle(fontWeight: FontWeight.w500),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _jyotish.dispose();
    super.dispose();
  }
}
1
likes
130
points
60
downloads

Publisher

unverified uploader

Weekly Downloads

A production-ready Flutter library for Vedic astrology (Jyotish) calculations using Swiss Ephemeris. Provides high-precision sidereal planetary positions with Lahiri ayanamsa, nakshatras, and complete birth chart analysis.

Repository (GitHub)
View/report issues
Contributing

Documentation

API reference

License

MIT (license)

Dependencies

ffi, flutter, intl, path

More

Packages that depend on jyotish

Packages that implement jyotish