Files
ocean-cleanup/src/services/analyticsService.ts
Paul Bailey 82635559db feat: implement data visualization charts for analytics dashboard
- Add TimeSeriesChart component for report trends over time
- Add LitterTypeChart component with pie chart for type distribution
- Add QuantityChart component with bar chart for quantity aggregation
- Update analytics service with new API methods for chart data
- Add new types for chart data structures (TimeSeriesDataPoint, LitterTypeDistribution, QuantityAggregation)
- Integrate charts into AnalyticsPage with responsive grid layout
- Add mock data fallback for development when API is not available
- Configure charts for mobile responsiveness
- Implement comparison metrics display in time series
- Add loading states and empty states for all charts

Implements task 11: Data visualization charts
Requirements: 5.2, 5.3, 5.4
2025-11-16 18:58:01 +00:00

97 lines
2.9 KiB
TypeScript

// Analytics service for API interactions
import { apiClient } from './api';
import type { AnalyticsSummary, TimeSeriesDataPoint, LitterTypeDistribution, QuantityAggregation } from '@/types';
class AnalyticsService {
/**
* Get summary statistics for the analytics dashboard
*/
async getSummary(dateRange?: { start: string; end: string }): Promise<AnalyticsSummary> {
const params = new URLSearchParams();
if (dateRange) {
params.append('startDate', dateRange.start);
params.append('endDate', dateRange.end);
}
const queryString = params.toString();
return apiClient.get<AnalyticsSummary>(`/analytics/summary${queryString ? `?${queryString}` : ''}`);
}
/**
* Get time series data for report trends
*/
async getTimeSeries(dateRange?: { start: string; end: string }): Promise<TimeSeriesDataPoint[]> {
const params = new URLSearchParams();
if (dateRange) {
params.append('startDate', dateRange.start);
params.append('endDate', dateRange.end);
}
const queryString = params.toString();
return apiClient.get<TimeSeriesDataPoint[]>(`/analytics/trends${queryString ? `?${queryString}` : ''}`);
}
/**
* Get litter type distribution data
*/
async getLitterTypeDistribution(dateRange?: { start: string; end: string }): Promise<LitterTypeDistribution[]> {
const params = new URLSearchParams();
if (dateRange) {
params.append('startDate', dateRange.start);
params.append('endDate', dateRange.end);
}
const queryString = params.toString();
return apiClient.get<LitterTypeDistribution[]>(`/analytics/litter-types${queryString ? `?${queryString}` : ''}`);
}
/**
* Get quantity estimation aggregation data
*/
async getQuantityAggregation(dateRange?: { start: string; end: string }): Promise<QuantityAggregation[]> {
const params = new URLSearchParams();
if (dateRange) {
params.append('startDate', dateRange.start);
params.append('endDate', dateRange.end);
}
const queryString = params.toString();
return apiClient.get<QuantityAggregation[]>(`/analytics/quantities${queryString ? `?${queryString}` : ''}`);
}
/**
* Export analytics data to CSV
*/
async exportToCSV(dateRange?: { start: string; end: string }): Promise<Blob> {
const params = new URLSearchParams();
if (dateRange) {
params.append('startDate', dateRange.start);
params.append('endDate', dateRange.end);
}
const queryString = params.toString();
const response = await fetch(
`${import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000/api'}/analytics/export${queryString ? `?${queryString}` : ''}`,
{
method: 'GET',
headers: {
'Accept': 'text/csv',
},
}
);
if (!response.ok) {
throw new Error('Failed to export data');
}
return response.blob();
}
}
export const analyticsService = new AnalyticsService();