Files
personal-portfolio/docs/project-lessons-learned/sprint-9-10-figure-factory-pattern.md
lmiranda c9cf744d84 feat: Complete Phase 5 dashboard implementation
Implement full 5-tab Toronto Neighbourhood Dashboard with real data
connectivity:

Dashboard Structure:
- Overview tab with livability scores and rankings
- Housing tab with affordability metrics
- Safety tab with crime statistics
- Demographics tab with population/income data
- Amenities tab with parks, schools, transit

Figure Factories (portfolio_app/figures/):
- bar_charts.py: ranking, stacked, horizontal bars
- scatter.py: scatter plots, bubble charts
- radar.py: spider/radar charts
- demographics.py: donut, age pyramid, income distribution

Service Layer (portfolio_app/toronto/services/):
- neighbourhood_service.py: queries dbt marts for all tab data
- geometry_service.py: generates GeoJSON from PostGIS
- Graceful error handling when database unavailable

Callbacks (portfolio_app/pages/toronto/callbacks/):
- map_callbacks.py: choropleth updates, map click handling
- chart_callbacks.py: supporting chart updates
- selection_callbacks.py: dropdown handlers, KPI updates

Data Pipeline (scripts/data/):
- load_toronto_data.py: orchestration script with CLI flags

Lessons Learned:
- Graceful error handling in service layers
- Modular callback structure for multi-tab dashboards
- Figure factory pattern for reusable charts

Closes: #64, #65, #66, #67, #68, #69, #70

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 11:46:18 -05:00

1.8 KiB

Sprint 9-10 - Figure Factory Pattern for Reusable Charts

Context

Creating multiple chart types across 5 dashboard tabs, with consistent styling and behavior needed across all visualizations.

Problem

Without a standardized approach, each callback would create figures inline with:

  • Duplicated styling code (colors, fonts, backgrounds)
  • Inconsistent hover templates
  • Hard-to-maintain figure creation logic
  • No reuse between tabs

Solution

Created a figures/ module with factory functions:

figures/
├── __init__.py           # Exports all factories
├── choropleth.py         # Map visualizations
├── bar_charts.py         # ranking_bar, stacked_bar, horizontal_bar
├── scatter.py            # scatter_figure, bubble_chart
├── radar.py              # radar_figure, comparison_radar
└── demographics.py       # age_pyramid, donut_chart

Factory pattern benefits:

  1. Consistent styling - dark theme applied once
  2. Type-safe interfaces - clear parameters for each chart type
  3. Easy testing - factories can be unit tested with sample data
  4. Reusability - same factory used across multiple tabs

Example factory signature:

def create_ranking_bar(
    data: list[dict],
    name_column: str,
    value_column: str,
    title: str = "",
    top_n: int = 5,
    bottom_n: int = 5,
    top_color: str = "#4CAF50",
    bottom_color: str = "#F44336",
) -> go.Figure:

Prevention

  • Create factories early - before implementing callbacks
  • Design generic interfaces - factories should work with any data matching the schema
  • Apply styling in one place - use constants for colors, fonts
  • Test factories independently - with synthetic data before integration

Tags

plotly, dash, design-patterns, python, visualization, reusability, code-organization