hyperliquid_chart_engine 0.1.0 copy "hyperliquid_chart_engine: ^0.1.0" to clipboard
hyperliquid_chart_engine: ^0.1.0 copied to clipboard

Professional financial charting engine for Flutter — TradingView-style charts with 21+ chart types, drawing tools, indicators, and real-time data.

example/lib/main.dart

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

import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Chart Engine Example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        brightness: Brightness.dark,
        scaffoldBackgroundColor: const Color(0xFF1a1c24),
      ),
      home: const ChartExampleScreen(),
    );
  }
}

class ChartExampleScreen extends ConsumerStatefulWidget {
  const ChartExampleScreen({super.key});

  @override
  ConsumerState<ChartExampleScreen> createState() => _ChartExampleScreenState();
}

class _ChartExampleScreenState extends ConsumerState<ChartExampleScreen> {
  ChartType _chartType = ChartType.candles;
  late List<BarPrimitive> _bars;
  bool _showSMA20 = true;
  bool _showSMA50 = true;
  bool _showSMA200 = true;
  bool _showEMA20 = false;
  bool _showEMA50 = false;
  bool _showEMA200 = false;
  bool _showRSI = false;
  bool _showMACD = false;
  bool _showStochastic = false;
  bool _showBollingerBands = false;
  bool _showVolume = true;

  @override
  void initState() {
    super.initState();
    _bars = _generateMockData();
  }

  static List<BarPrimitive> _generateMockData() {
    final bars = <BarPrimitive>[];
    double price = 65000.0;
    int time = DateTime.now()
        .subtract(const Duration(days: 100))
        .millisecondsSinceEpoch;

    for (int i = 0; i < 1500; i++) {
      final open = price;
      final close = open + (DateTime.now().microsecond % 1000) - 500.0;
      final high =
          (open > close ? open : close) + (DateTime.now().microsecond % 500);
      final low =
          (open < close ? open : close) - (DateTime.now().microsecond % 500);
      final volume = 10.0 + (DateTime.now().microsecond % 100);

      bars.add(
        BarPrimitive(
          timestamp: time,
          open: open,
          high: high,
          low: low,
          close: close,
          volume: volume,
        ),
      );

      price = close;
      time += const Duration(minutes: 5).inMilliseconds;
    }
    return bars;
  }

