Technical Documentation - dlangkip/epidash GitHub Wiki

Technical Documentation

This document provides technical details about EpiDash's architecture, code organization, and implementation. It's intended for developers who want to understand, extend, or contribute to the project.

Architecture Overview

EpiDash follows a modular frontend-backend architecture with clear separation of concerns:

Architecture Diagram

Note: Upload an architecture diagram to your wiki for better visualization

Core Components

  1. User Interface Layer

    • HTML/CSS frontend with responsive design
    • Client-side rendering of visualizations
    • User interaction handling
  2. Client Logic Layer

    • JavaScript modules for application functionality
    • Chart generation and management
    • State management and filter processing
  3. API Layer

    • RESTful endpoints for data retrieval
    • Parameter handling and validation
    • Data formatting and response generation
  4. Data Layer

    • PHP-based data processing
    • Mock data generation
    • Database integration (optional)
  5. Storage Layer

    • MySQL database schema (for database mode)
    • File-based configuration

Directory Structure

epidash/
  ├── api/                    # Backend API files
  │   ├── .env.example        # Environment variables template
  │   ├── config.php          # Configuration handling
  │   ├── connection.php      # Database connection management
  │   ├── get_data.php        # Main data retrieval endpoint
  │   └── process_data.php    # Data processing functions
  │
  ├── assets/                 # Frontend assets
  │   ├── css/                # Stylesheet files
  │   │   ├── dashboard.css   # Dashboard-specific styles
  │   │   └── style.css       # Global styles
  │   │
  │   ├── img/                # Image resources
  │   │   ├── favicon.svg     # Browser favicon
  │   │   ├── logo.svg        # Application logo
  │   │   └── ...             # Other images
  │   │
  │   └── js/                 # JavaScript modules
  │       ├── charts.js       # Chart initialization and updates
  │       ├── filters.js      # Filter handling logic
  │       ├── main.js         # Core application logic
  │       └── map.js          # Map initialization and updates
  │
  ├── data/                   # Data files and generators
  │   ├── disease_data.php    # Disease data generator
  │   └── regions.php         # Region data definitions
  │
  ├── database/               # Database files
  │   └── epidash.sql         # Database schema and seed data
  │
  ├── includes/               # Reusable PHP components
  │   ├── footer.php          # Page footer template
  │   ├── header.php          # Page header template
  │   └── sidebar.php         # Sidebar template
  │
  ├── .htaccess               # Apache server configuration
  └── index.php               # Main application entry point

Key Files and Their Purpose

Backend Files

File Purpose
api/config.php Loads environment variables, defines constants, sets up error handling
api/connection.php Manages database connections and includes mock data generation
api/get_data.php Primary API endpoint that handles data retrieval requests
api/process_data.php Contains functions for filtering, grouping, and calculating metrics

Data Flow

The application follows this data flow pattern:

  1. User Interaction

    • User selects filters or date ranges
    • JavaScript event handlers capture these interactions
    • State is updated in the dashboardState object
  2. Data Request

    • Frontend makes AJAX requests to the API
    • Requests include filter parameters
    • get_data.php processes these requests
  3. Data Processing

    • API retrieves raw data (mock or database)
    • Filters are applied server-side
    • Data is grouped if requested (daily, weekly, etc.)
  4. Response Handling

    • Frontend receives JSON response
    • Data is processed client-side for visualization
    • UI components are updated with new data
  5. Visualization Update

    • Chart.js instances are updated with new datasets
    • Leaflet map is refreshed with new region data
    • Tables and metrics are recalculated

State Management

EpiDash uses a centralized state object in main.js called dashboardState. This object contains:

const dashboardState = {
    filters: {
        // Current filter settings
    },
    data: {
        raw: null,      // Original unfiltered data
        filtered: null, // Data after applying filters
        metrics: {      // Calculated metrics
            // Metric values
        }
    },
    pagination: {
        // Pagination state for data tables
    },
    charts: {
        // References to Chart.js instances
    }
};

This state management approach:

  • Centralizes application data
  • Makes filter application consistent
  • Simplifies chart updates
  • Allows for future enhancements like state persistence

API Endpoints

GET /api/get_data.php

Retrieves epidemiological data based on provided parameters.

Parameters:

  • source (string): Data source to use ('mock', 'database', or 'both')
  • start_date (string): Start date in YYYY-MM-DD format
  • end_date (string): End date in YYYY-MM-DD format
  • disease (string, optional): Filter by specific disease
  • region (string, optional): Filter by specific region

