Telesport

Angular sports data visualization application

Links & Resources

Source Code

Check out the complete source code and documentation on GitHub.

View Repository
Live Demo

Experience the application in action through the live deployment.

Launch Application

Description

Angular application deployed on GitHub Pages with Olympic sports data visualization and interactive statistics tables.

Telesport is a sports data application developed with Angular that presents Olympic Games statistics, including medal tables and interactive charts.

User interface of Telesport showing the main dashboard and graphical data visualizations of Olympic statistics.

The project leverages several advanced Angular features to provide a smooth and interactive user experience. Data management is fully reactive thanks to the extensive use of Observables and RxJS, allowing real-time updates.

The modular architecture with lazy loading optimizes loading performance, while HTTP interceptors and authentication guards ensure application security. Data visualization is made possible through integration with a powerful charting library.

The main features include:

  • Angular Routing with navigation between sections
  • RxJS data streams for reactive data management
  • Interactive charts for exploring Olympic performance data
  • Responsive design optimized for mobile and desktop devices

Advanced techniques were used to ensure optimal performance:

  • OnPush Change Detection Strategy
  • Intelligent change detection
  • Complex calculations memoization
  • List virtualization to handle large data volumes

You can explore the application deployed on GitHub Pages and check the source code on GitHub.

// Example of Angular service with reactive data management
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable, combineLatest } from 'rxjs';
import { map, shareReplay, switchMap, tap } from 'rxjs/operators';
import { Medal, Country } from '../models/olympic.model';

@Injectable({
  providedIn: 'root'
})
export class OlympicService {
  private apiUrl = 'assets/data/olympic-medals.json';
  private countriesSubject = new BehaviorSubject<string[]>([]);
  private yearsSubject = new BehaviorSubject<number[]>([]);
  
  constructor(private http: HttpClient) {
    this.loadInitialData();
  }
  
  private loadInitialData(): void {
    this.http.get<Medal[]>(this.apiUrl).pipe(
      tap(medals => {
        const countries = [...new Set(medals.map(m => m.country))];
        const years = [...new Set(medals.map(m => m.year))];
        this.countriesSubject.next(countries);
        this.yearsSubject.next(years);
      }),
      shareReplay(1)
    ).subscribe();
  }
  
  getFilteredMedals(): Observable<Medal[]> {
    const countries$ = this.countriesSubject.asObservable();
    const years$ = this.yearsSubject.asObservable();
    
    return combineLatest([
      countries$, 
      years$, 
      this.http.get<Medal[]>(this.apiUrl)
    ]).pipe(
      map(([selectedCountries, selectedYears, allMedals]) => {
        return allMedals.filter(medal => 
          selectedCountries.includes(medal.country) && 
          selectedYears.includes(medal.year)
        );
      })
    );
  }
  
  // Other service methods...
}