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

A Flutter widget to display a GitHub-style heatmap of LeetCode submissions using the LeetCode GraphQL API.

LeetCode Heatmap Widget #

A highly customizable Flutter widget that displays a GitHub-style heatmap for LeetCode submission activity. Perfect for tracking coding progress and displaying achievements in your Flutter apps.

LeetCode Heatmap Preview

Features #

  • GitHub-style heatmap visualization
  • Highly customizable appearance and behavior
  • Responsive design with horizontal scrolling
  • Custom color schemes and gradients
  • Month and day labels (optional)
  • Interactive tooltips with submission counts
  • Statistics display (total submissions, streaks)
  • Smooth animations and transitions
  • Auto-scroll to current period
  • Extensive customization options

Getting Started #

Prerequisites #

  • Flutter SDK
  • LeetCode API integration (you'll need to implement LeetCodeApi and LeetCodeData classes)

Installation #

  1. Add the widget files to your Flutter project:

    lib/
    ├── widgets/
    │   └── leetcode_heatmap.dart
    ├── api/
    │   └── leetcode_api.dart
    └── models/
        └── leetcode_data.dart
    
  2. Import the widget in your Dart file:

    import 'package:your_app/widgets/leetcode_heatmap.dart';
    

📖 Basic Usage #

Simple Implementation #

LeetCodeHeatmap(
  username: 'your-leetcode-username',
)

With Custom Year #

LeetCodeHeatmap(
  username: 'your-leetcode-username',
  year: 2024,
)

🎨 Customization Options #

Cell Styling #

LeetCodeHeatmap(
  username: 'your-username',
  cellSize: 15.0,                    // Size of each cell
  cellSpacing: 2.0,                  // Spacing between cells
  cellBorderRadius: BorderRadius.circular(4), // Cell border radius
  colors: [                          // Custom color scheme
    Color(0xFFEBEDF0),              // No activity
    Color(0xFF9BE9A8),              // Low activity
    Color(0xFF40C463),              // Medium activity
    Color(0xFF30A14E),              // High activity
    Color(0xFF216E39),              // Very high activity
  ],
  futureCellColor: Colors.grey[200]!, // Color for future dates
  showBorder: true,                   // Add borders to cells
  borderColor: Colors.grey[300]!,     // Border color
  borderWidth: 1.0,                   // Border width
)

Text Styling #

LeetCodeHeatmap(
  username: 'your-username',
  statsTextStyle: TextStyle(
    fontSize: 16,
    fontWeight: FontWeight.bold,
    color: Colors.black87,
  ),
  legendTextStyle: TextStyle(
    fontSize: 12,
    color: Colors.grey[600],
  ),
  headerTextStyle: TextStyle(
    fontSize: 14,
    fontWeight: FontWeight.w500,
  ),
  tooltipTextStyle: TextStyle(
    fontSize: 12,
    color: Colors.white,
  ),
)

Layout Options #

LeetCodeHeatmap(
  username: 'your-username',
  padding: EdgeInsets.all(16.0),     // Widget padding
  weekSpacing: 3.0,                  // Spacing between weeks
  showScrollbar: true,               // Show/hide scrollbar
  autoScrollToEnd: true,             // Auto-scroll to current date
  showMonthLabels: true,             // Show month headers
  showDayLabels: true,               // Show day labels (Sun, Mon, etc.)
)

Feature Toggles #

LeetCodeHeatmap(
  username: 'your-username',
  showStats: true,                   // Show statistics
  showLegend: true,                  // Show color legend
  showTooltips: true,                // Show hover tooltips
  showMonthLabels: true,             // Show month labels
  showDayLabels: false,              // Show day-of-week labels
  showBorder: false,                 // Show cell borders
)

Custom Formatters #

LeetCodeHeatmap(
  username: 'your-username',
  tooltipFormatter: (count, date) {
    return 'Solved $count problems on ${date.day}/${date.month}/${date.year}';
  },
  statsFormatter: (totalDays, year) {
    return '$totalDays coding sessions in $year';
  },
  streakFormatter: (streak) {
    return '🔥 $streak day streak!';
  },
)

Animation Settings #

LeetCodeHeatmap(
  username: 'your-username',
  enableAnimation: true,             // Enable fade-in animation
  animationDuration: Duration(milliseconds: 500),
  animationCurve: Curves.easeInOut,
)

Custom Loading & Error States #

LeetCodeHeatmap(
  username: 'your-username',
  loadingWidget: CircularProgressIndicator(
    valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
  ),
  errorWidgetBuilder: (error) {
    return Container(
      padding: EdgeInsets.all(16),
      child: Column(
        children: [
          Icon(Icons.error, color: Colors.red, size: 48),
          SizedBox(height: 8),
          Text('Failed to load data: $error'),
          ElevatedButton(
            onPressed: () => _refreshHeatmap(),
            child: Text('Retry'),
          ),
        ],
      ),
    );
  },
)

🎨 Pre-built Themes #

GitHub Theme #

LeetCodeHeatmap(
  username: 'your-username',
  colors: [
    Color(0xFFEBEDF0),
    Color(0xFF9BE9A8),
    Color(0xFF40C463),
    Color(0xFF30A14E),
    Color(0xFF216E39),
  ],
  cellSize: 12.0,
  cellSpacing: 1.0,
)

Dark Theme #

LeetCodeHeatmap(
  username: 'your-username',
  colors: [
    Color(0xFF161B22),
    Color(0xFF0E4429),
    Color(0xFF006D32),
    Color(0xFF26A641),
    Color(0xFF39D353),
  ],
  backgroundColor: Color(0xFF0D1117),
  cellSize: 12.0,
  cellSpacing: 1.0,
  statsTextStyle: TextStyle(color: Colors.white),
  legendTextStyle: TextStyle(color: Colors.white70),
)

Vibrant Theme #

LeetCodeHeatmap(
  username: 'your-username',
  colors: [
    Colors.grey[100]!,
    Colors.blue[200]!,
    Colors.blue[400]!,
    Colors.blue[600]!,
    Colors.blue[800]!,
  ],
  cellSize: 14.0,
  cellSpacing: 2.0,
  cellBorderRadius: BorderRadius.circular(4),
  showBorder: true,
  borderColor: Colors.blue[100]!,
)

🔧 Required Dependencies #

You'll need to implement these classes for the widget to work:

LeetCodeApi Class #

class LeetCodeApi {
  static Future<LeetCodeData> fetchUserCalendar(
    String username, {
    int? year,
  }) async {
    // Your API implementation here
    // Return LeetCodeData object
  }
}

LeetCodeData Model #

class LeetCodeData {
  final int totalActiveDays;
  final int streak;
  final Map<dynamic, dynamic> submissionCalendar;

  LeetCodeData({
    required this.totalActiveDays,
    required this.streak,
    required this.submissionCalendar,
  });
}

📱 Responsive Design #

The widget automatically adapts to different screen sizes:

// For mobile devices
LeetCodeHeatmap(
  username: 'your-username',
  cellSize: 10.0,
  showDayLabels: false,
  showMonthLabels: true,
)

// For tablets/desktop
LeetCodeHeatmap(
  username: 'your-username',
  cellSize: 14.0,
  showDayLabels: true,
  showMonthLabels: true,
  weekSpacing: 3.0,
)

🔄 Refresh Functionality #

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final GlobalKey<_LeetCodeHeatmapState> _heatmapKey = GlobalKey();

  void _refreshHeatmap() {
    _heatmapKey.currentState?.refresh();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        LeetCodeHeatmap(
          key: _heatmapKey,
          username: 'your-username',
        ),
        ElevatedButton(
          onPressed: _refreshHeatmap,
          child: Text('Refresh'),
        ),
      ],
    );
  }
}

