"use client"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Cell, } from "recharts"; interface ModelDistributionChartProps { title: string; subtitle?: string; data: Array<{ name: string; value: number; color?: string; models?: Array<{ name: string; value: number; }>; }>; showLegend?: boolean; totalTokens?: number; } interface TooltipPayload { value: number; payload: { name: string; value: number; color?: string; models?: Array<{ name: string; value: number; }>; }; } // Couleurs par fournisseur selon l'image const providerColors: { [key: string]: string } = { Anthropic: "#7C3AED", // Violet vif OpenAI: "#059669", // Vert turquoise vif "Mistral AI": "#D97706", // Orange vif Meta: "#DB2777", // Rose/Magenta vif Google: "#2563EB", // Bleu vif Cohere: "#0891B2", // Cyan vif }; // Fonction pour regrouper les modèles par fournisseur const groupByProvider = (modelData: Array<{ name: string; value: number }>) => { const providerMap: { [key: string]: { value: number; models: Array<{ name: string; value: number }>; }; } = {}; modelData.forEach((model) => { let provider = ""; // Déterminer le fournisseur basé sur le nom du modèle if ( model.name.toLowerCase().includes("claude") || model.name.toLowerCase().includes("anthropic") ) { provider = "Anthropic"; } else if ( model.name.toLowerCase().includes("gpt") || model.name.toLowerCase().includes("openai") ) { provider = "OpenAI"; } else if (model.name.toLowerCase().includes("mistral")) { provider = "Mistral AI"; } else if ( model.name.toLowerCase().includes("llama") || model.name.toLowerCase().includes("meta") ) { provider = "Meta"; } else if ( model.name.toLowerCase().includes("palm") || model.name.toLowerCase().includes("gemini") || model.name.toLowerCase().includes("google") ) { provider = "Google"; } else if (model.name.toLowerCase().includes("cohere")) { provider = "Cohere"; } else { provider = "Autres"; } if (!providerMap[provider]) { providerMap[provider] = { value: 0, models: [] }; } providerMap[provider].value += model.value; providerMap[provider].models.push(model); }); return Object.entries(providerMap).map(([name, data]) => ({ name, value: data.value, models: data.models, color: providerColors[name] || "#6B7280", })); }; const CustomTooltip = ({ active, payload, }: { active?: boolean; payload?: TooltipPayload[]; }) => { if (active && payload && payload.length) { const data = payload[0].payload; return (

{data.name}

Tokens: {data.value.toLocaleString()}

{data.models && data.models.length > 0 && (

Modèles:

{data.models.slice(0, 5).map((model, index) => (

• {model.name}: {model.value.toLocaleString()}

))} {data.models.length > 5 && (

... et {data.models.length - 5} autres

)}
)}
); } return null; }; export function ModelDistributionChart({ title, subtitle, data, totalTokens, }: ModelDistributionChartProps) { // Si les données sont déjà groupées par fournisseur, les utiliser directement // Sinon, les regrouper automatiquement const groupedData = data[0]?.models ? data : groupByProvider(data); // Créer une liste de tous les modèles avec leurs couleurs const allModels = groupedData.flatMap( (provider) => provider.models?.map((model) => ({ name: model.name, color: provider.color, value: model.value, })) || [] ); return ( {title} {subtitle && (

{subtitle}

)}
{ if (value >= 1000000) return `${(value / 1000000).toFixed(1)}M`; if (value >= 1000) return `${(value / 1000).toFixed(1)}K`; return value.toString(); }} /> } /> {groupedData.map((entry, index) => ( ))} {/* Petites cartes légères pour chaque provider */}
{groupedData.map((item, index) => (

{item.name}

{item.value.toLocaleString()}

tokens

))}
{/* Total général */} {totalTokens && (

Total général:{" "} {totalTokens.toLocaleString()} {" "} tokens

)} {/* Légende dynamique des modèles */} {allModels.length > 0 && (

Modèles utilisés

{allModels .sort((a, b) => b.value - a.value) // Trier par usage décroissant .map((model, index) => (
{model.name}
))}
)}
); }