Response:

[
  {
    "date": "2023-01-15",
    "region": "Nairobi",
    "disease": "Malaria",
    "age_group": "25-44",
    "gender": "female",
    "cases": 45,
    "recoveries": 40,
    "deaths": 1,
    "active": 4
  },
  // Additional records...
]

GET /api/config_status.php

Retrieves configuration settings safe for client exposure.

Response:

{
  "defaultDataSource": "mock",
  "allowSourceSwitching": true,
  "availableSources": ["mock", "database", "both"],
  "version": "1.0.0",
  "appName": "EpiDash"
}

Mock Data Generation

The system generates realistic mock data in connection.php through the generateMockData() function. This data generator:

  1. Uses realistic disease distributions based on Kenya's epidemiological profile
  2. Incorporates seasonality patterns for applicable diseases
  3. Distributes cases across regions according to population density
  4. Creates age and gender distributions that reflect real-world patterns
  5. Calculates realistic recovery and mortality rates based on disease characteristics

This approach provides realistic data visualization without requiring a database connection.

Database Schema

When using the database mode, EpiDash uses the following core tables:

Regions Table

CREATE TABLE regions (
    region_code VARCHAR(10) PRIMARY KEY,
    region_name VARCHAR(100) NOT NULL,
    latitude DECIMAL(10, 8) NULL,
    longitude DECIMAL(11, 8) NULL,
    population INT UNSIGNED NULL
);

Diseases Table

CREATE TABLE diseases (
    disease_id INT AUTO_INCREMENT PRIMARY KEY,
    disease_name VARCHAR(100) NOT NULL,
    category VARCHAR(50) NULL,
    is_seasonal BOOLEAN DEFAULT FALSE
);

Epidemiological Data Table

CREATE TABLE epidemiological_data (
    data_id BIGINT AUTO_INCREMENT PRIMARY KEY,
    date_recorded DATE NOT NULL,
    region_code VARCHAR(10) NOT NULL,
    disease_id INT NOT NULL,
    age_group_id INT NOT NULL,
    gender ENUM('male', 'female', 'other') NOT NULL,
    cases INT UNSIGNED NOT NULL DEFAULT 0,
    recoveries INT UNSIGNED NOT NULL DEFAULT 0,
    deaths INT UNSIGNED NOT NULL DEFAULT 0,
    active INT UNSIGNED NOT NULL DEFAULT 0,
    FOREIGN KEY (region_code) REFERENCES regions(region_code),
    FOREIGN KEY (disease_id) REFERENCES diseases(disease_id),
    FOREIGN KEY (age_group_id) REFERENCES age_groups(age_group_id)
);

See the complete schema in database/epidash.sql including additional tables and relationships.

Visualization Implementation

Chart.js Implementation

EpiDash uses Chart.js for all chart visualizations. Key implementation details:

  1. Chart Initialization

    • Charts are initialized in charts.js with baseline configurations
    • Each chart has a dedicated initialization function (e.g., initializeTrendsChart())
  2. Dynamic Updates

    • Chart updates occur when filters change or new data arrives
    • Update functions rebuild datasets while preserving chart instances
  3. Chart Types Used

    • Line charts for time-series data (trends, recovery timeline)
    • Bar charts for comparisons (regional distribution)
    • Pie charts for proportional data (age distribution)

Leaflet.js for Geographic Visualization

The map functionality leverages Leaflet.js with these key features:

  1. Choropleth Implementation

    • Regions colored based on case counts
    • Color scale provides intuitive visualization of intensity
  2. Interactive Elements

    • Hover states show region name and case count
    • Click events zoom to specific regions
    • Pan and zoom controls for map navigation
  3. GeoJSON Integration

    • Region boundaries loaded from GeoJSON file
    • Data dynamically bound to geographic features

Performance Considerations

EpiDash implements several optimizations for smooth performance:

  1. Data Processing Efficiency

    • Server-side filtering reduces data transfer
    • Client-side state management minimizes API calls
  2. Pagination

    • Table data is paginated to handle large datasets
    • Only visible page data is rendered
  3. Responsiveness

    • CSS is optimized for minimal reflows
    • Debounced event handlers prevent excessive processing
  4. Asset Loading

    • CSS and JavaScript files are organized for efficient loading
    • External libraries loaded from CDNs with appropriate caching

Extending the Dashboard

Adding a New Visualization

