Overview
The Statistics screen provides detailed analytics with interactive charts, graphs, and comprehensive reporting tools for data-driven decision making.
Statistics Screen
Access advanced analytics from the admin panel’s Statistics tab:
admin/presentation/screens/statistics_screen.dart
class StatisticsScreen extends StatefulWidget {
final int adminId;
const StatisticsScreen({
super.key,
required this.adminId,
});
}
Time Period Selection
Filter reports by customizable time periods:
View metrics for the last week - ideal for short-term trends
Monthly overview for medium-term analysis
Complete historical data since platform launch
Period Selector Implementation
admin/presentation/screens/statistics_screen.dart
Widget _buildPeriodSelector() {
return Container(
decoration: BoxDecoration(
color: _surfaceColor.withValues(alpha: 0.8),
borderRadius: BorderRadius.circular(16),
),
child: Row(
children: [
_buildPeriodButton('7 días', '7d'),
_buildPeriodButton('30 días', '30d'),
_buildPeriodButton('Todo', 'all'),
],
),
);
}
Widget _buildPeriodButton(String label, String value) {
final isSelected = _selectedPeriod == value;
return Expanded(
child: GestureDetector(
onTap: () {
setState(() => _selectedPeriod = value);
_loadStats();
},
child: Container(
decoration: BoxDecoration(
color: isSelected ? _primaryColor : Colors.transparent,
borderRadius: BorderRadius.circular(12),
),
child: Text(label),
),
),
);
}
Registration Trends Chart
Visualize new user registrations over time with an interactive line chart:
Chart Data Structure
{
"registros_ultimos_7_dias": [
{"fecha": "2026-02-28", "cantidad": 35},
{"fecha": "2026-03-01", "cantidad": 42},
{"fecha": "2026-03-02", "cantidad": 38},
{"fecha": "2026-03-03", "cantidad": 51},
{"fecha": "2026-03-04", "cantidad": 47},
{"fecha": "2026-03-05", "cantidad": 55},
{"fecha": "2026-03-06", "cantidad": 49}
]
}
Line Chart Implementation
admin/presentation/screens/statistics_screen.dart
Widget _buildRegistrosChart() {
final registros = _stats?['registros_ultimos_7_dias'] ?? [];
return Container(
padding: const EdgeInsets.all(24),
child: Column(
children: [
Text('Registros Recientes', style: TextStyle(fontSize: 18)),
SizedBox(
height: 200,
child: LineChart(
LineChartData(
gridData: FlGridData(show: true, drawVerticalLine: false),
lineBarsData: [
LineChartBarData(
spots: _getChartSpots(registros),
isCurved: true,
color: _primaryColor,
barWidth: 3,
dotData: FlDotData(show: true),
belowBarData: BarAreaData(
show: true,
color: _primaryColor.withValues(alpha: 0.1),
),
),
],
),
),
),
],
),
);
}
List<FlSpot> _getChartSpots(List<dynamic> registros) {
return List.generate(
registros.length,
(index) {
final cantidad = int.tryParse(registros[index]['cantidad']?.toString() ?? '0') ?? 0;
return FlSpot(index.toDouble(), cantidad.toDouble());
},
);
}
Metrics Grid
A comprehensive grid displaying key platform statistics:
Total Users
All registered users on the platform
Total Clients
Passenger accounts (ride requesters)
Total Drivers
Active driver accounts
Trip Requests
All trip requests (completed, cancelled, in progress)
Stat Card Implementation
admin/presentation/screens/statistics_screen.dart
Widget _buildStatsGrid() {
final users = _stats?['usuarios'] ?? {};
final solicitudes = _stats?['solicitudes'] ?? {};
return GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
childAspectRatio: 1.5,
children: [
_buildStatCard(
'Total Usuarios',
users['total_usuarios']?.toString() ?? '0',
Icons.people_rounded,
_statCardColor1,
),
_buildStatCard(
'Clientes',
users['total_clientes']?.toString() ?? '0',
Icons.person_rounded,
_statCardColor2,
),
_buildStatCard(
'Conductores',
users['total_conductores']?.toString() ?? '0',
Icons.local_taxi_rounded,
_statCardColor3,
),
_buildStatCard(
'Solicitudes',
solicitudes['total_solicitudes']?.toString() ?? '0',
Icons.receipt_long_rounded,
_statCardColor4,
),
],
);
}
Trip Distribution Chart
Interactive pie chart showing the breakdown of trip statuses:
Distribution Data
{
"solicitudes": {
"completadas": 5200,
"canceladas": 540,
"en_proceso": 100
}
}
Pie Chart Implementation
admin/presentation/screens/statistics_screen.dart
Widget _buildDistributionChart() {
final solicitudes = _stats?['solicitudes'] ?? {};
final completadas = int.tryParse(solicitudes['completadas']?.toString() ?? '0') ?? 0;
final canceladas = int.tryParse(solicitudes['canceladas']?.toString() ?? '0') ?? 0;
final enProceso = int.tryParse(solicitudes['en_proceso']?.toString() ?? '0') ?? 0;
final total = completadas + canceladas + enProceso;
return PieChart(
PieChartData(
sectionsSpace: 2,
centerSpaceRadius: 40,
sections: [
PieChartSectionData(
value: completadas.toDouble(),
title: '${((completadas / total) * 100).toStringAsFixed(0)}%',
color: _statCardColor2, // Green
radius: 50,
),
PieChartSectionData(
value: canceladas.toDouble(),
title: '${((canceladas / total) * 100).toStringAsFixed(0)}%',
color: _statCardColor3, // Red
radius: 50,
),
PieChartSectionData(
value: enProceso.toDouble(),
title: '${((enProceso / total) * 100).toStringAsFixed(0)}%',
color: _primaryColor, // Yellow
radius: 50,
),
],
),
);
}
Chart Legend
admin/presentation/screens/statistics_screen.dart
Widget _buildLegendItem(String label, int value, Color color) {
return Row(
children: [
Container(
width: 12,
height: 12,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(3),
),
),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(label, style: TextStyle(fontSize: 11)),
Text(value.toString(), style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
],
),
],
);
}
Chart Color Coding
| Status | Color | Hex Code | Meaning |
|---|
| Completadas | Green | #11998e | Successfully finished trips |
| Canceladas | Red | #f5576c | Cancelled or failed trips |
| En Proceso | Yellow | #FFFF00 | Currently active trips |
Data Refresh
Pull to Refresh
Swipe down to manually reload all statistics
Period Change
Changing the time period automatically refreshes data
Navigation Refresh
Statistics reload when navigating back to the tab
Loading States
The statistics screen implements shimmer loading for all chart components:
admin/presentation/screens/statistics_screen.dart
Widget _buildShimmerLoading() {
return SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
children: [
_buildShimmerBox(height: 60),
_buildShimmerBox(height: 300),
GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
children: List.generate(4, (_) => _buildShimmerBox(height: 100)),
),
_buildShimmerBox(height: 200),
],
),
),
);
}
Empty State Handling
admin/presentation/screens/statistics_screen.dart
Widget _buildEmptyState() {
return Container(
padding: const EdgeInsets.all(40),
child: Column(
children: [
Icon(Icons.bar_chart_rounded, color: Colors.white30, size: 40),
const SizedBox(height: 16),
Text('No hay datos disponibles'),
Text('Las estadísticas aparecerán aquí'),
],
),
);
}
Animation System
Smooth animations enhance the user experience:
admin/presentation/screens/statistics_screen.dart
void _setupAnimations() {
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 600),
);
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(parent: _animationController, curve: Curves.easeOut),
);
_slideAnimation = Tween<Offset>(
begin: const Offset(0, 0.1),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _animationController,
curve: Curves.easeOutCubic,
));
}
All charts are interactive - tap on data points for detailed information.
Export Options
Export functionality is planned for future releases. Currently, you can take screenshots of charts for reporting.
Best Practices
Check statistics weekly to identify trends in user growth and trip activity.
Use different time periods to compare performance across weeks, months, and overall.
Monitor the cancellation rate - a high percentage may indicate service issues.
Use the registration chart to measure marketing campaign effectiveness.
Dashboard
Quick metrics overview
Audit Logs
Detailed activity tracking
Trip Monitoring
Real-time trip tracking