contribution_heatmap 0.3.2 copy "contribution_heatmap: ^0.3.2" to clipboard
contribution_heatmap: ^0.3.2 copied to clipboard

A high-performance, GitHub-like contribution heatmap calendar widget for Flutter. Built with a custom RenderBox for maximum efficiency and full customization.

Contribution Heatmap #

License: BSD-3-Clause Pub Version Pub Likes Pub Monthly Downloads Github Stars Github Open Isssues Github Pull Request Github Last Commit X (formerly Twitter) Follow

A high-performance, GitHub-like contribution heatmap widget for Flutter. This widget provides a visual representation of contribution data over time, similar to GitHub's contribution graph with proper i18n support and intelligent month separation.

Contribution Heatmap minimal Screenshot Contribution Heatmap with splittdMonthView and showDate

✨ Features #

  • πŸš€ Ultra-High Performance: Custom RenderBox implementation with optimized rendering pipeline
  • πŸ‘† Interactive: Full tap support with proper hit testing and gesture handling
  • 🎨 Fully Customizable: Colors, sizing, labels, and layout options
  • πŸ“… Split Month View: Visual month separation with intelligent empty cell insertion
  • πŸ“Š Cell Date Display: NEW! Show day numbers inside contribution cells
  • β™Ώ Accessibility Ready: Supports text scaling and high contrast modes
  • 🌍 Internationalized: Locale-aware text rendering with customizable start weekdays
  • πŸ’Ύ Memory Efficient: Optimized data structures minimize memory usage and GC pressure
  • πŸ”§ Smart Invalidation: Only recomputes what's needed, not on every frame

πŸš€ Quick Start #

Basic Usage #

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

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ContributionHeatmap(
      entries: [
        ContributionEntry(DateTime(2025, 8, 15), 5),
        ContributionEntry(DateTime(2025, 8, 16), 3),
        ContributionEntry(DateTime(2025, 8, 17), 8),
        // Add more entries...
      ],
      onCellTap: (date, value) {
        print('Tapped: $date with $value contributions');
      },
    );
  }
}

πŸ“… Split Month View #

Enable clear visual separation between months with intelligent spacing:

ContributionHeatmap(
  entries: myContributionData,
  splittedMonthView: true, // Adds visual gaps between months
  onCellTap: (date, value) {
    print('Tapped: $date with $value contributions');
  },
)

Cell Date Display (NEW!) #

Show day numbers inside each contribution cell for easier date identification:

ContributionHeatmap(
  entries: myContributionData,
  showCellDate: true, // Show date numbers inside cells
  cellSize: 16.0, // Larger cells work better with text
  cellDateTextStyle: TextStyle(
    fontSize: 8,
    color: Colors.white,
    fontWeight: FontWeight.bold,
  ),
  onCellTap: (date, value) {
    print('$date: $value contributions');
  },
)

Advanced Usage #

ContributionHeatmap(
  entries: myContributionData,
  
  // Custom date range
  minDate: DateTime(2025, 1, 1),
  maxDate: DateTime.now(),
  splittedMonthView: true,   // Visual separation between months
  showCellDate: true,        // NEW: Show date numbers in cells
  
  // Visual customization
  cellSize: 16.0,
  cellSpacing: 4.0,
  cellRadius: 3.0,
  padding: EdgeInsets.all(20),
  
  // Custom color scale
  colorScale: (value) {
    if (value == 0) return Colors.grey[100]!;
    if (value <= 2) return Colors.green[200]!;
    if (value <= 5) return Colors.green[400]!;
    return Colors.green[600]!;
  },
  
  // Custom text styles
  monthTextStyle: TextStyle(
    color: Colors.grey[600],
    fontSize: 12,
    fontWeight: FontWeight.w500,
  ),
  weekdayTextStyle: TextStyle(
    color: Colors.grey[500],
    fontSize: 11,
  ),
  cellDateTextStyle: TextStyle(   // NEW: Style for date numbers
    fontSize: 8,
    color: Colors.white,
    fontWeight: FontWeight.bold,
  ),
  
  // Week starts on Sunday (US style)
  startWeekday: DateTime.sunday,
  
  // Handle cell interactions
  onCellTap: (date, value) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('${date.toIso8601String().split('T')[0]}'),
        content: Text('$value contributions on this date'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: Text('Close'),
          ),
        ],
      ),
    );
  },
)

