Telesport
Angular sports data visualization application
Links & Resources
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.


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...
}