local-tool/: visionA-local desktop app
- M1: Wails shell + Go server + Next.js UI + Mock mode (macOS dmg ready)
- M2: i18n (zh-TW/en) + Settings 4-tab refactor
- M3: Embedded Python 3.12 runtime (python-build-standalone) + KneronPLUS wheels
- M4: Windows Inno Setup script (build on Windows runner)
- M5: Linux AppImage script + udev rule (build on Linux runner)
- M6: ffmpeg (GPL, pending legal review) + yt-dlp bundled
- Lifecycle: watchServer health check, fatal native dialog,
Wails IPC raise endpoint, stale process cleanup
.autoflow/: full PRD / Design Spec / Architecture / Testing docs
(4 rounds tri-party discussion + cross review)
.github/workflows/: macOS / Windows / Linux build CI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
49 lines
1.6 KiB
TypeScript
49 lines
1.6 KiB
TypeScript
'use client';
|
|
|
|
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, ResponsiveContainer, Cell } from 'recharts';
|
|
import type { ClassResult } from '@/types/inference';
|
|
import { useTranslation } from '@/lib/i18n';
|
|
|
|
interface ClassificationResultProps {
|
|
results: ClassResult[];
|
|
confidenceThreshold: number;
|
|
}
|
|
|
|
const COLORS = ['#8884d8', '#82ca9d', '#ffc658', '#ff7300', '#0088FE', '#00C49F', '#FFBB28', '#FF8042'];
|
|
|
|
export function ClassificationResult({ results, confidenceThreshold }: ClassificationResultProps) {
|
|
const { t } = useTranslation();
|
|
const filtered = results
|
|
.filter((r) => r.confidence >= confidenceThreshold)
|
|
.sort((a, b) => b.confidence - a.confidence)
|
|
.slice(0, 8);
|
|
|
|
const data = filtered.map((r) => ({
|
|
label: r.label,
|
|
confidence: +(r.confidence * 100).toFixed(1),
|
|
}));
|
|
|
|
if (data.length === 0) {
|
|
return (
|
|
<div className="flex h-48 items-center justify-center text-sm text-muted-foreground">
|
|
{t('inference.noResultsAboveThreshold')}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<ResponsiveContainer width="100%" height={250}>
|
|
<BarChart data={data} layout="vertical" margin={{ left: 80, right: 20, top: 5, bottom: 5 }}>
|
|
<CartesianGrid strokeDasharray="3 3" />
|
|
<XAxis type="number" domain={[0, 100]} unit="%" />
|
|
<YAxis type="category" dataKey="label" width={70} fontSize={12} />
|
|
<Bar dataKey="confidence" radius={[0, 4, 4, 0]}>
|
|
{data.map((_, index) => (
|
|
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
|
|
))}
|
|
</Bar>
|
|
</BarChart>
|
|
</ResponsiveContainer>
|
|
);
|
|
}
|