Skip to content

Feat: Fix to Yearly Heat Map Instead of Monthly Heat Map#18

Merged
7174Andy merged 2 commits into
mainfrom
feat/yearly-heatmap
Feb 14, 2026
Merged

Feat: Fix to Yearly Heat Map Instead of Monthly Heat Map#18
7174Andy merged 2 commits into
mainfrom
feat/yearly-heatmap

Conversation

@7174Andy
Copy link
Copy Markdown
Owner

@7174Andy 7174Andy commented Feb 14, 2026

Summary

  • Redesign the Heatmap tab from a monthly calendar grid to a GitHub-style yearly heatmap, showing all 365/366 days of a year at a glance with green color intensity based on spending levels
  • Add yearly summary cards below the heatmap displaying Total Spent, Daily Average, and Busiest Day
  • Fix tab refresh so that all tabs (not just Transactions) refresh after a dialog closes (e.g. PDF import), ensuring Statistics and Heatmap show up-to-date data immediately

Changes

Heatmap Tab (heatmap_tab.py) — Full Rewrite

  • Replaced the monthly calendar grid with a compact yearly heatmap (7 rows x 53 columns)
  • 5-level green color palette (#ebedf0 to #216e39) with quartile-based thresholds
  • Day-of-week labels (Mon/Wed/Fri) on the left, month abbreviations along the top
  • Hover tooltips showing exact spending and date
  • Click-to-filter: clicking a day cell navigates to the Transactions tab filtered to that date
  • Less/More legend at bottom-right
  • Year navigation (< >) to browse years with expense data
  • Three summary cards below the heatmap: Total Spent, Daily Average, Busiest Day

Repository (transaction_repository.py)

  • get_daily_spending_for_year(year) — returns daily spending totals keyed by ISO date string
  • get_years_with_expenses() — returns sorted descending list of years that have expense data

Statistics Service (statistics.py)

  • get_yearly_heatmap_data(year) — delegates to the new repository method
  • get_available_years() — delegates to the new repository method

Main Window (main_window.py)

  • Extracted _refresh_active_tab() to refresh whichever tab is currently visible
  • Dialog close handler now calls _refresh_active_tab() instead of hardcoded transactions_tab.refresh()
  • _on_tab_changed() simplified to delegate to _refresh_active_tab()

Test Plan

  • Unit tests for get_daily_spending_for_year() and get_years_with_expenses() in tests/core/test_repository.py
  • Unit tests for get_yearly_heatmap_data() and get_available_years() in tests/services/test_statistics.py
  • Manual: launch app, verify heatmap renders correctly with year navigation
  • Manual: hover over cells to see tooltips, click cells to filter transactions
  • Manual: import a PDF while on Statistics/Heatmap tab, verify data refreshes without needing to switch tabs

@7174Andy 7174Andy merged commit fb04a1f into main Feb 14, 2026
3 checks passed
@7174Andy 7174Andy deleted the feat/yearly-heatmap branch February 14, 2026 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant