ExportButton.tsx 3,62 ko
Newer Older
 * Export button component with Material-UI - export results to CSV/JSON.
import { Stack, Button } from '@mui/material';
import { Download as DownloadIcon } from '@mui/icons-material';
import { useSimulationStore } from '../../store/simulationStore';

export default function ExportButton() {
  const { config, simulationResults, analyticalResults, comparisonResults } =
    useSimulationStore();

  const exportToJSON = () => {
    const data = {
      config,
      simulationResults,
      analyticalResults,
      comparisonResults,
      timestamp: new Date().toISOString(),
    };

    const blob = new Blob([JSON.stringify(data, null, 2)], {
      type: 'application/json',
    });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `simulation-results-${Date.now()}.json`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  const exportToCSV = () => {
    if (!simulationResults && !analyticalResults) return;

    let csv = 'Queue,Metric,Simulation,Analytical,Difference %\n';

    // System totals
    if (simulationResults && analyticalResults) {
      csv += `System,Total L,${simulationResults.total_requests_completed},${analyticalResults.total_average_customers},-\n`;
      csv += `System,Total W,${simulationResults.average_system_time},${analyticalResults.total_average_time},-\n`;
    }

    // Coordinator
    if (simulationResults) {
      csv += `Coordinator,Utilization,${simulationResults.coordinator_stats.utilization}`;
      if (analyticalResults) {
        csv += `,${analyticalResults.coordinator.utilization},-`;
      }
      csv += '\n';
      csv += `Coordinator,Wait Time,${simulationResults.coordinator_stats.average_wait_time},-,-\n`;
      csv += `Coordinator,System Time,${simulationResults.coordinator_stats.average_system_time}`;
      if (analyticalResults) {
        csv += `,-,${analyticalResults.coordinator.average_time ?? 0},-`;
      }
      csv += '\n';
    }

    // Servers
    if (simulationResults) {
      Object.entries(simulationResults.server_stats).forEach(([serverId, stats]) => {
        csv += `${serverId},Utilization,${stats.utilization}`;
        if (analyticalResults && analyticalResults.servers[serverId]) {
          csv += `,${analyticalResults.servers[serverId].utilization},-`;
        }
        csv += '\n';
        csv += `${serverId},Wait Time,${stats.average_wait_time},-,-\n`;
        csv += `${serverId},System Time,${stats.average_system_time}`;
        if (analyticalResults && analyticalResults.servers[serverId]) {
          csv += `,${analyticalResults.servers[serverId].average_time ?? 0},-`;
        }
        csv += '\n';
      });
    }

    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `simulation-results-${Date.now()}.csv`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  const hasResults = simulationResults || analyticalResults;

  return (
    <Stack direction="row" spacing={1}>
      <Button
        onClick={exportToJSON}
        disabled={!hasResults}
        variant="contained"
        color="primary"
        size="small"
        startIcon={<DownloadIcon />}
        onClick={exportToCSV}
        disabled={!hasResults}
        variant="contained"
        color="success"
        size="small"
        startIcon={<DownloadIcon />}