// 中间件概览图表 — 状态 + 命中率 + QPS/连接(支持放大)// Logan.Li import { useMemo, type ReactNode } from 'react'; import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, Cell, PieChart, Pie, } from 'recharts'; import { Card, CardContent } from '@/components/ui/card'; import { BarChart3, PieChart as PieChartIcon, Percent } from 'lucide-react'; import type { MwTarget } from './helpers'; import { fmtHitRate, fmtVal } from './helpers'; import { ChartExpandShell } from '../shared/ChartExpandShell'; import { MonitorChartTooltip, MONITOR_PIE_STROKE, MonitorPieTooltip } from '../shared/monitorChartTheme'; import { useTranslation } from 'react-i18next'; interface Props { targets: MwTarget[]; } function shortName(name: string) { return name.length > 10 ? `${name.slice(0, 10)}…` : name; } export function MwOverviewCharts({ targets }: Props) { const { t } = useTranslation(); const statusData = useMemo(() => { const online = targets.filter((tg) => tg.status === 'online').length; const offline = targets.length - online; return [ { name: t('agent.agentOnline'), value: online, fill: 'var(--dg-green)' }, { name: t('agent.agentOffline'), value: offline, fill: 'var(--dg-red)' }, ].filter((d) => d.value > 0); }, [targets, t]); const redisHitData = useMemo(() => targets .filter((tg) => tg.description === 'redis' && tg.latest_metrics?.redis_hit_rate > 0) .map((tg) => ({ name: shortName(tg.name), fullName: tg.name, value: (tg.latest_metrics.redis_hit_rate || 0) * 100, fill: (tg.latest_metrics.redis_hit_rate || 0) >= 0.9 ? 'var(--dg-green)' : 'var(--dg-yellow)', })) .sort((a, b) => a.value - b.value), [targets]); const redisQpsData = useMemo(() => targets .filter((tg) => tg.description === 'redis' && tg.latest_metrics?.redis_qps > 0) .map((tg) => ({ name: shortName(tg.name), fullName: tg.name, value: tg.latest_metrics.redis_qps, fill: 'var(--dg-blue)' })) .sort((a, b) => b.value - a.value), [targets]); const mysqlConnData = useMemo(() => targets .filter((tg) => tg.description === 'mysql' && tg.latest_metrics?.mysql_connections > 0) .map((tg) => ({ name: shortName(tg.name), fullName: tg.name, value: tg.latest_metrics.mysql_connections, fill: 'var(--dg-blue)' })) .sort((a, b) => b.value - a.value), [targets]); if (targets.length === 0) return null; return (