To add a new chart type:

  1. Create initialization function in charts.js:

    function initializeNewChart() {
        const ctx = document.getElementById('new-chart').getContext('2d');
        dashboardState.charts.newChart = new Chart(ctx, {
            // Chart configuration
        });
    }
    
  2. Add update function:

    function updateNewChart() {
        const { filtered } = dashboardState.data;
        const chart = dashboardState.charts.newChart;
    
    // Process data and update chart
    chart.update();
    

    }

  3. Add function calls in main.js:

    function initializeCharts() {
        // Existing initializations
        initializeNewChart();
    }
    

    function updateCharts() { // Existing updates updateNewChart(); }

  4. Add HTML canvas in index.php:

    <div class="chart-container">
        <h2>New Visualization</h2>
        <div class="chart-wrapper">
            <canvas id="new-chart"></canvas>
        </div>
    </div>
    

Adding a New Filter

To add a new filter type:

  1. Add HTML in sidebar.php:

    <div class="filter-group">
        <label for="new-filter">New Filter:</label>
        <select id="new-filter" class="filter-control">
            <option value="all">All Options</option>
            <option value="option1">Option 1</option>
            <option value="option2">Option 2</option>
        </select>
    </div>
    
  2. Update the state object in main.js:

    const dashboardState = {
        filters: {
            // Existing filters
            newFilter: 'all'
        },
        // Rest of state
    };
    
  3. Add event listener in setupEventListeners():

    document.getElementById('new-filter').addEventListener('change', event => {
        dashboardState.filters.newFilter = event.target.value;
    });
    
  4. Update the filter logic in applyFilters():

    function applyFilters() {
        // Existing filter logic
    
    // Add new filter condition
    if (newFilter !== 'all') {
        filtered = filtered.filter(item =&gt; item.newFilterProperty === newFilter);
    }
    

    }

Browser Compatibility

EpiDash is designed to work with:

  • Chrome 70+
  • Firefox 60+
  • Safari 12+
  • Edge 79+
  • Opera 60+

The dashboard may work on older browsers but with limited functionality or visual inconsistencies.

Security Considerations

The dashboard implements several security measures:

  1. Input Validation

    • All API parameters are validated before use
    • Dates are checked for proper format
    • Numeric values are validated
  2. Output Sanitization

    • Data is sanitized before returned to the client
    • HTML special characters are escaped
  3. Environment Variables

    • Sensitive configuration is stored in .env files
    • .env files are excluded from version control
  4. Error Handling

    • Errors are logged but not exposed to clients in production
    • Custom error messages prevent information disclosure

Known Limitations

Current limitations that developers should be aware of:

  1. No authentication system is implemented (planned for future)
  2. Large datasets may cause performance issues in the browser
  3. Mobile view has limited functionality on very small screens
  4. No offline mode support
  5. Limited browser storage utilization for persistent state

Future Development Considerations

Areas for potential technical enhancement:

  1. Frontend Framework

    • Consider migrating to React or Vue for more complex UI requirements
    • Implement component-based architecture
  2. Backend Enhancements

    • Add caching layer for improved performance
    • Implement GraphQL for more flexible data queries
  3. Data Processing

    • Add support for more advanced statistical analysis
    • Implement predictive modeling capabilities
  4. Security

    • Add user authentication and authorization
    • Implement API rate limiting

Contributing Guidelines

When contributing to EpiDash, please follow these technical guidelines:

  1. Follow the existing code style and organization
  2. Add comments to explain complex logic
  3. Create unit tests for new functionality
  4. Keep dependencies minimal and justified
  5. Document API changes in this technical documentation

For more information on contributing, see the Contributing Guidelines page.

Troubleshooting Development Issues

API Returns No Data

Possible causes and solutions:

  • Check your .env configuration
  • Verify database connectivity if using database mode
  • Ensure date ranges are valid
  • Check server error logs for PHP errors

Visualization Not Rendering

Possible causes and solutions:

  • Check browser console for JavaScript errors
  • Verify the canvas element exists with correct ID
  • Ensure data is being correctly formatted for Chart.js
  • Test with a simple static dataset to isolate the issue

Changes Not Reflecting

Possible causes and solutions:

  • Clear browser cache or use private browsing
  • Check if your web server has caching enabled
  • Verify file paths and includes
  • Check for JavaScript console errors

Further References

For more information on the technologies used:

⚠️ **GitHub.com Fallback** ⚠️