tp_charts 1.0.0 copy "tp_charts: ^1.0.0" to clipboard
tp_charts: ^1.0.0 copied to clipboard

A beautiful animated line chart widget for Flutter with customizable styling, smooth animations, and interactive hover effects.

example/lib/main.dart

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'TP Charts Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: const ExampleHomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[50],
      appBar: AppBar(
        title: const Text('TP Charts Examples'),
        backgroundColor: Colors.blue,
        foregroundColor: Colors.white,
        elevation: 0,
      ),
      body: Padding(
        padding: const EdgeInsets.all(24.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              'TP Charts Examples',
              style: TextStyle(
                fontSize: 28,
                fontWeight: FontWeight.bold,
                color: Colors.black87,
              ),
            ),
            const SizedBox(height: 8),
            Text(
              'Choose an example to see different chart features',
              style: TextStyle(fontSize: 16, color: Colors.grey[600]),
            ),
            const SizedBox(height: 32),

            // Example Cards
            Expanded(
              child: ListView(
                children: [
                  _buildExampleCard(
                    context,
                    'Basic Chart with Manual Filters',
                    'Chart using string labels with manual filter buttons',
                    Icons.show_chart,
                    Colors.blue,
                    () => Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => const BasicChartExample(),
                      ),
                    ),
                  ),
                  const SizedBox(height: 16),
                  _buildExampleCard(
                    context,
                    'DateTime Chart with Auto Filters',
                    'Chart using DateTime data with automatic period filtering',
                    Icons.date_range,
                    Colors.green,
                    () => Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => const DateTimeChartExample(),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildExampleCard(
    BuildContext context,
    String title,
    String description,
    IconData icon,
    Color color,
    VoidCallback onTap,
  ) {
    return Card(
      elevation: 2,
      child: InkWell(
        onTap: onTap,
        borderRadius: BorderRadius.circular(8),
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Row(
            children: [
              Container(
                padding: const EdgeInsets.all(12),
                decoration: BoxDecoration(
                  color: color.withOpacity(0.1),
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Icon(icon, color: color, size: 24),
              ),
              const SizedBox(width: 16),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(
                      title,
                      style: const TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 4),
                    Text(
                      description,
                      style: TextStyle(fontSize: 14, color: Colors.grey[600]),
                    ),
                  ],
                ),
              ),
              Icon(Icons.arrow_forward_ios, color: Colors.grey[400], size: 16),
            ],
          ),
        ),
      ),
    );
  }
}

// Basic Chart Example (legacy mode)
class BasicChartExample extends StatefulWidget {
  const BasicChartExample({super.key});

  @override
  State<BasicChartExample> createState() => _BasicChartExampleState();
}

enum BasicFilterType { today, thisWeek, thisMonth }

class _BasicChartExampleState extends State<BasicChartExample> {
  BasicFilterType _selectedFilter = BasicFilterType.thisWeek;

  // Sample data for different time periods
  final Map<BasicFilterType, Map<String, dynamic>> _sampleData = {
    BasicFilterType.today: {
      'xValues': ['00:00', '06:00', '12:00', '18:00'],
      'yValues': [120.0, 350.0, 680.0, 520.0],
    },
    BasicFilterType.thisWeek: {
      'xValues': ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
      'yValues': [2400.0, 2100.0, 2800.0, 3200.0, 3800.0, 2900.0, 2200.0],
    },
    BasicFilterType.thisMonth: {
      'xValues': ['W1', 'W2', 'W3', 'W4'],
      'yValues': [8400.0, 9200.0, 7800.0, 10500.0],
    },
  };

  void _selectFilter(BasicFilterType filter) {
    if (_selectedFilter != filter) {
      setState(() {
        _selectedFilter = filter;
      });
    }
  }

  String _getFilterLabel(BasicFilterType filter) {
    switch (filter) {
      case BasicFilterType.today:
        return 'Today';
      case BasicFilterType.thisWeek:
        return 'This Week';
      case BasicFilterType.thisMonth:
        return 'This Month';
    }
  }

