/** * Graphique montrant l'évolution des compteurs de requêtes * - En file d'attente * - Traitées (requêtes qui sont passées par le serveur) * - Sorties (requêtes qui ont quitté le serveur) */ import { useMemo } from 'react'; import { Box, Typography, Paper } from '@mui/material'; import { TrendingUp as TrendingUpIcon, MenuBook as MenuBookIcon } from '@mui/icons-material'; import { Line } from 'react-chartjs-2'; import { useSimulationStore } from '../../store/simulationStore'; import { formatTime } from '../../utils/timeFormat'; export default function RequestCountersChart() { const { simulationResults, timeUnit } = useSimulationStore(); const chartData = useMemo(() => { if (!simulationResults?.time_series) return null; const { timestamps, cumulative_arrivals_per_queue, cumulative_departures_per_queue, customers_per_queue } = simulationResults.time_series; if (!timestamps || timestamps.length === 0) return null; if (!cumulative_arrivals_per_queue || !cumulative_departures_per_queue) return null; const datasets = []; // Couleurs pour les différents types de compteurs const colors = { waiting: { border: 'rgb(156, 39, 176)', bg: 'rgba(156, 39, 176, 0.5)' }, // Violet/Magenta treated: { border: 'rgb(76, 175, 80)', bg: 'rgba(76, 175, 80, 0.5)' }, // Vert arrivals: { border: 'rgb(33, 150, 243)', bg: 'rgba(33, 150, 243, 0.5)' }, // Bleu }; // Pour chaque queue (coordinateur + serveurs) const queueIds = Object.keys(cumulative_arrivals_per_queue); queueIds.forEach((queueId) => { const arrivalsData = cumulative_arrivals_per_queue[queueId]; const departuresData = cumulative_departures_per_queue[queueId]; const customersData = customers_per_queue[queueId]; if (!arrivalsData || !departuresData) return; // Créer les datasets pour cette queue const label = queueId === 'coordinator' ? 'Coordinateur' : queueId.replace('_', ' '); // En file d'attente (nombre de clients dans la queue) datasets.push({ label: `${label} - En file`, data: customersData, borderColor: colors.waiting.border, backgroundColor: colors.waiting.bg, borderWidth: 0, fill: false, tension: 0, pointRadius: 2, pointHoverRadius: 5, showLine: false, // Nuage de points uniquement yAxisID: 'y', }); // Requêtes traitées (sorties) datasets.push({ label: `${label} - Traitées`, data: departuresData, borderColor: colors.treated.border, backgroundColor: colors.treated.bg, borderWidth: 0, fill: false, tension: 0, pointRadius: 2, pointHoverRadius: 5, showLine: false, // Nuage de points uniquement yAxisID: 'y', }); // Requêtes arrivées (entrées) datasets.push({ label: `${label} - Sorties`, data: arrivalsData, borderColor: colors.arrivals.border, backgroundColor: colors.arrivals.bg, borderWidth: 0, fill: false, tension: 0, pointRadius: 2, pointHoverRadius: 5, showLine: false, // Nuage de points uniquement yAxisID: 'y', }); }); return { labels: timestamps.map(t => formatTime(t, timeUnit)), datasets, }; }, [simulationResults, timeUnit]); if (!simulationResults) { return null; } // Si les données des compteurs cumulés ne sont pas disponibles, afficher un message if (!chartData) { return ( Évolution des Compteurs de Requêtes Données de compteurs non disponibles Veuillez lancer une nouvelle simulation pour voir les compteurs cumulés. (Les simulations précédentes ne contenaient pas ces données) ); } const options = { responsive: true, maintainAspectRatio: false, interaction: { mode: 'index' as const, intersect: false, }, plugins: { legend: { position: 'top' as const, labels: { usePointStyle: true, padding: 15, boxWidth: 6, }, }, tooltip: { callbacks: { title: (items: any[]) => { if (items.length > 0) { return `Temps: ${items[0].label}`; } return ''; }, label: (context: any) => { return `${context.dataset.label}: ${context.parsed.y} requêtes`; }, }, }, }, scales: { x: { title: { display: true, text: `Temps (${timeUnit})`, font: { size: 13, weight: 'bold' as const, }, }, ticks: { maxTicksLimit: 10, }, }, y: { title: { display: true, text: 'Nombre de requêtes', font: { size: 13, weight: 'bold' as const, }, }, beginAtZero: true, ticks: { precision: 0, }, }, }, }; return ( Évolution des Compteurs de Requêtes {/* Graphique */} {/* Explications */} Légende: En file d'attente: Requêtes en attente de traitement Traitées: Requêtes ayant terminé le traitement Sorties: Requêtes arrivées dans la file Note: Ces courbes correspondent aux résultats 7 et 8 du sujet (compteurs de requêtes). ); }