  @override
  Widget build(BuildContext context) {
    final atrState = ref.watch(atr14Provider);
    final showATR = atrState?.visible ?? false;

    return Scaffold(
      appBar: AppBar(
        title: const Text('Hyperliquid Chart Engine'),
        backgroundColor: const Color(0xFF232530),
        actions: [
          DropdownButton<ChartType>(
            value: _chartType,
            dropdownColor: const Color(0xFF232530),
            items: const [
              DropdownMenuItem(value: ChartType.candles, child: Text('Candle')),
              DropdownMenuItem(value: ChartType.bars, child: Text('Bar')),
              DropdownMenuItem(value: ChartType.line, child: Text('Line')),
              DropdownMenuItem(value: ChartType.area, child: Text('Area')),
              DropdownMenuItem(
                value: ChartType.heikinAshi,
                child: Text('Heikin Ashi'),
              ),
              DropdownMenuItem(value: ChartType.renko, child: Text('Renko')),
              DropdownMenuItem(value: ChartType.kagi, child: Text('Kagi')),
              DropdownMenuItem(
                value: ChartType.pointFigure,
                child: Text('Point & Figure'),
              ),
            ],
            onChanged: (val) {
              if (val != null) setState(() => _chartType = val);
            },
          ),
          IconButton(
            icon: const Icon(Icons.show_chart),
            tooltip: 'Draw Trend Line',
            onPressed: () {
              ref.read(activeDrawingToolProvider.notifier).state =
                  DrawingToolType.trendLine;
            },
          ),
          IconButton(
            icon: const Icon(Icons.clear),
            tooltip: 'Clear Drawings',
            onPressed: () {
              ref.read(drawingsProvider.notifier).clearAll();
            },
          ),
          IconButton(
            icon: const Icon(Icons.ads_click),
            tooltip: 'Cursor Mode',
            onPressed: () {
              ref.read(activeDrawingToolProvider.notifier).state =
                  DrawingToolType.crosshair;
            },
          ),
          const SizedBox(width: 16),
        ],
      ),
      body: Row(
        children: [
          Expanded(
            child: Center(
              child: SizedBox(
                width: MediaQuery.of(context).size.width * 0.75,
                height: MediaQuery.of(context).size.height * 0.8,
                child: DecoratedBox(
                  decoration: BoxDecoration(
                    border: Border.all(color: Colors.white24),
                  ),
                  child: ChartWidget(
                    bars: _bars,
                    chartType: _chartType,
                    interval: IntervalType.m5,
                    showSMA20: _showSMA20,
                    showSMA50: _showSMA50,
                    showSMA200: _showSMA200,
                    showEMA20: _showEMA20,
                    showEMA50: _showEMA50,
                    showEMA200: _showEMA200,
                    showRSI: _showRSI,
                    showMACD: _showMACD,
                    macdHeightRatio: 0.3,
                    showStochastic: _showStochastic,
                    stochasticHeightRatio: 0.3,
                    showBollingerBands: _showBollingerBands,
                    showVolume: _showVolume,
                    panels: [
                      if (showATR)
                        const PanelConfig(
                          type: PanelType.atr,
                          heightRatio: 0.3,
                        ),
                    ],
                    onAlertCreated: (alert) {
                      ScaffoldMessenger.of(context).showSnackBar(
                        SnackBar(
                          content: Text('Alert created at ${alert.price}'),
                        ),
                      );
                    },
                    onAlertTriggered: (alert) {
                      ScaffoldMessenger.of(context).showSnackBar(
                        SnackBar(
                          content: Text('Alert triggered at ${alert.price}!'),
                          backgroundColor: Colors.green,
                        ),
                      );
                    },
                  ),
                ),
              ),
            ),
          ),
          const AlertControlPanel(),
        ],
      ),
      bottomNavigationBar: Container(
        color: const Color(0xFF232530),
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
        child: Wrap(
          alignment: WrapAlignment.center,
          crossAxisAlignment: WrapCrossAlignment.center,
          spacing: 16,
          children: [
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showSMA20,
                  onChanged: (val) => setState(() => _showSMA20 = val ?? false),
                ),
                const Text('SMA 20'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showSMA50,
                  onChanged: (val) => setState(() => _showSMA50 = val ?? false),
                ),
                const Text('SMA 50'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showSMA200,
                  onChanged: (val) =>
                      setState(() => _showSMA200 = val ?? false),
                ),
                const Text('SMA 200'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showEMA20,
                  activeColor: const Color(0xFF4CAF50),
                  onChanged: (val) => setState(() => _showEMA20 = val ?? false),
                ),
                const Text('EMA 20'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showEMA50,
                  activeColor: const Color(0xFF9C27B0),
                  onChanged: (val) => setState(() => _showEMA50 = val ?? false),
                ),
                const Text('EMA 50'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showEMA200,
                  activeColor: const Color(0xFF00BCD4),
                  onChanged: (val) =>
                      setState(() => _showEMA200 = val ?? false),
                ),
                const Text('EMA 200'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showRSI,
                  activeColor: Colors.blue,
                  onChanged: (val) => setState(() => _showRSI = val ?? false),
                ),
                const Text('RSI 14'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showMACD,
                  activeColor: Colors.blueAccent,
                  onChanged: (val) => setState(() => _showMACD = val ?? false),
                ),
                const Text('MACD'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showStochastic,
                  activeColor: Colors.deepOrange,
                  onChanged: (val) =>
                      setState(() => _showStochastic = val ?? false),
                ),
                const Text('Stochastic'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: showATR,
                  activeColor: const Color(0xFF9C27B0),
                  onChanged: (val) =>
                      ref.read(atr14Provider.notifier).toggleVisibility(),
                ),
                const Text('ATR'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showBollingerBands,
                  activeColor: const Color(0xFF2196F3),
                  onChanged: (val) =>
                      setState(() => _showBollingerBands = val ?? false),
                ),
                const Text('Bollinger'),
              ],
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Checkbox(
                  value: _showVolume,
                  activeColor: Colors.deepPurple,
                  onChanged: (val) =>
                      setState(() => _showVolume = val ?? false),
                ),
                const Text('Volume'),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class AlertControlPanel extends ConsumerWidget {
  const AlertControlPanel({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final alerts = ref.watch(alertsProvider);

    return Container(
      width: 250,
      color: Colors.grey[900],
      child: Column(
        children: [
          const Padding(
            padding: EdgeInsets.all(16),
            child: Text(
              'Price Alerts\n(Long Press for new)',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 18,
                fontWeight: FontWeight.bold,
                color: Colors.white,
              ),
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: alerts.length,
              itemBuilder: (context, index) {
                final alert = alerts[index];
                return ListTile(
                  title: Text(
                    'Price: ${alert.price.toStringAsFixed(2)}',
                    style: const TextStyle(color: Colors.white),
                  ),
                  subtitle: Text(
                    alert.condition == AlertCondition.crossingUp
                        ? '↑ Up'
                        : '↓ Down',
                    style: TextStyle(
                      color: alert.status == AlertStatus.active
                          ? Colors.blue
                          : Colors.green,
                    ),
                  ),
                  trailing: IconButton(
                    icon: const Icon(Icons.delete, color: Colors.red),
                    onPressed: () {
                      ref.read(alertsProvider.notifier).removeAlert(alert.id);
                    },
                  ),
                );
              },
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(16),
            child: ElevatedButton(
              onPressed: () {
                ref.read(alertsProvider.notifier).clearAll();
              },
              child: const Text('Clear All'),
            ),
          ),
        ],
      ),
    );
  }
}
1
likes
140
points
30
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Professional financial charting engine for Flutter — TradingView-style charts with 21+ chart types, drawing tools, indicators, and real-time data.

Homepage

License

MIT (license)

Dependencies

collection, equatable, flutter, flutter_riverpod, freezed_annotation, http, json_annotation, meta, uuid, web_socket_channel

More

Packages that depend on hyperliquid_chart_engine