🎯 Complete Example #

import 'package:flutter/material.dart';
import 'package:your_app/widgets/leetcode_heatmap.dart';

class LeetCodeProfilePage extends StatelessWidget {
  final String username;

  const LeetCodeProfilePage({
    Key? key,
    required this.username,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('$username\'s LeetCode Activity'),
        backgroundColor: Colors.green[700],
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'Coding Activity',
                style: Theme.of(context).textTheme.headlineSmall?.copyWith(
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 16),
              LeetCodeHeatmap(
                username: username,
                cellSize: 14.0,
                cellSpacing: 2.0,
                showMonthLabels: true,
                showDayLabels: true,
                colors: [
                  Colors.grey[100]!,
                  Colors.green[200]!,
                  Colors.green[400]!,
                  Colors.green[600]!,
                  Colors.green[800]!,
                ],
                statsTextStyle: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.w500,
                ),
                tooltipFormatter: (count, date) {
                  if (count == 0) return 'No submissions on ${date.day}/${date.month}';
                  return '$count problem${count > 1 ? 's' : ''} solved on ${date.day}/${date.month}/${date.year}';
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

🐛 Troubleshooting #

Common Issues #

  1. ScrollController Error: Make sure you're not reusing scroll controllers
  2. API Connection: Verify your LeetCode API implementation
  3. Data Format: Ensure submission calendar data is in the correct format
  4. Performance: For large datasets, consider implementing data pagination

Performance Tips #

  • Use appropriate cellSize for your screen size
  • Implement data caching in your API layer
  • Consider using enableAnimation: false for better performance on older devices

📄 License #

This widget is open source and available under the MIT License.

🤝 Contributing #

Contributions are welcome! Please feel free to submit issues and pull requests.

📞 Support #

If you encounter any issues or have questions, please create an issue in the repository.


Happy Coding! 🚀

2
likes
115
points
35
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter widget to display a GitHub-style heatmap of LeetCode submissions using the LeetCode GraphQL API.

Documentation

API reference

License

MIT (license)

Dependencies

flutter, http

More

Packages that depend on leetcode_heatmap