  @override
  Widget build(BuildContext context) {
    final currentData = _sampleData[_selectedFilter]!;

    return Scaffold(
      backgroundColor: Colors.grey[50],
      appBar: AppBar(
        title: const Text('Basic Chart Example'),
        backgroundColor: Colors.blue,
        foregroundColor: Colors.white,
        elevation: 0,
      ),
      body: Padding(
        padding: const EdgeInsets.all(24.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              'Sales Analytics',
              style: TextStyle(
                fontSize: 28,
                fontWeight: FontWeight.bold,
                color: Colors.black87,
              ),
            ),
            const SizedBox(height: 8),
            Text(
              'Track your performance over time',
              style: TextStyle(fontSize: 16, color: Colors.grey[600]),
            ),
            const SizedBox(height: 32),

            // Filter Buttons
            Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: BasicFilterType.values.map((filter) {
                final isSelected = _selectedFilter == filter;
                return Padding(
                  padding: const EdgeInsets.only(left: 8.0),
                  child: GestureDetector(
                    onTap: () => _selectFilter(filter),
                    child: AnimatedContainer(
                      duration: const Duration(milliseconds: 200),
                      padding: const EdgeInsets.symmetric(
                        horizontal: 16,
                        vertical: 8,
                      ),
                      decoration: BoxDecoration(
                        color: isSelected ? Colors.blue : Colors.grey[100],
                        borderRadius: BorderRadius.circular(16),
                      ),
                      child: Text(
                        _getFilterLabel(filter),
                        style: TextStyle(
                          color: isSelected ? Colors.white : Colors.grey[700],
                          fontWeight: isSelected
                              ? FontWeight.bold
                              : FontWeight.normal,
                        ),
                      ),
                    ),
                  ),
                );
              }).toList(),
            ),

            const SizedBox(height: 24),

            // Chart
            Expanded(
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(16),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withOpacity(0.05),
                      blurRadius: 10,
                      offset: const Offset(0, 2),
                    ),
                  ],
                ),
                padding: const EdgeInsets.all(24),
                child: CustomLineChart(
                  key: ValueKey(_selectedFilter),
                  xValues: List<String>.from(currentData['xValues']),
                  yValues: List<double>.from(currentData['yValues']),
                  color: Colors.blue,
                  pointBorderColor: Colors.blue,
                  pointCenterColor: Colors.white,
                  lineWidth: 3,
                  animationDuration: const Duration(milliseconds: 1200),
                  showFilterButtons: false, // Manual filter buttons above
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// DateTime Chart Example with automatic filtering
class DateTimeChartExample extends StatefulWidget {
  const DateTimeChartExample({super.key});

  @override
  State<DateTimeChartExample> createState() => _DateTimeChartExampleState();
}

class _DateTimeChartExampleState extends State<DateTimeChartExample> {
  FilterType selectedFilter = FilterType.allPeriod;

  List<DateTime> _generateSampleDates() {
    final now = DateTime.now();
    final List<DateTime> dates = [];

    // Gerar dados dos últimos 6 meses com dados semanais
    for (int i = 180; i >= 0; i -= 7) {
      dates.add(now.subtract(Duration(days: i)));
    }

    // Adicionar alguns dados desta semana
    for (int i = 6; i >= 0; i--) {
      dates.add(now.subtract(Duration(days: i)));
    }

    // Adicionar dados de hoje (por horas)
    for (int hour = 0; hour <= now.hour; hour += 2) {
      dates.add(DateTime(now.year, now.month, now.day, hour));
    }

    return dates;
  }

  List<double> _generateSampleValues(List<DateTime> dates) {
    return dates.map((date) {
      final daysSinceEpoch =
          date.millisecondsSinceEpoch / (1000 * 60 * 60 * 24);
      final base = daysSinceEpoch * 0.1;
      final variation = (daysSinceEpoch % 7) * 50;
      return (base + variation + 1000).clamp(500.0, 5000.0).toDouble();
    }).toList();
  }

  @override
  Widget build(BuildContext context) {
    final dates = _generateSampleDates();
    final values = _generateSampleValues(dates);

    return Scaffold(
      appBar: AppBar(
        title: const Text('DateTime Chart Example'),
        backgroundColor: Colors.green,
        foregroundColor: Colors.white,
        elevation: 0,
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              'Gráfico com Filtros Automáticos por Data',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            const Text(
              'Este gráfico recebe datas e valores, e automaticamente oferece filtros baseados nos dados disponíveis.',
              style: TextStyle(color: Colors.grey),
            ),
            const SizedBox(height: 24),

            // Botões de filtro
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ChartFilterButton(
                  label: 'Hoje',
                  selected: selectedFilter == FilterType.today,
                  onTap: () {
                    setState(() {
                      selectedFilter = FilterType.today;
                    });
                  },
                ),
                ChartFilterButton(
                  label: 'Esta Semana',
                  selected: selectedFilter == FilterType.thisWeek,
                  onTap: () {
                    setState(() {
                      selectedFilter = FilterType.thisWeek;
                    });
                  },
                ),
                ChartFilterButton(
                  label: 'Este Ano',
                  selected: selectedFilter == FilterType.thisYear,
                  onTap: () {
                    setState(() {
                      selectedFilter = FilterType.thisYear;
                    });
                  },
                ),
                ChartFilterButton(
                  label: 'Todos',
                  selected: selectedFilter == FilterType.allPeriod,
                  onTap: () {
                    setState(() {
                      selectedFilter = FilterType.allPeriod;
                    });
                  },
                ),
              ],
            ),

            const SizedBox(height: 20),

            Expanded(
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(16),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withOpacity(0.05),
                      blurRadius: 10,
                      offset: const Offset(0, 2),
                    ),
                  ],
                ),
                padding: const EdgeInsets.all(24),
                child: CustomLineChart(
                  dates: dates,
                  yValues: values,
                  color: Colors.green,
                  selectedFilter: selectedFilter,
                  onFilterChanged: (filter) {
                    setState(() {
                      selectedFilter = filter;
                    });
                  },
                ),
              ),
            ),

            const SizedBox(height: 16),
            const Text(
              'Filtros disponíveis:',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
            const Text(
              '• Hoje: Dados de hoje (por hora)\n'
              '• Esta Semana: Dados dos últimos 7 dias\n'
              '• Este Ano: Dados do ano atual\n'
              '• Todo o Período: Todos os dados disponíveis',
              style: TextStyle(color: Colors.grey),
            ),
          ],
        ),
      ),
    );
  }
}
0
likes
0
points
21
downloads

Documentation

Documentation

Publisher

unverified uploader

Weekly Downloads

A beautiful animated line chart widget for Flutter with customizable styling, smooth animations, and interactive hover effects.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, intl

More

Packages that depend on tp_charts