πŸ“Š Data Model #

ContributionEntry #

The Data structure for contribution data:

class ContributionEntry {
  final DateTime date;  // Day-level precision
  final int count;      // Number of contributions (>= 0)
  const ContributionEntry(this.date, this.count);
}

🌍 i18n Support #

Currently, this package supports English (EN) and

  • πŸ‡«πŸ‡· French (fr-FR)
  • πŸ‡©πŸ‡ͺ German (de-DE)
  • πŸ‡ͺπŸ‡Έ Spanish (es-ES)

More languages will be added soon.

Exemple de Contribution Heatmap en franΓ§ais (fr-FR) Exemple de Contribution Heatmap en franΓ§ais (fr-FR)

🎨 Customization Options #

Visual Properties #

Property Type Default Description
cellSize double 12.0 Size of each contribution cell
cellSpacing double 3.0 Spacing between cells
cellRadius double 2.0 Corner radius for rounded cells
padding EdgeInsets EdgeInsets.all(16) Outer padding around widget

Labels & Text #

Property Type Default Description
showMonthLabels bool true Show month names above the heatmap
showWeekdayLabels bool true Show day names on the left
showCellDate bool false NEW! Show date numbers inside cells
cellDateTextStyle TextStyle? null NEW! Custom style for cell date numbers
monthTextStyle TextStyle? null Custom style for month labels
weekdayTextStyle TextStyle? null Custom style for weekday labels

Date & Layout #

Property Type Default Description
minDate DateTime? null Override minimum date (auto-calculated if null)
maxDate DateTime? null Override maximum date (auto-calculated if null)
startWeekday int DateTime.monday First day of week (1=Mon, 7=Sun)
splittedMonthView bool false NEW! Enable visual month separation

Colors & Interaction #

Property Type Default Description
colorScale Color Function(int)? null Custom color mapping function
onCellTap void Function(DateTime, int)? null Callback for cell tap events

⚑ Performance Characteristics #

Rendering Performance #

  • O(1) cell value lookups during painting
  • Custom RenderBox implementation bypasses widget rebuilds
  • Smart invalidation - only recomputes when properties actually change
  • Efficient hit testing with proper bounds checking
  • Optimized split month rendering with minimal computational overhead
  • Intelligent cell date rendering with automatic size detection

Memory Efficiency #

  • HashMap-based data structure for fast lookups
  • Minimal object allocation during painting
  • Proper gesture recognizer cleanup prevents memory leaks
  • Optimized text rendering with cached TextPainter objects
  • Linear date sequence for efficient split month calculations

Scalability #

  • Handles thousands of data points efficiently
  • Constant time complexity for cell rendering
  • Responsive layout adapts to available space
  • Smooth interactions even with large datasets and split months

πŸ“ Contributing #

Feel free to contribute! Check out the guides for more information.

❀️‍πŸ”₯ Enjoying this package? #

Here are a few ways you can show support:

  • ⭐️ Star it on GitHub – stars help others discover it!
  • πŸ‘ Give it a thumbs up on pub.flutter-io.cn – every bit of appreciation counts!
  • πŸ‘‰ Try my TypeFast app, a fun way to sharpen your touch typing skills with games.
  • πŸ‘‰ Explore more of my work!
12
likes
160
points
974
downloads

Publisher

verified publisherabdullah.com.bd

Weekly Downloads

A high-performance, GitHub-like contribution heatmap calendar widget for Flutter. Built with a custom RenderBox for maximum efficiency and full customization.

Repository (GitHub)
View/report issues
Contributing

Topics

#heatmap #heatmap-calendar #contribution-chart #contribution-heatmap

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on contribution_heatmap